Skip to content

Commit

Permalink
Added PMP32 & PMP64 ACTs
Browse files Browse the repository at this point in the history
  • Loading branch information
UmerShahidengr committed Apr 23, 2024
1 parent 59ae6e7 commit 8ac1a16
Show file tree
Hide file tree
Showing 88 changed files with 21,603 additions and 0 deletions.
702 changes: 702 additions & 0 deletions coverage/pmp32_coverpoint_def_format.cgf

Large diffs are not rendered by default.

1,423 changes: 1,423 additions & 0 deletions coverage/pmp32_translated_coverpoints.cgf

Large diffs are not rendered by default.

702 changes: 702 additions & 0 deletions coverage/pmp64_coverpoint_def_format.cgf

Large diffs are not rendered by default.

1,423 changes: 1,423 additions & 0 deletions coverage/pmp64_translated_coverpoints.cgf

Large diffs are not rendered by default.

146 changes: 146 additions & 0 deletions riscv-test-suite/rv32i_m/pmp32/PMP-CFG-reg.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
// -----------
// Copyright (c) 2020. RISC-V International. All rights reserved.
// SPDX-License-Identifier: BSD-3-Clause
// -----------
//
// This test belongs to the test plan for RISC-V Privilege Arch Compliance developed by 10xEngineers
// which can be found here: https://docs.google.com/spreadsheets/d/1p13gic7BD6aq7n_dHrqti4QmlGpxY7FkF17RVbG4DC0/edit?usp=sharing
//
// This assembly file tests access of pmp registers in M, S, and U mode.
// pmp csrs are accessable only in M-mode so it should trap in S, and U mode.
//
/* COVERPOINTS: (Explanation of updates in /coverage/rv32i_priv.cgf)
pmpcfg0 & 0x20 == 0 : 0 // CHECK IF pmpcfg0[5]==0 (Hard wired zero bit)
pmpcfg0 & 0x40 == 0 : 0 // CHECK IF pmpcfg0[6]==0 (Hard wired zero bit)
pmpcfg0 & 0x80 == 0x80 : 0 // CHECK IF pmpcfg0[7]==1 (Lock bit)
(pmpcfg0 >> 8) & 0x20 == 0 : 0 // CHECK IF pmpcfg0[13]==0 (Hard wired zero bit)
(pmpcfg0 >> 8) & 0x40 == 0 : 0 // CHECK IF pmpcfg0[14]==0 (Hard wired zero bit)
(pmpcfg0 >> 8) & 0x80 == 0x80 : 0 // CHECK IF pmpcfg0[15]==1 (Lock bit)
(pmpcfg0 >> 16) & 0x20 == 0 : 0 // CHECK IF pmpcfg0[21]==0 (Hard wired zero bit)
(pmpcfg0 >> 16) & 0x40 == 0 : 0 // CHECK IF pmpcfg0[22]==0 (Hard wired zero bit)
(pmpcfg0 >> 16) & 0x80 == 0x80 : 0 // CHECK IF pmpcfg0[23]==1 (Lock bit)
(pmpcfg0 >> 24) & 0x20 == 0 : 0 // CHECK IF pmpcfg0[29]==0 (Hard wired zero bit)
(pmpcfg0 >> 24) & 0x40 == 0 : 0 // CHECK IF pmpcfg0[30]==0 (Hard wired zero bit)
(pmpcfg0 >> 24) & 0x80 == 0x80 : 0 // CHECK IF pmpcfg0[31]==1 (Lock bit)
// Same coverpoints are defined for pmpcfg1, pmpcfg2, and pmpcfg3
// Details are given in /coverage/rv32i_priv.cgf
*/
#include "model_test.h"
#include "arch_test.h"
RVTEST_ISA("RV32I_Zicsr")
# Test code region
.section .text.init
.globl rvtest_entry_point
rvtest_entry_point:
RVMODEL_BOOT
RVTEST_CODE_BEGIN

#ifdef TEST_CASE_1
RVTEST_CASE(1,"//check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; def rvtest_strap_routine=True; def TEST_CASE_1=True",pmp_cfg_locked_write_unrelated)
RVTEST_SIGBASE( x3,signature_x3_1)

.attribute unaligned_access, 0
.attribute stack_align, 16
.align 2
.option norvc
#define PMPCFG0 0x3A0 // Address of pmpcfg0 (HAS BEEN USED WHILE ITERATING THE LOOP)
#define PMPADDR0 0x3B0 // Address of pmpaddr0 (HAS BEEN USED WHILE ITERATING THE LOOP)
main:
//////////////////////// INITIAL VALUES ////////////////////////////////
LI(a5, -1) // SEtting up All locked bits (including everyother non-zero bit, which is redundent for this test)
LI(x9,0) // The register to carry offset value
LI(x5, 100) // A rondom number, to check if pmp regs get update after lock bit enable
// Loop to SET ALL pmpcfg REGs to zero
.set pmpcfgi, PMPCFG0 // Initialize an iterating variable with the address of pmpcfg0
.rept 4 // START OF LOOP
csrc pmpcfgi , a5 // Set all pmpcfg regs to zero (initial value)
.set pmpcfgi, pmpcfgi+1 // increment variable to next pmpcfg reg
.endr // END OF LOOP BODY
// Loop to SET ALL pmpaddr REGs to zero
.set pmpaddri, PMPADDR0 // Initialize an iterating variable with the address of pmpaddr0
.rept 16 // START OF LOOP
csrc pmpaddri, a5 // Set all pmpaddr regs to zero (initial value)
.set pmpaddri, pmpaddri+1 // increment variable pmpaddri to the next pmpaddr reg
.endr // END OF LOOP BODY

//////////////////// Locked bit TEST 1 /////////////////////////////////////////////
.set pmpcfgi, PMPCFG0 // Initialize an iterating variable with the address of pmpcfg0
.rept 4 // START OF LOOP
csrw pmpcfgi, a5 // WRITE pmpcfgi with ALL 1s, Locked the lock-bit [7,15,23,31]
nop // Added nop in case of trap
csrr a4, pmpcfgi // READ pmpcfgi
// THIS READ WILL ALSO CONFIRM THE ZERO BITs OF PMPCFGi REG.
// BIT 5-6, BIT 13-14, BIT 21-22, BIT 29-30 must be hardwired to zero
// Verify that LOCKED bits are HIGH, and ZERO bits are zero
RVTEST_SIGUPD(x3,a4)
// TRY TO WRITE CFG REGISTER AGAIN (TRAP in case of LOCKED bit is HIGH)
csrw pmpcfgi, x5 // WRITE pmpcfgi with some other values
nop // Added nop in case of trap
csrr a4, pmpcfgi // READ pmpcfgi
// Since Locked bit is high, so this should return the old value!!!
RVTEST_SIGUPD(x3,a4)

.set pmpaddri, PMPADDR0+4*(pmpcfgi-PMPCFG0)
// Initialize an iterating variable with the address of pmpaddr0 in 1st iteration (when pmpcfgi=pmpcfg0)
// Initialize an iterating variable with the address of pmpaddr4 in 2nd iteration (when pmpcfgi=pmpcfg1)
// Initialize an iterating variable with the address of pmpaddr8 in 3rd iteration (when pmpcfgi=pmpcfg2)
// Initialize an iterating variable with the address of pmpaddr12 in 4th iteration (when pmpcfgi=pmpcfg3)
.rept 4 // START OF LOOP
// TRY TO WRITE ADDRESS REGISTER.
csrw pmpaddri, a5 // WRITE pmpaddri with some other values
// The updated write will give a trap!!!
nop // Added nop in case of trap
csrr a4, pmpaddri // READ pmpaddr0, value should not have been changed
nop // Added nop in case of trap
RVTEST_SIGUPD(x3,a4)
.set pmpaddri, pmpaddri+1 // increment variable pmpaddri to the next pmpaddr reg
.endr // END OF INNER LOOP BODY

.set pmpcfgi, pmpcfgi+1 // increment variable to next pmpcfg reg
.endr // END OF OUTER LOOP BODY
#endif
# ---------------------------------------------------------------------------------------------
# HALT
RVTEST_CODE_END
RVMODEL_HALT

RVTEST_DATA_BEGIN
.align 4

rvtest_data:
.word 0xbabecafe
.word 0xbabecafe
.word 0xbabecafe
.word 0xbabecafe
RVTEST_DATA_END


RVMODEL_DATA_BEGIN
rvtest_sig_begin:
sig_begin_canary:
CANARY;
signature_x3_1:
.fill 32*(XLEN/32),4,0xdeadbeef

#ifdef rvtest_mtrap_routine

tsig_begin_canary:
CANARY;
mtrap_sigptr:
.fill 64*(XLEN/32),4,0xdeadbeef
tsig_end_canary:
CANARY;

#endif

#ifdef rvtest_gpr_save

gpr_save:
.fill 32*(XLEN/32),4,0xdeadbeef

#endif

sig_end_canary:
CANARY;
rvtest_sig_end:
RVMODEL_DATA_END
188 changes: 188 additions & 0 deletions riscv-test-suite/rv32i_m/pmp32/PMP-CSR-access.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
// -----------
// Copyright (c) 2020. RISC-V International. All rights reserved.
// SPDX-License-Identifier: BSD-3-Clause
// -----------
//
// This test belongs to the test plan for RISC-V Privilege Arch Compliance developed by 10xEngineers
// which can be found here: https://docs.google.com/spreadsheets/d/1p13gic7BD6aq7n_dHrqti4QmlGpxY7FkF17RVbG4DC0/edit?usp=sharing
//
// This assembly file tests access of pmp registers in M, S, and U mode.
// pmp csrs are accessable only in M-mode so it should trap in S, and U mode.
//
/* COVERPOINTS: (Explanation of updates in /coverage/rv32i_priv.cgf)
// Details are given in /coverage/rv32i_priv.cgf
*/
//
#define rvtest_strap_routine
#include "model_test.h"
#include "arch_test.h"
RVTEST_ISA("RV32I_Zicsr")
# Test code region
.section .text.init
.globl rvtest_entry_point
rvtest_entry_point:
RVMODEL_BOOT
RVTEST_CODE_BEGIN
#ifdef TEST_CASE_1
RVTEST_CASE(1,"//check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; def TEST_CASE_1=True",PMP_access_permission)
RVTEST_SIGBASE( x13,signature_x13_1)
.option nopic
.attribute unaligned_access, 0
.attribute stack_align, 16
.align 2
main:
#define PMPCFG0 0x3A0 // Address of pmpcfg0 (HAS BEEN USED WHILE ITERATING THE LOOP)
#define PMPADDR0 0x3B0 // Address of pmpaddr0 (HAS BEEN USED WHILE ITERATING THE LOOP)
main:
//////////////////////// INITIAL VALUES ////////////////////////////////
LI(a5, -1) // SEtting up All locked bits (including everyother non-zero bit, which is redundent for this test)
LI(x5, 100) // A rondom number, to check if pmp regs get update after lock bit enable
// Loop to SET ALL pmpcfg REGs to zero
.set pmpcfgi, PMPCFG0 // Initialize an iterating variable with the address of pmpcfg0
.rept 4 // START OF LOOP
csrc pmpcfgi , a5 // Set all pmpcfg regs to zero (initial value)
.set pmpcfgi, pmpcfgi+1 // increment variable to next pmpcfg reg
.endr // END OF LOOP BODY
// Loop to SET ALL pmpaddr REGs to zero
// Loop to SET ALL pmpaddr REGs to zero
.set pmpaddri, PMPADDR0 // Initialize an iterating variable with the address of pmpaddr0
.rept 16 // START OF LOOP
csrc pmpaddri, a5 // Set all pmpaddr regs to zero (initial value)
.set pmpaddri, pmpaddri+1 // increment variable pmpaddri to the next pmpaddr reg
.endr // END OF LOOP BODY
.set pmpaddri, PMPADDR0 // Initialize an iterating variable with the address of pmpaddr0
.rept 16 // START OF LOOP
csrs pmpaddri, a5 // Set all pmpaddr regs to zero (initial value)
.set pmpaddri, pmpaddri+1 // increment variable pmpaddri to the next pmpaddr reg
.endr // END OF LOOP BODY
//////////////// VERIFICATION /////////////////////////////////////////
// READING pmpaddr in M-mode /////////////////////////////////////////
.set pmpaddri, PMPADDR0 // Initialize an iterating variable with the address of pmpaddr0
.rept 16 // START OF LOOP
csrr a4, pmpaddri // READING pmpaddri (i is from 0-15)
nop // Added nop in case of trap
RVTEST_SIGUPD(x13,a4) // Storing into signature file
.set pmpaddri, pmpaddri+1 // increment variable pmpaddri to the next pmpaddr reg
.endr // END OF LOOP BODY
// WRITING pmpcfg registers //////////////////////////////////////////
// Write in M-mode will be valid, Write in other modes will cause trap
LI(a5, PMP_R| PMP_W | PMP_X | PMP_TOR) // LOCKED BIT IS NOT SET
// Loop to Write ALL pmpcfg regs
.set pmpcfgi, PMPCFG0 // Initialize an iterating variable with the address of pmpcfg0
.rept 4 // START OF LOOP
csrw pmpcfgi, a5 // Write pmpcfgi
nop // Added nop in case of trap
.set pmpcfgi, pmpcfgi+1 // increment variable to next pmpcfg reg
.endr // END OF LOOP BODY
//////////////// VERIFICATION /////////////////////////////////////////
// READING pmpcfg in M-mode /////////////////////////////////////////
// Loop to verify the contents of pmpcfg regs
.set pmpcfgi, PMPCFG0 // Initialize an iterating variable with the address of pmpcfg0
.rept 4 // START OF LOOP
csrr a4, pmpcfg0 // Read pmpcfg0
nop // Added nop in case of trap
RVTEST_SIGUPD(x13,a4)
.set pmpcfgi, pmpcfgi+1 // increment variable to next pmpcfg reg
.endr // END OF LOOP BODY
/////////////////// Switch to S-mode ////////////////////////////////////////////
csrw satp, zero // Disable address translation.
LI(t2, -1)
csrw pmpaddr0, t2 // Updated pmpaddr0 to define PMP region consisting
// of whole physical memory
csrr t0, pmpaddr0 // Verify its value by reading back
nop // Added nop in case of trap
RVTEST_SIGUPD(x13,t0)
nop // Added nop in case of trap
LI(a5, PMP_L| PMP_R| PMP_W | PMP_X | PMP_TOR) // LOCKED BIT IS SET
csrw pmpcfg0, a5

RVTEST_GOTO_LOWER_MODE Smode // GO into S mode
// REPEATING THE SAME TEST //////////////////////////////////////////
// IN Smode now
/////////////////// TEST 01 ////////////////////////////////////////////
// WRITING pmpaddr registers //////////////////////////////////////////
// Write in M-mode will be valid, Write in other modes will cause trap
csrw pmpaddr0, x2 // Write pmpaddr0 in S mode (TRAP)
nop // Added nop in case of trap
// READING pmpaddr in S-mode /////////////////////////////////////////
csrr a4, pmpaddr0 // Reading pmpaddr0 in S mode (TRAP)
nop // Added nop in case of trap
/////////////////// Switch back to M-mode ////////////////////////////////////////////
RVTEST_GOTO_MMODE
csrr a4, mstatus // VERIFICATION of M-mode
nop // Added nop in case of trap
RVTEST_SIGUPD(x13,a4)
/////////////////// Switch to U-mode ////////////////////////////////////////////
csrw satp, zero // Disable address translation.
LI(t2, -1)
csrw pmpaddr0, t2 // Updated pmpaddr0 to define PMP region consisting
// of whole physical memory
csrr t0, pmpaddr0 // Verify its value by reading back
nop // Added nop in case of trap
RVTEST_SIGUPD(x13,t0)
nop // Added nop in case of trap
LI(a5, PMP_L| PMP_R| PMP_W | PMP_X | PMP_TOR) // LOCKED BIT IS SET
csrw pmpcfg0, a5
// These steps are repeated and can be removed but it will make sure that you will switch mode
// with full access on physical memory
RVTEST_GOTO_LOWER_MODE Umode
// REPEATING THE SAME TEST //////////////////////////////////////////
// IN U-mode now
/////////////////// TEST 01 ////////////////////////////////////////////
// WRITING pmpaddr registers //////////////////////////////////////////
// Write in M-mode will be valid, Write in other modes will cause trap
csrw pmpaddr0, x2 // Write pmpaddr0 in u mode (TRAP)
nop // Added nop in case of trap
//////////////// VERIFICATION /////////////////////////////////////////
// READING pmpaddr in S-mode /////////////////////////////////////////
csrr a4, pmpaddr0 // Reading pmpaddr0 in U mode (TRAP)
nop // Added nop in case of trap

#endif

# ---------------------------------------------------------------------------------------------
# HALT
RVTEST_CODE_END
RVMODEL_HALT

RVTEST_DATA_BEGIN
.align 4

rvtest_data:
.word 0xbabecafe
.word 0xbabecafe
.word 0xbabecafe
.word 0xbabecafe
RVTEST_DATA_END


RVMODEL_DATA_BEGIN
rvtest_sig_begin:
sig_begin_canary:
CANARY;
signature_x13_1:
.fill 32*(XLEN/32),4,0xdeadbeef

#ifdef rvtest_mtrap_routine

tsig_begin_canary:
CANARY;
mtrap_sigptr:
.fill 64*(XLEN/32),4,0xdeadbeef
tsig_end_canary:
CANARY;

#endif

#ifdef rvtest_gpr_save

gpr_save:
.fill 32*(XLEN/32),4,0xdeadbeef

#endif

sig_end_canary:
CANARY;
rvtest_sig_end:
RVMODEL_DATA_END
Loading

0 comments on commit 8ac1a16

Please sign in to comment.