Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pmp tests #284

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
# CHANGELOG
## [3.7.6] - 2023-10-27
Add PMP Tests


## [3.7.5] - 2023-10-11
Add missing check ISA fields in recently modified div and amo tests
Expand Down
146 changes: 146 additions & 0 deletions riscv-test-suite/rv32i_m/privilege/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",pmpcfg)
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
182 changes: 182 additions & 0 deletions riscv-test-suite/rv32i_m/privilege/pmp32/PMP-CSR-access.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
// -----------
// 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",pmpcfg)
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
.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
//////////////// 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
Loading