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

Physical Memory Protection (32/64) Tests and Covergroups #462

Open
wants to merge 25 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
095f7ef
PMP32 and PMP64 Covergroups added
MuhammadHammad001 Apr 29, 2024
5a44a3f
YAML basedHeaders/Macros file for the coverpoints added
MuhammadHammad001 Apr 29, 2024
dfcad6b
Added PMP32 and PMP64 ACTs
UmerShahidengr Apr 29, 2024
6ecb0ef
Added Changelog entry
UmerShahidengr Apr 29, 2024
05f23bb
PMP Macros added in Header file, PMP tests updated to support byte an…
MuhammadHammad001 Jul 2, 2024
d5a1e8e
64 bit PMP Tests and coverpoints updated
MuhammadHammad001 Jul 2, 2024
1214bb0
32 bit PMP Coverpoints updated to more compact version
MuhammadHammad001 Jul 2, 2024
a0bc569
Merge branch 'dev' into pmp_cov_test
MuhammadHammad001 Jul 2, 2024
65cb741
Changelog entry removed for the PMP Tests and Coverpoints
MuhammadHammad001 Jul 18, 2024
a460920
Merge branch 'dev' into pmp_cov_test
UmerShahidengr Jul 23, 2024
bb318a9
Update rv32_pmp.cgf
UmerShahidengr Aug 2, 2024
a4ed357
Merge branch 'dev' into pmp_cov_test
UmerShahidengr Aug 2, 2024
ccfa08f
Update rv64_pmp.cgf
UmerShahidengr Aug 2, 2024
4650b89
Merge branch 'dev' into pmp_cov_test
jamesbeyond Oct 7, 2024
408b032
Merge branch 'dev' into pmp_cov_test
UmerShahidengr Oct 9, 2024
9c5341e
Merge branch 'dev' into pmp_cov_test
UmerShahidengr Oct 15, 2024
112ed98
Merge branch 'riscv-non-isa:dev' into pmp_cov_test
UmerShahidengr Oct 18, 2024
a48e1ef
Merge branch 'dev' into pmp_cov_test
UmerShahidengr Oct 18, 2024
21489f3
Merge branch 'riscv-non-isa:dev' into pmp_cov_test
UmerShahidengr Oct 18, 2024
304f853
Changed the CI to see the artifacts
UmerShahidengr Oct 18, 2024
7695c7c
Reverted the change in CI
UmerShahidengr Oct 18, 2024
c068f3c
Merge branch 'dev' into pmp_cov_test
UmerShahidengr Oct 25, 2024
1be1bcb
Removed __pycache__ folders
UmerShahidengr Oct 25, 2024
4a42f28
removed riscof work folder
MuhammadHammad001 Oct 26, 2024
7954b57
RISCOF work folder in rv64 removed
MuhammadHammad001 Oct 26, 2024
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
935 changes: 935 additions & 0 deletions coverage/header_file.yaml

Large diffs are not rendered by default.

836 changes: 836 additions & 0 deletions coverage/rv32_pmp.cgf

Large diffs are not rendered by default.

836 changes: 836 additions & 0 deletions coverage/rv64_pmp.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; mac PMP_MACROS; mac PMP_helper_Coverpoints",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
Loading