From 3843c736e427a2b52a0d06e6220b073afa4be401 Mon Sep 17 00:00:00 2001 From: shehzmak <108384507+shehzmak@users.noreply.github.com> Date: Thu, 31 Oct 2024 14:43:03 +0500 Subject: [PATCH 1/4] Update test_macros.h, removed TEST_RI macro (#545) Signed-off-by: shehzmak <108384507+shehzmak@users.noreply.github.com> --- riscv-test-suite/env/test_macros.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/riscv-test-suite/env/test_macros.h b/riscv-test-suite/env/test_macros.h index 0b5cca2ec..4ed2bc010 100644 --- a/riscv-test-suite/env/test_macros.h +++ b/riscv-test-suite/env/test_macros.h @@ -888,13 +888,6 @@ ADDI(swreg, swreg, RVMODEL_CBZ_BLOCKSIZE) inst destreg, reg1, reg2, imm ;\ ) -//Tests for a instructions with register-register operand -#define TEST_RI_OP(inst, destreg, reg1, reg2, imm, correctval, val1, val2, swreg, offset, testreg) \ - TEST_CASE(testreg, destreg, correctval, swreg, offset, \ - LI(reg1, MASK_XLEN(val1)) ;\ - LI(reg2, MASK_XLEN(val2)) ;\ - inst destreg, reg1, reg2, imm ;\ - ) //Tests for a instructions with register-register operand #define TEST_RR_OP(inst, destreg, reg1, reg2, correctval, val1, val2, swreg, offset, testreg) \ From b9ec39c447c808a11b2f51213f4d0f601ade5108 Mon Sep 17 00:00:00 2001 From: MingZhu Yan <69898423+trdthg@users.noreply.github.com> Date: Tue, 5 Nov 2024 01:09:12 +0800 Subject: [PATCH 2/4] [CTG] Fix `cross()` missing inxFlag param (#546) --- riscv-isac/riscv_isac/coverage.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/riscv-isac/riscv_isac/coverage.py b/riscv-isac/riscv_isac/coverage.py index 9d01af5b0..cd0f0b92a 100644 --- a/riscv-isac/riscv_isac/coverage.py +++ b/riscv-isac/riscv_isac/coverage.py @@ -166,7 +166,7 @@ class cross(): BASE_REG_DICT = { 'x'+str(i) : 'x'+str(i) for i in range(32)} - def __init__(self,label,coverpoint,xlen,flen,addr_pairs,sig_addrs,window_size): + def __init__(self,label,coverpoint,xlen,flen,addr_pairs,sig_addrs,window_size,inxFlg): self.label = label self.coverpoint = coverpoint @@ -1536,7 +1536,7 @@ def compute(trace_file, test_name, cgf, parser_name, decoder_name, detailed, xle if 'cross_comb' in value and len(value['cross_comb'])!=0: for coverpt in value['cross_comb'].keys(): if(isinstance(coverpt,str)): - new_obj = cross(cov_labels,coverpt,xlen,flen,addr_pairs,sig_addrs,window_size) + new_obj = cross(cov_labels,coverpt,xlen,flen,addr_pairs,sig_addrs,window_size,inxFlg) obj_dict[(cov_labels,coverpt)] = new_obj From 956b77ed3c15e75b35e227c81e2a649414be6c20 Mon Sep 17 00:00:00 2001 From: Pagerd <60070497+Pagerd@users.noreply.github.com> Date: Tue, 5 Nov 2024 01:09:50 +0800 Subject: [PATCH 3/4] fix isac string bug (#544) Co-authored-by: James Shi --- riscv-isac/riscv_isac/fp_dataset.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/riscv-isac/riscv_isac/fp_dataset.py b/riscv-isac/riscv_isac/fp_dataset.py index 6a4a63fe5..b6b31304b 100644 --- a/riscv-isac/riscv_isac/fp_dataset.py +++ b/riscv-isac/riscv_isac/fp_dataset.py @@ -49,11 +49,11 @@ rounding_modes = ['0','1','2','3','4'] sanitise_cvpt = lambda rm,x,iflen,flen,c,inxFlg: x + ' fcsr == '+hex(rm<<5) + ' and rm_val == 7 ' \ - + ('' if iflen == flen or inxFlg else ''.join([' and rs'+str(x)+'_nan_prefix == 0x' \ + + ('' if iflen >= flen or inxFlg else ''.join([' and rs'+str(x)+'_nan_prefix == 0x' \ + 'f'*int((flen-iflen)/4) for x in range(1,c+1)])) sanitise_norm = lambda rm,x,iflen,flen,c,inxFlg: x + ' fcsr == 0'\ - + ('' if iflen == flen or inxFlg else ''.join([' and rs'+str(x)+'_nan_prefix == 0x' \ + + ('' if iflen >= flen or inxFlg else ''.join([' and rs'+str(x)+'_nan_prefix == 0x' \ + 'f'*int((flen-iflen)/4) for x in range(1,c+1)])) sanitise_norm_nopref = lambda rm,x,iflen,flen,c,inxFlg: x + ' fcsr == 0' From 32ea218409a8de5ab7cf76c44f74b0cbd6cbcde6 Mon Sep 17 00:00:00 2001 From: Muhammad Hammad Bashir <139617104+MuhammadHammad001@users.noreply.github.com> Date: Mon, 4 Nov 2024 22:12:56 +0500 Subject: [PATCH 4/4] Physical Memory Protection (32/64) Tests and Covergroups (#462) * PMP32 and PMP64 Covergroups added * YAML basedHeaders/Macros file for the coverpoints added * Added PMP32 and PMP64 ACTs * Added Changelog entry * PMP Macros added in Header file, PMP tests updated to support byte and half word access, PMP Coverpoints updated to a new pattern * 64 bit PMP Tests and coverpoints updated * 32 bit PMP Coverpoints updated to more compact version * Changelog entry removed for the PMP Tests and Coverpoints * Update rv32_pmp.cgf Updated pmp_cfg_locked_write_unrelated coverpoint based on Allen comment Signed-off-by: Umer Shahid * Update rv64_pmp.cgf Updated pmp_cfg_locked_write_unrelated coverpoint in rv64 to update a minor bug Signed-off-by: Umer Shahid * Changed the CI to see the artifacts * Reverted the change in CI * Removed __pycache__ folders * removed riscof work folder * RISCOF work folder in rv64 removed --------- Signed-off-by: Muhammad Hammad Bashir <139617104+MuhammadHammad001@users.noreply.github.com> Signed-off-by: Umer Shahid Co-authored-by: umershahidengr Co-authored-by: James Shi --- coverage/header_file.yaml | 935 ++++++++++++++++++ coverage/rv32_pmp.cgf | 836 ++++++++++++++++ coverage/rv64_pmp.cgf | 836 ++++++++++++++++ .../riscof_sail_cSim.cpython-310.pyc | Bin 5456 -> 0 bytes .../riscof_spike_simple.cpython-310.pyc | Bin 3476 -> 0 bytes .../__pycache__/__init__.cpython-38.pyc | Bin 243 -> 0 bytes .../riscof_sail_cSim.cpython-310.pyc | Bin 4759 -> 0 bytes .../riscof_sail_cSim.cpython-38.pyc | Bin 4450 -> 0 bytes .../__pycache__/riscof_model.cpython-38.pyc | Bin 3225 -> 0 bytes .../__pycache__/riscof_spike.cpython-310.pyc | Bin 3360 -> 0 bytes .../__pycache__/riscof_spike.cpython-38.pyc | Bin 3197 -> 0 bytes .../riscof_spike_simple.cpython-310.pyc | Bin 3455 -> 0 bytes .../riscof_spike_simple.cpython-38.pyc | Bin 3496 -> 0 bytes riscv-test-suite/rv32i_m/pmp32/PMP-CFG-reg.S | 146 +++ .../rv32i_m/pmp32/PMP-CSR-access.S | 188 ++++ .../pmp32/pmp-NA4-R-priority-level-2.S | 224 +++++ .../rv32i_m/pmp32/pmp-NA4-R-priority.S | 202 ++++ riscv-test-suite/rv32i_m/pmp32/pmp-NA4-R.S | 239 +++++ .../pmp32/pmp-NA4-RW-priority-level-2.S | 220 +++++ .../rv32i_m/pmp32/pmp-NA4-RW-priority.S | 201 ++++ riscv-test-suite/rv32i_m/pmp32/pmp-NA4-RW.S | 240 +++++ riscv-test-suite/rv32i_m/pmp32/pmp-NA4-RWX.S | 254 +++++ .../pmp32/pmp-NA4-RX-priority-level-2.S | 220 +++++ .../rv32i_m/pmp32/pmp-NA4-RX-priority.S | 201 ++++ riscv-test-suite/rv32i_m/pmp32/pmp-NA4-RX.S | 238 +++++ .../pmp32/pmp-NA4-X-priority-level-2.S | 221 +++++ .../rv32i_m/pmp32/pmp-NA4-X-priority.S | 201 ++++ riscv-test-suite/rv32i_m/pmp32/pmp-NA4-X.S | 238 +++++ .../pmp32/pmp-NAPOT-R-priority-level-2.S | 220 +++++ .../rv32i_m/pmp32/pmp-NAPOT-R-priority.S | 201 ++++ riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-R.S | 239 +++++ .../pmp32/pmp-NAPOT-RW-priority-level-2.S | 221 +++++ .../rv32i_m/pmp32/pmp-NAPOT-RW-priority.S | 201 ++++ riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-RW.S | 239 +++++ .../rv32i_m/pmp32/pmp-NAPOT-RWX.S | 240 +++++ .../pmp32/pmp-NAPOT-RX-priority-level-2.S | 221 +++++ .../rv32i_m/pmp32/pmp-NAPOT-RX-priority.S | 201 ++++ riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-RX.S | 239 +++++ .../pmp32/pmp-NAPOT-X-priority-level-2.S | 221 +++++ .../rv32i_m/pmp32/pmp-NAPOT-X-priority.S | 201 ++++ riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-X.S | 239 +++++ .../pmp32/pmp-TOR-R-priority-level-2.S | 227 +++++ .../rv32i_m/pmp32/pmp-TOR-R-priority.S | 206 ++++ riscv-test-suite/rv32i_m/pmp32/pmp-TOR-R.S | 245 +++++ .../pmp32/pmp-TOR-RW-priority-level-2..S | 229 +++++ .../rv32i_m/pmp32/pmp-TOR-RW-priority.S | 206 ++++ riscv-test-suite/rv32i_m/pmp32/pmp-TOR-RW.S | 245 +++++ riscv-test-suite/rv32i_m/pmp32/pmp-TOR-RWX.S | 245 +++++ .../pmp32/pmp-TOR-RX-priority-level-2.S | 229 +++++ .../rv32i_m/pmp32/pmp-TOR-RX-priority.S | 206 ++++ riscv-test-suite/rv32i_m/pmp32/pmp-TOR-RX.S | 245 +++++ .../pmp32/pmp-TOR-X-priority-level-2.S | 229 +++++ .../rv32i_m/pmp32/pmp-TOR-X-priority.S | 206 ++++ riscv-test-suite/rv32i_m/pmp32/pmp-TOR-X.S | 245 +++++ .../rv64i_m/pmp64/pmp64-CFG-reg.S | 132 +++ .../rv64i_m/pmp64/pmp64-CSR-access.S | 243 +++++ .../pmp64/pmp64-NA4-R-priority-level-2.S | 236 +++++ .../rv64i_m/pmp64/pmp64-NA4-R-priority.S | 215 ++++ riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-R.S | 240 +++++ .../pmp64/pmp64-NA4-RW-priority-level-2.S | 233 +++++ .../rv64i_m/pmp64/pmp64-NA4-RW-priority.S | 214 ++++ riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-RW.S | 242 +++++ .../rv64i_m/pmp64/pmp64-NA4-RWX.S | 255 +++++ .../pmp64/pmp64-NA4-RX-priority-level-2.S | 233 +++++ .../rv64i_m/pmp64/pmp64-NA4-RX-priority.S | 214 ++++ riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-RX.S | 240 +++++ .../pmp64/pmp64-NA4-X-priority-level-2.S | 234 +++++ .../rv64i_m/pmp64/pmp64-NA4-X-priority.S | 214 ++++ riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-X.S | 239 +++++ .../pmp64/pmp64-NAPOT-R-priority-level-2.S | 233 +++++ .../rv64i_m/pmp64/pmp64-NAPOT-R-priority.S | 213 ++++ .../rv64i_m/pmp64/pmp64-NAPOT-R.S | 241 +++++ .../pmp64/pmp64-NAPOT-RW-priority-level-2.S | 233 +++++ .../rv64i_m/pmp64/pmp64-NAPOT-RW-priority.S | 213 ++++ .../rv64i_m/pmp64/pmp64-NAPOT-RW.S | 240 +++++ .../rv64i_m/pmp64/pmp64-NAPOT-RWX.S | 240 +++++ .../pmp64/pmp64-NAPOT-RX-priority-level-2.S | 233 +++++ .../rv64i_m/pmp64/pmp64-NAPOT-RX-priority.S | 213 ++++ .../rv64i_m/pmp64/pmp64-NAPOT-RX.S | 240 +++++ .../pmp64/pmp64-NAPOT-X-priority-level-2.S | 233 +++++ .../rv64i_m/pmp64/pmp64-NAPOT-X-priority.S | 213 ++++ .../rv64i_m/pmp64/pmp64-NAPOT-X.S | 240 +++++ .../pmp64/pmp64-TOR-R-priority-level-2.S | 239 +++++ .../rv64i_m/pmp64/pmp64-TOR-R-priority.S | 218 ++++ riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-R.S | 248 +++++ .../pmp64/pmp64-TOR-RW-priority-level-2..S | 240 +++++ .../rv64i_m/pmp64/pmp64-TOR-RW-priority.S | 218 ++++ riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-RW.S | 248 +++++ .../rv64i_m/pmp64/pmp64-TOR-RWX.S | 248 +++++ .../pmp64/pmp64-TOR-RX-priority-level-2.S | 240 +++++ .../rv64i_m/pmp64/pmp64-TOR-RX-priority.S | 219 ++++ riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-RX.S | 248 +++++ .../pmp64/pmp64-TOR-X-priority-level-2.S | 240 +++++ .../rv64i_m/pmp64/pmp64-TOR-X-priority.S | 219 ++++ riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-X.S | 248 +++++ 95 files changed, 21128 insertions(+) create mode 100644 coverage/header_file.yaml create mode 100644 coverage/rv32_pmp.cgf create mode 100644 coverage/rv64_pmp.cgf delete mode 100644 riscof-plugins/rv32/sail_cSim/__pycache__/riscof_sail_cSim.cpython-310.pyc delete mode 100644 riscof-plugins/rv32/spike_simple/__pycache__/riscof_spike_simple.cpython-310.pyc delete mode 100644 riscof-plugins/rv64/sail_cSim/__pycache__/__init__.cpython-38.pyc delete mode 100644 riscof-plugins/rv64/sail_cSim/__pycache__/riscof_sail_cSim.cpython-310.pyc delete mode 100644 riscof-plugins/rv64/sail_cSim/__pycache__/riscof_sail_cSim.cpython-38.pyc delete mode 100644 riscof-plugins/rv64/spike_simple/__pycache__/riscof_model.cpython-38.pyc delete mode 100644 riscof-plugins/rv64/spike_simple/__pycache__/riscof_spike.cpython-310.pyc delete mode 100644 riscof-plugins/rv64/spike_simple/__pycache__/riscof_spike.cpython-38.pyc delete mode 100644 riscof-plugins/rv64/spike_simple/__pycache__/riscof_spike_simple.cpython-310.pyc delete mode 100755 riscof-plugins/rv64/spike_simple/__pycache__/riscof_spike_simple.cpython-38.pyc create mode 100644 riscv-test-suite/rv32i_m/pmp32/PMP-CFG-reg.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/PMP-CSR-access.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-NA4-R-priority-level-2.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-NA4-R-priority.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-NA4-R.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-NA4-RW-priority-level-2.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-NA4-RW-priority.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-NA4-RW.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-NA4-RWX.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-NA4-RX-priority-level-2.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-NA4-RX-priority.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-NA4-RX.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-NA4-X-priority-level-2.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-NA4-X-priority.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-NA4-X.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-R-priority-level-2.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-R-priority.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-R.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-RW-priority-level-2.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-RW-priority.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-RW.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-RWX.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-RX-priority-level-2.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-RX-priority.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-RX.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-X-priority-level-2.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-X-priority.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-X.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-TOR-R-priority-level-2.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-TOR-R-priority.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-TOR-R.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-TOR-RW-priority-level-2..S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-TOR-RW-priority.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-TOR-RW.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-TOR-RWX.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-TOR-RX-priority-level-2.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-TOR-RX-priority.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-TOR-RX.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-TOR-X-priority-level-2.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-TOR-X-priority.S create mode 100644 riscv-test-suite/rv32i_m/pmp32/pmp-TOR-X.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-CFG-reg.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-CSR-access.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-R-priority-level-2.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-R-priority.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-R.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-RW-priority-level-2.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-RW-priority.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-RW.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-RWX.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-RX-priority-level-2.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-RX-priority.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-RX.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-X-priority-level-2.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-X-priority.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-X.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-R-priority-level-2.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-R-priority.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-R.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-RW-priority-level-2.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-RW-priority.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-RW.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-RWX.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-RX-priority-level-2.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-RX-priority.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-RX.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-X-priority-level-2.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-X-priority.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-X.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-R-priority-level-2.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-R-priority.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-R.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-RW-priority-level-2..S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-RW-priority.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-RW.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-RWX.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-RX-priority-level-2.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-RX-priority.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-RX.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-X-priority-level-2.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-X-priority.S create mode 100644 riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-X.S diff --git a/coverage/header_file.yaml b/coverage/header_file.yaml new file mode 100644 index 000000000..b7386d8f0 --- /dev/null +++ b/coverage/header_file.yaml @@ -0,0 +1,935 @@ +common: + MSTATUS_UIE: 0x00000001 + MSTATUS_SIE: 0x00000002 + MSTATUS_HIE: 0x00000004 + MSTATUS_MIE: 0x00000008 + MSTATUS_UPIE: 0x00000010 + MSTATUS_SPIE: 0x00000020 + MSTATUS_HPIE: 0x00000040 + MSTATUS_MPIE: 0x00000080 + MSTATUS_SPP: 0x00000100 + MSTATUS_HPP: 0x00000600 + MSTATUS_MPP: 0x00001800 + MSTATUS_FS: 0x00006000 + MSTATUS_VS: 0x00000600 + MSTATUS_XS: 0x00018000 + MSTATUS_MPRV: 0x00020000 + MSTATUS_SUM: 0x00040000 + MSTATUS_MXR: 0x00080000 + MSTATUS_TVM: 0x00100000 + MSTATUS_TW: 0x00200000 + MSTATUS_TSR: 0x00400000 + MSTATUS32_SD: 0x80000000 + MSTATUS_UXL: 0x0000000300000000 + MSTATUS_SXL: 0x0000000C00000000 + MSTATUS64_SD: 0x8000000000000000 + SSTATUS_UIE: 0x00000001 + SSTATUS_SIE: 0x00000002 + SSTATUS_UPIE: 0x00000010 + SSTATUS_SPIE: 0x00000020 + SSTATUS_SPP: 0x00000100 + SSTATUS_FS: 0x00006000 + SSTATUS_XS: 0x00018000 + SSTATUS_SUM: 0x00040000 + SSTATUS_MXR: 0x00080000 + SSTATUS32_SD: 0x80000000 + SSTATUS_UXL: 0x0000000300000000 + SSTATUS64_SD: 0x8000000000000000 + DCSR_CAUSE_NONE: 0 + DCSR_CAUSE_SWBP: 1 + DCSR_CAUSE_HWBP: 2 + DCSR_CAUSE_DEBUGINT: 3 + DCSR_CAUSE_STEP: 4 + DCSR_CAUSE_HALT: 5 + MCONTROL_TYPE_NONE: 0 + MCONTROL_TYPE_MATCH: 2 + MCONTROL_ACTION_DEBUG_EXCEPTION: 0 + MCONTROL_ACTION_DEBUG_MODE: 1 + MCONTROL_ACTION_TRACE_START: 2 + MCONTROL_ACTION_TRACE_STOP: 3 + MCONTROL_ACTION_TRACE_EMIT: 4 + MCONTROL_MATCH_EQUAL: 0 + MCONTROL_MATCH_NAPOT: 1 + MCONTROL_MATCH_GE: 2 + MCONTROL_MATCH_LT: 3 + MCONTROL_MATCH_MASK_LOW: 4 + MCONTROL_MATCH_MASK_HIGH: 5 + SIP_SSIP: MIP_SSIP + SIP_STIP: MIP_STIP + PRV_U: 0 + PRV_S: 1 + PRV_H: 2 + PRV_M: 3 + SATP32_MODE: 0x80000000 + SATP32_ASID: 0x7FC00000 + SATP32_PPN: 0x003FFFFF + SATP64_MODE: 0xF000000000000000 + SATP64_ASID: 0x0FFFF00000000000 + SATP64_PPN: 0x00000FFFFFFFFFFF + SATP_MODE_OFF: 0 + SATP_MODE_SV32: 1 + SATP_MODE_SV39: 8 + SATP_MODE_SV48: 9 + SATP_MODE_SV57: 10 + SATP_MODE_SV64: 11 + PMP_R: 0x01 + PMP_W: 0x02 + PMP_X: 0x04 + PMP_A: 0x18 + PMP_L: 0x80 + PMP_SHIFT: 2 + PMP_TOR: 0x08 + PMP_NA4: 0x10 + PMP_NAPOT: 0x18 + IRQ_S_SOFT: 1 + IRQ_H_SOFT: 2 + IRQ_M_SOFT: 3 + IRQ_S_TIMER: 5 + IRQ_H_TIMER: 6 + IRQ_M_TIMER: 7 + IRQ_S_EXT: 9 + IRQ_H_EXT: 10 + IRQ_M_EXT: 11 + IRQ_COP: 12 + IRQ_HOST: 13 + DEFAULT_RSTVEC: 0x00001000 + CLINT_BASE: 0x02000000 + CLINT_SIZE: 0x000c0000 + EXT_IO_BASE: 0x40000000 + DRAM_BASE: 0x80000000 + PTE_V: 0x001 + PTE_R: 0x002 + PTE_W: 0x004 + PTE_X: 0x008 + PTE_U: 0x010 + PTE_G: 0x020 + PTE_A: 0x040 + PTE_D: 0x080 + PTE_SOFT: 0x300 + PTE_PPN_SHIFT: 10 + RISCV_PGSHIFT: 12 + MATCH_BEQ: 0x63 + MASK_BEQ: 0x707f + MATCH_BNE: 0x1063 + MASK_BNE: 0x707f + MATCH_BLT: 0x4063 + MASK_BLT: 0x707f + MATCH_BGE: 0x5063 + MASK_BGE: 0x707f + MATCH_BLTU: 0x6063 + MASK_BLTU: 0x707f + MATCH_BGEU: 0x7063 + MASK_BGEU: 0x707f + MATCH_JALR: 0x67 + MASK_JALR: 0x707f + MATCH_JAL: 0x6f + MASK_JAL: 0x7f + MATCH_LUI: 0x37 + MASK_LUI: 0x7f + MATCH_AUIPC: 0x17 + MASK_AUIPC: 0x7f + MATCH_ADDI: 0x13 + MASK_ADDI: 0x707f + MATCH_SLLI: 0x1013 + MASK_SLLI: 0xfc00707f + MATCH_SLTI: 0x2013 + MASK_SLTI: 0x707f + MATCH_SLTIU: 0x3013 + MASK_SLTIU: 0x707f + MATCH_XORI: 0x4013 + MASK_XORI: 0x707f + MATCH_SRLI: 0x5013 + MASK_SRLI: 0xfc00707f + MATCH_SRAI: 0x40005013 + MASK_SRAI: 0xfc00707f + MATCH_ORI: 0x6013 + MASK_ORI: 0x707f + MATCH_ANDI: 0x7013 + MASK_ANDI: 0x707f + MATCH_ADD: 0x33 + MASK_ADD: 0xfe00707f + MATCH_SUB: 0x40000033 + MASK_SUB: 0xfe00707f + MATCH_SLL: 0x1033 + MASK_SLL: 0xfe00707f + MATCH_SLT: 0x2033 + MASK_SLT: 0xfe00707f + MATCH_SLTU: 0x3033 + MASK_SLTU: 0xfe00707f + MATCH_XOR: 0x4033 + MASK_XOR: 0xfe00707f + MATCH_SRL: 0x5033 + MASK_SRL: 0xfe00707f + MATCH_SRA: 0x40005033 + MASK_SRA: 0xfe00707f + MATCH_OR: 0x6033 + MASK_OR: 0xfe00707f + MATCH_AND: 0x7033 + MASK_AND: 0xfe00707f + MATCH_ADDIW: 0x1b + MASK_ADDIW: 0x707f + MATCH_SLLIW: 0x101b + MASK_SLLIW: 0xfe00707f + MATCH_SRLIW: 0x501b + MASK_SRLIW: 0xfe00707f + MATCH_SRAIW: 0x4000501b + MASK_SRAIW: 0xfe00707f + MATCH_ADDW: 0x3b + MASK_ADDW: 0xfe00707f + MATCH_SUBW: 0x4000003b + MASK_SUBW: 0xfe00707f + MATCH_SLLW: 0x103b + MASK_SLLW: 0xfe00707f + MATCH_SRLW: 0x503b + MASK_SRLW: 0xfe00707f + MATCH_SRAW: 0x4000503b + MASK_SRAW: 0xfe00707f + MATCH_LB: 0x3 + MASK_LB: 0x707f + MATCH_LH: 0x1003 + MASK_LH: 0x707f + MATCH_LW: 0x2003 + MASK_LW: 0x707f + MATCH_LD: 0x3003 + MASK_LD: 0x707f + MATCH_LBU: 0x4003 + MASK_LBU: 0x707f + MATCH_LHU: 0x5003 + MASK_LHU: 0x707f + MATCH_LWU: 0x6003 + MASK_LWU: 0x707f + MATCH_SB: 0x23 + MASK_SB: 0x707f + MATCH_SH: 0x1023 + MASK_SH: 0x707f + MATCH_SW: 0x2023 + MASK_SW: 0x707f + MATCH_SD: 0x3023 + MASK_SD: 0x707f + MATCH_FENCE: 0xf + MASK_FENCE: 0x707f + MATCH_FENCE_I: 0x100f + MASK_FENCE_I: 0x707f + MATCH_MUL: 0x2000033 + MASK_MUL: 0xfe00707f + MATCH_MULH: 0x2001033 + MASK_MULH: 0xfe00707f + MATCH_MULHSU: 0x2002033 + MASK_MULHSU: 0xfe00707f + MATCH_MULHU: 0x2003033 + MASK_MULHU: 0xfe00707f + MATCH_DIV: 0x2004033 + MASK_DIV: 0xfe00707f + MATCH_DIVU: 0x2005033 + MASK_DIVU: 0xfe00707f + MATCH_REM: 0x2006033 + MASK_REM: 0xfe00707f + MATCH_REMU: 0x2007033 + MASK_REMU: 0xfe00707f + MATCH_MULW: 0x200003b + MASK_MULW: 0xfe00707f + MATCH_DIVW: 0x200403b + MASK_DIVW: 0xfe00707f + MATCH_DIVUW: 0x200503b + MASK_DIVUW: 0xfe00707f + MATCH_REMW: 0x200603b + MASK_REMW: 0xfe00707f + MATCH_REMUW: 0x200703b + MASK_REMUW: 0xfe00707f + MATCH_AMOADD_W: 0x202f + MASK_AMOADD_W: 0xf800707f + MATCH_AMOXOR_W: 0x2000202f + MASK_AMOXOR_W: 0xf800707f + MATCH_AMOOR_W: 0x4000202f + MASK_AMOOR_W: 0xf800707f + MATCH_AMOAND_W: 0x6000202f + MASK_AMOAND_W: 0xf800707f + MATCH_AMOMIN_W: 0x8000202f + MASK_AMOMIN_W: 0xf800707f + MATCH_AMOMAX_W: 0xa000202f + MASK_AMOMAX_W: 0xf800707f + MATCH_AMOMINU_W: 0xc000202f + MASK_AMOMINU_W: 0xf800707f + MATCH_AMOMAXU_W: 0xe000202f + MASK_AMOMAXU_W: 0xf800707f + MATCH_AMOSWAP_W: 0x800202f + MASK_AMOSWAP_W: 0xf800707f + MATCH_LR_W: 0x1000202f + MASK_LR_W: 0xf9f0707f + MATCH_SC_W: 0x1800202f + MASK_SC_W: 0xf800707f + MATCH_AMOADD_D: 0x302f + MASK_AMOADD_D: 0xf800707f + MATCH_AMOXOR_D: 0x2000302f + MASK_AMOXOR_D: 0xf800707f + MATCH_AMOOR_D: 0x4000302f + MASK_AMOOR_D: 0xf800707f + MATCH_AMOAND_D: 0x6000302f + MASK_AMOAND_D: 0xf800707f + MATCH_AMOMIN_D: 0x8000302f + MASK_AMOMIN_D: 0xf800707f + MATCH_AMOMAX_D: 0xa000302f + MASK_AMOMAX_D: 0xf800707f + MATCH_AMOMINU_D: 0xc000302f + MASK_AMOMINU_D: 0xf800707f + MATCH_AMOMAXU_D: 0xe000302f + MASK_AMOMAXU_D: 0xf800707f + MATCH_AMOSWAP_D: 0x800302f + MASK_AMOSWAP_D: 0xf800707f + MATCH_LR_D: 0x1000302f + MASK_LR_D: 0xf9f0707f + MATCH_SC_D: 0x1800302f + MASK_SC_D: 0xf800707f + MATCH_ECALL: 0x73 + MASK_ECALL: 0xffffffff + MATCH_EBREAK: 0x100073 + MASK_EBREAK: 0xffffffff + MATCH_URET: 0x200073 + MASK_URET: 0xffffffff + MATCH_SRET: 0x10200073 + MASK_SRET: 0xffffffff + MATCH_MRET: 0x30200073 + MASK_MRET: 0xffffffff + MATCH_DRET: 0x7b200073 + MASK_DRET: 0xffffffff + MATCH_SFENCE_VMA: 0x12000073 + MASK_SFENCE_VMA: 0xfe007fff + MATCH_WFI: 0x10500073 + MASK_WFI: 0xffffffff + MATCH_CSRRW: 0x1073 + MASK_CSRRW: 0x707f + MATCH_CSRRS: 0x2073 + MASK_CSRRS: 0x707f + MATCH_CSRRC: 0x3073 + MASK_CSRRC: 0x707f + MATCH_CSRRWI: 0x5073 + MASK_CSRRWI: 0x707f + MATCH_CSRRSI: 0x6073 + MASK_CSRRSI: 0x707f + MATCH_CSRRCI: 0x7073 + MASK_CSRRCI: 0x707f + MATCH_FADD_S: 0x53 + MASK_FADD_S: 0xfe00007f + MATCH_FSUB_S: 0x8000053 + MASK_FSUB_S: 0xfe00007f + MATCH_FMUL_S: 0x10000053 + MASK_FMUL_S: 0xfe00007f + MATCH_FDIV_S: 0x18000053 + MASK_FDIV_S: 0xfe00007f + MATCH_FSGNJ_S: 0x20000053 + MASK_FSGNJ_S: 0xfe00707f + MATCH_FSGNJN_S: 0x20001053 + MASK_FSGNJN_S: 0xfe00707f + MATCH_FSGNJX_S: 0x20002053 + MASK_FSGNJX_S: 0xfe00707f + MATCH_FMIN_S: 0x28000053 + MASK_FMIN_S: 0xfe00707f + MATCH_FMAX_S: 0x28001053 + MASK_FMAX_S: 0xfe00707f + MATCH_FSQRT_S: 0x58000053 + MASK_FSQRT_S: 0xfff0007f + MATCH_FADD_D: 0x2000053 + MASK_FADD_D: 0xfe00007f + MATCH_FSUB_D: 0xa000053 + MASK_FSUB_D: 0xfe00007f + MATCH_FMUL_D: 0x12000053 + MASK_FMUL_D: 0xfe00007f + MATCH_FDIV_D: 0x1a000053 + MASK_FDIV_D: 0xfe00007f + MATCH_FSGNJ_D: 0x22000053 + MASK_FSGNJ_D: 0xfe00707f + MATCH_FSGNJN_D: 0x22001053 + MASK_FSGNJN_D: 0xfe00707f + MATCH_FSGNJX_D: 0x22002053 + MASK_FSGNJX_D: 0xfe00707f + MATCH_FMIN_D: 0x2a000053 + MASK_FMIN_D: 0xfe00707f + MATCH_FMAX_D: 0x2a001053 + MASK_FMAX_D: 0xfe00707f + MATCH_FCVT_S_D: 0x40100053 + MASK_FCVT_S_D: 0xfff0007f + MATCH_FCVT_D_S: 0x42000053 + MASK_FCVT_D_S: 0xfff0007f + MATCH_FSQRT_D: 0x5a000053 + MASK_FSQRT_D: 0xfff0007f + MATCH_FADD_Q: 0x6000053 + MASK_FADD_Q: 0xfe00007f + MATCH_FSUB_Q: 0xe000053 + MASK_FSUB_Q: 0xfe00007f + MATCH_FMUL_Q: 0x16000053 + MASK_FMUL_Q: 0xfe00007f + MATCH_FDIV_Q: 0x1e000053 + MASK_FDIV_Q: 0xfe00007f + MATCH_FSGNJ_Q: 0x26000053 + MASK_FSGNJ_Q: 0xfe00707f + MATCH_FSGNJN_Q: 0x26001053 + MASK_FSGNJN_Q: 0xfe00707f + MATCH_FSGNJX_Q: 0x26002053 + MASK_FSGNJX_Q: 0xfe00707f + MATCH_FMIN_Q: 0x2e000053 + MASK_FMIN_Q: 0xfe00707f + MATCH_FMAX_Q: 0x2e001053 + MASK_FMAX_Q: 0xfe00707f + MATCH_FCVT_S_Q: 0x40300053 + MASK_FCVT_S_Q: 0xfff0007f + MATCH_FCVT_Q_S: 0x46000053 + MASK_FCVT_Q_S: 0xfff0007f + MATCH_FCVT_D_Q: 0x42300053 + MASK_FCVT_D_Q: 0xfff0007f + MATCH_FCVT_Q_D: 0x46100053 + MASK_FCVT_Q_D: 0xfff0007f + MATCH_FSQRT_Q: 0x5e000053 + MASK_FSQRT_Q: 0xfff0007f + MATCH_FLE_S: 0xa0000053 + MASK_FLE_S: 0xfe00707f + MATCH_FLT_S: 0xa0001053 + MASK_FLT_S: 0xfe00707f + MATCH_FEQ_S: 0xa0002053 + MASK_FEQ_S: 0xfe00707f + MATCH_FLE_D: 0xa2000053 + MASK_FLE_D: 0xfe00707f + MATCH_FLT_D: 0xa2001053 + MASK_FLT_D: 0xfe00707f + MATCH_FEQ_D: 0xa2002053 + MASK_FEQ_D: 0xfe00707f + MATCH_FLE_Q: 0xa6000053 + MASK_FLE_Q: 0xfe00707f + MATCH_FLT_Q: 0xa6001053 + MASK_FLT_Q: 0xfe00707f + MATCH_FEQ_Q: 0xa6002053 + MASK_FEQ_Q: 0xfe00707f + MATCH_FCVT_W_S: 0xc0000053 + MASK_FCVT_W_S: 0xfff0007f + MATCH_FCVT_WU_S: 0xc0100053 + MASK_FCVT_WU_S: 0xfff0007f + MATCH_FCVT_L_S: 0xc0200053 + MASK_FCVT_L_S: 0xfff0007f + MATCH_FCVT_LU_S: 0xc0300053 + MASK_FCVT_LU_S: 0xfff0007f + MATCH_FMV_X_W: 0xe0000053 + MASK_FMV_X_W: 0xfff0707f + MATCH_FCLASS_S: 0xe0001053 + MASK_FCLASS_S: 0xfff0707f + MATCH_FCVT_W_D: 0xc2000053 + MASK_FCVT_W_D: 0xfff0007f + MATCH_FCVT_WU_D: 0xc2100053 + MASK_FCVT_WU_D: 0xfff0007f + MATCH_FCVT_L_D: 0xc2200053 + MASK_FCVT_L_D: 0xfff0007f + MATCH_FCVT_LU_D: 0xc2300053 + MASK_FCVT_LU_D: 0xfff0007f + MATCH_FMV_X_D: 0xe2000053 + MASK_FMV_X_D: 0xfff0707f + MATCH_FCLASS_D: 0xe2001053 + MASK_FCLASS_D: 0xfff0707f + MATCH_FCVT_W_Q: 0xc6000053 + MASK_FCVT_W_Q: 0xfff0007f + MATCH_FCVT_WU_Q: 0xc6100053 + MASK_FCVT_WU_Q: 0xfff0007f + MATCH_FCVT_L_Q: 0xc6200053 + MASK_FCVT_L_Q: 0xfff0007f + MATCH_FCVT_LU_Q: 0xc6300053 + MASK_FCVT_LU_Q: 0xfff0007f + MATCH_FMV_X_Q: 0xe6000053 + MASK_FMV_X_Q: 0xfff0707f + MATCH_FCLASS_Q: 0xe6001053 + MASK_FCLASS_Q: 0xfff0707f + MATCH_FCVT_S_W: 0xd0000053 + MASK_FCVT_S_W: 0xfff0007f + MATCH_FCVT_S_WU: 0xd0100053 + MASK_FCVT_S_WU: 0xfff0007f + MATCH_FCVT_S_L: 0xd0200053 + MASK_FCVT_S_L: 0xfff0007f + MATCH_FCVT_S_LU: 0xd0300053 + MASK_FCVT_S_LU: 0xfff0007f + MATCH_FMV_W_X: 0xf0000053 + MASK_FMV_W_X: 0xfff0707f + MATCH_FCVT_D_W: 0xd2000053 + MASK_FCVT_D_W: 0xfff0007f + MATCH_FCVT_D_WU: 0xd2100053 + MASK_FCVT_D_WU: 0xfff0007f + MATCH_FCVT_D_L: 0xd2200053 + MASK_FCVT_D_L: 0xfff0007f + MATCH_FCVT_D_LU: 0xd2300053 + MASK_FCVT_D_LU: 0xfff0007f + MATCH_FMV_D_X: 0xf2000053 + MASK_FMV_D_X: 0xfff0707f + MATCH_FCVT_Q_W: 0xd6000053 + MASK_FCVT_Q_W: 0xfff0007f + MATCH_FCVT_Q_WU: 0xd6100053 + MASK_FCVT_Q_WU: 0xfff0007f + MATCH_FCVT_Q_L: 0xd6200053 + MASK_FCVT_Q_L: 0xfff0007f + MATCH_FCVT_Q_LU: 0xd6300053 + MASK_FCVT_Q_LU: 0xfff0007f + MATCH_FMV_Q_X: 0xf6000053 + MASK_FMV_Q_X: 0xfff0707f + MATCH_FLW: 0x2007 + MASK_FLW: 0x707f + MATCH_FLD: 0x3007 + MASK_FLD: 0x707f + MATCH_FLQ: 0x4007 + MASK_FLQ: 0x707f + MATCH_FSW: 0x2027 + MASK_FSW: 0x707f + MATCH_FSD: 0x3027 + MASK_FSD: 0x707f + MATCH_FSQ: 0x4027 + MASK_FSQ: 0x707f + MATCH_FMADD_S: 0x43 + MASK_FMADD_S: 0x600007f + MATCH_FMSUB_S: 0x47 + MASK_FMSUB_S: 0x600007f + MATCH_FNMSUB_S: 0x4b + MASK_FNMSUB_S: 0x600007f + MATCH_FNMADD_S: 0x4f + MASK_FNMADD_S: 0x600007f + MATCH_FMADD_D: 0x2000043 + MASK_FMADD_D: 0x600007f + MATCH_FMSUB_D: 0x2000047 + MASK_FMSUB_D: 0x600007f + MATCH_FNMSUB_D: 0x200004b + MASK_FNMSUB_D: 0x600007f + MATCH_FNMADD_D: 0x200004f + MASK_FNMADD_D: 0x600007f + MATCH_FMADD_Q: 0x6000043 + MASK_FMADD_Q: 0x600007f + MATCH_FMSUB_Q: 0x6000047 + MASK_FMSUB_Q: 0x600007f + MATCH_FNMSUB_Q: 0x600004b + MASK_FNMSUB_Q: 0x600007f + MATCH_FNMADD_Q: 0x600004f + MASK_FNMADD_Q: 0x600007f + MATCH_C_NOP: 0x1 + MASK_C_NOP: 0xffff + MATCH_C_ADDI16SP: 0x6101 + MASK_C_ADDI16SP: 0xef83 + MATCH_C_JR: 0x8002 + MASK_C_JR: 0xf07f + MATCH_C_JALR: 0x9002 + MASK_C_JALR: 0xf07f + MATCH_C_EBREAK: 0x9002 + MASK_C_EBREAK: 0xffff + MATCH_C_LD: 0x6000 + MASK_C_LD: 0xe003 + MATCH_C_SD: 0xe000 + MASK_C_SD: 0xe003 + MATCH_C_ADDIW: 0x2001 + MASK_C_ADDIW: 0xe003 + MATCH_C_LDSP: 0x6002 + MASK_C_LDSP: 0xe003 + MATCH_C_SDSP: 0xe002 + MASK_C_SDSP: 0xe003 + MATCH_C_ADDI4SPN: 0x0 + MASK_C_ADDI4SPN: 0xe003 + MATCH_C_FLD: 0x2000 + MASK_C_FLD: 0xe003 + MATCH_C_LW: 0x4000 + MASK_C_LW: 0xe003 + MATCH_C_FLW: 0x6000 + MASK_C_FLW: 0xe003 + MATCH_C_FSD: 0xa000 + MASK_C_FSD: 0xe003 + MATCH_C_SW: 0xc000 + MASK_C_SW: 0xe003 + MATCH_C_FSW: 0xe000 + MASK_C_FSW: 0xe003 + MATCH_C_ADDI: 0x1 + MASK_C_ADDI: 0xe003 + MATCH_C_JAL: 0x2001 + MASK_C_JAL: 0xe003 + MATCH_C_LI: 0x4001 + MASK_C_LI: 0xe003 + MATCH_C_LUI: 0x6001 + MASK_C_LUI: 0xe003 + MATCH_C_SRLI: 0x8001 + MASK_C_SRLI: 0xec03 + MATCH_C_SRAI: 0x8401 + MASK_C_SRAI: 0xec03 + MATCH_C_ANDI: 0x8801 + MASK_C_ANDI: 0xec03 + MATCH_C_SUB: 0x8c01 + MASK_C_SUB: 0xfc63 + MATCH_C_XOR: 0x8c21 + MASK_C_XOR: 0xfc63 + MATCH_C_OR: 0x8c41 + MASK_C_OR: 0xfc63 + MATCH_C_AND: 0x8c61 + MASK_C_AND: 0xfc63 + MATCH_C_SUBW: 0x9c01 + MASK_C_SUBW: 0xfc63 + MATCH_C_ADDW: 0x9c21 + MASK_C_ADDW: 0xfc63 + MATCH_C_J: 0xa001 + MASK_C_J: 0xe003 + MATCH_C_BEQZ: 0xc001 + MASK_C_BEQZ: 0xe003 + MATCH_C_BNEZ: 0xe001 + MASK_C_BNEZ: 0xe003 + MATCH_C_SLLI: 0x2 + MASK_C_SLLI: 0xe003 + MATCH_C_FLDSP: 0x2002 + MASK_C_FLDSP: 0xe003 + MATCH_C_LWSP: 0x4002 + MASK_C_LWSP: 0xe003 + MATCH_C_FLWSP: 0x6002 + MASK_C_FLWSP: 0xe003 + MATCH_C_MV: 0x8002 + MASK_C_MV: 0xf003 + MATCH_C_ADD: 0x9002 + MASK_C_ADD: 0xf003 + MATCH_C_FSDSP: 0xa002 + MASK_C_FSDSP: 0xe003 + MATCH_C_SWSP: 0xc002 + MASK_C_SWSP: 0xe003 + MATCH_C_FSWSP: 0xe002 + MASK_C_FSWSP: 0xe003 + MATCH_CUSTOM0: 0xb + MASK_CUSTOM0: 0x707f + MATCH_CUSTOM0_RS1: 0x200b + MASK_CUSTOM0_RS1: 0x707f + MATCH_CUSTOM0_RS1_RS2: 0x300b + MASK_CUSTOM0_RS1_RS2: 0x707f + MATCH_CUSTOM0_RD: 0x400b + MASK_CUSTOM0_RD: 0x707f + MATCH_CUSTOM0_RD_RS1: 0x600b + MASK_CUSTOM0_RD_RS1: 0x707f + MATCH_CUSTOM0_RD_RS1_RS2: 0x700b + MASK_CUSTOM0_RD_RS1_RS2: 0x707f + MATCH_CUSTOM1: 0x2b + MASK_CUSTOM1: 0x707f + MATCH_CUSTOM1_RS1: 0x202b + MASK_CUSTOM1_RS1: 0x707f + MATCH_CUSTOM1_RS1_RS2: 0x302b + MASK_CUSTOM1_RS1_RS2: 0x707f + MATCH_CUSTOM1_RD: 0x402b + MASK_CUSTOM1_RD: 0x707f + MATCH_CUSTOM1_RD_RS1: 0x602b + MASK_CUSTOM1_RD_RS1: 0x707f + MATCH_CUSTOM1_RD_RS1_RS2: 0x702b + MASK_CUSTOM1_RD_RS1_RS2: 0x707f + MATCH_CUSTOM2: 0x5b + MASK_CUSTOM2: 0x707f + MATCH_CUSTOM2_RS1: 0x205b + MASK_CUSTOM2_RS1: 0x707f + MATCH_CUSTOM2_RS1_RS2: 0x305b + MASK_CUSTOM2_RS1_RS2: 0x707f + MATCH_CUSTOM2_RD: 0x405b + MASK_CUSTOM2_RD: 0x707f + MATCH_CUSTOM2_RD_RS1: 0x605b + MASK_CUSTOM2_RD_RS1: 0x707f + MATCH_CUSTOM2_RD_RS1_RS2: 0x705b + MASK_CUSTOM2_RD_RS1_RS2: 0x707f + MATCH_CUSTOM3: 0x7b + MASK_CUSTOM3: 0x707f + MATCH_CUSTOM3_RS1: 0x207b + MASK_CUSTOM3_RS1: 0x707f + MATCH_CUSTOM3_RS1_RS2: 0x307b + MASK_CUSTOM3_RS1_RS2: 0x707f + MATCH_CUSTOM3_RD: 0x407b + MASK_CUSTOM3_RD: 0x707f + MATCH_CUSTOM3_RD_RS1: 0x607b + MASK_CUSTOM3_RD_RS1: 0x707f + MATCH_CUSTOM3_RD_RS1_RS2: 0x707b + MASK_CUSTOM3_RD_RS1_RS2: 0x707f + CSR_FFLAGS: 0x1 + CSR_FRM: 0x2 + CSR_FCSR: 0x3 + CSR_CYCLE: 0xc00 + CSR_TIME: 0xc01 + CSR_INSTRET: 0xc02 + CSR_HEDELEG: 0x602 + CSR_HPMCOUNTER3: 0xc03 + CSR_HPMCOUNTER4: 0xc04 + CSR_HPMCOUNTER5: 0xc05 + CSR_HPMCOUNTER6: 0xc06 + CSR_HPMCOUNTER7: 0xc07 + CSR_HPMCOUNTER8: 0xc08 + CSR_HPMCOUNTER9: 0xc09 + CSR_HPMCOUNTER10: 0xc0a + CSR_HPMCOUNTER11: 0xc0b + CSR_HPMCOUNTER12: 0xc0c + CSR_HPMCOUNTER13: 0xc0d + CSR_HPMCOUNTER14: 0xc0e + CSR_HPMCOUNTER15: 0xc0f + CSR_HPMCOUNTER16: 0xc10 + CSR_HPMCOUNTER17: 0xc11 + CSR_HPMCOUNTER18: 0xc12 + CSR_HPMCOUNTER19: 0xc13 + CSR_HPMCOUNTER20: 0xc14 + CSR_HPMCOUNTER21: 0xc15 + CSR_HPMCOUNTER22: 0xc16 + CSR_HPMCOUNTER23: 0xc17 + CSR_HPMCOUNTER24: 0xc18 + CSR_HPMCOUNTER25: 0xc19 + CSR_HPMCOUNTER26: 0xc1a + CSR_HPMCOUNTER27: 0xc1b + CSR_HPMCOUNTER28: 0xc1c + CSR_HPMCOUNTER29: 0xc1d + CSR_HPMCOUNTER30: 0xc1e + CSR_HPMCOUNTER31: 0xc1f + CSR_VSATP: 0x280 + CSR_HSTATUS: 0x600 + CSR_SSTATUS: 0x100 + CSR_SIE: 0x104 + CSR_STVEC: 0x105 + CSR_SCOUNTEREN: 0x106 + CSR_SSCRATCH: 0x140 + CSR_SEPC: 0x141 + CSR_SCAUSE: 0x142 + CSR_STVAL: 0x143 + CSR_SIP: 0x144 + CSR_SATP: 0x180 + CSR_SEDELEG: 0x102 + CSR_MSTATUS: 0x300 + CSR_MSTATUSH: 0x310 + CSR_MISA: 0x301 + CSR_MEDELEG: 0x302 + CSR_MIDELEG: 0x303 + CSR_MIE: 0x304 + CSR_MTVEC: 0x305 + CSR_MCOUNTEREN: 0x306 + CSR_MSCRATCH: 0x340 + CSR_MEPC: 0x341 + CSR_MCAUSE: 0x342 + CSR_MTVAL: 0x343 + CSR_MIP: 0x344 + CSR_PMPCFG0: 0x3a0 + CSR_PMPCFG1: 0x3a1 + CSR_PMPCFG2: 0x3a2 + CSR_PMPCFG3: 0x3a3 + CSR_PMPADDR0: 0x3b0 + CSR_PMPADDR1: 0x3b1 + CSR_PMPADDR2: 0x3b2 + CSR_PMPADDR3: 0x3b3 + CSR_PMPADDR4: 0x3b4 + CSR_PMPADDR5: 0x3b5 + CSR_PMPADDR6: 0x3b6 + CSR_PMPADDR7: 0x3b7 + CSR_PMPADDR8: 0x3b8 + CSR_PMPADDR9: 0x3b9 + CSR_PMPADDR10: 0x3ba + CSR_PMPADDR11: 0x3bb + CSR_PMPADDR12: 0x3bc + CSR_PMPADDR13: 0x3bd + CSR_PMPADDR14: 0x3be + CSR_PMPADDR15: 0x3bf + CSR_TSELECT: 0x7a0 + CSR_TDATA1: 0x7a1 + CSR_TDATA2: 0x7a2 + CSR_TDATA3: 0x7a3 + CSR_DCSR: 0x7b0 + CSR_DPC: 0x7b1 + CSR_DSCRATCH: 0x7b2 + CSR_MCYCLE: 0xb00 + CSR_MINSTRET: 0xb02 + CSR_MHPMCOUNTER3: 0xb03 + CSR_MHPMCOUNTER4: 0xb04 + CSR_MHPMCOUNTER5: 0xb05 + CSR_MHPMCOUNTER6: 0xb06 + CSR_MHPMCOUNTER7: 0xb07 + CSR_MHPMCOUNTER8: 0xb08 + CSR_MHPMCOUNTER9: 0xb09 + CSR_MHPMCOUNTER10: 0xb0a + CSR_MHPMCOUNTER11: 0xb0b + CSR_MHPMCOUNTER12: 0xb0c + CSR_MHPMCOUNTER13: 0xb0d + CSR_MHPMCOUNTER14: 0xb0e + CSR_MHPMCOUNTER15: 0xb0f + CSR_MHPMCOUNTER16: 0xb10 + CSR_MHPMCOUNTER17: 0xb11 + CSR_MHPMCOUNTER18: 0xb12 + CSR_MHPMCOUNTER19: 0xb13 + CSR_MHPMCOUNTER20: 0xb14 + CSR_MHPMCOUNTER21: 0xb15 + CSR_MHPMCOUNTER22: 0xb16 + CSR_MHPMCOUNTER23: 0xb17 + CSR_MHPMCOUNTER24: 0xb18 + CSR_MHPMCOUNTER25: 0xb19 + CSR_MHPMCOUNTER26: 0xb1a + CSR_MHPMCOUNTER27: 0xb1b + CSR_MHPMCOUNTER28: 0xb1c + CSR_MHPMCOUNTER29: 0xb1d + CSR_MHPMCOUNTER30: 0xb1e + CSR_MHPMCOUNTER31: 0xb1f + CSR_MHPMEVENT3: 0x323 + CSR_MHPMEVENT4: 0x324 + CSR_MHPMEVENT5: 0x325 + CSR_MHPMEVENT6: 0x326 + CSR_MHPMEVENT7: 0x327 + CSR_MHPMEVENT8: 0x328 + CSR_MHPMEVENT9: 0x329 + CSR_MHPMEVENT10: 0x32a + CSR_MHPMEVENT11: 0x32b + CSR_MHPMEVENT12: 0x32c + CSR_MHPMEVENT13: 0x32d + CSR_MHPMEVENT14: 0x32e + CSR_MHPMEVENT15: 0x32f + CSR_MHPMEVENT16: 0x330 + CSR_MHPMEVENT17: 0x331 + CSR_MHPMEVENT18: 0x332 + CSR_MHPMEVENT19: 0x333 + CSR_MHPMEVENT20: 0x334 + CSR_MHPMEVENT21: 0x335 + CSR_MHPMEVENT22: 0x336 + CSR_MHPMEVENT23: 0x337 + CSR_MHPMEVENT24: 0x338 + CSR_MHPMEVENT25: 0x339 + CSR_MHPMEVENT26: 0x33a + CSR_MHPMEVENT27: 0x33b + CSR_MHPMEVENT28: 0x33c + CSR_MHPMEVENT29: 0x33d + CSR_MHPMEVENT30: 0x33e + CSR_MHPMEVENT31: 0x33f + CSR_MVENDORID: 0xf11 + CSR_MARCHID: 0xf12 + CSR_MIMPID: 0xf13 + CSR_MHARTID: 0xf14 + CSR_CYCLEH: 0xc80 + CSR_TIMEH: 0xc81 + CSR_INSTRETH: 0xc82 + CSR_HPMCOUNTER3H: 0xc83 + CSR_HPMCOUNTER4H: 0xc84 + CSR_HPMCOUNTER5H: 0xc85 + CSR_HPMCOUNTER6H: 0xc86 + CSR_HPMCOUNTER7H: 0xc87 + CSR_HPMCOUNTER8H: 0xc88 + CSR_HPMCOUNTER9H: 0xc89 + CSR_HPMCOUNTER10H: 0xc8a + CSR_HPMCOUNTER11H: 0xc8b + CSR_HPMCOUNTER12H: 0xc8c + CSR_HPMCOUNTER13H: 0xc8d + CSR_HPMCOUNTER14H: 0xc8e + CSR_HPMCOUNTER15H: 0xc8f + CSR_HPMCOUNTER16H: 0xc90 + CSR_HPMCOUNTER17H: 0xc91 + CSR_HPMCOUNTER18H: 0xc92 + CSR_HPMCOUNTER19H: 0xc93 + CSR_HPMCOUNTER20H: 0xc94 + CSR_HPMCOUNTER21H: 0xc95 + CSR_HPMCOUNTER22H: 0xc96 + CSR_HPMCOUNTER23H: 0xc97 + CSR_HPMCOUNTER24H: 0xc98 + CSR_HPMCOUNTER25H: 0xc99 + CSR_HPMCOUNTER26H: 0xc9a + CSR_HPMCOUNTER27H: 0xc9b + CSR_HPMCOUNTER28H: 0xc9c + CSR_HPMCOUNTER29H: 0xc9d + CSR_HPMCOUNTER30H: 0xc9e + CSR_HPMCOUNTER31H: 0xc9f + CSR_MCYCLEH: 0xb80 + CSR_MINSTRETH: 0xb82 + CSR_MHPMCOUNTER3H: 0xb83 + CSR_MHPMCOUNTER4H: 0xb84 + CSR_MHPMCOUNTER5H: 0xb85 + CSR_MHPMCOUNTER6H: 0xb86 + CSR_MHPMCOUNTER7H: 0xb87 + CSR_MHPMCOUNTER8H: 0xb88 + CSR_MHPMCOUNTER9H: 0xb89 + CSR_MHPMCOUNTER10H: 0xb8a + CSR_MHPMCOUNTER11H: 0xb8b + CSR_MHPMCOUNTER12H: 0xb8c + CSR_MHPMCOUNTER13H: 0xb8d + CSR_MHPMCOUNTER14H: 0xb8e + CSR_MHPMCOUNTER15H: 0xb8f + CSR_MHPMCOUNTER16H: 0xb90 + CSR_MHPMCOUNTER17H: 0xb91 + CSR_MHPMCOUNTER18H: 0xb92 + CSR_MHPMCOUNTER19H: 0xb93 + CSR_MHPMCOUNTER20H: 0xb94 + CSR_MHPMCOUNTER21H: 0xb95 + CSR_MHPMCOUNTER22H: 0xb96 + CSR_MHPMCOUNTER23H: 0xb97 + CSR_MHPMCOUNTER24H: 0xb98 + CSR_MHPMCOUNTER25H: 0xb99 + CSR_MHPMCOUNTER26H: 0xb9a + CSR_MHPMCOUNTER27H: 0xb9b + CSR_MHPMCOUNTER28H: 0xb9c + CSR_MHPMCOUNTER29H: 0xb9d + CSR_MHPMCOUNTER30H: 0xb9e + CSR_MHPMCOUNTER31H: 0xb9f + CAUSE_MISALIGNED_FETCH: 0x0 + CAUSE_FETCH_ACCESS: 0x1 + CAUSE_ILLEGAL_INSTRUCTION: 0x2 + CAUSE_BREAKPOINT: 0x3 + CAUSE_MISALIGNED_LOAD: 0x4 + CAUSE_LOAD_ACCESS: 0x5 + CAUSE_MISALIGNED_STORE: 0x6 + CAUSE_STORE_ACCESS: 0x7 + CAUSE_USER_ECALL: 0x8 + CAUSE_SUPERVISOR_ECALL: 0x9 + CAUSE_HYPERVISOR_ECALL: 0xa + CAUSE_MACHINE_ECALL: 0xb + CAUSE_FETCH_PAGE_FAULT: 0xc + CAUSE_LOAD_PAGE_FAULT: 0xd + CAUSE_STORE_PAGE_FAULT: 0xf + CSR_MENTROPY: 0xF15 + CSR_MNOISE: 0x7A9 + DCSR_XDEBUGVER: (3U<<30) + DCSR_NDRESET: (1<<29) + DCSR_FULLRESET: (1<<28) + DCSR_EBREAKM: (1<<15) + DCSR_EBREAKH: (1<<14) + DCSR_EBREAKS: (1<<13) + DCSR_EBREAKU: (1<<12) + DCSR_STOPCYCLE: (1<<10) + DCSR_STOPTIME: (1<<9) + DCSR_CAUSE: (7<<6) + DCSR_DEBUGINT: (1<<5) + DCSR_HALT: (1<<3) + DCSR_STEP: (1<<2) + DCSR_PRV: (3<<0) + MCONTROL_SELECT: (1<<19) + MCONTROL_TIMING: (1<<18) + MCONTROL_ACTION: (0x3f<<12) + MCONTROL_CHAIN: (1<<11) + MCONTROL_MATCH: (0xf<<7) + MCONTROL_M: (1<<6) + MCONTROL_H: (1<<5) + MCONTROL_S: (1<<4) + MCONTROL_U: (1<<3) + MCONTROL_EXECUTE: (1<<2) + MCONTROL_STORE: (1<<1) + MCONTROL_LOAD: (1<<0) + MIP_SSIP: (1 << IRQ_S_SOFT) + MIP_HSIP: (1 << IRQ_H_SOFT) + MIP_MSIP: (1 << IRQ_M_SOFT) + MIP_STIP: (1 << IRQ_S_TIMER) + MIP_HTIP: (1 << IRQ_H_TIMER) + MIP_MTIP: (1 << IRQ_M_TIMER) + MIP_SEIP: (1 << IRQ_S_EXT) + MIP_HEIP: (1 << IRQ_H_EXT) + MIP_MEIP: (1 << IRQ_M_EXT) + RISCV_PGSIZE: (1 << RISCV_PGSHIFT) + +PMP_MACROS: + PMPCFG_BIT_SET: 1 + PMPCFG_BIT_NOT_SET: 0 + PMPCFG_ONLY_R_SET: 0x01 + PMPCFG_ONLY_X_SET: 0x04 + PMPCFG_ONLY_RW_SET: 0x03 + PMPCFG_ONLY_RX_SET: 0x05 + PMPCFG_ONLY_RWX_SET: 0x07 + PMPCFG_OFF_MODE: 0x00 + PMPCFG_TOR_MODE: 0x08 + PMPCFG_NA4_MODE: 0x10 + PMPCFG_NAPOT_MODE: 0x18 + PMPCFG_R_BIT: 0x01 + PMPCFG_W_BIT: 0x02 + PMPCFG_X_BIT: 0x04 + PMPCFG_RWX_BIT: 0x07 + PMPCFG_A_BIT: 0x18 + PMPCFG_RW_BIT: 0x60 + PMPCFG_L_BIT: 0x80 + PMPCFG_ALL_BIT: 0xFF + +PMP_helper_Coverpoints: + NAPOT_REGION_ADDRESS_MATCH: ((rs1_val + imm_val) ^ (pmpaddr1<<2)) & ~(((pmpaddr1 ^ (pmpaddr1+1))<<2) | 3) ==0 and ((rs1_val+imm_val+access_len-1 ) ^ (pmpaddr1<<2)) & ~(((pmpaddr1 ^ (pmpaddr1+1))<<2) | 3) ==0 + NAPOT_PRIORITY_REGION_MATCH: ((rs1_val + imm_val) ^ (pmpaddr3<<2)) & ~(((pmpaddr3 ^ (pmpaddr3+1))<<2) | 3) ==0 and ((rs1_val+imm_val+access_len-1 ) ^ (pmpaddr3<<2)) & ~(((pmpaddr3 ^ (pmpaddr3+1))<<2) | 3) ==0 + NAPOT_PRIORITY_2_REGION_MATCH: ((rs1_val + imm_val) ^ (pmpaddr1<<2)) & ~(((pmpaddr1 ^ (pmpaddr1+1))<<2) | 3) ==0 and ((rs1_val+imm_val+access_len-1 ) ^ (pmpaddr1<<2)) & ~(((pmpaddr1 ^ (pmpaddr1+1))<<2) | 3) ==0 + TOR_REGION_ADDRESS_MATCH: (rs1_val + imm_val >= (pmpaddr1 << 2)) and (rs1_val + imm_val < (pmpaddr2 << 2)) + TOR_PRIORITY_REGION_MATCH: (rs1_val + imm_val >= (pmpaddr2 << 2)) and (rs1_val + imm_val < (pmpaddr3 << 2)) + TOR_PRIORITY_2_REGION_MATCH: (rs1_val + imm_val >= (pmpaddr0 << 2)) and (rs1_val + imm_val < (pmpaddr1 << 2)) + NA4_REGION_ADDRESS_MATCH: (rs1_val + imm_val == (pmpaddr1 << 2)) + NA4_PRIORITY_REGION_MATCH: (rs1_val + imm_val == (pmpaddr3 << 2)) + NA4_PRIORITY_2_REGION_MATCH: (rs1_val + imm_val == (pmpaddr1 << 2)) \ No newline at end of file diff --git a/coverage/rv32_pmp.cgf b/coverage/rv32_pmp.cgf new file mode 100644 index 000000000..1b65ddc5d --- /dev/null +++ b/coverage/rv32_pmp.cgf @@ -0,0 +1,836 @@ +# This coverpoint checks the coverage of Lock bit test. +# req = The old value of the pmpcfgs and pmpaddrs should be equal to the new one since the Lock bit is set and the new write try will fail. +pmp_cfg_locked_write_unrelated: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw}" : 0 + csr_comb: + # (Lock bit set) and (req) and (old_value_pmpcfg != 0) + (pmpcfg{{0 ... 15} >> 2} >> {0, 8, 16, 24}{[$2%4]} & 0x80 == 0x80) and (((old("pmpcfg$2") ^ pmpcfg$2) >> $3 & 0xFF) == 0x00) and old("pmpcfg$2") != 0: 0 + (pmpcfg{{0 ... 15} >> 2} >> {0, 8, 16, 24}{[$1%4]} & 0x80 == 0x80) and (old("pmpaddr$1") == (pmpaddr$1)) and (pmpcfg$2 != 0): 0 + +#This coverpoint checks the coverage of pmp-CSR-access.cgf (PMP CSRs accesses in different modes) +#Checks pmpcgf and pmpaddr are only accessible in M mode and gets fault in S and U mode when accessed. +PMP_access_permission: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw}" : 0 + csr_comb: + #Check successful update for pmpcfg in M Mode + mode == 'M' and ((old("pmpcfg{0 ... 3}") != (pmpcfg$1)) and pmpcfg$1 != 0x0): 0 + #Check successful update for pmpaddr in M Mode + mode == 'M' and ((old("pmpaddr{0 ... 15}") != (pmpaddr$1)) and pmpaddr$1 != 0x0): 0 #pmpaddr successfully updated in M mode + #Check for fault for pmpcfg, pmpaddr in S, U Mode + mode == {'S', 'U'} and mcause == ${CAUSE_ILLEGAL_INSTRUCTION}: 0 #check for illegal instruction fault + +# This coverpoint checks the coverage for the pmp-NAPOT-R.S +# R bit is set for pmpcfg but wx is not set for the region, so there should be store and fetch access fault. +PMP_NAPOT_r: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Check Lock bit is set, R bit is set, W bit not set, X bit not set, NAPOT Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NAPOT_MODE}+${PMPCFG_ONLY_R_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw instruction + mnemonic == {'sb', 'sh', 'sw'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check for execute fault + mode == 'M' and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_FETCH_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x99) and ${NAPOT_REGION_ADDRESS_MATCH}': 0 + +# This coverpoint checks the coverage for the pmp-NAPOT-X.S +# X bit is set for pmpcfg but RW is not set for the region, so there should be load and store access fault. +PMP_NAPOT_x: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Check Lock bit is set, R bit is set, W bit not set, X bit not set, NAPOT Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NAPOT_MODE}+${PMPCFG_ONLY_X_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw instruction + mnemonic == {'sb', 'sh', 'sw'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check for load fault on lb, lh, lw instruction + mnemonic == {'lb', 'lh', 'lw'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_LOAD_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x9C) and ${NAPOT_REGION_ADDRESS_MATCH}': 0 + +# This coverpoint checks the coverage for the pmp-NAPOT-RW.S +# RW bit is set for pmpcfg but X is not set for the region, so there should be fetch access fault. +PMP_NAPOT_rw: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Check Lock bit is set, R bit is set, W bit not set, X bit not set, NAPOT Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NAPOT_MODE}+${PMPCFG_ONLY_RW_SET}": 0 + val_comb: + #Check for execute fault + mode == 'M' and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_FETCH_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x9B) and ${NAPOT_REGION_ADDRESS_MATCH}': 0 + +# This coverpoint checks the coverage for the pmp-NAPOT-RX.S +# RX bit is set for pmpcfg but W is not set for the region, so there should be store access fault. +PMP_NAPOT_rx: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Check Lock bit is set, R bit is set, W bit not set, X bit not set, NAPOT Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NAPOT_MODE}+${PMPCFG_ONLY_RX_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw instruction + mnemonic == {'sb', 'sh', 'sw'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x9D) and ${NAPOT_REGION_ADDRESS_MATCH}': 0 + +# This coverpoint checks the coverage for the pmp-NAPOT-RWX.S +# R,W,X bit is set for pmpcfg, so there should be NO access fault. +PMP_NAPOT_rwx: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Check Lock bit is set, R bit is set, W bit not set, X bit not set, NAPOT Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NAPOT_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + val_comb: + #Check the napot region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x9F) and ${NAPOT_REGION_ADDRESS_MATCH}': 0 + +# This coverpoint checks the coverage for the pmp-TOR-R.S +# R bit is set for pmpcfg but wx is not set for the region, so there should be store and fetch access fault. +PMP_TOR_r: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Check Lock bit is set, R bit is set, W bit not set, X bit not set, NAPOT Mode is set + "(pmpcfg0 >> 16) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_R_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw instruction + mnemonic == {'sb', 'sh', 'sw'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check for execute fault + mode == 'M' and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_FETCH_ACCESS}): 0 + #Check the tor region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 16) & 0x9F == 0x89) and ${TOR_REGION_ADDRESS_MATCH}': 0 + +# This coverpoint checks the coverage for the pmp-TOR-X.S +# X bit is set for pmpcfg but RW is not set for the region, so there should be load and store access fault. +PMP_TOR_x: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Check Lock bit is set, R bit not set, W bit not set, X bit is set, NAPOT Mode is set + "(pmpcfg0 >> 16) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_X_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw instruction + mnemonic == {'sb', 'sh', 'sw'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check for load fault on lb, lh, lw instruction + mnemonic == {'lb', 'lh', 'lw'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_LOAD_ACCESS}): 0 + #Check the tor region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 16) & 0x9F == 0x8C) and ${TOR_REGION_ADDRESS_MATCH}': 0 + +# This coverpoint checks the coverage for the pmp-TOR-RW.S +# RW bit is set for pmpcfg but X is not set for the region, so there should be fetch access fault. +PMP_TOR_rw: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Check Lock bit is set, R bit is set, W bit is set, X bit not set, NAPOT Mode is set + "(pmpcfg0 >> 16) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RW_SET}": 0 + val_comb: + #Check for execute fault + mode == 'M' and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_FETCH_ACCESS}): 0 + #Check the tor region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 16) & 0x9F == 0x8B) and ${NAPOT_REGION_ADDRESS_MATCH}': 0 + +# This coverpoint checks the coverage for the pmp-TOR-RX.S +# RX bit is set for pmpcfg but W is not set for the region, so there should be store access fault. +PMP_TOR_rx: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Check Lock bit is set, R bit is set, W bit not set, X bit is set, TOR Mode is set + "(pmpcfg0 >> 16) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RX_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw instruction + mnemonic == {'sb', 'sh', 'sw'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check the tor region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 16) & 0x9F == 0x8D) and ${NAPOT_REGION_ADDRESS_MATCH}': 0 + +# This coverpoint checks the coverage for the pmp-TOR-RWX.S +# R,W,X bit is set for pmpcfg, so there should be NO access fault. +PMP_TOR_rwx: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg0 >> 16) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + val_comb: + #Check the tor region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 16) & 0x9F == 0x8F) and ${NAPOT_REGION_ADDRESS_MATCH}': 0 + +# This coverpoint checks the coverage for the pmp-NA4-R.S +# R bit is set for pmpcfg but wx is not set for the region, so there should be store and fetch access fault. +PMP_NA4_r: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Check Lock bit is set, R bit is set, W bit not set, X bit not set, NAPOT Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NA4_MODE}+${PMPCFG_ONLY_R_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw instruction + mnemonic == {'sb', 'sh', 'sw'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check for execute fault + mode == 'M' and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_FETCH_ACCESS}): 0 + #Check the na4 region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x91) and ${NA4_REGION_ADDRESS_MATCH}': 0 + +# This coverpoint checks the coverage for the pmp-NA4-X.S +# X bit is set for pmpcfg but RW is not set for the region, so there should be load and store access fault. +PMP_NA4_x: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Check Lock bit is set, R bit not set, W bit not set, X bit set, NA4 Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NA4_MODE}+${PMPCFG_ONLY_X_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw instruction + mnemonic == {'sb', 'sh', 'sw'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check for load fault on lb, lh, lw instruction + mnemonic == {'lb', 'lh', 'lw'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_LOAD_ACCESS}): 0 + #Check the na4 region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x94) and ${NA4_REGION_ADDRESS_MATCH}': 0 + +# This coverpoint checks the coverage for the pmp-NA4-RW.S +# RW bit is set for pmpcfg but X is not set for the region, so there should be fetch access fault. +PMP_NA4_rw: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Check Lock bit is set, R bit is set, W bit is set, X bit not set, NA4 Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NA4_MODE}+${PMPCFG_ONLY_RW_SET}": 0 + val_comb: + #Check for execute fault + mode == 'M' and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_FETCH_ACCESS}): 0 + #Check the na4 region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x93) and ${NA4_REGION_ADDRESS_MATCH}': 0 + +# This coverpoint checks the coverage for the pmp-NA4-RX.S +# RX bit is set for pmpcfg but W is not set for the region, so there should be store access fault. +PMP_NA4_rx: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Check Lock bit is set, R bit is set, W bit not set, X bit not set, NAPOT Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NA4_MODE}+${PMPCFG_ONLY_RX_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw instruction + mnemonic == {'sb', 'sh', 'sw'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x95) and ${NA4_REGION_ADDRESS_MATCH}': 0 + +# This coverpoint checks the coverage for the pmp-NA4-RWX.S +# R,W,X bit is set for pmpcfg, so there should be NO access fault. +PMP_NA4_rwx: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Check Lock bit is set, R bit is set, W bit not set, X bit not set, NAPOT Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NA4_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + val_comb: + #Check the napot region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x97) and ${NA4_REGION_ADDRESS_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_NAPOT_r_priority.S +# This is a priority test. +# pmpcfg3 --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0 --> high priority entry gets R permission -- NAPOT region selected +# R succeeds while we get Store fault and fetch access fault +PMP_NAPOT_priority_r: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg3 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit is set, W bit not set, X bit not set, NAPOT Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NAPOT_MODE}+${PMPCFG_ONLY_R_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw instruction + mnemonic == {'sb', 'sh', 'sw'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check for execute fault + mode == 'M' and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_FETCH_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 24) & 0x9F == 0x99) and ${NAPOT_PRIORITY_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_NAPOT_x_priority.S +# This is a priority test. +# pmpcfg3 --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0 --> high priority entry gets X permission -- NAPOT region selected +# fetch succeeds while we get read access fault and store access fault +PMP_NAPOT_priority_x: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg3 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit is set, W bit not set, X bit not set, NAPOT Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NAPOT_MODE}+${PMPCFG_ONLY_X_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw instruction + mnemonic == {'sb', 'sh', 'sw'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check for load fault on lb, lh, lw instruction + mnemonic == {'lb', 'lh', 'lw'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_LOAD_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 24) & 0x9F == 0x9C) and ${NAPOT_PRIORITY_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_NAPOT_rw_priority.S +# This is a priority test. +# pmpcfg3 --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0 --> high priority entry gets RW permission -- NAPOT region selected +# load, store succeeds while we get fetch access fault +PMP_NAPOT_priority_rw: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg3 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit not set, NAPOT Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NAPOT_MODE}+${PMPCFG_ONLY_RW_SET}": 0 + val_comb: + #Check for execute fault + mode == 'M' and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_FETCH_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 24) & 0x9F == 0x9B) and ${NAPOT_PRIORITY_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_NAPOT_rx_priority.S +# This is a priority test. +# pmpcfg3 --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0 --> high priority entry gets R X permission -- NAPOT region selected +# load, fetch succeeds while we get store access fault +PMP_NAPOT_priority_rx: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg3 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit is set, W bit not set, X bit is set, NAPOT Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NAPOT_MODE}+${PMPCFG_ONLY_RX_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw instruction + mnemonic == {'sb', 'sh', 'sw'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 24) & 0x9F == 0x9D) and ${NAPOT_PRIORITY_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_TOR_r_priority.S +# This is a priority test. +# pmpcfg3 --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0 --> high priority entry gets R permission -- TOR region selected +# R succeeds while we get Store fault and fetch access fault +PMP_TOR_priority_r: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg3 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit is set, W bit not set, X bit not set, TOR Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_R_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw instruction + mnemonic == {'sb', 'sh', 'sw'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check for execute fault + mode == 'M' and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_FETCH_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 24) & 0x9F == 0x89) and ${TOR_PRIORITY_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_TOR_x_priority.S +# This is a priority test. +# pmpcfg3 --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0 --> high priority entry gets X permission -- TOR region selected +# X succeeds while we get load and store access faults +PMP_TOR_priority_x: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg3 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit not set, TOR Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_X_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw instruction + mnemonic == {'sb', 'sh', 'sw'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check for load fault on lb, lh, lw instruction + mnemonic == {'lb', 'lh', 'lw'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_LOAD_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 24) & 0x9F == 0x8C) and ${TOR_PRIORITY_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_TOR_rw_priority.S +# This is a priority test. +# pmpcfg3 --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0 --> high priority entry gets RW permission -- TOR region selected +# R,W succeeds while we get fetch access fault +PMP_TOR_priority_rw: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg3 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit not set, TOR Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RW_SET}": 0 + val_comb: + #Check for execute fault + mode == 'M' and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_FETCH_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 24) & 0x9F == 0x8B) and ${TOR_PRIORITY_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_TOR_rx_priority.S +# This is a priority test. +# pmpcfg3 --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0 --> high priority entry gets R X permission -- TOR region selected +# R,X succeeds while we get store access faults +PMP_TOR_priority_rx: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg3 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit is set, W bit not set, X bit is set, TOR Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RX_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw instruction + mnemonic == {'sb', 'sh', 'sw'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 24) & 0x9F == 0x8D) and ${TOR_PRIORITY_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_NA4_r_priority.S +# This is a priority test. +# pmpcfg3 --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0 --> high priority entry gets R permission -- NA4 region selected +# R succeeds while we get store and fetch access fault +PMP_NA4_priority_r: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg3 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit is set, W bit not set, X bit not set, NA4 Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NA4_MODE}+${PMPCFG_ONLY_R_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw instruction + mnemonic == {'sb', 'sh', 'sw'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check for execute fault + mode == 'M' and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_FETCH_ACCESS}): 0 + #Check the na4 region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 24) & 0x9F == 0x91) and ${NA4_PRIORITY_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_NA4_x_priority.S +# This is a priority test. +# pmpcfg3 --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0 --> high priority entry gets X permission -- NA4 region selected +# X succeeds while we get load and store access fault +PMP_NA4_priority_x: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg3 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit not set, NA4 Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NA4_MODE}+${PMPCFG_ONLY_X_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw instruction + mnemonic == {'sb', 'sh', 'sw'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check for load fault on lb, lh, lw instruction + mnemonic == {'lb', 'lh', 'lw'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_LOAD_ACCESS}): 0 + #Check the na4 region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 24) & 0x9F == 0x94) and ${NA4_PRIORITY_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_NA4_rw_priority.S +# This is a priority test. +# pmpcfg3 --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0 --> high priority entry gets RW permission -- NA4 region selected +# R,W succeeds while we get fetch access fault +PMP_NA4_priority_rw: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg3 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit not set, NA4 Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NA4_MODE}+${PMPCFG_ONLY_RW_SET}": 0 + val_comb: + #Check for execute fault + mode == 'M' and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_FETCH_ACCESS}): 0 + #Check the na4 region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 24) & 0x9F == 0x93) and ${NA4_PRIORITY_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_NA4_rx_priority.S +# This is a priority test. +# pmpcfg3 --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0 --> high priority entry gets R X permission -- NA4 region selected +# R,X succeeds while we get store access fault +PMP_NA4_priority_rx: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg3 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit is set, W bit not set, X bit is set, NA4 Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NA4_MODE}+${PMPCFG_ONLY_RX_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw instruction + mnemonic == {'sb', 'sh', 'sw'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check the na4 region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 24) & 0x9F == 0x95) and ${NA4_PRIORITY_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_NAPOT_r_priority_level_2.S +# This is a priority test. +# pmpcfg3[31:24] --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0[31:24] --> high priority entry gets permission -- TOR region selected +# pmpcfg0[15:8] --> highest priority entry gets R permission -- NAPOT region selected +# R succeeds while we get Store fault and fetch access fault +PMP_NAPOT_priority_r_level_2: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg3 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit not set, W bit not set, X bit not set, TOR Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_BIT_NOT_SET}": 0 + # Higest priority entry -- Check Lock bit is set, R bit is set, W bit not set, X bit not set, NAPOT Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NAPOT_MODE}+${PMPCFG_ONLY_R_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw instruction + mnemonic == {'sb', 'sh', 'sw'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check for execute fault + mode == 'M' and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_FETCH_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x99) and ${NAPOT_PRIORITY_2_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_NAPOT_x_priority_level_2.S +# This is a priority test. +# pmpcfg3[31:24] --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0[31:24] --> high priority entry gets permission -- TOR region selected +# pmpcfg0[15:8] --> highest priority entry gets X permission -- NAPOT region selected +# X succeeds while we get load and store access fault +PMP_NAPOT_priority_x_level_2: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg3 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit not set, W bit not set, X bit not set, TOR Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_BIT_NOT_SET}": 0 + # Higest priority entry -- Check Lock bit is set, R bit not set, W bit not set, X bit is set, NAPOT Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NAPOT_MODE}+${PMPCFG_ONLY_X_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw instruction + mnemonic == {'sb', 'sh', 'sw'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check for load fault on lb, lh, lw instruction + mnemonic == {'lb', 'lh', 'lw'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_LOAD_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x9C) and ${NAPOT_PRIORITY_2_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_NAPOT_rw_priority_level_2.S +# This is a priority test. +# pmpcfg3[31:24] --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0[31:24] --> high priority entry gets permission -- TOR region selected +# pmpcfg0[15:8] --> highest priority entry gets RW permission -- NAPOT region selected +# R,W succeeds while we get fetch access fault +PMP_NAPOT_priority_rw_level_2: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg3 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit not set, W bit not set, X bit not set, TOR Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_BIT_NOT_SET}": 0 + # Higest priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit not set, NAPOT Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NAPOT_MODE}+${PMPCFG_ONLY_RW_SET}": 0 + val_comb: + #Check for execute fault + mode == 'M' and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_FETCH_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x9B) and ${NAPOT_PRIORITY_2_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_NAPOT_rx_priority_level_2.S +# This is a priority test. +# pmpcfg3[31:24] --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0[31:24] --> high priority entry gets permission -- TOR region selected +# pmpcfg0[15:8] --> highest priority entry gets R X permission -- NAPOT region selected +# R,X succeeds while we get store access fault +PMP_NAPOT_priority_rx_level_2: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg3 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit not set, W bit not set, X bit not set, TOR Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_BIT_NOT_SET}": 0 + # Higest priority entry -- Check Lock bit is set, R bit is set, W bit not set, X bit is set, NAPOT Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NAPOT_MODE}+${PMPCFG_ONLY_RX_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw instruction + mnemonic == {'sb', 'sh', 'sw'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x9D) and ${NAPOT_PRIORITY_2_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_TOR_r_priority_level_2.S +# This is a priority test. +# pmpcfg3[31:24] --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0[31:24] --> high priority entry gets permission -- TOR region selected +# pmpcfg0[15:8] --> highest priority entry gets R permission -- TOR region selected +# R succeeds while we get store and fetch access fault +PMP_TOR_priority_r_level_2: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg3 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit not set, W bit not set, X bit not set, TOR Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_BIT_NOT_SET}": 0 + # Higest priority entry -- Check Lock bit is set, R bit is set, W bit not set, X bit not set, TOR Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_R_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw instruction + mnemonic == {'sb', 'sh', 'sw'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check for execute fault + mode == 'M' and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_FETCH_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x89) and ${TOR_PRIORITY_2_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_TOR_x_priority_level_2.S +# This is a priority test. +# pmpcfg3[31:24] --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0[31:24] --> high priority entry gets permission -- TOR region selected +# pmpcfg0[15:8] --> highest priority entry gets X permission -- TOR region selected +# X succeeds while we get load and store access fault +PMP_TOR_priority_x_level_2: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg3 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit not set, W bit not set, X bit not set, TOR Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_BIT_NOT_SET}": 0 + # Higest priority entry -- Check Lock bit is set, R bit not set, W bit not set, X bit is set, TOR Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_X_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw instruction + mnemonic == {'sb', 'sh', 'sw'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check for load fault on lb, lh, lw instruction + mnemonic == {'lb', 'lh', 'lw'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_LOAD_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x8C) and ${TOR_PRIORITY_2_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_TOR_rw_priority_level_2.S +# This is a priority test. +# pmpcfg3[31:24] --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0[31:24] --> high priority entry gets permission -- TOR region selected +# pmpcfg0[15:8] --> highest priority entry gets RW permission -- TOR region selected +# R,W succeeds while we get fetch access fault +PMP_TOR_priority_rw_level_2: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg3 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit not set, W bit not set, X bit not set, TOR Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_BIT_NOT_SET}": 0 + # Higest priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit not set, TOR Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RW_SET}": 0 + val_comb: + #Check for execute fault + mode == 'M' and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_FETCH_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x8B) and ${TOR_PRIORITY_2_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_TOR_rx_priority_level_2.S +# This is a priority test. +# pmpcfg3[31:24] --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0[31:24] --> high priority entry gets permission -- TOR region selected +# pmpcfg0[15:8] --> highest priority entry gets R X permission -- TOR region selected +# R, X succeeds while we get store access fault +PMP_TOR_priority_rx_level_2: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg3 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit not set, W bit not set, X bit not set, TOR Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_BIT_NOT_SET}": 0 + # Higest priority entry -- Check Lock bit is set, R bit is set, W bit not set, X bit is set, TOR Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RX_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw instruction + mnemonic == {'sb', 'sh', 'sw'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x8D) and ${TOR_PRIORITY_2_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_NA4_r_priority_level_2.S +# This is a priority test. +# pmpcfg3[31:24] --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0[31:24] --> high priority entry gets permission -- TOR region selected +# pmpcfg0[15:8] --> highest priority entry gets R permission -- NA4 region selected +# R succeeds while we get store and fetch access fault +PMP_NA4_priority_r_level_2: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg3 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit not set, W bit not set, X bit not set, TOR Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_BIT_NOT_SET}": 0 + # Higest priority entry -- Check Lock bit is set, R bit is set, W bit not set, X bit not set, NA4 Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NA4_MODE}+${PMPCFG_ONLY_R_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw instruction + mnemonic == {'sb', 'sh', 'sw'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check for execute fault + mode == 'M' and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_FETCH_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x91) and ${NA4_PRIORITY_2_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_NA4_rw_priority_level_2.S +# This is a priority test. +# pmpcfg3[31:24] --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0[31:24] --> high priority entry gets permission -- TOR region selected +# pmpcfg0[15:8] --> highest priority entry gets RW permission -- NA4 region selected +# R,W succeeds while we get fetch access fault +PMP_NA4_priority_rw_level_2: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg3 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit not set, W bit not set, X bit not set, TOR Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_BIT_NOT_SET}": 0 + # Higest priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit not set, NA4 Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NA4_MODE}+${PMPCFG_ONLY_RW_SET}": 0 + val_comb: + #Check for execute fault + mode == 'M' and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_FETCH_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x93) and ${NA4_PRIORITY_2_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_NA4_x_priority_level_2.S +# This is a priority test. +# pmpcfg3[31:24] --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0[31:24] --> high priority entry gets permission -- TOR region selected +# pmpcfg0[15:8] --> highest priority entry gets X permission -- NA4 region selected +# X succeeds while we get load and store access fault +PMP_NA4_priority_x_level_2: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg3 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit not set, W bit not set, X bit not set, TOR Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_BIT_NOT_SET}": 0 + # Higest priority entry -- Check Lock bit is set, R bit not set, W bit not set, X bit is set, NA4 Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NA4_MODE}+${PMPCFG_ONLY_X_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw instruction + mnemonic == {'sb', 'sh', 'sw'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check for load fault on lb, lh, lw instruction + mnemonic == {'lb', 'lh', 'lw'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_LOAD_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x94) and ${NA4_PRIORITY_2_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_NA4_rx_priority_level_2.S +# This is a priority test. +# pmpcfg3[31:24] --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0[31:24] --> high priority entry gets permission -- TOR region selected +# pmpcfg0[15:8] --> highest priority entry gets R X permission -- NA4 region selected +# R,X succeeds while we get store access fault +PMP_NA4_priority_rx_level_2: + config: + - check ISA:=regex(.*32.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg3 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit not set, W bit not set, X bit not set, TOR Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_BIT_NOT_SET}": 0 + # Higest priority entry -- Check Lock bit is set, R bit is set, W bit not set, X bit is set, NA4 Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NA4_MODE}+${PMPCFG_ONLY_RX_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw instruction + mnemonic == {'sb', 'sh', 'sw'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"lw", "lh", "lb", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x95) and ${NA4_PRIORITY_2_REGION_MATCH}': 0 diff --git a/coverage/rv64_pmp.cgf b/coverage/rv64_pmp.cgf new file mode 100644 index 000000000..616dbad5f --- /dev/null +++ b/coverage/rv64_pmp.cgf @@ -0,0 +1,836 @@ +# This coverpoint checks the coverage of Lock bit test. +# req = The old value of the pmpcfgs and pmpaddrs should be equal to the new one since the Lock bit is set and the new write try will fail. +pmp_cfg_locked_write_unrelated: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw}" : 0 + csr_comb: + # (Lock bit set) and (req) and (old_value_pmpcfg != 0) + (old("pmpaddr{0 ... 15}") ^ (pmpaddr$1) == 0x00) and (pmpcfg{0,2}{[$1/8]} >> {[($1%8)*8]} & 0x80 == 0x80): 0 + (pmpcfg{0, 2} >> {[($1%8)*8]} & 0x80 == 0x80) and ((old("pmpcfg$1") & (0xFF << $2)) ^ (pmpcfg$1 & (0xFF << $2)) == 0x00) and old("pmpcfg$1") != 0: 0 + +#This coverpoint checks the coverage of pmp-CSR-access.cgf (PMP CSRs accesses in different modes) +#Checks pmpcgf and pmpaddr are only accessible in M mode and gets fault in S and U mode when accessed. +PMP_access_permission: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw}" : 0 + csr_comb: + #Check successful update for pmpcfg in M Mode + mode == 'M' and (((old("pmpcfg{0 , 2}") ^ (pmpcfg$1)) != 0x00) and pmpcfg$1 != 0x0): 0 #pmpcfg successfully updated in M mode + #Check successful update for pmpaddr in M Mode + mode == 'M' and (((old("pmpaddr{0 ... 15}") ^ (pmpaddr$1)) != 0x00) and pmpaddr$1 != 0x0): 0 #pmpaddr successfully updated in M mode + #Check for fault for pmpcfg, pmpaddr in S, U Mode + mode == {'S', 'U'} and mcause == ${CAUSE_ILLEGAL_INSTRUCTION}: 0 #check for illegal instruction fault + +# This coverpoint checks the coverage for the pmp-NAPOT-R.S +# R bit is set for pmpcfg but wx is not set for the region, so there should be store and fetch access fault. +PMP_NAPOT_r: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Check Lock bit is set, R bit is set, W bit not set, X bit not set, NAPOT Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NAPOT_MODE}+${PMPCFG_ONLY_R_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw, sd instruction + mnemonic == {'sb', 'sh', 'sw', 'sd'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check for execute fault + mode == 'M' and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_FETCH_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x99) and ${NAPOT_REGION_ADDRESS_MATCH}': 0 + +# This coverpoint checks the coverage for the pmp-NAPOT-X.S +# X bit is set for pmpcfg but RW is not set for the region, so there should be load and store access fault. +PMP_NAPOT_x: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Check Lock bit is set, R bit is set, W bit not set, X bit not set, NAPOT Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NAPOT_MODE}+${PMPCFG_ONLY_X_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw, sd instruction + mnemonic == {'sb', 'sh', 'sw', 'sd'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check for load fault on lb, lh, lw, ld instruction + mnemonic == {'lb', 'lh', 'lw', 'ld'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_LOAD_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x9C) and ${NAPOT_REGION_ADDRESS_MATCH}': 0 + +# This coverpoint checks the coverage for the pmp-NAPOT-RW.S +# RW bit is set for pmpcfg but X is not set for the region, so there should be fetch access fault. +PMP_NAPOT_rw: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Check Lock bit is set, R bit is set, W bit not set, X bit not set, NAPOT Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NAPOT_MODE}+${PMPCFG_ONLY_RW_SET}": 0 + val_comb: + #Check for execute fault + mode == 'M' and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_FETCH_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x9B) and ${NAPOT_REGION_ADDRESS_MATCH}': 0 + +# This coverpoint checks the coverage for the pmp-NAPOT-RX.S +# RX bit is set for pmpcfg but W is not set for the region, so there should be store access fault. +PMP_NAPOT_rx: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Check Lock bit is set, R bit is set, W bit not set, X bit not set, NAPOT Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NAPOT_MODE}+${PMPCFG_ONLY_RX_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw, sd instruction + mnemonic == {'sb', 'sh', 'sw', 'sd'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x9D) and ${NAPOT_REGION_ADDRESS_MATCH}': 0 + +# This coverpoint checks the coverage for the pmp-NAPOT-RWX.S +# R,W,X bit is set for pmpcfg, so there should be NO access fault. +PMP_NAPOT_rwx: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Check Lock bit is set, R bit is set, W bit not set, X bit not set, NAPOT Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NAPOT_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + val_comb: + #Check the napot region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x9F) and ${NAPOT_REGION_ADDRESS_MATCH}': 0 + +# This coverpoint checks the coverage for the pmp-TOR-R.S +# R bit is set for pmpcfg but wx is not set for the region, so there should be store and fetch access fault. +PMP_TOR_r: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Check Lock bit is set, R bit is set, W bit not set, X bit not set, NAPOT Mode is set + "(pmpcfg0 >> 16) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_R_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw, sd instruction + mnemonic == {'sb', 'sh', 'sw', 'sd'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check for execute fault + mode == 'M' and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_FETCH_ACCESS}): 0 + #Check the tor region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 16) & 0x9F == 0x89) and ${TOR_REGION_ADDRESS_MATCH}': 0 + +# This coverpoint checks the coverage for the pmp-TOR-X.S +# X bit is set for pmpcfg but RW is not set for the region, so there should be load and store access fault. +PMP_TOR_x: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Check Lock bit is set, R bit not set, W bit not set, X bit is set, NAPOT Mode is set + "(pmpcfg0 >> 16) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_X_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw, sd instruction + mnemonic == {'sb', 'sh', 'sw', 'sd'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check for load fault on lb, lh, lw, ld instruction + mnemonic == {'lb', 'lh', 'lw', 'ld'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_LOAD_ACCESS}): 0 + #Check the tor region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 16) & 0x9F == 0x8C) and ${TOR_REGION_ADDRESS_MATCH}': 0 + +# This coverpoint checks the coverage for the pmp-TOR-RW.S +# RW bit is set for pmpcfg but X is not set for the region, so there should be fetch access fault. +PMP_TOR_rw: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Check Lock bit is set, R bit is set, W bit is set, X bit not set, NAPOT Mode is set + "(pmpcfg0 >> 16) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RW_SET}": 0 + val_comb: + #Check for execute fault + mode == 'M' and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_FETCH_ACCESS}): 0 + #Check the tor region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 16) & 0x9F == 0x8B) and ${NAPOT_REGION_ADDRESS_MATCH}': 0 + +# This coverpoint checks the coverage for the pmp-TOR-RX.S +# RX bit is set for pmpcfg but W is not set for the region, so there should be store access fault. +PMP_TOR_rx: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Check Lock bit is set, R bit is set, W bit not set, X bit is set, TOR Mode is set + "(pmpcfg0 >> 16) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RX_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw, sd instruction + mnemonic == {'sb', 'sh', 'sw', 'sd'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check the tor region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 16) & 0x9F == 0x8D) and ${NAPOT_REGION_ADDRESS_MATCH}': 0 + +# This coverpoint checks the coverage for the pmp-TOR-RWX.S +# R,W,X bit is set for pmpcfg, so there should be NO access fault. +PMP_TOR_rwx: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg0 >> 16) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + val_comb: + #Check the tor region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 16) & 0x9F == 0x8F) and ${NAPOT_REGION_ADDRESS_MATCH}': 0 + +# This coverpoint checks the coverage for the pmp-NA4-R.S +# R bit is set for pmpcfg but wx is not set for the region, so there should be store and fetch access fault. +PMP_NA4_r: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Check Lock bit is set, R bit is set, W bit not set, X bit not set, NAPOT Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NA4_MODE}+${PMPCFG_ONLY_R_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw, sd instruction + mnemonic == {'sb', 'sh', 'sw', 'sd'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check for execute fault + mode == 'M' and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_FETCH_ACCESS}): 0 + #Check the na4 region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x91) and ${NA4_REGION_ADDRESS_MATCH}': 0 + +# This coverpoint checks the coverage for the pmp-NA4-X.S +# X bit is set for pmpcfg but RW is not set for the region, so there should be load and store access fault. +PMP_NA4_x: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Check Lock bit is set, R bit not set, W bit not set, X bit set, NA4 Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NA4_MODE}+${PMPCFG_ONLY_X_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw, sd instruction + mnemonic == {'sb', 'sh', 'sw', 'sd'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check for load fault on lb, lh, lw, ld instruction + mnemonic == {'lb', 'lh', 'lw', 'ld'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_LOAD_ACCESS}): 0 + #Check the na4 region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x94) and ${NA4_REGION_ADDRESS_MATCH}': 0 + +# This coverpoint checks the coverage for the pmp-NA4-RW.S +# RW bit is set for pmpcfg but X is not set for the region, so there should be fetch access fault. +PMP_NA4_rw: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Check Lock bit is set, R bit is set, W bit is set, X bit not set, NA4 Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NA4_MODE}+${PMPCFG_ONLY_RW_SET}": 0 + val_comb: + #Check for execute fault + mode == 'M' and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_FETCH_ACCESS}): 0 + #Check the na4 region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x93) and ${NA4_REGION_ADDRESS_MATCH}': 0 + +# This coverpoint checks the coverage for the pmp-NA4-RX.S +# RX bit is set for pmpcfg but W is not set for the region, so there should be store access fault. +PMP_NA4_rx: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Check Lock bit is set, R bit is set, W bit not set, X bit not set, NAPOT Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NA4_MODE}+${PMPCFG_ONLY_RX_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw, sd instruction + mnemonic == {'sb', 'sh', 'sw', 'sd'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x95) and ${NA4_REGION_ADDRESS_MATCH}': 0 + +# This coverpoint checks the coverage for the pmp-NA4-RWX.S +# R,W,X bit is set for pmpcfg, so there should be NO access fault. +PMP_NA4_rwx: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Check Lock bit is set, R bit is set, W bit not set, X bit not set, NAPOT Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NA4_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + val_comb: + #Check the napot region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x97) and ${NA4_REGION_ADDRESS_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_NAPOT_r_priority.S +# This is a priority test. +# pmpcfg3 --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0 --> high priority entry gets R permission -- NAPOT region selected +# R succeeds while we get Store fault and fetch access fault +PMP_NAPOT_priority_r: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg2 >> 56) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit is set, W bit not set, X bit not set, NAPOT Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NAPOT_MODE}+${PMPCFG_ONLY_R_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw, sd instruction + mnemonic == {'sb', 'sh', 'sw', 'sd'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check for execute fault + mode == 'M' and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_FETCH_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 24) & 0x9F == 0x99) and ${NAPOT_PRIORITY_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_NAPOT_x_priority.S +# This is a priority test. +# pmpcfg3 --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0 --> high priority entry gets X permission -- NAPOT region selected +# fetch succeeds while we get read access fault and store access fault +PMP_NAPOT_priority_x: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg2 >> 56) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit is set, W bit not set, X bit not set, NAPOT Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NAPOT_MODE}+${PMPCFG_ONLY_X_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw, sd instruction + mnemonic == {'sb', 'sh', 'sw', 'sd'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check for load fault on lb, lh, lw, ld instruction + mnemonic == {'lb', 'lh', 'lw', 'ld'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_LOAD_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 24) & 0x9F == 0x9C) and ${NAPOT_PRIORITY_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_NAPOT_rw_priority.S +# This is a priority test. +# pmpcfg3 --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0 --> high priority entry gets RW permission -- NAPOT region selected +# load, store succeeds while we get fetch access fault +PMP_NAPOT_priority_rw: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg2 >> 56) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit not set, NAPOT Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NAPOT_MODE}+${PMPCFG_ONLY_RW_SET}": 0 + val_comb: + #Check for execute fault + mode == 'M' and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_FETCH_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 24) & 0x9F == 0x9B) and ${NAPOT_PRIORITY_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_NAPOT_rx_priority.S +# This is a priority test. +# pmpcfg3 --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0 --> high priority entry gets R X permission -- NAPOT region selected +# load, fetch succeeds while we get store access fault +PMP_NAPOT_priority_rx: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg2 >> 56) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit is set, W bit not set, X bit is set, NAPOT Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NAPOT_MODE}+${PMPCFG_ONLY_RX_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw, sd instruction + mnemonic == {'sb', 'sh', 'sw', 'sd'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 24) & 0x9F == 0x9D) and ${NAPOT_PRIORITY_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_TOR_r_priority.S +# This is a priority test. +# pmpcfg3 --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0 --> high priority entry gets R permission -- TOR region selected +# R succeeds while we get Store fault and fetch access fault +PMP_TOR_priority_r: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg2 >> 56) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit is set, W bit not set, X bit not set, TOR Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_R_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw, sd instruction + mnemonic == {'sb', 'sh', 'sw', 'sd'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check for execute fault + mode == 'M' and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_FETCH_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 24) & 0x9F == 0x89) and ${TOR_PRIORITY_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_TOR_x_priority.S +# This is a priority test. +# pmpcfg3 --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0 --> high priority entry gets X permission -- TOR region selected +# X succeeds while we get load and store access faults +PMP_TOR_priority_x: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg2 >> 56) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit not set, TOR Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_X_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw, sd instruction + mnemonic == {'sb', 'sh', 'sw', 'sd'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check for load fault on lb, lh, lw, ld instruction + mnemonic == {'lb', 'lh', 'lw', 'ld'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_LOAD_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 24) & 0x9F == 0x8C) and ${TOR_PRIORITY_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_TOR_rw_priority.S +# This is a priority test. +# pmpcfg3 --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0 --> high priority entry gets RW permission -- TOR region selected +# R,W succeeds while we get fetch access fault +PMP_TOR_priority_rw: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg2 >> 56) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit not set, TOR Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RW_SET}": 0 + val_comb: + #Check for execute fault + mode == 'M' and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_FETCH_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 24) & 0x9F == 0x8B) and ${TOR_PRIORITY_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_TOR_rx_priority.S +# This is a priority test. +# pmpcfg3 --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0 --> high priority entry gets R X permission -- TOR region selected +# R,X succeeds while we get store access faults +PMP_TOR_priority_rx: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg2 >> 56) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit is set, W bit not set, X bit is set, TOR Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RX_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw, sd instruction + mnemonic == {'sb', 'sh', 'sw', 'sd'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 24) & 0x9F == 0x8D) and ${TOR_PRIORITY_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_NA4_r_priority.S +# This is a priority test. +# pmpcfg3 --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0 --> high priority entry gets R permission -- NA4 region selected +# R succeeds while we get store and fetch access fault +PMP_NA4_priority_r: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg2 >> 56) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit is set, W bit not set, X bit not set, NA4 Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NA4_MODE}+${PMPCFG_ONLY_R_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw, sd instruction + mnemonic == {'sb', 'sh', 'sw', 'sd'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check for execute fault + mode == 'M' and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_FETCH_ACCESS}): 0 + #Check the na4 region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 24) & 0x9F == 0x91) and ${NA4_PRIORITY_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_NA4_x_priority.S +# This is a priority test. +# pmpcfg3 --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0 --> high priority entry gets X permission -- NA4 region selected +# X succeeds while we get load and store access fault +PMP_NA4_priority_x: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg2 >> 56) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit not set, NA4 Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NA4_MODE}+${PMPCFG_ONLY_X_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw, sd instruction + mnemonic == {'sb', 'sh', 'sw', 'sd'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check for load fault on lb, lh, lw, ld instruction + mnemonic == {'lb', 'lh', 'lw', 'ld'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_LOAD_ACCESS}): 0 + #Check the na4 region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 24) & 0x9F == 0x94) and ${NA4_PRIORITY_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_NA4_rw_priority.S +# This is a priority test. +# pmpcfg3 --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0 --> high priority entry gets RW permission -- NA4 region selected +# R,W succeeds while we get fetch access fault +PMP_NA4_priority_rw: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg2 >> 56) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit not set, NA4 Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NA4_MODE}+${PMPCFG_ONLY_RW_SET}": 0 + val_comb: + #Check for execute fault + mode == 'M' and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_FETCH_ACCESS}): 0 + #Check the na4 region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 24) & 0x9F == 0x93) and ${NA4_PRIORITY_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_NA4_rx_priority.S +# This is a priority test. +# pmpcfg3 --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0 --> high priority entry gets R X permission -- NA4 region selected +# R,X succeeds while we get store access fault +PMP_NA4_priority_rx: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg2 >> 56) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit is set, W bit not set, X bit is set, NA4 Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NA4_MODE}+${PMPCFG_ONLY_RX_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw, sd instruction + mnemonic == {'sb', 'sh', 'sw', 'sd'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check the na4 region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 24) & 0x9F == 0x95) and ${NA4_PRIORITY_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_NAPOT_r_priority_level_2.S +# This is a priority test. +# pmpcfg3[31:24] --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0[31:24] --> high priority entry gets permission -- TOR region selected +# pmpcfg0[15:8] --> highest priority entry gets R permission -- NAPOT region selected +# R succeeds while we get Store fault and fetch access fault +PMP_NAPOT_priority_r_level_2: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg2 >> 56) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit not set, W bit not set, X bit not set, TOR Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_BIT_NOT_SET}": 0 + # Higest priority entry -- Check Lock bit is set, R bit is set, W bit not set, X bit not set, NAPOT Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NAPOT_MODE}+${PMPCFG_ONLY_R_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw, sd instruction + mnemonic == {'sb', 'sh', 'sw', 'sd'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check for execute fault + mode == 'M' and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_FETCH_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x99) and ${NAPOT_PRIORITY_2_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_NAPOT_x_priority_level_2.S +# This is a priority test. +# pmpcfg3[31:24] --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0[31:24] --> high priority entry gets permission -- TOR region selected +# pmpcfg0[15:8] --> highest priority entry gets X permission -- NAPOT region selected +# X succeeds while we get load and store access fault +PMP_NAPOT_priority_x_level_2: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg2 >> 56) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit not set, W bit not set, X bit not set, TOR Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_BIT_NOT_SET}": 0 + # Higest priority entry -- Check Lock bit is set, R bit not set, W bit not set, X bit is set, NAPOT Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NAPOT_MODE}+${PMPCFG_ONLY_X_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw, sd instruction + mnemonic == {'sb', 'sh', 'sw', 'sd'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check for load fault on lb, lh, lw, ld instruction + mnemonic == {'lb', 'lh', 'lw', 'ld'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_LOAD_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x9C) and ${NAPOT_PRIORITY_2_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_NAPOT_rw_priority_level_2.S +# This is a priority test. +# pmpcfg3[31:24] --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0[31:24] --> high priority entry gets permission -- TOR region selected +# pmpcfg0[15:8] --> highest priority entry gets RW permission -- NAPOT region selected +# R,W succeeds while we get fetch access fault +PMP_NAPOT_priority_rw_level_2: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg2 >> 56) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit not set, W bit not set, X bit not set, TOR Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_BIT_NOT_SET}": 0 + # Higest priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit not set, NAPOT Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NAPOT_MODE}+${PMPCFG_ONLY_RW_SET}": 0 + val_comb: + #Check for execute fault + mode == 'M' and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_FETCH_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x9B) and ${NAPOT_PRIORITY_2_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_NAPOT_rx_priority_level_2.S +# This is a priority test. +# pmpcfg3[31:24] --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0[31:24] --> high priority entry gets permission -- TOR region selected +# pmpcfg0[15:8] --> highest priority entry gets R X permission -- NAPOT region selected +# R,X succeeds while we get store access fault +PMP_NAPOT_priority_rx_level_2: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg2 >> 56) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit not set, W bit not set, X bit not set, TOR Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_BIT_NOT_SET}": 0 + # Higest priority entry -- Check Lock bit is set, R bit is set, W bit not set, X bit is set, NAPOT Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NAPOT_MODE}+${PMPCFG_ONLY_RX_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw, sd instruction + mnemonic == {'sb', 'sh', 'sw', 'sd'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x9D) and ${NAPOT_PRIORITY_2_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_TOR_r_priority_level_2.S +# This is a priority test. +# pmpcfg3[31:24] --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0[31:24] --> high priority entry gets permission -- TOR region selected +# pmpcfg0[15:8] --> highest priority entry gets R permission -- TOR region selected +# R succeeds while we get store and fetch access fault +PMP_TOR_priority_r_level_2: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg2 >> 56) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit not set, W bit not set, X bit not set, TOR Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_BIT_NOT_SET}": 0 + # Higest priority entry -- Check Lock bit is set, R bit is set, W bit not set, X bit not set, TOR Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_R_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw, sd instruction + mnemonic == {'sb', 'sh', 'sw', 'sd'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check for execute fault + mode == 'M' and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_FETCH_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x89) and ${TOR_PRIORITY_2_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_TOR_x_priority_level_2.S +# This is a priority test. +# pmpcfg3[31:24] --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0[31:24] --> high priority entry gets permission -- TOR region selected +# pmpcfg0[15:8] --> highest priority entry gets X permission -- TOR region selected +# X succeeds while we get load and store access fault +PMP_TOR_priority_x_level_2: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg2 >> 56) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit not set, W bit not set, X bit not set, TOR Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_BIT_NOT_SET}": 0 + # Higest priority entry -- Check Lock bit is set, R bit not set, W bit not set, X bit is set, TOR Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_X_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw, sd instruction + mnemonic == {'sb', 'sh', 'sw', 'sd'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check for load fault on lb, lh, lw, ld instruction + mnemonic == {'lb', 'lh', 'lw', 'ld'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_LOAD_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x8C) and ${TOR_PRIORITY_2_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_TOR_rw_priority_level_2.S +# This is a priority test. +# pmpcfg3[31:24] --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0[31:24] --> high priority entry gets permission -- TOR region selected +# pmpcfg0[15:8] --> highest priority entry gets RW permission -- TOR region selected +# R,W succeeds while we get fetch access fault +PMP_TOR_priority_rw_level_2: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg2 >> 56) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit not set, W bit not set, X bit not set, TOR Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_BIT_NOT_SET}": 0 + # Higest priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit not set, TOR Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RW_SET}": 0 + val_comb: + #Check for execute fault + mode == 'M' and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_FETCH_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x8B) and ${TOR_PRIORITY_2_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_TOR_rx_priority_level_2.S +# This is a priority test. +# pmpcfg3[31:24] --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0[31:24] --> high priority entry gets permission -- TOR region selected +# pmpcfg0[15:8] --> highest priority entry gets R X permission -- TOR region selected +# R, X succeeds while we get store access fault +PMP_TOR_priority_rx_level_2: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg2 >> 56) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit not set, W bit not set, X bit not set, TOR Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_BIT_NOT_SET}": 0 + # Higest priority entry -- Check Lock bit is set, R bit is set, W bit not set, X bit is set, TOR Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RX_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw, sd instruction + mnemonic == {'sb', 'sh', 'sw', 'sd'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x8D) and ${TOR_PRIORITY_2_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_NA4_r_priority_level_2.S +# This is a priority test. +# pmpcfg3[31:24] --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0[31:24] --> high priority entry gets permission -- TOR region selected +# pmpcfg0[15:8] --> highest priority entry gets R permission -- NA4 region selected +# R succeeds while we get store and fetch access fault +PMP_NA4_priority_r_level_2: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg2 >> 56) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit not set, W bit not set, X bit not set, TOR Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_BIT_NOT_SET}": 0 + # Higest priority entry -- Check Lock bit is set, R bit is set, W bit not set, X bit not set, NA4 Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NA4_MODE}+${PMPCFG_ONLY_R_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw, sd instruction + mnemonic == {'sb', 'sh', 'sw', 'sd'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check for execute fault + mode == 'M' and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_FETCH_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x91) and ${NA4_PRIORITY_2_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_NA4_rw_priority_level_2.S +# This is a priority test. +# pmpcfg3[31:24] --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0[31:24] --> high priority entry gets permission -- TOR region selected +# pmpcfg0[15:8] --> highest priority entry gets RW permission -- NA4 region selected +# R,W succeeds while we get fetch access fault +PMP_NA4_priority_rw_level_2: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg2 >> 56) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit not set, W bit not set, X bit not set, TOR Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_BIT_NOT_SET}": 0 + # Higest priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit not set, NA4 Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NA4_MODE}+${PMPCFG_ONLY_RW_SET}": 0 + val_comb: + #Check for execute fault + mode == 'M' and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_FETCH_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x93) and ${NA4_PRIORITY_2_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_NA4_x_priority_level_2.S +# This is a priority test. +# pmpcfg3[31:24] --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0[31:24] --> high priority entry gets permission -- TOR region selected +# pmpcfg0[15:8] --> highest priority entry gets X permission -- NA4 region selected +# X succeeds while we get load and store access fault +PMP_NA4_priority_x_level_2: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg2 >> 56) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit not set, W bit not set, X bit not set, TOR Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_BIT_NOT_SET}": 0 + # Higest priority entry -- Check Lock bit is set, R bit not set, W bit not set, X bit is set, NA4 Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NA4_MODE}+${PMPCFG_ONLY_X_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw, sd instruction + mnemonic == {'sb', 'sh', 'sw', 'sd'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check for load fault on lb, lh, lw, ld instruction + mnemonic == {'lb', 'lh', 'lw', 'ld'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_LOAD_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x94) and ${NA4_PRIORITY_2_REGION_MATCH}': 0 + +# This coverpoint checks the coverage for the PMP_NA4_rx_priority_level_2.S +# This is a priority test. +# pmpcfg3[31:24] --> low priority entry gets RWX permission -- TOR region selected +# pmpcfg0[31:24] --> high priority entry gets permission -- TOR region selected +# pmpcfg0[15:8] --> highest priority entry gets R X permission -- NA4 region selected +# R,X succeeds while we get store access fault +PMP_NA4_priority_rx_level_2: + config: + - check ISA:=regex(.*64.*); check ISA:=regex(.*I.*Zicsr.*); def rvtest_mtrap_routine=True; + mnemonics: + "{csrrs, csrrw, ld, sd, lw, sw, lb, sb, lh, sh}" : 0 + csr_comb: + # Low priority entry -- Check Lock bit is set, R bit is set, W bit is set, X bit is set, TOR Mode is set + "(pmpcfg2 >> 56) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_ONLY_RWX_SET}": 0 + # High priority entry -- Check Lock bit is set, R bit not set, W bit not set, X bit not set, TOR Mode is set + "(pmpcfg0 >> 24) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_TOR_MODE}+${PMPCFG_BIT_NOT_SET}": 0 + # Higest priority entry -- Check Lock bit is set, R bit is set, W bit not set, X bit is set, NA4 Mode is set + "(pmpcfg0 >> 8) & ${PMPCFG_ALL_BIT} == ${PMPCFG_L_BIT}+${PMPCFG_NA4_MODE}+${PMPCFG_ONLY_RX_SET}": 0 + val_comb: + #Check for store fault on sb , sh, sw, sd instruction + mnemonic == {'sb', 'sh', 'sw', 'sd'} and mode_change == {'M to M', 'U to M', 'S to M'} and (mcause == ${CAUSE_STORE_ACCESS}): 0 + #Check the napot region is accessed at least once + '(mnemonic == {"ld", "lw", "lh", "lb", "sd", "sw", "sh", "sb"}) and ((pmpcfg0 >> 8) & 0x9F == 0x95) and ${NA4_PRIORITY_2_REGION_MATCH}': 0 diff --git a/riscof-plugins/rv32/sail_cSim/__pycache__/riscof_sail_cSim.cpython-310.pyc b/riscof-plugins/rv32/sail_cSim/__pycache__/riscof_sail_cSim.cpython-310.pyc deleted file mode 100644 index eb7e0f53f432994e21791e6142809a0326be7c93..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5456 zcmai2OOG5^6|Q$zzvtz#$8qe6NkRsxXU1?BenQmUz2GgCeFXy2+H z+wE=^u|vcH7O(_FkHjVmb}ZQN6JW#ciX9S?S8S1m9KLg_re~ZCP^G%BbMCpXbH8&= zrOjqd!E@pFf8J!zDazlea`-V&c>`ZILBbTKMoPEH)vhY*T33^~-qmGpbPbuCT~p>( z*OGaqTS2ZxmDujuY9XWAtx8%gu6OIQO^+IJv)e4`t+?H7%d!#8#IxO5RSC?=+@8{% z|DM83W<64v6*M2}-36xJQkE-^F-v8ASrzu}Anr$A9-!RnM}w^}In-i=ndke&d-&1I zO7>k80)^IxwW(N_hBfJ3^K)fWWd<`J*;tdsDvuPb$!1mLHfypvYdliB)z1|}>DDlt zmZ)Z47`gtfFcvdK(apkmfO(~SXs)eXT3H)@m!kd-rGwn*$Wp+$)9Hjsm^%;7jhzSQ$G&=K85NW*d~JN$TcG61L#3yV)KD2|zf*s% zj`fi?!MgU;u`$9~4HUkV>l1@%d#bAB=BH|IF@0q0D*PzG}ijHhCVZ_E&HTXX>F2*(d(ejmee0lsWXSDb8J@j{VB$qmE+B#&pg(=z~*Sp zBjbkhqvqJ6mXXEgkE3N|Eh)z_f~ws40pFaobX%13}bIA5Hmc?{9V^ip`oFd_<^Vu8rt{rZDG83?e_PD zB3cC(^u_()qYLMstzW*ltO*UR+U1K7oAm=SsCiitIqNPciWC36O7o=c``ev7 z$Z}avH#^0CW~+Sn!ui$d$(K}j+OX2U&re|3C4AW{Naoa>tUy<@-)2rcJy`ywj(X<o z-@m#YG8O<9lN1OTg&Rf5 z*-vewrVkemH1D9Zzi$`OUs@KrQBwErX=Gg{uq}JgyCr1|jT`A?FW@D zdK&2+bg}{tTXKApbdyz~lQl^*lIMZu`_#)*YNMpKSaV9fF{QQ&DlEW$&-X{Lz&)MK zTv0R{adt}iq@>K1l=&%Tr=%>Dlw(uMy^^w6QjSk4pOusoC1q(!`9(=NSyG;xQhr-f zPL-7BC)lALEU&z&R`w*XOki8FpJbQ+m{%vTmF#q3iSqiVDmydnVM<=J+64y!^I z(17`Tp?7Suh@Qu%GUnM?aBJ{BByHM$f_($tz`;l_7F-gYURoFCHlSeb@f*-b(So7s zr#ugsdoKzSK95E|M-+|k3jOlMn?k>N>)NnFXtWVt9hy=9@&1B0Ny|DN0_Vge)+B0f{i<9blQXvHV49C0r7=L^1-oDhso`7~e+Sm6EG| z+Q0ASJO~N|BlEv(NpLHyzMSNN)u$?7AiC||^Ds55vC)p)vSEJD&L04Y)Jr^EIEXv%TdpE1_QFo7yQIU7p? zW>1~qA^@ONf-XQH!lKV`LFtn7GXPYAgd?fAAXcxE!<`365D(1!GyOGY{H%bIDkJl* z^axrFw?0zg;{IuD!c~CVKDOZI!oeL^ki%IY+oQ^)L7@yBZn)`~QH^FauCn^L#u^0| zfVz2H8N=c3H76~!wU(4gdyht$LBBRes(@z(IYu2fMh!NL`Yh&Zu{i=Dv^GceQIq7r z*{Gwe^kyNeMl#s^o=&ah`e=pIyp;*x^Z z+T)o~n;jovK9JhJ^9N87D2(R-#>znDe`6;``mYq${*8{dS+)eOS@b?x_MS)Eb0Y); z)PCo$BZRr=^-p#RqgL7TSQTK8W-@Az(0|VwFC-c}Jzl^ZVMeezV=_Og%Mju!$_wDt zsV3p;%=)ml`VL%ma%EN?e~D*Uoz@YxHpq`B;(PFp;f{BDqAIVH^p@$0JyBOVsn+AC z)Vacg%@ufOL*osfIZxEr_=l3mAvY;?NWu+a#h%a8Y*-^^TuV5}!`ey~ZY5qm;KA@+ z$LWNKK9P0$alhjOsPe1lE|=9U?uE(KHKNi~I@6BQx1(rO`hqJ651jL_zkKdB(e~5b zfFtU0BX1*!q|X+~DQ!E$hSTw51RimmCIDZ|ZD`6S?-Bwh34Si-2q&=vAsZ>MGE6p8 z^eALHov-a}oPk!99R*RzR~s8zC$n#I%tgfLGY0Z65;i3j~+oP7b4} z6X80J$V(WyWC&UF!ri3ELzsvj5d_{wnO~%YY=fwIjJY|&FvN=W!uAEO7e$y7d9Q_S zcpDP}hHq`Uq~)T%9e6C@vQmV1hHRHgFC#bpE)CEn0mV&_%g`zGtCWKX9X@hl&uko1 zA-RHsb}1}1s>ONiw(H2Z`-H@7CKrM|)63i!uh z618lw(dVfjWEmo#?I^e>D)i$3e;c4l(5EyO7S08A4#TMMA5yOd-TQQNMLGktQ1-Wr beSV#O<75sJTiHM3B9~{0v!&P87PS8Whd{a( diff --git a/riscof-plugins/rv32/spike_simple/__pycache__/riscof_spike_simple.cpython-310.pyc b/riscof-plugins/rv32/spike_simple/__pycache__/riscof_spike_simple.cpython-310.pyc deleted file mode 100644 index f4d1ac5c7fabf9df470e81867f313ed7f91aa6a4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3476 zcmaJ^O>Y~=8Q$5QT`rePQl>2{a#LqvBu0sVk}4TaT*r=GJ8lg)su4S=OQ6`UI7?}z z{h()-vPF|9P`k*fJ@uB02=tOee?b33`v>OQlW#o-Y13zhlw=t}mzdAzozM53=Y3h! z>z;vc<8S}$f4yQD|5A-NKZ?dJB=Hwy%wQxny0emWiEf)+Q^6xJ+lLENqkHBT2BXY=WiUH# zzO=e6Mjjb$=QVa_Y_^GXAII4sjmjAH#vmPTC;3rNPszObS@VYY1eMrOXTdoL&R}-w zS4N*Oi_upu&R{d=m4P!5DanzSOIlB!Jn4}) zmQ**XQWHu116gUjGm~UEDeYb7 zu)^rr+Bf(IkfO^*PShT!=GX|`vdStN+W=P47{&qd^vD`|-DP8{di>*_>b$3Z+~duA z8Vn<_QiO4}WrO*9CXZMhqnpflWU$6jt=-&|POr%O$@XaVVH!sw4&uCwd649TVHxz3 zG!6z)xg*dK%mjx#Dw85#d97|q(ucPn|56&<){Wg_OGs~~Lp4m=i5SE^X%BSal@Z^L z%a9LqN!IQ?ZZF{4hl7|)Hw=?JDZ@}&5P&>S@=|(_4n!GepFK}XX%<3KJty5Ql3Z5U zungnpv9v^q@%b6Vco6M7+1tDPvLU zcG2(5?m(>a{f+h2Hw|qrfL)vz-^$>Cx3KCvNa6yr7V%7%y2K@cbHQ#|E!raIY!AJo z#Zv>1uC1p`^ypJ{6X_0;SVuNiMrMqa`4EPD*IdGrUNYu23pFH0RZj>L#`CZ@N59uc zd-2mrXPEEh#k0JFyXtKBdO;^s=e_Y_Z4w-R9Z|wA6xPcM7N<9|m__+P(CP0dBH2pP zq&&E>lQ0(NK_@Rn$X44MjA!evzqlQLG-nOW3&MK-{aVJ~BC%HP8sDNBS5zpU!M zI-gQ!h#m0v(KX9HP@tzQHHp$h#5d6v7m+!(W0^KJ&HtK6)H45LszlB2OzM3%S~{h) zlkvSHKEo86Wt8f)+Ww77X&i!Qrcl|kF#)6CHCxLD-gT2v#U46yK&9R>vOb<6wK?J+BcINZ`W$H-BM;_CbB-(=Bfps=XXZ%j80pWEvoi#{ zr0kqBJ4nn$mRdfPhetznX~M?ge?tYMv} zKJ`h1{7`zIj#{ToLl5q$$9wcOP;rs8RqTUvOL(6{JZNZ_=qIfFw)sbM*;s;y;P1g| zU>QG*!Xr7m6+MHiWh||ilkp~_e{M4Md^VLpcp2n)I#%hNyX7ZKiS~4acW~d$d=&3IohxMtVsK(eH zSH|Adp48B4@~@FEum+@z-7{l%T$zHrCjQuGO?@8=u(E|YTAhOCCVpL0E6%;5 zi1Ax;eRS>rOx5XN`3_hyOG@x?8qBsBtltbU^{5{Ac8cKA=C6V;zTCVtYTfFw0PKHV zfymY;*SU%Y+Kc==3ciF)I`Q*FlwwAxG>@`aIy}yb{g{8Ma97>Xmw19)xjp_P)mKw} zcd&~nXZi_BN4e|>5kXo!i#floM3wL6%PLb>B)y2Sa28p}8X|(;5L6$fDPIKIZp_%- zRXTWp4N0ojkh-lmrL}{ghaX6)gl3R-8R#gl7w-ABIndQ94Hu&S<|3pcaNufrIXqCkXp2SWNP3@Q36nyqK1voP;M zK#Hg%FG1ob)x|k@`kw?>o>o>7Tt2{xh&Ua!GAv3Rx{f>5o%7uEoixdTdG_k z6=PR?Y5vUDEB-t$mzRQd{qt?_dH;^#zcLORo_NJ(g_T|eSxPBTqQdM`mCCBE$g?AJ zk;`F@hlH&KGO2#d&xQ+XUi;*HrdMc2~!!V36Ne^ji^G3yv6x%Xv+OV7i7{q8ayP9NEy^N}R zC}}ivNTk50_#7Y!KmtYp13BgzAb%jI4jtv@YUpQ*Oq*Hvls4ONg_>1+>O!`J!X{qK|s7GKcj5q*H8&H zvI{mb*rWH&&$S)K4Q@WNVUHRa_Efq3NP|61UgwQRtZ#p=nOeVwnY3gr_oLVgZbgag zPODxXB}2?96C-QAce%G7uoJ^qP^Z*E%3lPf&>m|0Y|J8UtbfVAU=w4kA7Va7Y+{bF zwnI&vD~v;v>qm@fg~g4B>^H2aa8M64@e+8<6)nZAAF{FLRSSE+c34NRwW1wSPeb)I zc}4NR2}(ur!>S|w3EKN7Xtg7q*Z-(PzQr3#^0S%d25H8KRZ!a{HJ(wMC#W6XQnGiU zxur&JL8c3P7I>TN8Jjn>&sr0Udd3#-oI%eRGe3h7n0DvaV*{()-IA3cOLwB((Tmqr z>7*GCot;cLv*mY^D9@vGxA&NqTbldXb}sAFGcoXsJ!yXY_NVVjO}0gp2M4rE-Y37f zxbbBB%B59Z>gd(4T#{Cl55hoN167!be>)ug{#EsnFh)SAwGDEuPI(%#5$UUya(rIil{p^&!ck-Xc{hCC+wt(QSo7WJ1<& z-Or0K`PsdwkVamBJsl>VvP{o%X)3#_{&r3kL9R`9N2#>cvV`|SX~PFRHUAbl3YIKU zO|eAW77w?FyQ>vx=3%@eO<(NhvU2uB3Xij^5zD zIE7&mqu?dT7Fk`lS)JMJIkw2o<7a<&LBGIGtG=_$WTVBo^zotw6wi)7s_RJCk@8E( z#^fFFI^>K~UFWFp8)r0*RMt$?RLg@e;w)NQqaP~U9=tMfhw1G!yPLXLJ2%_j=fh;+ zxHp^!>l5di^I&80#%TOZ-rXQ@+=LcqlXz#Jn-@4GL<&!CD-pw|g<4Q*Jt=1w}d8wQA9s zj0zl?yVyyOM?yAAqr4#D)8o|$vSfg9sAts_FJT#lOIZ(@Y?4W|-5$mjKcaq>{g{aL zxudM2ou5ZmVf53Psq5eBNT#9xPp4$ozZoshH*_u<9EWd6t3XQIsr8c>Ot<`CRJp(n9SFz!9&X>3i&YGf|ybcWrchGQojG(`7 z@a9#VBF{izJEr`!q_j&)XGZy`q;yNl!i@5(lCoG*mS&Wwq%4<|Q!~mzNjY6o&K$y? zeOwC@v#1*9;TKCB_&o}C8KqRv<7%HYq<_$|e6mHdBJ{MOU_ibvaT&=?fb zmF~YQ-dXSW$TUmtf0f+Lr}>mCo!gSu9?tFh@#)4%K;FqVG+f-ti_qnz59L=OOwo#1_HBKC-W*4lzjyMe2;jgb$2fc_QV;o z|14!IlsS}9&|a-5x0^wNZ@;WzvN9al0uW?IhuOm0T#+U(Z{B2?(@&jW` zD&q=ap-B~G6{S6{9yYnn3H#Jm2(#8{Mw1$EOzONjaBbtE7o^EkIYDbnvAkgL+H*$ims$ z@MWxyK4~k7MdHRRPeGDoYe%@JNRoFZ9gKB)MT52Wq&x2LGh@sLw9cKsg1UgTh_Ip! znfNz9J2w8H@y?$N^eylea4kUkxl(!wedoqYN_yeWKgU4-koqq_k5Oyb*SLP5ojh!qFFw<3^5q;J9v>Qb2G=g9MF1GH?Tgg<|uS zD`j(6_))sKj+XEfH;+c)=Brm;;D{zp&gv;aI7K{aF{n zdj*g<-UW^6AUg+~ssKylGo2p;=j6(3zB(bTm z!gy16QpOnc2B?-pNrOP2x}a=q)>MBL+wIXq#8Uept28o>oa~+$*xQNyU1=#Nlg;A; zqA=uBkkA%Gyw|a$w_s5IJ~D@0U@rsV+vN|)UhnEZ(CKbEt)FKXbW^7r$ka`6G*!ZF zr0YyKmzn;Z`Hfk%ji%mx;yrLY%&NY%wOXe~7ukzPSKadfw1>d6o@{#FouMC>6g+bj z1P7tvdD!6`uQ$(AuM)9=nTn4n8zPgf@<|kgaSWEZk%V&vfnQ-ETSUs+$ZXBTgQcn4 zOLl$HQMA=%bUlC~<;tjbdez7# zxq7zKQ*dK?9#55BPyR6?2tmtkNyFl!>u*sr#eurH~z)-bS0g6@2+cPzvpd)@Kto(SOUP#zdcCEr)DsPOz^B zj<{SHGn4CwjA@0%jVJ6^tgtz#2e#M(kGY`@bQ+&%ex-2w)maUr)`oUSBXu>>;I`r~ zK(Q4+EIQOr(4HNmRS$Ju`=bu|Ca){WKQA=bNi$}wfZ8gle_v1=$EYj3sbv2J%}q6H z6Ebbsv&vg!&&1r)K0QCRXk=pXm2()GVCCm91JgcxF)^^i?QLm?*p|pmoGSlE78vo?ptvh$!+c;}?uG@_VaS;beoJZUp(F)vR zpVpQn*#qj$S3VL!5od$$*l^!*J8RO)N5e=+$M;Fz_ocBH71BbAi{mGi1K1{aY%}i?fQ#>?(mUVgZ{Jl^4CyktfkkO!{|HD z*4PDh;TuQ4$S$(8YHXd2*Ot;pyBAW@I{Hyt$9EfFeia1*OY^k}IWyzb);ZdJ7e3TAdZ_9mrY3kl^A77rnJD$9f zcP|WG4|@~tUnkzh&&vzA1JS}1o}64yBOVMMx!&&mIFEPYBrYCZ-;X(u2Cg^A@`5Mv z&b$?fVmD5re5vbWcf7tC4eoCy@!+7F@FnGrJ6=_k<3k;boG&im8xJyZ;PY6>dTEp& zrhM*4^)O3^n1@C>ruZ(lQFN$y6NPM$Np!S6<`v(kaaFuQ#M&|$>?u z*Yy{=VScR}`q#Rt|95j#j4w_6@X5UcrGcIp60FIID_o@)|TCuR%k9f~oojZ@djJ@(pCLBg)f~ z(kdw{3(B8LO1q@2E+~H~DQhL=)PnN2l5)DFoS9+OePsEmS=h76#DsOo{?C{&3ujhE z20c5^ibai|qdS1FFC;7_VJ#%CDGBRk3B{%L>ogB#=~929xEJI9N2;;l|6R%7c$rfL z&c?R1_TixZsynvhWO(JW zE7=`s+_`s4vRJYYBugc`Em`(Y9VdE|!sQF!3Odt;FeC~LWSRE&mQQNhy2>#x*}XvS@CjfyzQWi`nH?mr6B zM4DunG>~b<56Li_vTT5Cp6?T{v>xoo;l2Ra(!?1mDBFo|Q$bm{W2^9*r)s5enX0KP zT43r`$`F-K8JXhcxU+Ufal)^FIsY*VWK!hJ26OSXUh%at>R^0cuY=b?zHPJd$}$|4 z#_bcKxC+e^0V$T}f;RIx= z8w5UUw5F-U>(eT4%(;*dn&-4>4f>n27RFi|+HB>J?u0hv2#(m`X`@D>nARtCzKZ@T zR%`J!3L%U(Cbda}^t?@)NY^TKRY?awb!gCNX(0d;(oks~KaKs-r%ffXM%-BC8AvuE z>m1@PB1yh7rFEU%&;XRyrYn;cKR3a;Kx;i?pY$oaDjCN%}F#%P}gpFuqpy5HI!*ET-@%%K~m`}`aH#??h1__{$D zh=?BoZ~)49eOXo4fC3K zx89X2VRk%bAs~gX^ts1Jpzws~@s1a{NvU18L@#% zoJS$;=wX}}`5Y0Lv;oo36XpB*?v8pPY1#aZPH@ z-Be*%X%eS&)K(GrnR~EWzd7sA0=4xwC{^oc*#-TgZcGJ+<#>?zzQW(4 zOB?+@6?-UTvqbq}lq6tT+VwqRA($sD6a?LKy38GBGE;Aya%#?Z6s2=oc?vH1NYGUw zYx!trD6%lhbKuYYBzh<-^xDA_2|fT%$WmOGg+N~rdY26f(rmY@uG_gsohgS-zVZbj zMcFQCcy0k);}s&Si)L?S8Sq_-dO=`PR^dx`)q`t(HGMbo(I8sy+DwXS&?Xv69 zb8mHGce+6$8O;jBf(1+Wa#*sS1uG=@0W9uzR{0Bv34G`F! zbbJHf5C8Eu{&~+ZzNXIGpN-BP6!|9*Zg7?x;k0HU(|t2Eb!~-~uIxRWlu zw89n69vf@!Yn;s3T4T!FPK$mX*D2cFem>aC%K1n_Ja2#2tRrutks5Rtx(DvSLi-D2 zmvNI@uRPpA?}$6Nyz$Dw9X#Gd?R{a`M%cvuzH0D6UB*QkT2G%oP1sx8ko2f5p~%03 z)W%EWfQ{J5`~zdg$UHGQo3ODpg6s}GaizAn`4UKNbL%Dh9jl!K_oTt?k#*>b`{1%y zjnd=}cPHk^h`hSV8yedI*3cN{0rBx4D9q3=CxK0 z-aa(NSGe-f-hlp2ji_(y~rPkd^&G9qeX#8ua6OUt%Db zG7dysXH~iWn&hMGM;~whLK%XDqwIrfM=F1+F`A~FO!m_xbox{&zmCOTT1R3~Dt6`m z_S&*?$1b|M*zeY4Nk8tX5_vm95vrE?KE{6{Sb1vSf|< z<)Dc4?u~dy5}Tms5PF%6BYlJp8Pski3f&cLpli0WWt#6Q8^@B$J$z2JZ~%SDR5OZ_ zJeD$wzBK;*aHB5z8~v=`8Hhs@;vboyrZF)`R{= zQSo#RM!K`!KNe(07g6N7^M+04tii-z(c)Y%vu&&DBPxz2!;v+aJGiOrK3N4adnKl9hTMevIm*; z_L3y%6|qS6Z@suO4i;Ze*3ds;iN4OQBIR*;9Q1adWis2z@~l3-wV!dGmO-zqWX|{M|Kw+J)^pmb5Hes@ z=eI& zRqUQ(T(P@~CBp_8;!bvJ=;Zwy*Mp&(<^5}$!J4C-L7n9?Z01$WqvN>9l}#Hc3(sC$ z#@2JCYd=5?;i(^>u4sYjUBx>)gDmHdfyfU)46AFuXSZ3Kb>A)aurt@Vo|DjXoPQlO zJQS_$JMfk@BE|`xD3r$Zqonw1er~QB7vR~&Z5RU-{{K-#68E5?SMW5Cr4?~H-{ki1 z*;t#*K@+Q+kw0Shj9>o+F^P?!sIfh=xr^FCjR-S#xi_A#NG7&84afY6Irg~E{Syz| zh#(W3c-#b6>!gj5_NsBxnUG`Yj+{|r)SNhDAH5~<26UNsz-1hq8F{0|1TJUXDsA2! zxA>BtjonB7s5P<1ZA8wMQG3Fe@mY=bS)9ei{7g z$=2oJ%AJG<@S-0DmtTstq$q7vsol$#!9vXOV diff --git a/riscof-plugins/rv64/spike_simple/__pycache__/riscof_spike.cpython-310.pyc b/riscof-plugins/rv64/spike_simple/__pycache__/riscof_spike.cpython-310.pyc deleted file mode 100644 index 8895634b1d11fcb2a6808237d6f3d7ea1a85b0a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3360 zcmaJ@&2QYs73YvcE|<$)No(1TT*GD4B!yb6q{@b4$MHvM*R26ZH7W;i7i|fOLrIkQ zv7X_|)_NBOY8N@Rr`~$e0=eW*=>O1j4|DCw|3Z*9{mpPC*+x+k^ZDM)n|bfe`@OQ= z_6&T*?MumTR}AA{YVhVqF}Q;w{)&njjATZ?Zb_f$vDr6uYxOPN(mvI#-M4k?^c~$c z`VF*Z*2vwyOX@wE{iddQd8^-=&G~t|-`0IA>*RC&IbtOC(fritFZ{w_l-aKgW+!tm zt$vr0O=H=4jguK0%S5`5lYEdxRf2wJkPUaz;&>)jJa2y1Y#=^GCo$Ar)ID$q(x+b< z+k~0SdgbB{S|aY?u*NF`cW_w~t^1`xjeZmIJ!y+Ux}Qkv$&)8Bc|(ZOohoxE;vc9g zt0KOWR3RT0lC0f- zygU!J4+jaCZWyLTT7{vszyN-p7M1ii4@H&aKYyN9(kz9fdQV763)x`9DomckVxq$O zVwi_odL!BrijB9_iQH5~p_biNPPJX~Tn~8%)MYBENV087aV#O7{b#D>4oF`U*$l%t zi-ZWnuZ?d$S=}x3WOXPKzIv~WhdHz)R(UGogI>hr-CmW5YE`?Co-MZ_2L7}%IOGf1 z?>!W80acfHrb}JolEArOcdah%l11CY?5I<(IMzh0RC@fWzKL=dMXaM5E59+u$|DFv zy=R`syF72qdKP*pjH;OsUI`z!H%5QZCw}qMNpD!}7v-~}hwJxt;yCE#>KZp+tWAQG zuO}*)TG8UXWJz{2PgqnO2EFZrRHR#JmR5&1cT>iaBIp&Rs92V6)xC&U%6CN2+d19t zaWHysH7O2Ov$WV>$=E67K`>g-l((klf*0$PpjQSjE>D6NS0=ER`>f>qAxpVzieXwM zs#{yS6_@z{BEvXm%amV&j+AqOhkvO0zPg{XQiv1qA7ZMmK2StYIbRxOsYq^NEYxbp zb}ZATruiQeg<9snO;xD*tx3IaNAtC{P8Y_<(FkjG#85WV_WCC}m2rfaF@>#`j0vIx zUZ%BV;Em2Psv-fbWHP6=p0*g`fqL^gUSPXDi#0!n3&57%31xj;Q(7~Me?qxEqqJv~ z&I#q=j50T)%%4zxGovij6r6>!uJS5y)MriD8Ju-d`xNj2K6Q3O+Pg6J+Uq;Gr0n1| z4@zDoEPS3Ng*2~Tk>=%fY4QU}9!TrK=4XnF3EjKwk5eI36tcmB=M-B+;A(s zIkL0C)hofsNwdM_^XQz6w|qcHt=istMXa9U@uwn*i=s_^fS_0b9**!lVKSm0 zq=HiOPv(+w9wD56AFcp%|8FWF!`W--9bC<0X)~OzHyQminV8C9_L|t;481YAXZ-Fd zz=w=srU@NW=AgCF0!k(hb0^0;DhE3`4a54WIdNyw-lln))?_W#I&!g-ub}0;G4ZfN z>&VAUd&xLzPgTI_jO}q_>`m=S3!^#yH`Md211@84VeF0@Q-q?4Kla(2*2g@YYJNs- zP7$;weqpkOiO;%vXPkQ68v9dg(gw74$L%R0#?w#GKZ6}DHBxfK->XG-M!~Cg#l?-0 zxB7XspQymI^7=b`qvpvN*@U0Zh>rjdBTtQj-hR;AlT95LG-{|=F>><56$HkSw<6M= zBC3Ww8PS!j+!DCVW$w-xVw`0TZhuU}oeetB(ueSPg((Cfh|btL`C$?}_s zxxwkMx5J}im_=Mg&}%BpeM4@HuK%B{dOe8mA;#rtg{YbZ^$~;hTLHEnwUc(S!5#@<=c#@X~30L`) zbd`p_z`Nt;)f$CfvZdzk;uKNA^t+Re!qfn)mC>aO9o4(a`V;LMsfR zeS!2U40YbXf2_3lGgbW_m2A(Fk~qmSu$;o!4-|{SGM$Na(GhiEqJ&z$>3-y%o&TPu zEuYaofS3$>i(M61r6-14176075CF~HEO{;)&?R#39ry%nUFP7ekd*Ck75k8M9SZ5I zY@*y=(XqMqnfciiQbi;W$dP38w0m|&d^@Y>3O8jFY2QOgL@wwk$#5lwpKshy-&Lcv d`)RGoTgs(1R=bAEs7`+$ec$vE$6a&L{4Xt>bOrzb diff --git a/riscof-plugins/rv64/spike_simple/__pycache__/riscof_spike.cpython-38.pyc b/riscof-plugins/rv64/spike_simple/__pycache__/riscof_spike.cpython-38.pyc deleted file mode 100644 index 62174dc94d2feb29e54e0a35277e88cc10b2f3cf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3197 zcmZuz&2Jn@74PbCDdwnwe7b1 zW45X%i6=84k)S<+IB?+TIW9-e%XJT&5r?{R%D;fv!0*+J?QBH1>hrxPwEsK~L+mUTrCvr^7BW_wZa!u<+o@rZA z3$0zWNVsL`*RipbrYS;qPx&Na0eFg&#i4H zY~j4}aR;*_?%;{mD+_nze#;tn&pT`hK5_Ov`4PDIs#V#- z72eFASh3%3DvwlGyCsBX`=aWod@83+fuzTxG?!<~Wwp-u^Rcr3=y*Ot<4WEfS^T z_zUabH#TU2~>O=?5tDt$UgWV$j4eg{`<}m~W5!bBQBWq@>fMkNP&sT@-Z%)r8!}f&*GH6R7v> zb9j>HtVPd34@GdAiQ$wmw!1n0jXCj)A5I6OYQL(VRRi3Au#=|Y05?l_Z@suY4UfNp zYG7-krDZL$;#Qf7q&f%(+fQ?qZ{4ksYJa^DCzSi)_>`f1V`?dUab+3~>hQ(YY53yW6bAF3)p9=;xs2Lsls6f5 z=cewYbveYAaaxKsEd$h*KJzl(mJb`;G1JuWiTv+UE9usEn8A);bYPj{*_NlD()Hd;Jrg#yUi}n88-7))c`3 z57Sw-@I)^NPJsYcvV}Ldp0OCh0X=ze{9=No_8igv5nKSa42~&cLFp_g-DAqH7nI(D z(m$sBc|loPP?nD=e_c>c%_%qw7c1md;FzEF@8UGhddBz^paDL0c2m2%F!trwcW_DF z$8#RmvdKjJyvQnTU%#g9t5>uwpK5krJNF-cs9CPrCz_R-eWcm8X7@A`n%&hb9k<90 zxAI$Kw-{c(7LL8V7+$>+uDRMBHF=?QyQmWpA0%a=x!J(M1DD^!)<-5cFWxYmym%T) z0>^jF?rx3pLOcXTk-u0@pTEbutjqfE7C!FG?QJAddWuJ14;>%HnEDQ)VgqD2#Pfv7 zn0b(dqW16XRqGrgxV#NlfVuxa6^P;Owaf~>;c<)^PULODf6u1IVfNZs-Hw9^yJ!9C zFTfr)ftjX!!i9&{MGGXEdcvO`tw;`bd>R4ynLYJIAc8|5+(3#MPCRXct8>`JOn22f z?9C{s^e675HEGY>X@Jp^e1m#f^uT59otpTQ)(qih+NrqcPdj4CNMrX&FzL*kX%`5& zGU?73vp#FkKMg5|Mzq!+nY!7W5zB;=#;Hzij)RR)lKqTA$olL5;v2V*$4Cjf<%0MC zk$xP|C>-pEgFW3gFWdkCz520N9;_q8je~WS?^H=MlG)e^2lupBCaJ8Iyg^*o!@&TK zWTM{>ju~$uPKGDL!H!I-QISZBdeM9>={BvDFZ-0 zNORg_J~oFkngq(p1I>wPPNI0L9cVQ2p{JM(6!niH?_8zYK?IIGl>;?|ZY_3x_v!ga z0v=&mRpB)1`=~4@WEbp9yvuzDKWgrN;I8lsu4kXOIgqmJgT{_<@@N61ZAc&J%t#-C zI0jUW00Xh^#_?yPq*zdZ=LW<;=)^I!t&qjUu|a2f3ENAG{PI&&y0^goG%E_QoPfo* ziG>iuBs`=@MOyb6cevfXjl~i7U|qFK!Al2fv^A7eLW zNNsoE0kCXcg115Dvm+_KAhS78x=V;%Z?Bv9H}{a`#T4=}05tLt-9GL{XBWh8Ce4zt zNw<+(eT*HEaCx*d9EULKt^1jq8btJO&h>bk9N0uhle19XviQ5mStwR^ZQuSMH|t0M diff --git a/riscof-plugins/rv64/spike_simple/__pycache__/riscof_spike_simple.cpython-310.pyc b/riscof-plugins/rv64/spike_simple/__pycache__/riscof_spike_simple.cpython-310.pyc deleted file mode 100644 index 12489fb7dc036babfe670bb7513117c867fc2aff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3455 zcmaJ^O>Y~=8Q$5QT`rePN~SFHThBq-^qE;ovW%ch%;)pY=ljm{zATze z&%pQ3-(T7Kdf71kr5bO46pgz`;;+b7rnSuNxulw--m7cO%No7Ltk2Jyy{4{PX)BxS%@HHE59g;w@60a@Mw$KEV0JwB z%IdWld17>&H`tl6-XYT6h_gW&l`-nAK|0({@}r)IOR z#V`UZMHtsuGMK+-@`yDtdX5=S4AwfTb>`Nk(=YO^WP7yoIE^C_2XS7;JV^4vune}6 zG!6z)xg*dKRDweul}V8=zfrd&>EnAFzmx{Ibz`^K6w<47sD?>95reod?SU@5GUD5D z8S-H+$?AiR&OEMtIEcA)!!XH{G7O~!0m$J-HuU2-7EM6Ikn6GRUMJiT!BKpNvw>ql`hXV!+W-D*o)Jz5o zp4i#);DEQWz2CM? zK{tzdf9Lkg)k$#tbwvpiP*^`JSe)L@Vix5GL3e9E5y@tfCgs8HorJMC54w3FN|q*@ zRW0JBvMCXCw@;?q2uAO%#QFY8n&f-SDLX+P2BR|?In^~6yj+_E-6D8-brQV1Hh~`9 z=LO#jS;A#q43jce)ye`I{URG+$*`ZX4&@)rL>dr{Uhqa6q-a^Pa zjY?@8f>NeX*^)5w?HyRd>YKYbzHEU81_j3p3SXpgF3s!Lq7AdCdqwC`lFh%*3IPh$W8~>uLUC~Ne5Tgf{rciVVR^t*3%+l;X#z8 zlImqF&;$PoHgIGanlH4#316rtZ$ju@>##S6Ny?r85dpH6b)NdvCoS?r=|ehdpE3?ICL?SubkAPG4U`%bICYtP8CJ9#`d^2_NMlvfz}-V8u>hH zLCV-YGj_+dDadQ$k9{_$?_(ZTHa|n_Q_$SR&rNn_;>p;ZJt{nc`IK;d$FRbY&(f&uV%gD(NmO-T>Z&@VUc~lO0Jfh2Ku|2Ya?q|};qCPJK|GAQV0Q0@^ z@y+Y2H?OX)t*x!z2)bR^r{>-($HQ-frGt}ZcbiA~Fpaq4+#8A*za_UuH~-I6-7c2z zf)%r*1P`Y{wZ&lVPJpRL&A7i)1eex-9sK6Y^-H7n-98Jz{WXyL-pOqE~1?2Cnz1|og+B^ zw0ItKeou)iH_ew+rmjeO5o2K$M92o5e}4$7kJ6Mc0PVCYc6XHy9$`b0sx_o;>rH9x zAim)Tk}9DJ(r&|2ae#|k4wcfSi#w`ntt0v$?qQb$3c zU6}u|#yV%UDS)e?cCn+VR(fK%Ip9S<76RUOCyigo z8m<(f{WeSkDlam~mWcAUxuQTsaR);BRZz98*}5{F`B@iYPedJg2@*f4F3iBwe;T;* zw6cyk@)1@ZwZtQ8tb4j@4bM=m>6xmvJWI8)Nm3X4+ntNara_Msbic=yyi(co3x*Ga>RUf5vPe9zcg_C=19zKnC42ztj#1 zHK_T@0U0c6ztTX48g-zp(K>BF>wKx1npcPOo3bTF(J}Ky1gA64+Q(60-R{5Nza5gL zLu=5-*It1l{smR8z0{6KNlN{XWMY*16mD=%CT4CNnNy4ErFm@gerZyDLrZnM(Yan~ zz6~?lvBMwdHEO*iM9ZBoNU^0>)q!SjXy*j@8uOXjY^FJ%ab`2E&$M*Q)bjRmga4gq z6N_lYt-Lc`q4jgz8G5CqdT_>P+WVlliS=9SbM4n~qtB7PN*hQo&4=1=Zcc2RDQ((Z zhnW&?vJQ74+Ow}q1Kz5&C+#px52JxJpM3oEmr|3Kdc0!uNz4MlT$bjHyHPqC=k8$? zGj|l^LjeyR08qun>1xZ0R0m z+)W}OqIBS%1o4=Oe(|&YC%d0Ka`%-^-D-DO66H}4M}kpztk`k)!z_-oQ(S!ciiP2B zx!o%u;dsQjbbKGz`@S>=ESGvFq>1;H=1~@jkJ4N=_RmDll1I;@T-JgE zp_rXW1ilivjiwG)Pt=e%!Jee^2|IhldB&w3XM+KpYB4pmC_5Mrx;1GE79UD8-~%D; z<5O%sTZC~S1h;St0_TGg_}N!P)_q@5eE%!$&Ccd9OW5XEFuwUT%VM#~BN1kYz3Oqq z=JG4gXmGWKXY@yBybVWOha$cYl}0*xgSf)>J7F|P&)nYONhG3!D30>8?O{YIOWj_Y ziJZpKLDdU*js`6jdp&iF8=EXW*^Hy~xF6F6W!EjPD9Z9w*O1O>#*cj(@k-szFiS?T zrynM?Yw}wlI$B! zs~hGwx}krgoBDr>^-FqKtPC%Z6c?ifp*EBz4gvdeZ3_5yPAJ*XCV;J_L5&R!Q0+U^ z1VpoxCT!4-(vfe_8gKwM0mmN9nzRo3YbcGG=@xCysqviJno)1j_MH0rIki(!>BhGl(iY<>YVbA8ReZB<=UL`?-}L#jIw?~Svu*)jJ7ca ziH~%J@%FS?n!G126p@P zNAUWx1Bf%qc+RN*JZ7oX@86U9-8)j}C!TTt-mWxu_dhObXyFIZc45V%`}bVWxO-=} zu%mc%_l_DoDr#!LTuF8%i6r@zB#9(Hm*h~Ahmuf9b|eXl8r(86&Z z8~~K38DM%gPHEr01kqrc5zo>DU-()pz)hny@S;nR1metxeqt#T9uP16jhrpP!xx}4&2h2xfOrg zVXT936w`aaBd`Me0-S2WZ*5jqVWtE9MXAO(ZvxjUDb_Cek=igs@VfXA$1zb*E+nB- z5(uncPjpNZ(22mj(3wnVacofof-b<@R4>uEFbOk%2NY_7Dd`h5AxI{G8-nrFK1V35 zo$Is)j$wjxIndhc+Qcax$Dj>N4`8;ACI@Z@oGJ-uOq(Sn21l*ZqOCs=2>aSm zo3@o%cgk96p98#38fsOi1jn7Pf+S(F>KP<30KY4HvYs=M`xx33WEFOD)&~H7{a^Ts zMqfmOG|0!C@ojjDH^ePWx0ksPT6+(rodhAzM6tS~U=SlP?gl}ZNFzL@#eKKe19MRj z{-gO;+W_|NV%Qt-ARWg6N9exizPK|fu0B#miyK0su#Yj!?XGal+xRM0SD=z+8YE1a zBL5J_7GwbsZ84#&jPPCTZ6T>8hAfWZnn{pSY4CBX>{1EUZ7Q4e9K8GENaWJQI8nWf zip0`Hl2i-`{?dRK@*EJzSDXgGf8`Rj%G=o6hU>tIPhk)71a2eHIW!e@A@b@bxuw4c zcHALrI@WJR+>4dn24*lQGGs6f--qxwhREZ~mhV3s2l0#oDT4}(Kxq2@3F88CE#Fsx zpJQz153%|bD%qZ;7a_b2uq>j}caa4{6vtqK9xPf=VU}R(t?Q2C+)|Y8RizWaHO7Am z46-4{2P2+^Ob7^s!zhM9HM{pnAa%@gIV~(2Z%(@~;KT KL2zm5j{ZONVxs{7 diff --git a/riscv-test-suite/rv32i_m/pmp32/PMP-CFG-reg.S b/riscv-test-suite/rv32i_m/pmp32/PMP-CFG-reg.S new file mode 100644 index 000000000..a27d0d183 --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/PMP-CFG-reg.S @@ -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 diff --git a/riscv-test-suite/rv32i_m/pmp32/PMP-CSR-access.S b/riscv-test-suite/rv32i_m/pmp32/PMP-CSR-access.S new file mode 100644 index 000000000..c36838928 --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/PMP-CSR-access.S @@ -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 \ No newline at end of file diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-R-priority-level-2.S b/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-R-priority-level-2.S new file mode 100644 index 000000000..d8bc8e36e --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-R-priority-level-2.S @@ -0,0 +1,224 @@ +// ----------- +// 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 +/* Test Name: pmp-NA4-priority-r-level-2.S +// Tests the priority by assigning only R permissions to the highest priority while no permissions to high priority region and R-W-X to low priority region +*/ + +#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_NA4_priority_r_level_2) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg3 [31:24] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled. This is the low priority region +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with nothing enabled +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION). This is the high priority region +// in TOR Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION3 ((((PMP_R|PMP_L|PMP_NA4)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +// PMPADDRESS14 = value to be loaded pmpaddr14 to declare lower address of Region-1 +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr14 to declare region1 +// PMPADDRESS15 = value to be loaded pmpaddr15 to declare upper address of Region-1 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of Region-2 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of Region-2 +#define PMPADDRESS3 RETURN_INSTRUCTION +// PMPADDRESS3 = value to be loaded pmpaddr1 to declare upper address of Region-3 +#define PMPADDRESS1 TEST_FOR_EXECUTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration +/* PMP is configure in the following order: +1. Address 0x8000 0000 to Address RVMODEL_DATA_END => PMP TOR (Low Priority) Region with RWX enabled. For this purpose, pmpaddr14 has been given the value of 0 and pmpaddr15 is given address to RVMODEL_DATA_END to declare the region from 0->RVMODEL_DATA_END into a single PMP region. + +2. Address RAM_LOCATION_FOR_TEST to Address RETURN_INSTRUCTION => PMP region under test. This region has been declared by entering RAM_LOCATION_FOR_TEST into pmpaddr2 and address to RETURN_INSTRUCTION label into pmpaddr3. Then a PMP region is configure from pmpaddr2(RAM_LOCATION_FOR_TEST) to pmpaddr3(RETURN_INSTRUCTION) into TOR mode by setting pmpcfg0[31:24]=PMPREGION2 + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg3, x4 // Updated pmpcfg3 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION3) + // Value to be stored in pmpcfg register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 0*(XLEN/32),4,NOP +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-R-priority.S b/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-R-priority.S new file mode 100644 index 000000000..587abd94d --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-R-priority.S @@ -0,0 +1,202 @@ + +// ----------- +// 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 +/* Test Name: pmp-NA4-priority-r.S +// PMP Test in NA4 address matching mode +// Description: +// Tests the priority by assigning only R permissions to the high priority while R-W-X to low priority region +*/ + +#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_NA4_priority_r) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg3[31:24] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in NAPOT Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_R|PMP_NA4)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of region3 +#define PMPADDRESS2 TEST_FOR_EXECUTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg3, x4 // Updated pmpcfg3 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-R.S b/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-R.S new file mode 100644 index 000000000..e6756be13 --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-R.S @@ -0,0 +1,239 @@ +// ----------- +// 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 +/* Test Name: pmp-NA4-R.S +// PMP Test in NA4 address matching mode +// Description: +=> Foreach mode in MPP (including M), for Load/store instruction, perform the instruction referencing an address where the associated pmpcfg.W=0 and observe an access fault or not. +=> Foreach mode, perform instruction fetches to an address where the associated pmpcfg.X=0 and observe an access fault or not. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +=> Do the same for loads where pmpcfg.R=1 and pmpcfg.W=0 to make sure that the W bit only affects stores and AMOs. +*/ +/* COVERPOINTS: (Explanation of updates in /coverage/rv32i_priv.cgf) + (pmpcfg0 >> 8) & 0x18 == 0x10 : 0 // CHECK pmp2cfg in NA4 mode? + (pmpcfg0 >> 8) & 0x01 == 0x01 : 0 // CHECK R-bit in pmp2cfg was HIGH + (pmpcfg0 >> 8) & 0x02 == 0x02 : 0 // CHECK W-bit in pmp2cfg was HIGH + (pmpcfg0 >> 8) & 0x04 == 0x04 : 0 // CHECK X-bit in pmp2cfg was HIGH +// 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_NA4_r) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg0 [7:0] value to configure address 0->RAM_LOCATION_FOR_TEST in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in NA4 Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_R|PMP_L|PMP_NA4)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(rvtest_code_end) +// in TOR Mode with RWX enabled +// ALSO NOTE THAT PMPREGION2 IS INSIDE THIS REGION, so this test will also check the priority order of PMP regions +#define PMPREGION3 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg1[7:0] value to configure address (rvtest_code_end)->(PMP_region_High) +// in TOR Mode with RWX enabled +#define PMPREGION4 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS0 RAM_LOCATION_FOR_TEST // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS1 TEST_FOR_EXECUTION +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of region3 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of region3 +#define PMPADDRESS3 rvtest_code_end +// PMPADDRESS4 = value to be loaded pmpaddr4 to declare upper address of region4 +#define PMPADDRESS4 PMP_region_High + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration +/* PMP is configure in the following order: +1. Address 0x0000 0000 to Address RAM_LOCATION_FOR_TEST => PMP TOR Region with RWX enabled. This region is the part of the code memory containing our code. For this purpose, pmpaddr0 has been given the value of RAM_LOCATION_FOR_TEST to declare the region from 0->RAM_LOCATION_FOR_TEST into a single PMP region. + +2. Address TEST_FOR_EXECUTION to Address RETURN_INSTRUCTION =====> This is the PMP region under test (A 4byte region == Granularity of Sail. This region has been declared by entering TEST_FOR_EXECUTION into pmpaddr1 and RETURN_INSTRUCTION into pmpaddr2. Then a PMP region is configure into NA4 mode by setting pmpcfg0[15:8]=((PMP_R|PMP_L|PMP_NA4)&0xFF) + +3. Address RAM_LOCATION_FOR_TEST to Address rvtest_code_end => Another PMP region under test. This region has been declared by entering rvtest_code_end into pmpaddr3 and RAM_LOCATION_FOR_TEST into pmpaddr2. configure pmpaddr2(RAM_LOCATION_FOR_TEST) to pmpaddr3(rvtest_code_end) into TOR mode by setting pmpcfg0[31:24]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) + +4. Address rvtest_code_end to address PMP_region_High => PMP TOR Region with RWX enabled. This region is the part of the code memory containing trap handler, epilogs, and other important macro definitions. For this purpose, configure pmpaddr3(rvtest_code_end) to pmpaddr4(PMP_region_High) into TOR mode by setting pmpcfg1[7:0]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)). This PMP Region is mandatory to access signature area in S,U mode */ + /* Assigning addresses to PMP address registers */ + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS4) // Value to be stored in pmpaddr4 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr4, x4 // Updated pmpaddr4 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1 | PMPREGION2 | PMPREGION3) + // Value to be stored in pmpcfg register ; Setting Up PMP Region-1,2,3 + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION4) + // Value to be stored in pmpcfg1 register ; Setting up PMP Region-4 + csrs pmpcfg1, x4 // Updated pmpcfg1 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-RW-priority-level-2.S b/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-RW-priority-level-2.S new file mode 100644 index 000000000..2b84a4322 --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-RW-priority-level-2.S @@ -0,0 +1,220 @@ +// ----------- +// 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 +/* Test Name: pmp-TOR-priority-rw-level-2.S +// Tests the priority by assigning only R,W permissions to the highest priority while no permissions to high priority region and R-W-X to low priority region +*/ + +#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_NA4_priority_rw_level_2) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg3 [31:24] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled. This is the low priority region +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with nothing enabled +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION). This is the high priority region +// in TOR Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION3 ((((PMP_R|PMP_W|PMP_L|PMP_NA4)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +// PMPADDRESS14 = value to be loaded pmpaddr14 to declare lower address of Region-1 +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr14 to declare region1 +// PMPADDRESS15 = value to be loaded pmpaddr15 to declare upper address of Region-1 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of Region-2 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of Region-2 +#define PMPADDRESS3 RETURN_INSTRUCTION +// PMPADDRESS3 = value to be loaded pmpaddr1 to declare upper address of Region-3 +#define PMPADDRESS1 TEST_FOR_EXECUTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg3, x4 // Updated pmpcfg3 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION3) + // Value to be stored in pmpcfg register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 0*(XLEN/32),4,NOP +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-RW-priority.S b/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-RW-priority.S new file mode 100644 index 000000000..6ca157f61 --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-RW-priority.S @@ -0,0 +1,201 @@ +// ----------- +// 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 +/* Test Name: pmp-NA4-priority-rw.S +// PMP Test in NA4 address matching mode +// Description: +// Tests the priority by assigning only R,W permissions to the high priority while R-W-X to low priority region +*/ + +#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_NA4_priority_rw) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg3[31:24] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in NAPOT Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_R|PMP_W|PMP_NA4)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of region3 +#define PMPADDRESS2 TEST_FOR_EXECUTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg3, x4 // Updated pmpcfg3 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-RW.S b/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-RW.S new file mode 100644 index 000000000..6d4137419 --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-RW.S @@ -0,0 +1,240 @@ +// ----------- +// 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 +/* Test Name: pmp-NA4-RW.S +// PMP Test in NA4 address matching mode +// Description: +=> Foreach mode in MPP (including M), for Load/store instruction, perform the instruction referencing an address where the associated pmpcfg.W=0 and observe an access fault or not. +=> Foreach mode, perform instruction fetches to an address where the associated pmpcfg.X=0 and observe an access fault or not. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +=> Do the same for loads where pmpcfg.R=1 and pmpcfg.W=0 to make sure that the W bit only affects stores and AMOs. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +*/ +/* COVERPOINTS: (Explanation of updates in /coverage/rv32i_priv.cgf) + (pmpcfg0 >> 8) & 0x18 == 0x10 : 0 // CHECK pmp2cfg in NA4 mode? + (pmpcfg0 >> 8) & 0x01 == 0x01 : 0 // CHECK R-bit in pmp2cfg was HIGH + (pmpcfg0 >> 8) & 0x02 == 0x02 : 0 // CHECK W-bit in pmp2cfg was HIGH + (pmpcfg0 >> 8) & 0x04 == 0x04 : 0 // CHECK X-bit in pmp2cfg was HIGH +// 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_NA4_rw) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg0 [7:0] value to configure address 0->RAM_LOCATION_FOR_TEST in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in NA4 Mode with RW enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_R|PMP_W|PMP_L|PMP_NA4)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(rvtest_code_end) +// in TOR Mode with RWX enabled +// ALSO NOTE THAT PMPREGION2 IS INSIDE THIS REGION, so this test will also check the priority order of PMP regions +#define PMPREGION3 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg1[7:0] value to configure address (rvtest_code_end)->(PMP_region_High) +// in TOR Mode with RWX enabled +#define PMPREGION4 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS0 RAM_LOCATION_FOR_TEST // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS1 TEST_FOR_EXECUTION +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of region3 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of region3 +#define PMPADDRESS3 rvtest_code_end +// PMPADDRESS4 = value to be loaded pmpaddr4 to declare upper address of region4 +#define PMPADDRESS4 PMP_region_High + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration +/* PMP is configure in the following order: +1. Address 0x0000 0000 to Address RAM_LOCATION_FOR_TEST => PMP TOR Region with RWX enabled. This region is the part of the code memory containing our code. For this purpose, pmpaddr0 has been given the value of RAM_LOCATION_FOR_TEST to declare the region from 0->RAM_LOCATION_FOR_TEST into a single PMP region. + +2. Address TEST_FOR_EXECUTION to Address RETURN_INSTRUCTION =====> This is the PMP region under test (A 4byte region == Granularity of Sail. This region has been declared by entering TEST_FOR_EXECUTION into pmpaddr1 and RETURN_INSTRUCTION into pmpaddr2. Then a PMP region is configure into NA4 mode by setting pmpcfg0[15:8]=((PMP_R|PMP_W|PMP_L|PMP_NA4)&0xFF) + +3. Address RAM_LOCATION_FOR_TEST to Address rvtest_code_end => Another PMP region under test. This region has been declared by entering rvtest_code_end into pmpaddr3 and RAM_LOCATION_FOR_TEST into pmpaddr2. configure pmpaddr2(RAM_LOCATION_FOR_TEST) to pmpaddr3(rvtest_code_end) into TOR mode by setting pmpcfg0[31:24]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) + +4. Address rvtest_code_end to address PMP_region_High => PMP TOR Region with RWX enabled. This region is the part of the code memory containing trap handler, epilogs, and other important macro definitions. For this purpose, configure pmpaddr3(rvtest_code_end) to pmpaddr4(PMP_region_High) into TOR mode by setting pmpcfg1[7:0]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)). This PMP Region is mandatory to access signature area in S,U mode */ + /* Assigning addresses to PMP address registers */ + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS4) // Value to be stored in pmpaddr4 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr4, x4 // Updated pmpaddr4 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1 | PMPREGION2 | PMPREGION3) + // Value to be stored in pmpcfg register ; Setting Up PMP Region-1,2,3 + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION4) + // Value to be stored in pmpcfg1 register ; Setting up PMP Region-4 + csrs pmpcfg1, x4 // Updated pmpcfg1 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-RWX.S b/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-RWX.S new file mode 100644 index 000000000..d9394d103 --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-RWX.S @@ -0,0 +1,254 @@ +// ----------- +// 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 +/* Test Name: pmp-NA4-RWX.S +// PMP Test in NA4 address matching mode +// Description: +=> Foreach mode in MPP (including M), for Load/store instruction, perform the instruction referencing an address where the associated pmpcfg.W=1 and observe an access fault or not. +=> Foreach mode, perform instruction fetches to an address where the associated pmpcfg.X=0 and observe an access fault or not. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +*/ +/* COVERPOINTS: (Explanation of updates in /coverage/rv32i_priv.cgf) + (pmpcfg0 >> 8) & 0x18 == 0x10 : 0 // CHECK pmp2cfg in NA4 mode? + (pmpcfg0 >> 8) & 0x01 == 0x01 : 0 // CHECK R-bit in pmp2cfg was HIGH + (pmpcfg0 >> 8) & 0x02 == 0x02 : 0 // CHECK W-bit in pmp2cfg was HIGH + (pmpcfg0 >> 8) & 0x04 == 0x04 : 0 // CHECK X-bit in pmp2cfg was HIGH +// 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_NA4_rwx) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + +// pmpcfg0 [7:0] value to configure address 0->RAM_LOCATION_FOR_TEST in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in NA4 Mode with RW enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_NA4)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(rvtest_code_end) +// in TOR Mode with RWX enabled +// ALSO NOTE THAT PMPREGION2 IS INSIDE THIS REGION, so this test will also check the priority order of PMP regions +#define PMPREGION3 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg1[7:0] value to configure address (rvtest_code_end)->(PMP_region_High) +// in TOR Mode with RWX enabled +#define PMPREGION4 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS0 RAM_LOCATION_FOR_TEST // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS1 TEST_FOR_EXECUTION +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of region3 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of region3 +#define PMPADDRESS3 rvtest_code_end +// PMPADDRESS4 = value to be loaded pmpaddr4 to declare upper address of region4 +#define PMPADDRESS4 PMP_region_High + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration +/* PMP is configure in the following order: +1. Address 0x0000 0000 to Address RAM_LOCATION_FOR_TEST => PMP TOR Region with RWX enabled. +This region is the part of the code memory containing our code and the region between code_end to data_begin. +For this purpose, pmpaddr0 has been given the value of RAM_LOCATION_FOR_TEST to +declare the region from 0->RAM_LOCATION_FOR_TEST into a single PMP region. + +2. Address TEST_FOR_EXECUTION to Address RETURN_INSTRUCTION =====> This is the PMP region under test (A 4byte region == Granularity of Sail.) +This region has been declared by entering TEST_FOR_EXECUTION into pmpaddr1 and RETURN_INSTRUCTION into pmpaddr2. +Then a PMP region is configure into NA4 mode by setting pmpcfg0[15:8]=PMPREGION2 + +3. Address RAM_LOCATION_FOR_TEST to Address rvtest_code_end => Another PMP region under test. +This region has been declared by entering rvtest_code_end into pmpaddr3 and +RAM_LOCATION_FOR_TEST into pmpaddr2. configure pmpaddr2(RAM_LOCATION_FOR_TEST) +to pmpaddr3(rvtest_code_end) into TOR mode +by setting pmpcfg0[31:24]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) + +4. Address rvtest_code_end to address PMP_region_High => PMP TOR Region with RWX enabled. +This region is the part of the code memory containing trap handler, epilogs, and other important macro definitions. +For this purpose, configure pmpaddr3(rvtest_code_end) to pmpaddr4(PMP_region_High) +into TOR mode by setting pmpcfg1[7:0]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)). +This PMP Region is mandatory to access signature area in S,U mode */ + + /* Assigning addresses to PMP address registers */ + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS4) // Value to be stored in pmpaddr4 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr4, x4 // Updated pmpaddr4 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1 | PMPREGION2 | PMPREGION3) + // Value to be stored in pmpcfg register ; Setting Up PMP Region-1,2,3 + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION4) + // Value to be stored in pmpcfg1 register ; Setting up PMP Region-4 + csrs pmpcfg1, x4 // Updated pmpcfg1 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + nop + j exit +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-RX-priority-level-2.S b/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-RX-priority-level-2.S new file mode 100644 index 000000000..9e18144b3 --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-RX-priority-level-2.S @@ -0,0 +1,220 @@ +// ----------- +// 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 +/* Test Name: pmp-TOR-priority-rx-level-2.S +// Tests the priority by assigning only R,X permissions to the highest priority while no permissions to high priority region and R-W-X to low priority region +*/ + +#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_NA4_priority_rx_level_2) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg3 [31:24] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled. This is the low priority region +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with nothing enabled +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION). This is the high priority region +// in TOR Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION3 ((((PMP_R|PMP_X|PMP_L|PMP_NA4)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +// PMPADDRESS14 = value to be loaded pmpaddr14 to declare lower address of Region-1 +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr14 to declare region1 +// PMPADDRESS15 = value to be loaded pmpaddr15 to declare upper address of Region-1 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of Region-2 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of Region-2 +#define PMPADDRESS3 RETURN_INSTRUCTION +// PMPADDRESS3 = value to be loaded pmpaddr1 to declare upper address of Region-3 +#define PMPADDRESS1 TEST_FOR_EXECUTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg3, x4 // Updated pmpcfg3 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION3) + // Value to be stored in pmpcfg register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 0*(XLEN/32),4,NOP +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-RX-priority.S b/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-RX-priority.S new file mode 100644 index 000000000..6cfba0c46 --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-RX-priority.S @@ -0,0 +1,201 @@ +// ----------- +// 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 +/* Test Name: pmp-NA4-priority-rx.S +// PMP Test in NA4 address matching mode +// Description: +// Tests the priority by assigning only R,X permissions to the high priority while R-W-X to low priority region +*/ + +#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_NA4_priority_rx) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg3[31:24] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in NAPOT Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_R|PMP_X|PMP_NA4)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of region3 +#define PMPADDRESS2 TEST_FOR_EXECUTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg3, x4 // Updated pmpcfg3 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-RX.S b/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-RX.S new file mode 100644 index 000000000..0fd809790 --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-RX.S @@ -0,0 +1,238 @@ +// ----------- +// 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 +/* Test Name: pmp-NA4-RX.S +// PMP Test in NA4 address matching mode +// Description: +=> Foreach mode in MPP (including M), for Load/store instruction, perform the instruction referencing an address where the associated pmpcfg.W=1 and observe an access fault or not. +=> Foreach mode, perform instruction fetches to an address where the associated pmpcfg.X=0 and observe an access fault or not. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +*/ +/* COVERPOINTS: (Explanation of updates in /coverage/rv32i_priv.cgf) + (pmpcfg0 >> 8) & 0x18 == 0x10 : 0 // CHECK pmp2cfg in NA4 mode? + (pmpcfg0 >> 8) & 0x01 == 0x01 : 0 // CHECK R-bit in pmp2cfg was HIGH + (pmpcfg0 >> 8) & 0x02 == 0x02 : 0 // CHECK W-bit in pmp2cfg was HIGH + (pmpcfg0 >> 8) & 0x04 == 0x04 : 0 // CHECK X-bit in pmp2cfg was HIGH +// 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_NA4_rx) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg0 [7:0] value to configure address 0->RAM_LOCATION_FOR_TEST in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in NA4 Mode with RX enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_R|PMP_X|PMP_L|PMP_NA4)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(rvtest_code_end) +// in TOR Mode with RWX enabled +// ALSO NOTE THAT PMPREGION2 IS INSIDE THIS REGION, so this test will also check the priority order of PMP regions +#define PMPREGION3 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg1[7:0] value to configure address (rvtest_code_end)->(PMP_region_High) +// in TOR Mode with RWX enabled +#define PMPREGION4 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS0 RAM_LOCATION_FOR_TEST // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS1 TEST_FOR_EXECUTION +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of region3 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of region3 +#define PMPADDRESS3 rvtest_code_end +// PMPADDRESS4 = value to be loaded pmpaddr4 to declare upper address of region4 +#define PMPADDRESS4 PMP_region_High + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration +/* PMP is configure in the following order: +1. Address 0x0000 0000 to Address RAM_LOCATION_FOR_TEST => PMP TOR Region with RWX enabled. This region is the part of the code memory containing our code. For this purpose, pmpaddr0 has been given the value of RAM_LOCATION_FOR_TEST to declare the region from 0->RAM_LOCATION_FOR_TEST into a single PMP region. + +2. Address TEST_FOR_EXECUTION to Address RETURN_INSTRUCTION =====> This is the PMP region under test (A 4byte region == Granularity of Sail. This region has been declared by entering TEST_FOR_EXECUTION into pmpaddr1 and RETURN_INSTRUCTION into pmpaddr2. Then a PMP region is configure into NA4 mode by setting pmpcfg0[15:8]=PMPREGION2 + +3. Address RAM_LOCATION_FOR_TEST to Address rvtest_code_end => Another PMP region under test. This region has been declared by entering rvtest_code_end into pmpaddr3 and RAM_LOCATION_FOR_TEST into pmpaddr2. configure pmpaddr2(RAM_LOCATION_FOR_TEST) to pmpaddr3(rvtest_code_end) into TOR mode by setting pmpcfg0[31:24]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) + +4. Address rvtest_code_end to address PMP_region_High => PMP TOR Region with RWX enabled. This region is the part of the code memory containing trap handler, epilogs, and other important macro definitions. For this purpose, configure pmpaddr3(rvtest_code_end) to pmpaddr4(PMP_region_High) into TOR mode by setting pmpcfg1[7:0]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)). This PMP Region is mandatory to access signature area in S,U mode */ + /* Assigning addresses to PMP address registers */ + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS4) // Value to be stored in pmpaddr4 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr4, x4 // Updated pmpaddr4 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1 | PMPREGION2 | PMPREGION3) + // Value to be stored in pmpcfg register ; Setting Up PMP Region-1,2,3 + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION4) + // Value to be stored in pmpcfg1 register ; Setting up PMP Region-4 + csrs pmpcfg1, x4 // Updated pmpcfg1 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-X-priority-level-2.S b/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-X-priority-level-2.S new file mode 100644 index 000000000..8b67ed450 --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-X-priority-level-2.S @@ -0,0 +1,221 @@ +// ----------- +// 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 +/* Test Name: pmp-TOR-priority-x-level-2.S +// Tests the priority by assigning only X permissions to the highest priority while no permissions to high priority region and R-W-X to low priority region +*/ + +#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_NA4_priority_x_level_2) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg3 [31:24] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled. This is the low priority region +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with nothing enabled +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION). This is the high priority region +// in TOR Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION3 ((((PMP_X|PMP_L|PMP_NA4)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +// PMPADDRESS14 = value to be loaded pmpaddr14 to declare lower address of Region-1 +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr14 to declare region1 +// PMPADDRESS15 = value to be loaded pmpaddr15 to declare upper address of Region-1 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of Region-2 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of Region-2 +#define PMPADDRESS3 RETURN_INSTRUCTION +// PMPADDRESS3 = value to be loaded pmpaddr1 to declare upper address of Region-3 +#define PMPADDRESS1 TEST_FOR_EXECUTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg3, x4 // Updated pmpcfg3 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION3) + // Value to be stored in pmpcfg register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 0*(XLEN/32),4,NOP +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-X-priority.S b/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-X-priority.S new file mode 100644 index 000000000..9e9f667e7 --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-X-priority.S @@ -0,0 +1,201 @@ +// ----------- +// 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 +/* Test Name: pmp-NA4-priority-x.S +// PMP Test in NA4 address matching mode +// Description: +// Tests the priority by assigning only X permissions to the high priority while R-W-X to low priority region +*/ + +#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_NA4_priority_x) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg3[31:24] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in NAPOT Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_X|PMP_NA4)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of region3 +#define PMPADDRESS2 TEST_FOR_EXECUTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg3, x4 // Updated pmpcfg3 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-X.S b/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-X.S new file mode 100644 index 000000000..a9ca012f2 --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-NA4-X.S @@ -0,0 +1,238 @@ +// ----------- +// 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 +/* Test Name: pmp-NA4-X.S +// PMP Test in NA4 address matching mode +// Description: +=> Foreach mode in MPP (including M), for Load/store instruction, perform the instruction referencing an address where the associated pmpcfg.W=1 and observe an access fault or not. +=> Foreach mode, perform instruction fetches to an address where the associated pmpcfg.X=0 and observe an access fault or not. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +*/ +/* COVERPOINTS: (Explanation of updates in /coverage/rv32i_priv.cgf) + (pmpcfg0 >> 8) & 0x18 == 0x10 : 0 // CHECK pmp2cfg in NA4 mode? + (pmpcfg0 >> 8) & 0x01 == 0x01 : 0 // CHECK R-bit in pmp2cfg was HIGH + (pmpcfg0 >> 8) & 0x02 == 0x02 : 0 // CHECK W-bit in pmp2cfg was HIGH + (pmpcfg0 >> 8) & 0x04 == 0x04 : 0 // CHECK X-bit in pmp2cfg was HIGH +// 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_NA4_x) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg0 [7:0] value to configure address 0->RAM_LOCATION_FOR_TEST in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in NA4 Mode with X enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_X|PMP_L|PMP_NA4)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(rvtest_code_end) +// in TOR Mode with RWX enabled +// ALSO NOTE THAT PMPREGION2 IS INSIDE THIS REGION, so this test will also check the priority order of PMP regions +#define PMPREGION3 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg1[7:0] value to configure address (rvtest_code_end)->(PMP_region_High) +// in TOR Mode with RWX enabled +#define PMPREGION4 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS0 RAM_LOCATION_FOR_TEST // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS1 TEST_FOR_EXECUTION +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of region3 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of region3 +#define PMPADDRESS3 rvtest_code_end +// PMPADDRESS4 = value to be loaded pmpaddr4 to declare upper address of region4 +#define PMPADDRESS4 PMP_region_High + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration +/* PMP is configure in the following order: +1. Address 0x0000 0000 to Address RAM_LOCATION_FOR_TEST => PMP TOR Region with RWX enabled. This region is the part of the code memory containing our code. For this purpose, pmpaddr0 has been given the value of RAM_LOCATION_FOR_TEST to declare the region from 0->RAM_LOCATION_FOR_TEST into a single PMP region. + +2. Address TEST_FOR_EXECUTION to Address RETURN_INSTRUCTION =====> This is the PMP region under test (A 4byte region == Granularity of Sail. This region has been declared by entering TEST_FOR_EXECUTION into pmpaddr1 and RETURN_INSTRUCTION into pmpaddr2. Then a PMP region is configure into NA4 mode by setting pmpcfg0[15:8]=PMPREGION2 + +3. Address RAM_LOCATION_FOR_TEST to Address rvtest_code_end => Another PMP region under test. This region has been declared by entering rvtest_code_end into pmpaddr3 and RAM_LOCATION_FOR_TEST into pmpaddr2. configure pmpaddr2(RAM_LOCATION_FOR_TEST) to pmpaddr3(rvtest_code_end) into TOR mode by setting pmpcfg0[31:24]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) + +4. Address rvtest_code_end to address PMP_region_High => PMP TOR Region with RWX enabled. This region is the part of the code memory containing trap handler, epilogs, and other important macro definitions. For this purpose, configure pmpaddr3(rvtest_code_end) to pmpaddr4(PMP_region_High) into TOR mode by setting pmpcfg1[7:0]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)). This PMP Region is mandatory to access signature area in S,U mode */ + /* Assigning addresses to PMP address registers */ + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS4) // Value to be stored in pmpaddr4 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr4, x4 // Updated pmpaddr4 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1 | PMPREGION2 | PMPREGION3) + // Value to be stored in pmpcfg register ; Setting Up PMP Region-1,2,3 + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION4) + // Value to be stored in pmpcfg1 register ; Setting up PMP Region-4 + csrs pmpcfg1, x4 // Updated pmpcfg1 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-R-priority-level-2.S b/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-R-priority-level-2.S new file mode 100644 index 000000000..86d0dd365 --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-R-priority-level-2.S @@ -0,0 +1,220 @@ +// ----------- +// 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 +/* Test Name: pmp-NAPOT-priority-r-level-2.S +// Tests the priority by assigning only R permissions to the highest priority while no permissions to high priority region and R-W-X to low priority region +*/ + +#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_NAPOT_priority_r_level_2) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg3 [31:24] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled. This is the low priority region +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with nothing enabled +#define PMPREGION2 ((((PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION3 ((((PMP_R|PMP_L|PMP_NAPOT)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +// PMPADDRESS14 = value to be loaded pmpaddr14 to declare lower address of Region-1 +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr14 to declare region1 +// PMPADDRESS15 = value to be loaded pmpaddr15 to declare upper address of Region-1 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of Region-2 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of Region-2 +#define PMPADDRESS3 RETURN_INSTRUCTION +// PMPADDRESS3 = value to be loaded pmpaddr1 to declare upper address of Region-3 +#define PMPADDRESS1 TEST_FOR_EXECUTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg3, x4 // Updated pmpcfg3 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION3) + // Value to be stored in pmpcfg register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,NOP +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-R-priority.S b/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-R-priority.S new file mode 100644 index 000000000..18f67cbc4 --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-R-priority.S @@ -0,0 +1,201 @@ +// ----------- +// 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 +/* Test Name: pmp-NAPOT-priority-r.S +// PMP Test in NAPOT address matching mode +// Description: +// Tests the priority by assigning only R permissions to the high priority while R-W-X to low priority region +*/ + +#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_NAPOT_priority_r) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg3[31:24] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in NAPOT Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_R|PMP_NAPOT)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of region3 +#define PMPADDRESS2 TEST_FOR_EXECUTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg3, x4 // Updated pmpcfg3 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-R.S b/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-R.S new file mode 100644 index 000000000..83d71d904 --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-R.S @@ -0,0 +1,239 @@ +// ----------- +// 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 +/* Test Name: pmp-NAPOT-R.S +// PMP Test in NAPOT address matching mode +// Description: +=> Foreach mode in MPP (including M), for Load/store instruction, perform the instruction referencing an address where the associated pmpcfg.W=0 and observe an access fault or not. +=> Foreach mode, perform instruction fetches to an address where the associated pmpcfg.X=0 and observe an access fault or not. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +=> Do the same for loads where pmpcfg.R=1 and pmpcfg.W=0 to make sure that the W bit only affects stores and AMOs. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +*/ +/* COVERPOINTS: (Explanation of updates in /coverage/rv32i_priv.cgf) + (pmpcfg0 >> 16) & 0x18 == 0x18 : 0 // CHECK pmp2cfg in NAPOT mode? + (pmpcfg0 >> 16) & 0x01 == 0x01 : 0 // CHECK R-bit in pmp2cfg was HIGH + (pmpcfg0 >> 16) & 0x02 == 0x02 : 0 // CHECK W-bit in pmp2cfg was HIGH + (pmpcfg0 >> 16) & 0x04 == 0x04 : 0 // CHECK X-bit in pmp2cfg was HIGH +// 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_NAPOT_r) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg0 [7:0] value to configure address 0->RAM_LOCATION_FOR_TEST in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in NAPOT Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_R|PMP_L|PMP_NAPOT)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(rvtest_code_end) +// in TOR Mode with RWX enabled +// ALSO NOTE THAT PMPREGION2 IS INSIDE THIS REGION, so this test will also check the priority order of PMP regions +#define PMPREGION3 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg1[7:0] value to configure address (rvtest_code_end)->(PMP_region_High) +// in TOR Mode with RWX enabled +#define PMPREGION4 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS0 RAM_LOCATION_FOR_TEST // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS1 TEST_FOR_EXECUTION +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of region3 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of region3 +#define PMPADDRESS3 rvtest_code_end +// PMPADDRESS4 = value to be loaded pmpaddr4 to declare upper address of region4 +#define PMPADDRESS4 PMP_region_High + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration +/* PMP is configure in the following order: +1. Address 0x0000 0000 to Address RAM_LOCATION_FOR_TEST => PMP TOR Region with RWX enabled. This region is the part of the code memory containing our code. For this purpose, pmpaddr0 has been given the value of RAM_LOCATION_FOR_TEST to declare the region from 0->RAM_LOCATION_FOR_TEST into a single PMP region. + +2. Address TEST_FOR_EXECUTION to Address RETURN_INSTRUCTION =====> This is the PMP region under test (A 4byte region == Granularity of Sail. This region has been declared by entering TEST_FOR_EXECUTION into pmpaddr1. Then a PMP region is configure into NAPOT mode by setting pmpcfg0[15:8]=PMPREGION2 + +3. Address RAM_LOCATION_FOR_TEST to Address rvtest_code_end => Another PMP region under test. This region has been declared by entering rvtest_code_end into pmpaddr3 and RAM_LOCATION_FOR_TEST into pmpaddr2. configure pmpaddr2(RAM_LOCATION_FOR_TEST) to pmpaddr3(rvtest_code_end) into TOR mode by setting pmpcfg0[31:24]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) + +4. Address rvtest_code_end to address PMP_region_High => PMP TOR Region with RWX enabled. This region is the part of the code memory containing trap handler, epilogs, and other important macro definitions. For this purpose, configure pmpaddr3(rvtest_code_end) to pmpaddr4(PMP_region_High) into TOR mode by setting pmpcfg1[7:0]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)). This PMP Region is mandatory to access signature area in S,U mode */ + /* Assigning addresses to PMP address registers */ + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS4) // Value to be stored in pmpaddr4 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr4, x4 // Updated pmpaddr4 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1 | PMPREGION2 | PMPREGION3) + // Value to be stored in pmpcfg register ; Setting Up PMP Region-1,2,3 + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION4) + // Value to be stored in pmpcfg1 register ; Setting up PMP Region-4 + csrs pmpcfg1, x4 // Updated pmpcfg1 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-RW-priority-level-2.S b/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-RW-priority-level-2.S new file mode 100644 index 000000000..034021993 --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-RW-priority-level-2.S @@ -0,0 +1,221 @@ +// ----------- +// 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 +/* Test Name: pmp-NAPOT-priority-rw-level-2.S +// Tests the priority by assigning only R, w permissions to the highest priority while no permissions to high priority region and R-W-X to low priority region +*/ + +#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_NAPOT_priority_rw_level_2) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg3 [31:24] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled. This is the low priority region +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with nothing enabled +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION3 ((((PMP_R|PMP_W|PMP_L|PMP_NAPOT)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +// PMPADDRESS14 = value to be loaded pmpaddr14 to declare lower address of Region-1 +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr14 to declare region1 +// PMPADDRESS15 = value to be loaded pmpaddr15 to declare upper address of Region-1 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of Region-2 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of Region-2 +#define PMPADDRESS3 RETURN_INSTRUCTION +// PMPADDRESS3 = value to be loaded pmpaddr1 to declare upper address of Region-3 +#define PMPADDRESS1 TEST_FOR_EXECUTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg3, x4 // Updated pmpcfg3 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION3) + // Value to be stored in pmpcfg register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,NOP +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-RW-priority.S b/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-RW-priority.S new file mode 100644 index 000000000..f1bebe5f0 --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-RW-priority.S @@ -0,0 +1,201 @@ +// ----------- +// 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 +/* Test Name: pmp-NAPOT-priority-rw.S +// PMP Test in NAPOT address matching mode +// Description: +// Tests the priority by assigning only R,W permissions to the high priority while R-W-X to low priority region +*/ + +#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_NAPOT_priority_rw) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg3[31:24] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in NAPOT Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_R|PMP_W|PMP_NAPOT)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of region3 +#define PMPADDRESS2 TEST_FOR_EXECUTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg3, x4 // Updated pmpcfg3 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-RW.S b/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-RW.S new file mode 100644 index 000000000..b983e2cb9 --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-RW.S @@ -0,0 +1,239 @@ +// ----------- +// 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 +/* Test Name: pmp-NAPOT-RW.S +// PMP Test in NAPOT address matching mode +// Description: +=> Foreach mode in MPP (including M), for Load/store instruction, perform the instruction referencing an address where the associated pmpcfg.W=0 and observe an access fault or not. +=> Foreach mode, perform instruction fetches to an address where the associated pmpcfg.X=0 and observe an access fault or not. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +=> Do the same for loads where pmpcfg.R=1 and pmpcfg.W=0 to make sure that the W bit only affects stores and AMOs. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +*/ +/* COVERPOINTS: (Explanation of updates in /coverage/rv32i_priv.cgf) + (pmpcfg0 >> 16) & 0x18 == 0x18 : 0 // CHECK pmp2cfg in NAPOT mode? + (pmpcfg0 >> 16) & 0x01 == 0x01 : 0 // CHECK R-bit in pmp2cfg was HIGH + (pmpcfg0 >> 16) & 0x02 == 0x02 : 0 // CHECK W-bit in pmp2cfg was HIGH + (pmpcfg0 >> 16) & 0x04 == 0x04 : 0 // CHECK X-bit in pmp2cfg was HIGH +// 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_NAPOT_rw) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg0 [7:0] value to configure address 0->RAM_LOCATION_FOR_TEST in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in NAPOT Mode with RW enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_R|PMP_W|PMP_L|PMP_NAPOT)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(rvtest_code_end) +// in TOR Mode with RWX enabled +// ALSO NOTE THAT PMPREGION2 IS INSIDE THIS REGION, so this test will also check the priority order of PMP regions +#define PMPREGION3 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg1[7:0] value to configure address (rvtest_code_end)->(PMP_region_High) +// in TOR Mode with RWX enabled +#define PMPREGION4 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS0 RAM_LOCATION_FOR_TEST // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS1 TEST_FOR_EXECUTION +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of region3 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of region3 +#define PMPADDRESS3 rvtest_code_end +// PMPADDRESS4 = value to be loaded pmpaddr4 to declare upper address of region4 +#define PMPADDRESS4 PMP_region_High + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration +/* PMP is configure in the following order: +1. Address 0x0000 0000 to Address RAM_LOCATION_FOR_TEST => PMP TOR Region with RWX enabled. This region is the part of the code memory containing our code. For this purpose, pmpaddr0 has been given the value of RAM_LOCATION_FOR_TEST to declare the region from 0->RAM_LOCATION_FOR_TEST into a single PMP region. + +2. Address TEST_FOR_EXECUTION to Address RETURN_INSTRUCTION =====> This is the PMP region under test (A 4byte region == Granularity of Sail. This region has been declared by entering TEST_FOR_EXECUTION into pmpaddr1 and RETURN_INSTRUCTION into pmpaddr2. Then a PMP region is configure into NA4 mode by setting pmpcfg0[15:8]=PMPREGION2 + +3. Address RAM_LOCATION_FOR_TEST to Address rvtest_code_end => Another PMP region under test. This region has been declared by entering rvtest_code_end into pmpaddr3 and RAM_LOCATION_FOR_TEST into pmpaddr2. configure pmpaddr2(RAM_LOCATION_FOR_TEST) to pmpaddr3(rvtest_code_end) into TOR mode by setting pmpcfg0[31:24]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) + +4. Address rvtest_code_end to address PMP_region_High => PMP TOR Region with RWX enabled. This region is the part of the code memory containing trap handler, epilogs, and other important macro definitions. For this purpose, configure pmpaddr3(rvtest_code_end) to pmpaddr4(PMP_region_High) into TOR mode by setting pmpcfg1[7:0]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)). This PMP Region is mandatory to access signature area in S,U mode */ + /* Assigning addresses to PMP address registers */ + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS4) // Value to be stored in pmpaddr4 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr4, x4 // Updated pmpaddr4 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1 | PMPREGION2 | PMPREGION3) + // Value to be stored in pmpcfg register ; Setting Up PMP Region-1,2,3 + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION4) + // Value to be stored in pmpcfg1 register ; Setting up PMP Region-4 + csrs pmpcfg1, x4 // Updated pmpcfg1 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-RWX.S b/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-RWX.S new file mode 100644 index 000000000..98db31688 --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-RWX.S @@ -0,0 +1,240 @@ +// ----------- +// 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 +/* Test Name: pmp-NAPOT-RWX.S +// PMP Test in NAPOT address matching mode +// Description: +=> Foreach mode in MPP (including M), for Load/store instruction, perform the instruction referencing an address where the associated pmpcfg.W=0 and observe an access fault or not. +=> Foreach mode, perform instruction fetches to an address where the associated pmpcfg.X=0 and observe an access fault or not. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +=> Do the same for loads where pmpcfg.R=1 and pmpcfg.W=0 to make sure that the W bit only affects stores and AMOs. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +*/ +/* COVERPOINTS: (Explanation of updates in /coverage/rv32i_priv.cgf) + (pmpcfg0 >> 16) & 0x18 == 0x18 : 0 // CHECK pmp2cfg in NAPOT mode? + (pmpcfg0 >> 16) & 0x01 == 0x01 : 0 // CHECK R-bit in pmp2cfg was HIGH + (pmpcfg0 >> 16) & 0x02 == 0x02 : 0 // CHECK W-bit in pmp2cfg was HIGH + (pmpcfg0 >> 16) & 0x04 == 0x04 : 0 // CHECK X-bit in pmp2cfg was HIGH +// 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_NAPOT_rwx) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg0 [7:0] value to configure address 0->RAM_LOCATION_FOR_TEST in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in NAPOT Mode with RWX enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_NAPOT)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(rvtest_code_end) +// in TOR Mode with RWX enabled +// ALSO NOTE THAT PMPREGION2 IS INSIDE THIS REGION, so this test will also check the priority order of PMP regions +#define PMPREGION3 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg1[7:0] value to configure address (rvtest_code_end)->(PMP_region_High) +// in TOR Mode with RWX enabled +#define PMPREGION4 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS0 RAM_LOCATION_FOR_TEST // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS1 TEST_FOR_EXECUTION +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of region3 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of region3 +#define PMPADDRESS3 rvtest_code_end +// PMPADDRESS4 = value to be loaded pmpaddr4 to declare upper address of region4 +#define PMPADDRESS4 PMP_region_High + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration +/* PMP is configure in the following order: +1. Address 0x0000 0000 to Address RAM_LOCATION_FOR_TEST => PMP TOR Region with RWX enabled. This region is the part of the code memory containing our code. For this purpose, pmpaddr0 has been given the value of RAM_LOCATION_FOR_TEST to declare the region from 0->RAM_LOCATION_FOR_TEST into a single PMP region. + +2. Address TEST_FOR_EXECUTION to Address RETURN_INSTRUCTION =====> This is the PMP region under test (A 4byte region == Granularity of Sail. This region has been declared by entering TEST_FOR_EXECUTION into pmpaddr1 and RETURN_INSTRUCTION into pmpaddr2. Then a PMP region is configure into NA4 mode by setting pmpcfg0[15:8]=PMPREGION2 + +3. Address RAM_LOCATION_FOR_TEST to Address rvtest_code_end => Another PMP region under test. This region has been declared by entering rvtest_code_end into pmpaddr3 and RAM_LOCATION_FOR_TEST into pmpaddr2. configure pmpaddr2(RAM_LOCATION_FOR_TEST) to pmpaddr3(rvtest_code_end) into TOR mode by setting pmpcfg0[31:24]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) + +4. Address rvtest_code_end to address PMP_region_High => PMP TOR Region with RWX enabled. This region is the part of the code memory containing trap handler, epilogs, and other important macro definitions. For this purpose, configure pmpaddr3(rvtest_code_end) to pmpaddr4(PMP_region_High) into TOR mode by setting pmpcfg1[7:0]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)). This PMP Region is mandatory to access signature area in S,U mode */ + /* Assigning addresses to PMP address registers */ + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS4) // Value to be stored in pmpaddr4 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr4, x4 // Updated pmpaddr4 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1 | PMPREGION2 | PMPREGION3) + // Value to be stored in pmpcfg register ; Setting Up PMP Region-1,2,3 + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION4) + // Value to be stored in pmpcfg1 register ; Setting up PMP Region-4 + csrs pmpcfg1, x4 // Updated pmpcfg1 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +TEST_FOR_EXECUTION: + addi x0, x0, 0 + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-RX-priority-level-2.S b/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-RX-priority-level-2.S new file mode 100644 index 000000000..c0942070a --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-RX-priority-level-2.S @@ -0,0 +1,221 @@ +// ----------- +// 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 +/* Test Name: pmp-NAPOT-priority-rx-level-2.S +// Tests the priority by assigning only R,X permissions to the highest priority while no permissions to high priority region and R-W-X to low priority region +*/ + +#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_NAPOT_priority_rx_level_2) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg3 [31:24] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled. This is the low priority region +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with nothing enabled +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION3 ((((PMP_R|PMP_X|PMP_L|PMP_NAPOT)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +// PMPADDRESS14 = value to be loaded pmpaddr14 to declare lower address of Region-1 +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr14 to declare region1 +// PMPADDRESS15 = value to be loaded pmpaddr15 to declare upper address of Region-1 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of Region-2 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of Region-2 +#define PMPADDRESS3 RETURN_INSTRUCTION +// PMPADDRESS3 = value to be loaded pmpaddr1 to declare upper address of Region-3 +#define PMPADDRESS1 TEST_FOR_EXECUTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg3, x4 // Updated pmpcfg3 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION3) + // Value to be stored in pmpcfg register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,NOP +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-RX-priority.S b/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-RX-priority.S new file mode 100644 index 000000000..7f9ae80cb --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-RX-priority.S @@ -0,0 +1,201 @@ +// ----------- +// 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 +/* Test Name: pmp-NAPOT-priority-rx.S +// PMP Test in NAPOT address matching mode +// Description: +// Tests the priority by assigning only R,X permissions to the high priority while R-W-X to low priority region +*/ + +#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_NAPOT_priority_rx) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg3[31:24] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in NAPOT Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_R|PMP_X|PMP_NAPOT)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of region3 +#define PMPADDRESS2 TEST_FOR_EXECUTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg3, x4 // Updated pmpcfg3 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-RX.S b/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-RX.S new file mode 100644 index 000000000..1a24d6354 --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-RX.S @@ -0,0 +1,239 @@ +// ----------- +// 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 +/* Test Name: pmp-NAPOT-RX.S +// PMP Test in NAPOT address matching mode +// Description: +=> Foreach mode in MPP (including M), for Load/store instruction, perform the instruction referencing an address where the associated pmpcfg.W=0 and observe an access fault or not. +=> Foreach mode, perform instruction fetches to an address where the associated pmpcfg.X=0 and observe an access fault or not. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +=> Do the same for loads where pmpcfg.R=1 and pmpcfg.W=0 to make sure that the W bit only affects stores and AMOs. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +*/ +/* COVERPOINTS: (Explanation of updates in /coverage/rv32i_priv.cgf) + (pmpcfg0 >> 16) & 0x18 == 0x18 : 0 // CHECK pmp2cfg in NAPOT mode? + (pmpcfg0 >> 16) & 0x01 == 0x01 : 0 // CHECK R-bit in pmp2cfg was HIGH + (pmpcfg0 >> 16) & 0x02 == 0x02 : 0 // CHECK W-bit in pmp2cfg was HIGH + (pmpcfg0 >> 16) & 0x04 == 0x04 : 0 // CHECK X-bit in pmp2cfg was HIGH +// 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_NAPOT_rx) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg0 [7:0] value to configure address 0->RAM_LOCATION_FOR_TEST in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in NAPOT Mode with RX enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_R|PMP_X|PMP_L|PMP_NAPOT)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(rvtest_code_end) +// in TOR Mode with RWX enabled +// ALSO NOTE THAT PMPREGION2 IS INSIDE THIS REGION, so this test will also check the priority order of PMP regions +#define PMPREGION3 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg1[7:0] value to configure address (rvtest_code_end)->(PMP_region_High) +// in TOR Mode with RWX enabled +#define PMPREGION4 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS0 RAM_LOCATION_FOR_TEST // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS1 TEST_FOR_EXECUTION +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of region3 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of region3 +#define PMPADDRESS3 rvtest_code_end +// PMPADDRESS4 = value to be loaded pmpaddr4 to declare upper address of region4 +#define PMPADDRESS4 PMP_region_High + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration +/* PMP is configure in the following order: +1. Address 0x0000 0000 to Address RAM_LOCATION_FOR_TEST => PMP TOR Region with RWX enabled. This region is the part of the code memory containing our code. For this purpose, pmpaddr0 has been given the value of RAM_LOCATION_FOR_TEST to declare the region from 0->RAM_LOCATION_FOR_TEST into a single PMP region. + +2. Address TEST_FOR_EXECUTION to Address RETURN_INSTRUCTION =====> This is the PMP region under test (A 4byte region == Granularity of Sail. This region has been declared by entering TEST_FOR_EXECUTION into pmpaddr1 and RETURN_INSTRUCTION into pmpaddr2. Then a PMP region is configure into NA4 mode by setting pmpcfg0[15:8]=PMPREGION2 + +3. Address RAM_LOCATION_FOR_TEST to Address rvtest_code_end => Another PMP region under test. This region has been declared by entering rvtest_code_end into pmpaddr3 and RAM_LOCATION_FOR_TEST into pmpaddr2. configure pmpaddr2(RAM_LOCATION_FOR_TEST) to pmpaddr3(rvtest_code_end) into TOR mode by setting pmpcfg0[31:24]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) + +4. Address rvtest_code_end to address PMP_region_High => PMP TOR Region with RWX enabled. This region is the part of the code memory containing trap handler, epilogs, and other important macro definitions. For this purpose, configure pmpaddr3(rvtest_code_end) to pmpaddr4(PMP_region_High) into TOR mode by setting pmpcfg1[7:0]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)). This PMP Region is mandatory to access signature area in S,U mode */ + /* Assigning addresses to PMP address registers */ + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS4) // Value to be stored in pmpaddr4 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr4, x4 // Updated pmpaddr4 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1 | PMPREGION2 | PMPREGION3) + // Value to be stored in pmpcfg register ; Setting Up PMP Region-1,2,3 + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION4) + // Value to be stored in pmpcfg1 register ; Setting up PMP Region-4 + csrs pmpcfg1, x4 // Updated pmpcfg1 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-X-priority-level-2.S b/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-X-priority-level-2.S new file mode 100644 index 000000000..c2d00fc45 --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-X-priority-level-2.S @@ -0,0 +1,221 @@ +// ----------- +// 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 +/* Test Name: pmp-NAPOT-priority-x-level-2.S +// Tests the priority by assigning only X permissions to the highest priority while no permissions to high priority region and R-W-X to low priority region +*/ + +#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_NAPOT_priority_x_level_2) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg3 [31:24] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled. This is the low priority region +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with nothing enabled +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION3 ((((PMP_X|PMP_L|PMP_NAPOT)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +// PMPADDRESS14 = value to be loaded pmpaddr14 to declare lower address of Region-1 +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr14 to declare region1 +// PMPADDRESS15 = value to be loaded pmpaddr15 to declare upper address of Region-1 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of Region-2 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of Region-2 +#define PMPADDRESS3 RETURN_INSTRUCTION +// PMPADDRESS3 = value to be loaded pmpaddr1 to declare upper address of Region-3 +#define PMPADDRESS1 TEST_FOR_EXECUTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg3, x4 // Updated pmpcfg3 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION3) + // Value to be stored in pmpcfg register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,NOP +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-X-priority.S b/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-X-priority.S new file mode 100644 index 000000000..3be250bb8 --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-X-priority.S @@ -0,0 +1,201 @@ +// ----------- +// 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 +/* Test Name: pmp-NAPOT-priority-x.S +// PMP Test in NAPOT address matching mode +// Description: +// Tests the priority by assigning only X permissions to the high priority while R-W-X to low priority region +*/ + +#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_NAPOT_priority_x) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg3[31:24] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in NAPOT Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_X|PMP_NAPOT)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of region3 +#define PMPADDRESS2 TEST_FOR_EXECUTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg3, x4 // Updated pmpcfg3 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-X.S b/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-X.S new file mode 100644 index 000000000..874ae62dd --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-NAPOT-X.S @@ -0,0 +1,239 @@ +// ----------- +// 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 +/* Test Name: pmp-NAPOT-X.S +// PMP Test in NAPOT address matching mode +// Description: +=> Foreach mode in MPP (including M), for Load/store instruction, perform the instruction referencing an address where the associated pmpcfg.W=0 and observe an access fault or not. +=> Foreach mode, perform instruction fetches to an address where the associated pmpcfg.X=0 and observe an access fault or not. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +=> Do the same for loads where pmpcfg.R=1 and pmpcfg.W=0 to make sure that the W bit only affects stores and AMOs. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +*/ +/* COVERPOINTS: (Explanation of updates in /coverage/rv32i_priv.cgf) + (pmpcfg0 >> 16) & 0x18 == 0x18 : 0 // CHECK pmp2cfg in NAPOT mode? + (pmpcfg0 >> 16) & 0x01 == 0x01 : 0 // CHECK R-bit in pmp2cfg was HIGH + (pmpcfg0 >> 16) & 0x02 == 0x02 : 0 // CHECK W-bit in pmp2cfg was HIGH + (pmpcfg0 >> 16) & 0x04 == 0x04 : 0 // CHECK X-bit in pmp2cfg was HIGH +// 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_NAPOT_x) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg0 [7:0] value to configure address 0->RAM_LOCATION_FOR_TEST in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in NAPOT Mode with X enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_X|PMP_L|PMP_NAPOT)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(rvtest_code_end) +// in TOR Mode with RWX enabled +// ALSO NOTE THAT PMPREGION2 IS INSIDE THIS REGION, so this test will also check the priority order of PMP regions +#define PMPREGION3 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg1[7:0] value to configure address (rvtest_code_end)->(PMP_region_High) +// in TOR Mode with RWX enabled +#define PMPREGION4 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS0 RAM_LOCATION_FOR_TEST // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS1 TEST_FOR_EXECUTION +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of region3 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of region3 +#define PMPADDRESS3 rvtest_code_end +// PMPADDRESS4 = value to be loaded pmpaddr4 to declare upper address of region4 +#define PMPADDRESS4 PMP_region_High + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration +/* PMP is configure in the following order: +1. Address 0x0000 0000 to Address RAM_LOCATION_FOR_TEST => PMP TOR Region with RWX enabled. This region is the part of the code memory containing our code. For this purpose, pmpaddr0 has been given the value of RAM_LOCATION_FOR_TEST to declare the region from 0->RAM_LOCATION_FOR_TEST into a single PMP region. + +2. Address TEST_FOR_EXECUTION to Address RETURN_INSTRUCTION =====> This is the PMP region under test (A 4byte region == Granularity of Sail. This region has been declared by entering TEST_FOR_EXECUTION into pmpaddr1 and RETURN_INSTRUCTION into pmpaddr2. Then a PMP region is configure into NA4 mode by setting pmpcfg0[15:8]=PMPREGION2 + +3. Address RAM_LOCATION_FOR_TEST to Address rvtest_code_end => Another PMP region under test. This region has been declared by entering rvtest_code_end into pmpaddr3 and RAM_LOCATION_FOR_TEST into pmpaddr2. configure pmpaddr2(RAM_LOCATION_FOR_TEST) to pmpaddr3(rvtest_code_end) into TOR mode by setting pmpcfg0[31:24]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) + +4. Address rvtest_code_end to address PMP_region_High => PMP TOR Region with RWX enabled. This region is the part of the code memory containing trap handler, epilogs, and other important macro definitions. For this purpose, configure pmpaddr3(rvtest_code_end) to pmpaddr4(PMP_region_High) into TOR mode by setting pmpcfg1[7:0]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)). This PMP Region is mandatory to access signature area in S,U mode */ + /* Assigning addresses to PMP address registers */ + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS4) // Value to be stored in pmpaddr4 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr4, x4 // Updated pmpaddr4 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1 | PMPREGION2 | PMPREGION3) + // Value to be stored in pmpcfg register ; Setting Up PMP Region-1,2,3 + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION4) + // Value to be stored in pmpcfg1 register ; Setting up PMP Region-4 + csrs pmpcfg1, x4 // Updated pmpcfg1 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-R-priority-level-2.S b/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-R-priority-level-2.S new file mode 100644 index 000000000..5c9fb450d --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-R-priority-level-2.S @@ -0,0 +1,227 @@ +// ----------- +// 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 +/* Test Name: pmp-TOR-priority-r-level-2.S +// Tests the priority by assigning only R permissions to the highest priority while no permissions to high priority region and R-W-X to low priority region +*/ + +#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_TOR_priority_r_level_2) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg3 [31:24] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled. This is the low priority region +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with nothing enabled +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION3 ((((PMP_R|PMP_L|PMP_TOR)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +// PMPADDRESS14 = value to be loaded pmpaddr14 to declare lower address of Region-1 +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr14 to declare region1 +// PMPADDRESS15 = value to be loaded pmpaddr15 to declare upper address of Region-1 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of Region-2 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of Region-2 +#define PMPADDRESS3 RETURN_INSTRUCTION +// PMPADDRESS2 = value to be loaded pmpaddr0 to declare lower address of Region-3 +#define PMPADDRESS0 TEST_FOR_EXECUTION +// PMPADDRESS3 = value to be loaded pmpaddr1 to declare upper address of Region-3 +#define PMPADDRESS1 RETURN_INSTRUCTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg3, x4 // Updated pmpcfg3 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION3) + // Value to be stored in pmpcfg register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 0*(XLEN/32),4,NOP +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-R-priority.S b/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-R-priority.S new file mode 100644 index 000000000..27e11d132 --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-R-priority.S @@ -0,0 +1,206 @@ +// ----------- +// 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 +/* Test Name: pmp-TOR-priority-r.S +// Tests the priority by assigning only R permissions to the high priority while R-W-X to low priority region +*/ + +#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_TOR_priority_r) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg3 [31:24] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled. This is the low priority region +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_R|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +// PMPADDRESS14 = value to be loaded pmpaddr14 to declare lower address of Region-1 +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr14 to declare region1 +// PMPADDRESS15 = value to be loaded pmpaddr15 to declare upper address of Region-1 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr3 to declare lower address of Region-2 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of Region-2 +#define PMPADDRESS3 RETURN_INSTRUCTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg3, x4 // Updated pmpcfg3 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 0*(XLEN/32),4,NOP +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-R.S b/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-R.S new file mode 100644 index 000000000..354428982 --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-R.S @@ -0,0 +1,245 @@ +// ----------- +// 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 +/* Test Name: pmp-tor-R.S +// PMP Test in TOR address matching mode +// Description: +=> Foreach mode in MPP (including M), for Load/store instruction, perform the instruction referencing an address where the associated pmpcfg.W=1 and observe an access fault or not. +=> Foreach mode, perform instruction fetches to an address where the associated pmpcfg.X=0 and observe an access fault or not. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +=> Do the same for loads where pmpcfg.R=1 and pmpcfg.W=0 to make sure that the W bit only affects stores and AMOs. +*/ +/* COVERPOINTS: (Explanation of updates in /coverage/rv32i_priv.cgf) + (pmpcfg0 >> 16) & 0x18 == 0x08 : 0 // CHECK pmp2cfg in TOR mode? + (pmpcfg0 >> 16) & 0x01 == 0x01 : 0 // CHECK R-bit in pmp2cfg was HIGH + (pmpcfg0 >> 16) & 0x02 == 0x02 : 0 // CHECK W-bit in pmp2cfg was HIGH + (pmpcfg0 >> 16) & 0x04 == 0x04 : 0 // CHECK X-bit in pmp2cfg was HIGH +// 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_TOR_r) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg0 [7:0] value to configure address 0->RAM_LOCATION_FOR_TEST in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[23:16] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in TOR Mode with X enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_R|PMP_L|PMP_TOR)&0xFF) << PMP2_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg1[7:0] value to configure address (RAM_LOCATION_FOR_TEST)->(rvtest_code_end) +// in TOR Mode with RW enabled +// ALSO NOTE THAT PMPREGION2 IS INSIDE THIS REGION, so this test will also check the priority order of PMP regions +#define PMPREGION3 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg1[15:8] value to configure address (rvtest_code_end)->(PMP_region_High) +// in TOR Mode with RWX enabled +#define PMPREGION4 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS0 RAM_LOCATION_FOR_TEST // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS1 TEST_FOR_EXECUTION +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare upper address of region2 +#define PMPADDRESS2 RETURN_INSTRUCTION +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare lower address of region3 +#define PMPADDRESS3 RAM_LOCATION_FOR_TEST +// PMPADDRESS4 = value to be loaded pmpaddr4 to declare upper address of region3 +#define PMPADDRESS4 rvtest_code_end +// PMPADDRESS5 = value to be loaded pmpaddr5 to declare upper address of region4 +#define PMPADDRESS5 PMP_region_High + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration +/* PMP is configure in the following order: +1. Address 0x8000 0000 to Address RAM_LOCATION_FOR_TEST => PMP TOR Region with RWX enabled. This region is the part of the code memory containing our code. For this purpose, pmpaddr0 has been given the value of RAM_LOCATION_FOR_TEST to declare the region from 0->RAM_LOCATION_FOR_TEST into a single PMP region. + +2. Address TEST_FOR_EXECUTION to Address RETURN_INSTRUCTION => PMP region under test. This region has been declared by entering TEST_FOR_EXECUTION into pmpaddr1 and rvtest_code_end into pmpaddr2. Then a PMP region is configure from pmpaddr2(RETURN_INSTRUCTION) to pmpaddr1(TEST_FOR_EXECUTION) into TOR mode by setting pmpcfg0[23:16]=PMPREGION2 + +3. Address RAM_LOCATION_FOR_TEST to Address rvtest_code_end => PMP region under test. This region has been declared by entering rvtest_code_end into pmpaddr4 and RAM_LOCATION_FOR_TEST into pmpaddr3. configure pmpaddr4(RAM_LOCATION_FOR_TEST) to pmpaddr5(rvtest_code_end) into TOR mode by setting pmpcfg1[15:8]=PMPREGION3 + +4. Address rvtest_code_end to address PMP_region_High => PMP TOR Region with RWX enabled. This region is the part of the code memory containing trap handler, epilogs, and other important macro definitions. For this purpose, configure pmpaddr4(rvtest_code_end) to pmpaddr5(PMP_region_High) into TOR mode by setting pmpcfg1[15:8]=PMPREGION4. This PMP Region is mandatory to access signature area in S,U mode */ + /* Assigning addresses to PMP address registers */ + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS4) // Value to be stored in pmpaddr4 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr4, x4 // Updated pmpaddr4 + nop // Added nop in case of trap + LA(x4, PMPADDRESS5) // Value to be stored in pmpaddr5 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr5, x4 // Updated pmpaddr5 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1 | PMPREGION2) + // Value to be stored in pmpcfg register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION3 | PMPREGION4) + // Value to be stored in pmpcfg1 register + csrs pmpcfg1, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-RW-priority-level-2..S b/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-RW-priority-level-2..S new file mode 100644 index 000000000..ed328850f --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-RW-priority-level-2..S @@ -0,0 +1,229 @@ +// ----------- +// 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 +/* Test Name: pmp-TOR-priority-rw-level-2.S +// Tests the priority by assigning only R,W permissions to the highest priority while no permissions to high priority region and R-W-X to low priority region +*/ + +#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_TOR_priority_rw_level_2) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg3 [31:24] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled. This is the low priority region +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with nothing enabled +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with R,W enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION3 ((((PMP_R|PMP_W|PMP_L|PMP_TOR)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +// PMPADDRESS14 = value to be loaded pmpaddr14 to declare lower address of Region-1 +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr14 to declare region1 +// PMPADDRESS15 = value to be loaded pmpaddr15 to declare upper address of Region-1 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of Region-2 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of Region-2 +#define PMPADDRESS3 RETURN_INSTRUCTION +// PMPADDRESS2 = value to be loaded pmpaddr0 to declare lower address of Region-3 +#define PMPADDRESS0 TEST_FOR_EXECUTION +// PMPADDRESS3 = value to be loaded pmpaddr1 to declare upper address of Region-3 +#define PMPADDRESS1 RETURN_INSTRUCTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg3, x4 // Updated pmpcfg3 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION3) + // Value to be stored in pmpcfg register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 1*(XLEN/32),4,NOP //Single + +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-RW-priority.S b/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-RW-priority.S new file mode 100644 index 000000000..8b390e2e8 --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-RW-priority.S @@ -0,0 +1,206 @@ +// ----------- +// 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 +/* Test Name: pmp-TOR-priority-rw.S +// Tests the priority by assigning only rw permissions to the high priority while R-W-X to low priority region +*/ + +#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_TOR_priority_rw) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg3 [31:24] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled. This is the low priority region +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_R|PMP_W|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +// PMPADDRESS14 = value to be loaded pmpaddr14 to declare lower address of Region-1 +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr14 to declare region1 +// PMPADDRESS15 = value to be loaded pmpaddr15 to declare upper address of Region-1 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr3 to declare lower address of Region-2 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of Region-2 +#define PMPADDRESS3 RETURN_INSTRUCTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg3, x4 // Updated pmpcfg3 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 0*(XLEN/32),4,NOP +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-RW.S b/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-RW.S new file mode 100644 index 000000000..7a0ad484e --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-RW.S @@ -0,0 +1,245 @@ +// ----------- +// 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 +/* Test Name: pmp-tor-RW.S +// PMP Test in TOR address matching mode +// Description: +=> Foreach mode in MPP (including M), for Load/store instruction, perform the instruction referencing an address where the associated pmpcfg.W=1 and observe an access fault or not. +=> Foreach mode, perform instruction fetches to an address where the associated pmpcfg.X=0 and observe an access fault or not. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +=> Do the same for loads where pmpcfg.R=1 and pmpcfg.W=0 to make sure that the W bit only affects stores and AMOs. +*/ +/* COVERPOINTS: (Explanation of updates in /coverage/rv32i_priv.cgf) + (pmpcfg0 >> 16) & 0x18 == 0x08 : 0 // CHECK pmp2cfg in TOR mode? + (pmpcfg0 >> 16) & 0x01 == 0x01 : 0 // CHECK R-bit in pmp2cfg was HIGH + (pmpcfg0 >> 16) & 0x02 == 0x02 : 0 // CHECK W-bit in pmp2cfg was HIGH + (pmpcfg0 >> 16) & 0x04 == 0x04 : 0 // CHECK X-bit in pmp2cfg was HIGH +// 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_TOR_rw) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg0 [7:0] value to configure address 0->RAM_LOCATION_FOR_TEST in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[23:16] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in TOR Mode with X enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_R|PMP_W|PMP_L|PMP_TOR)&0xFF) << PMP2_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg1[7:0] value to configure address (RAM_LOCATION_FOR_TEST)->(rvtest_code_end) +// in TOR Mode with RW enabled +// ALSO NOTE THAT PMPREGION2 IS INSIDE THIS REGION, so this test will also check the priority order of PMP regions +#define PMPREGION3 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg1[15:8] value to configure address (rvtest_code_end)->(PMP_region_High) +// in TOR Mode with RWX enabled +#define PMPREGION4 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS0 RAM_LOCATION_FOR_TEST // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS1 TEST_FOR_EXECUTION +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare upper address of region2 +#define PMPADDRESS2 RETURN_INSTRUCTION +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare lower address of region3 +#define PMPADDRESS3 RAM_LOCATION_FOR_TEST +// PMPADDRESS4 = value to be loaded pmpaddr4 to declare upper address of region3 +#define PMPADDRESS4 rvtest_code_end +// PMPADDRESS5 = value to be loaded pmpaddr5 to declare upper address of region4 +#define PMPADDRESS5 PMP_region_High + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration +/* PMP is configure in the following order: +1. Address 0x8000 0000 to Address RAM_LOCATION_FOR_TEST => PMP TOR Region with RWX enabled. This region is the part of the code memory containing our code. For this purpose, pmpaddr0 has been given the value of RAM_LOCATION_FOR_TEST to declare the region from 0->RAM_LOCATION_FOR_TEST into a single PMP region. + +2. Address TEST_FOR_EXECUTION to Address RETURN_INSTRUCTION => PMP region under test. This region has been declared by entering TEST_FOR_EXECUTION into pmpaddr1 and rvtest_code_end into pmpaddr2. Then a PMP region is configure from pmpaddr2(RETURN_INSTRUCTION) to pmpaddr1(TEST_FOR_EXECUTION) into TOR mode by setting pmpcfg0[23:16]=PMPREGION2 + +3. Address RAM_LOCATION_FOR_TEST to Address rvtest_code_end => PMP region under test. This region has been declared by entering rvtest_code_end into pmpaddr4 and RAM_LOCATION_FOR_TEST into pmpaddr3. configure pmpaddr4(RAM_LOCATION_FOR_TEST) to pmpaddr5(rvtest_code_end) into TOR mode by setting pmpcfg1[15:8]=PMPREGION3 + +4. Address rvtest_code_end to address PMP_region_High => PMP TOR Region with RWX enabled. This region is the part of the code memory containing trap handler, epilogs, and other important macro definitions. For this purpose, configure pmpaddr4(rvtest_code_end) to pmpaddr5(PMP_region_High) into TOR mode by setting pmpcfg1[15:8]=PMPREGION4. This PMP Region is mandatory to access signature area in S,U mode */ + /* Assigning addresses to PMP address registers */ + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS4) // Value to be stored in pmpaddr4 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr4, x4 // Updated pmpaddr4 + nop // Added nop in case of trap + LA(x4, PMPADDRESS5) // Value to be stored in pmpaddr5 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr5, x4 // Updated pmpaddr5 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1 | PMPREGION2) + // Value to be stored in pmpcfg register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION3 | PMPREGION4) + // Value to be stored in pmpcfg1 register + csrs pmpcfg1, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-RWX.S b/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-RWX.S new file mode 100644 index 000000000..378903513 --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-RWX.S @@ -0,0 +1,245 @@ +// ----------- +// 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 +/* Test Name: pmp-tor-RWX.S +// PMP Test in TOR address matching mode +// Description: +=> Foreach mode in MPP (including M), for Load/store instruction, perform the instruction referencing an address where the associated pmpcfg.W=1 and observe an access fault or not. +=> Foreach mode, perform instruction fetches to an address where the associated pmpcfg.X=0 and observe an access fault or not. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +=> Do the same for loads where pmpcfg.R=1 and pmpcfg.W=0 to make sure that the W bit only affects stores and AMOs. +*/ +/* COVERPOINTS: (Explanation of updates in /coverage/rv32i_priv.cgf) + (pmpcfg0 >> 16) & 0x18 == 0x08 : 0 // CHECK pmp2cfg in TOR mode? + (pmpcfg0 >> 16) & 0x01 == 0x01 : 0 // CHECK R-bit in pmp2cfg was HIGH + (pmpcfg0 >> 16) & 0x02 == 0x02 : 0 // CHECK W-bit in pmp2cfg was HIGH + (pmpcfg0 >> 16) & 0x04 == 0x04 : 0 // CHECK X-bit in pmp2cfg was HIGH +// 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_TOR_rwx) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg0 [7:0] value to configure address 0->RAM_LOCATION_FOR_TEST in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[23:16] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in TOR Mode with RWX enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP2_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg1[7:0] value to configure address (RAM_LOCATION_FOR_TEST)->(rvtest_code_end) +// in TOR Mode with RW enabled +// ALSO NOTE THAT PMPREGION2 IS INSIDE THIS REGION, so this test will also check the priority order of PMP regions +#define PMPREGION3 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg1[15:8] value to configure address (rvtest_code_end)->(PMP_region_High) +// in TOR Mode with RWX enabled +#define PMPREGION4 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS0 RAM_LOCATION_FOR_TEST // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS1 TEST_FOR_EXECUTION +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare upper address of region2 +#define PMPADDRESS2 RETURN_INSTRUCTION +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare lower address of region3 +#define PMPADDRESS3 RAM_LOCATION_FOR_TEST +// PMPADDRESS4 = value to be loaded pmpaddr4 to declare upper address of region3 +#define PMPADDRESS4 rvtest_code_end +// PMPADDRESS5 = value to be loaded pmpaddr5 to declare upper address of region4 +#define PMPADDRESS5 PMP_region_High + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration +/* PMP is configure in the following order: +1. Address 0x8000 0000 to Address RAM_LOCATION_FOR_TEST => PMP TOR Region with RWX enabled. This region is the part of the code memory containing our code. For this purpose, pmpaddr0 has been given the value of RAM_LOCATION_FOR_TEST to declare the region from 0->RAM_LOCATION_FOR_TEST into a single PMP region. + +2. Address TEST_FOR_EXECUTION to Address RETURN_INSTRUCTION => PMP region under test. This region has been declared by entering TEST_FOR_EXECUTION into pmpaddr1 and rvtest_code_end into pmpaddr2. Then a PMP region is configure from pmpaddr2(RETURN_INSTRUCTION) to pmpaddr1(TEST_FOR_EXECUTION) into TOR mode by setting pmpcfg0[23:16]=PMPREGION2 + +3. Address RAM_LOCATION_FOR_TEST to Address rvtest_code_end => PMP region under test. This region has been declared by entering rvtest_code_end into pmpaddr4 and RAM_LOCATION_FOR_TEST into pmpaddr3. configure pmpaddr4(RAM_LOCATION_FOR_TEST) to pmpaddr5(rvtest_code_end) into TOR mode by setting pmpcfg1[15:8]=PMPREGION3 + +4. Address rvtest_code_end to address PMP_region_High => PMP TOR Region with RWX enabled. This region is the part of the code memory containing trap handler, epilogs, and other important macro definitions. For this purpose, configure pmpaddr4(rvtest_code_end) to pmpaddr5(PMP_region_High) into TOR mode by setting pmpcfg1[15:8]=PMPREGION4. This PMP Region is mandatory to access signature area in S,U mode */ + /* Assigning addresses to PMP address registers */ + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS4) // Value to be stored in pmpaddr4 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr4, x4 // Updated pmpaddr4 + nop // Added nop in case of trap + LA(x4, PMPADDRESS5) // Value to be stored in pmpaddr5 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr5, x4 // Updated pmpaddr5 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1 | PMPREGION2) + // Value to be stored in pmpcfg register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION3 | PMPREGION4) + // Value to be stored in pmpcfg1 register + csrs pmpcfg1, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-RX-priority-level-2.S b/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-RX-priority-level-2.S new file mode 100644 index 000000000..8a2b734c0 --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-RX-priority-level-2.S @@ -0,0 +1,229 @@ +// ----------- +// 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 +/* Test Name: pmp-TOR-priority-rx-level-2.S +// Tests the priority by assigning only R, X permissions to the highest priority while no permissions to high priority region and R-W-X to low priority region +*/ + +#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_TOR_priority_rx_level_2) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg3 [31:24] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled. This is the low priority region +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with nothing enabled +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with R,W enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION3 ((((PMP_R|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +// PMPADDRESS14 = value to be loaded pmpaddr14 to declare lower address of Region-1 +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr14 to declare region1 +// PMPADDRESS15 = value to be loaded pmpaddr15 to declare upper address of Region-1 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of Region-2 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of Region-2 +#define PMPADDRESS3 RETURN_INSTRUCTION +// PMPADDRESS2 = value to be loaded pmpaddr0 to declare lower address of Region-3 +#define PMPADDRESS0 TEST_FOR_EXECUTION +// PMPADDRESS3 = value to be loaded pmpaddr1 to declare upper address of Region-3 +#define PMPADDRESS1 RETURN_INSTRUCTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg3, x4 // Updated pmpcfg3 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION3) + // Value to be stored in pmpcfg register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 1*(XLEN/32),4,NOP //Single + +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-RX-priority.S b/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-RX-priority.S new file mode 100644 index 000000000..97163d001 --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-RX-priority.S @@ -0,0 +1,206 @@ +// ----------- +// 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 +/* Test Name: pmp-TOR-priority-rx.S +// Tests the priority by assigning only rx permissions to the high priority while R-W-X to low priority region +*/ + +#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_TOR_priority_rx) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg3 [31:24] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled. This is the low priority region +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_R|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +// PMPADDRESS14 = value to be loaded pmpaddr14 to declare lower address of Region-1 +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr14 to declare region1 +// PMPADDRESS15 = value to be loaded pmpaddr15 to declare upper address of Region-1 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr3 to declare lower address of Region-2 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of Region-2 +#define PMPADDRESS3 RETURN_INSTRUCTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg3, x4 // Updated pmpcfg3 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 0*(XLEN/32),4,NOP +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-RX.S b/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-RX.S new file mode 100644 index 000000000..4d649f194 --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-RX.S @@ -0,0 +1,245 @@ +// ----------- +// 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 +/* Test Name: pmp-tor-RX.S +// PMP Test in TOR address matching mode +// Description: +=> Foreach mode in MPP (including M), for Load/store instruction, perform the instruction referencing an address where the associated pmpcfg.W=1 and observe an access fault or not. +=> Foreach mode, perform instruction fetches to an address where the associated pmpcfg.X=0 and observe an access fault or not. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +=> Do the same for loads where pmpcfg.R=1 and pmpcfg.W=0 to make sure that the W bit only affects stores and AMOs. +*/ +/* COVERPOINTS: (Explanation of updates in /coverage/rv32i_priv.cgf) + (pmpcfg0 >> 16) & 0x18 == 0x08 : 0 // CHECK pmp2cfg in TOR mode? + (pmpcfg0 >> 16) & 0x01 == 0x01 : 0 // CHECK R-bit in pmp2cfg was HIGH + (pmpcfg0 >> 16) & 0x02 == 0x02 : 0 // CHECK W-bit in pmp2cfg was HIGH + (pmpcfg0 >> 16) & 0x04 == 0x04 : 0 // CHECK X-bit in pmp2cfg was HIGH +// 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_TOR_rx) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg0 [7:0] value to configure address 0->RAM_LOCATION_FOR_TEST in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[23:16] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in TOR Mode with RX enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_R|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP2_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg1[7:0] value to configure address (RAM_LOCATION_FOR_TEST)->(rvtest_code_end) +// in TOR Mode with RW enabled +// ALSO NOTE THAT PMPREGION2 IS INSIDE THIS REGION, so this test will also check the priority order of PMP regions +#define PMPREGION3 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg1[15:8] value to configure address (rvtest_code_end)->(PMP_region_High) +// in TOR Mode with RWX enabled +#define PMPREGION4 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS0 RAM_LOCATION_FOR_TEST // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS1 TEST_FOR_EXECUTION +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare upper address of region2 +#define PMPADDRESS2 RETURN_INSTRUCTION +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare lower address of region3 +#define PMPADDRESS3 RAM_LOCATION_FOR_TEST +// PMPADDRESS4 = value to be loaded pmpaddr4 to declare upper address of region3 +#define PMPADDRESS4 rvtest_code_end +// PMPADDRESS5 = value to be loaded pmpaddr5 to declare upper address of region4 +#define PMPADDRESS5 PMP_region_High + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration +/* PMP is configure in the following order: +1. Address 0x8000 0000 to Address RAM_LOCATION_FOR_TEST => PMP TOR Region with RWX enabled. This region is the part of the code memory containing our code. For this purpose, pmpaddr0 has been given the value of RAM_LOCATION_FOR_TEST to declare the region from 0->RAM_LOCATION_FOR_TEST into a single PMP region. + +2. Address TEST_FOR_EXECUTION to Address RETURN_INSTRUCTION => PMP region under test. This region has been declared by entering TEST_FOR_EXECUTION into pmpaddr1 and rvtest_code_end into pmpaddr2. Then a PMP region is configure from pmpaddr2(RETURN_INSTRUCTION) to pmpaddr1(TEST_FOR_EXECUTION) into TOR mode by setting pmpcfg0[23:16]=PMPREGION2 + +3. Address RAM_LOCATION_FOR_TEST to Address rvtest_code_end => PMP region under test. This region has been declared by entering rvtest_code_end into pmpaddr4 and RAM_LOCATION_FOR_TEST into pmpaddr3. configure pmpaddr4(RAM_LOCATION_FOR_TEST) to pmpaddr5(rvtest_code_end) into TOR mode by setting pmpcfg1[15:8]=PMPREGION3 + +4. Address rvtest_code_end to address PMP_region_High => PMP TOR Region with RWX enabled. This region is the part of the code memory containing trap handler, epilogs, and other important macro definitions. For this purpose, configure pmpaddr4(rvtest_code_end) to pmpaddr5(PMP_region_High) into TOR mode by setting pmpcfg1[15:8]=PMPREGION4. This PMP Region is mandatory to access signature area in S,U mode */ + /* Assigning addresses to PMP address registers */ + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS4) // Value to be stored in pmpaddr4 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr4, x4 // Updated pmpaddr4 + nop // Added nop in case of trap + LA(x4, PMPADDRESS5) // Value to be stored in pmpaddr5 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr5, x4 // Updated pmpaddr5 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1 | PMPREGION2) + // Value to be stored in pmpcfg register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION3 | PMPREGION4) + // Value to be stored in pmpcfg1 register + csrs pmpcfg1, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-X-priority-level-2.S b/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-X-priority-level-2.S new file mode 100644 index 000000000..e5ab4c0eb --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-X-priority-level-2.S @@ -0,0 +1,229 @@ +// ----------- +// 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 +/* Test Name: pmp-TOR-priority-x-level-2.S +// Tests the priority by assigning only X permissions to the highest priority while no permissions to high priority region and R-W-X to low priority region +*/ + +#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_TOR_priority_x_level_2) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg3 [31:24] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled. This is the low priority region +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with nothing enabled +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with R,W enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION3 ((((PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +// PMPADDRESS14 = value to be loaded pmpaddr14 to declare lower address of Region-1 +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr14 to declare region1 +// PMPADDRESS15 = value to be loaded pmpaddr15 to declare upper address of Region-1 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of Region-2 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of Region-2 +#define PMPADDRESS3 RETURN_INSTRUCTION +// PMPADDRESS2 = value to be loaded pmpaddr0 to declare lower address of Region-3 +#define PMPADDRESS0 TEST_FOR_EXECUTION +// PMPADDRESS3 = value to be loaded pmpaddr1 to declare upper address of Region-3 +#define PMPADDRESS1 RETURN_INSTRUCTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg3, x4 // Updated pmpcfg3 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION3) + // Value to be stored in pmpcfg register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 1*(XLEN/32),4,NOP //Single + +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-X-priority.S b/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-X-priority.S new file mode 100644 index 000000000..af7c92458 --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-X-priority.S @@ -0,0 +1,206 @@ +// ----------- +// 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 +/* Test Name: pmp-TOR-priority-x.S +// Tests the priority by assigning only X permissions to the high priority while R-W-X to low priority region +*/ + +#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_TOR_priority_x) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg3 [31:24] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled. This is the low priority region +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +// PMPADDRESS14 = value to be loaded pmpaddr14 to declare lower address of Region-1 +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr14 to declare region1 +// PMPADDRESS15 = value to be loaded pmpaddr15 to declare upper address of Region-1 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr3 to declare lower address of Region-2 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of Region-2 +#define PMPADDRESS3 RETURN_INSTRUCTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg3, x4 // Updated pmpcfg3 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 0*(XLEN/32),4,NOP +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END diff --git a/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-X.S b/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-X.S new file mode 100644 index 000000000..4dc4e4fb9 --- /dev/null +++ b/riscv-test-suite/rv32i_m/pmp32/pmp-TOR-X.S @@ -0,0 +1,245 @@ +// ----------- +// 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 +/* Test Name: pmp-tor-X.S +// PMP Test in TOR address matching mode +// Description: +=> Foreach mode in MPP (including M), for Load/store instruction, perform the instruction referencing an address where the associated pmpcfg.W=1 and observe an access fault or not. +=> Foreach mode, perform instruction fetches to an address where the associated pmpcfg.X=0 and observe an access fault or not. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +=> Do the same for loads where pmpcfg.R=1 and pmpcfg.W=0 to make sure that the W bit only affects stores and AMOs. +*/ +/* COVERPOINTS: (Explanation of updates in /coverage/rv32i_priv.cgf) + (pmpcfg0 >> 16) & 0x18 == 0x08 : 0 // CHECK pmp2cfg in TOR mode? + (pmpcfg0 >> 16) & 0x01 == 0x01 : 0 // CHECK R-bit in pmp2cfg was HIGH + (pmpcfg0 >> 16) & 0x02 == 0x02 : 0 // CHECK W-bit in pmp2cfg was HIGH + (pmpcfg0 >> 16) & 0x04 == 0x04 : 0 // CHECK X-bit in pmp2cfg was HIGH +// 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_TOR_x) +RVTEST_SIGBASE( x13,signature_x13_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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop + +.endm + +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 + csrw pmpcfgi , x0 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg0 [7:0] value to configure address 0->RAM_LOCATION_FOR_TEST in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[23:16] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in TOR Mode with RX enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP2_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg1[7:0] value to configure address (RAM_LOCATION_FOR_TEST)->(rvtest_code_end) +// in TOR Mode with RW enabled +// ALSO NOTE THAT PMPREGION2 IS INSIDE THIS REGION, so this test will also check the priority order of PMP regions +#define PMPREGION3 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg1[15:8] value to configure address (rvtest_code_end)->(PMP_region_High) +// in TOR Mode with RWX enabled +#define PMPREGION4 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS0 RAM_LOCATION_FOR_TEST // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS1 TEST_FOR_EXECUTION +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare upper address of region2 +#define PMPADDRESS2 RETURN_INSTRUCTION +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare lower address of region3 +#define PMPADDRESS3 RAM_LOCATION_FOR_TEST +// PMPADDRESS4 = value to be loaded pmpaddr4 to declare upper address of region3 +#define PMPADDRESS4 rvtest_code_end +// PMPADDRESS5 = value to be loaded pmpaddr5 to declare upper address of region4 +#define PMPADDRESS5 PMP_region_High + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration +/* PMP is configure in the following order: +1. Address 0x8000 0000 to Address RAM_LOCATION_FOR_TEST => PMP TOR Region with RWX enabled. This region is the part of the code memory containing our code. For this purpose, pmpaddr0 has been given the value of RAM_LOCATION_FOR_TEST to declare the region from 0->RAM_LOCATION_FOR_TEST into a single PMP region. + +2. Address TEST_FOR_EXECUTION to Address RETURN_INSTRUCTION => PMP region under test. This region has been declared by entering TEST_FOR_EXECUTION into pmpaddr1 and rvtest_code_end into pmpaddr2. Then a PMP region is configure from pmpaddr2(RETURN_INSTRUCTION) to pmpaddr1(TEST_FOR_EXECUTION) into TOR mode by setting pmpcfg0[23:16]=PMPREGION2 + +3. Address RAM_LOCATION_FOR_TEST to Address rvtest_code_end => PMP region under test. This region has been declared by entering rvtest_code_end into pmpaddr4 and RAM_LOCATION_FOR_TEST into pmpaddr3. configure pmpaddr4(RAM_LOCATION_FOR_TEST) to pmpaddr5(rvtest_code_end) into TOR mode by setting pmpcfg1[15:8]=PMPREGION3 + +4. Address rvtest_code_end to address PMP_region_High => PMP TOR Region with RWX enabled. This region is the part of the code memory containing trap handler, epilogs, and other important macro definitions. For this purpose, configure pmpaddr4(rvtest_code_end) to pmpaddr5(PMP_region_High) into TOR mode by setting pmpcfg1[15:8]=PMPREGION4. This PMP Region is mandatory to access signature area in S,U mode */ + /* Assigning addresses to PMP address registers */ + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS4) // Value to be stored in pmpaddr4 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr4, x4 // Updated pmpaddr4 + nop // Added nop in case of trap + LA(x4, PMPADDRESS5) // Value to be stored in pmpaddr5 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr5, x4 // Updated pmpaddr5 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1 | PMPREGION2) + // Value to be stored in pmpcfg register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION3 | PMPREGION4) + // Value to be stored in pmpcfg1 register + csrs pmpcfg1, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-CFG-reg.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-CFG-reg.S new file mode 100644 index 000000000..6cdf8785e --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-CFG-reg.S @@ -0,0 +1,132 @@ +// ----------- +// 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. +// +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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 3 + .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 2 // START OF LOOP + csrc pmpcfgi , a5 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 2 // 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 8 // 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+2 // increment variable to next pmpcfg reg .endr // END OF OUTER LOOP BODY + .endr +#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 128*(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 diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-CSR-access.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-CSR-access.S new file mode 100644 index 000000000..44a7c240c --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-CSR-access.S @@ -0,0 +1,243 @@ +// ----------- +// 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. +// +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf +// +#define rvtest_strap_routine +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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 3 +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 2 // START OF LOOP + csrc pmpcfgi , a5 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 +//////////////// 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 pmpaddr in M-mode ///////////////////////////////////////// + LI(a4,0x01) // RANDOM VALUE + .set pmpaddri, PMPADDR0 // Initialize an iterating variable with the address of pmpaddr0 + .rept 16 // START OF LOOP + csrw pmpaddri, a4 // WRITING 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 2 // START OF LOOP + csrw pmpcfgi, a5 // Write pmpcfgi + nop // Added nop in case of trap + .set pmpcfgi, pmpcfgi+2 // 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 2 // START OF LOOP + csrr a4, pmpcfg0 // Read pmpcfg0 + nop // Added nop in case of trap + RVTEST_SIGUPD(x13,a4) + .set pmpcfgi, pmpcfgi+2 // 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 + 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 //////////////////////////////////////////// +// READING pmpaddr in S-mode ///////////////////////////////////////// + .set pmpaddri, PMPADDR0 // Initialize an iterating variable with the address of pmpaddr0 + .rept 4 // 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 pmpaddr in S-mode ///////////////////////////////////////// + LI(a4,0x01) // RANDOM VALUE + .set pmpaddri, PMPADDR0 // Initialize an iterating variable with the address of pmpaddr0 + .rept 4 // START OF LOOP + csrw pmpaddri, a4 // WRITING 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 2 // START OF LOOP + csrw pmpcfgi, a5 // Write pmpcfgi + nop // Added nop in case of trap + .set pmpcfgi, pmpcfgi+2 // increment variable to next pmpcfg reg + .endr // END OF LOOP BODY +//////////////// VERIFICATION ///////////////////////////////////////// +// READING pmpcfg in S-mode ///////////////////////////////////////// + // Loop to verify the contents of pmpcfg regs + .set pmpcfgi, PMPCFG0 // Initialize an iterating variable with the address of pmpcfg0 + .rept 2 // START OF LOOP + csrr a4, pmpcfg0 // Read pmpcfg0 + nop // Added nop in case of trap + RVTEST_SIGUPD(x13,a4) + .set pmpcfgi, pmpcfgi+2 // increment variable to next pmpcfg reg + .endr // END OF LOOP BODY +/////////////////// 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 + 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 +// READING pmpaddr in U-mode ///////////////////////////////////////// + .set pmpaddri, PMPADDR0 // Initialize an iterating variable with the address of pmpaddr0 + .rept 4 // 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 pmpaddr in U-mode ///////////////////////////////////////// + LI(a4,0x01) // RANDOM VALUE + .set pmpaddri, PMPADDR0 // Initialize an iterating variable with the address of pmpaddr0 + .rept 4 // START OF LOOP + csrw pmpaddri, a4 // WRITING 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 2 // START OF LOOP + csrw pmpcfgi, a5 // Write pmpcfgi + nop // Added nop in case of trap + .set pmpcfgi, pmpcfgi+2 // increment variable to next pmpcfg reg + .endr // END OF LOOP BODY +//////////////// VERIFICATION ///////////////////////////////////////// +// READING pmpcfg in U-mode ///////////////////////////////////////// + // Loop to verify the contents of pmpcfg regs + .set pmpcfgi, PMPCFG0 // Initialize an iterating variable with the address of pmpcfg0 + .rept 2 // START OF LOOP + csrr a4, pmpcfg0 // Read pmpcfg0 + nop // Added nop in case of trap + RVTEST_SIGUPD(x13,a4) + .set pmpcfgi, pmpcfgi+2 // increment variable to next pmpcfg reg + .endr // END OF 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_x13_1: + .fill 32*(XLEN/32),4,0xdeadbeef + +#ifdef rvtest_mtrap_routine + +tsig_begin_canary: +CANARY; +mtrap_sigptr: + .fill 256*(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 \ No newline at end of file diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-R-priority-level-2.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-R-priority-level-2.S new file mode 100644 index 000000000..7c8b443b6 --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-R-priority-level-2.S @@ -0,0 +1,236 @@ +// ----------- +// 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 +/* Test Name: pmp-NA4-priority-r-level-2.S +// Tests the priority by assigning only R permissions to the highest priority while no permissions to high priority region and R-W-X to low priority region +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf +*/ + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_NA4_priority_r_level_2) +RVTEST_SIGBASE( x13,signature_x13_1) + + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP7_CFG_SHIFT 56 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg2 [63:56] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled. This is the low priority region +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP7_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with nothing enabled +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION). This is the high priority region +// in TOR Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION3 ((((PMP_R|PMP_L|PMP_NA4)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +// PMPADDRESS14 = value to be loaded pmpaddr14 to declare lower address of Region-1 +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr14 to declare region1 +// PMPADDRESS15 = value to be loaded pmpaddr15 to declare upper address of Region-1 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of Region-2 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of Region-2 +#define PMPADDRESS3 RETURN_INSTRUCTION +// PMPADDRESS3 = value to be loaded pmpaddr1 to declare upper address of Region-3 +#define PMPADDRESS1 TEST_FOR_EXECUTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration +/* PMP is configure in the following order: +1. Address 0x8000 0000 to Address RVMODEL_DATA_END => PMP TOR (Low Priority) Region with RWX enabled. For this purpose, pmpaddr14 has been given the value of 0 and pmpaddr15 is given address to RVMODEL_DATA_END to declare the region from 0->RVMODEL_DATA_END into a single PMP region. + +2. Address RAM_LOCATION_FOR_TEST to Address RETURN_INSTRUCTION => PMP region under test. This region has been declared by entering RAM_LOCATION_FOR_TEST into pmpaddr2 and address to RETURN_INSTRUCTION label into pmpaddr3. Then a PMP region is configure from pmpaddr2(RAM_LOCATION_FOR_TEST) to pmpaddr3(RETURN_INSTRUCTION) into TOR mode by setting pmpcfg0[31:24]=PMPREGION2 + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg2, x4 // Updated pmpcfg2 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION3) + // Value to be stored in pmpcfg register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 4*(XLEN/32),8,0x12345678 + .align 3 + +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-R-priority.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-R-priority.S new file mode 100644 index 000000000..d6750776c --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-R-priority.S @@ -0,0 +1,215 @@ + +// ----------- +// 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 +/* Test Name: pmp-NA4-priority-r.S +// PMP Test in NA4 address matching mode +// Description: +// Tests the priority by assigning only R permissions to the high priority while R-W-X to low priority region +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf +*/ + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_NA4_priority_r) +RVTEST_SIGBASE( x13,signature_x13_1) + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP7_CFG_SHIFT 56 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg2[63:56] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP7_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in NAPOT Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_R|PMP_NA4)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of region3 +#define PMPADDRESS2 TEST_FOR_EXECUTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg2, x4 // Updated pmpcfg3 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 + .align 3 + +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-R.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-R.S new file mode 100644 index 000000000..2d1d7bdd0 --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-R.S @@ -0,0 +1,240 @@ +// ----------- +// 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 +/* Test Name: pmp-NA4-R.S +// PMP Test in NA4 address matching mode +// Description: +=> Foreach mode in MPP (including M), for Load/store instruction, perform the instruction referencing an address where the associated pmpcfg.W=0 and observe an access fault or not. +=> Foreach mode, perform instruction fetches to an address where the associated pmpcfg.X=0 and observe an access fault or not. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +=> Do the same for loads where pmpcfg.R=1 and pmpcfg.W=0 to make sure that the W bit only affects stores and AMOs. +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf +*/ +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_NA4_r) +RVTEST_SIGBASE( x13,signature_x13_1) + + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP4_CFG_SHIFT 32 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg0 [7:0] value to configure address 0->RAM_LOCATION_FOR_TEST in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in NA4 Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_R|PMP_L|PMP_NA4)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(rvtest_code_end) +// in TOR Mode with RWX enabled +// ALSO NOTE THAT PMPREGION2 IS INSIDE THIS REGION, so this test will also check the priority order of PMP regions +#define PMPREGION3 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[39:32] value to configure address (rvtest_code_end)->(PMP_region_High) +// in TOR Mode with RWX enabled +#define PMPREGION4 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP4_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS0 RAM_LOCATION_FOR_TEST // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS1 TEST_FOR_EXECUTION +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of region3 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of region3 +#define PMPADDRESS3 rvtest_code_end +// PMPADDRESS4 = value to be loaded pmpaddr4 to declare upper address of region4 +#define PMPADDRESS4 PMP_region_High + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration +/* PMP is configure in the following order: +1. Address 0x0000 0000 to Address RAM_LOCATION_FOR_TEST => PMP TOR Region with RWX enabled. This region is the part of the code memory containing our code. For this purpose, pmpaddr0 has been given the value of RAM_LOCATION_FOR_TEST to declare the region from 0->RAM_LOCATION_FOR_TEST into a single PMP region. + +2. Address TEST_FOR_EXECUTION to Address RETURN_INSTRUCTION =====> This is the PMP region under test (A 4byte region == Granularity of Sail. This region has been declared by entering TEST_FOR_EXECUTION into pmpaddr1 and RETURN_INSTRUCTION into pmpaddr2. Then a PMP region is configure into NA4 mode by setting pmpcfg0[15:8]=((PMP_R|PMP_L|PMP_NA4)&0xFF) + +3. Address RAM_LOCATION_FOR_TEST to Address rvtest_code_end => Another PMP region under test. This region has been declared by entering rvtest_code_end into pmpaddr3 and RAM_LOCATION_FOR_TEST into pmpaddr2. configure pmpaddr2(RAM_LOCATION_FOR_TEST) to pmpaddr3(rvtest_code_end) into TOR mode by setting pmpcfg0[31:24]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) + +4. Address rvtest_code_end to address PMP_region_High => PMP TOR Region with RWX enabled. This region is the part of the code memory containing trap handler, epilogs, and other important macro definitions. For this purpose, configure pmpaddr3(rvtest_code_end) to pmpaddr4(PMP_region_High) into TOR mode by setting pmpcfg1[7:0]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)). This PMP Region is mandatory to access signature area in S,U mode */ + /* Assigning addresses to PMP address registers */ + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS4) // Value to be stored in pmpaddr4 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr4, x4 // Updated pmpaddr4 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1 | PMPREGION2 | PMPREGION3 | PMPREGION4) + // Value to be stored in pmpcfg register ; Setting Up PMP Region-1,2,3,4 + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 + .align 3 + +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-RW-priority-level-2.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-RW-priority-level-2.S new file mode 100644 index 000000000..428559210 --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-RW-priority-level-2.S @@ -0,0 +1,233 @@ +// ----------- +// 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 +/* Test Name: pmp-TOR-priority-rw-level-2.S +// Tests the priority by assigning only R,W permissions to the highest priority while no permissions to high priority region and R-W-X to low priority region +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf +*/ + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_NA4_priority_rw_level_2) +RVTEST_SIGBASE( x13,signature_x13_1) + + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP7_CFG_SHIFT 56 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg2 [63:56] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled. This is the low priority region +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP7_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with nothing enabled +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION). This is the high priority region +// in TOR Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION3 ((((PMP_R|PMP_W|PMP_L|PMP_NA4)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +// PMPADDRESS14 = value to be loaded pmpaddr14 to declare lower address of Region-1 +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr14 to declare region1 +// PMPADDRESS15 = value to be loaded pmpaddr15 to declare upper address of Region-1 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of Region-2 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of Region-2 +#define PMPADDRESS3 RETURN_INSTRUCTION +// PMPADDRESS3 = value to be loaded pmpaddr1 to declare upper address of Region-3 +#define PMPADDRESS1 TEST_FOR_EXECUTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg2, x4 // Updated pmpcfg2 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION3) + // Value to be stored in pmpcfg register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 0*(XLEN/32),4,NOP + .align 3 + +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-RW-priority.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-RW-priority.S new file mode 100644 index 000000000..301155517 --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-RW-priority.S @@ -0,0 +1,214 @@ +// ----------- +// 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 +/* Test Name: pmp-NA4-priority-rw.S +// PMP Test in NA4 address matching mode +// Description: +// Tests the priority by assigning only R,W permissions to the high priority while R-W-X to low priority region +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf +*/ + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_NA4_priority_rw) +RVTEST_SIGBASE( x13,signature_x13_1) + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP7_CFG_SHIFT 56 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg2[63:56] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP7_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in NAPOT Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_R|PMP_W|PMP_NA4)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of region3 +#define PMPADDRESS2 TEST_FOR_EXECUTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg2, x4 // Updated pmpcfg2 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 + .align 3 + +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-RW.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-RW.S new file mode 100644 index 000000000..111b5b9b0 --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-RW.S @@ -0,0 +1,242 @@ +// ----------- +// 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 +/* Test Name: pmp-NA4-RW.S +// PMP Test in NA4 address matching mode +// Description: +=> Foreach mode in MPP (including M), for Load/store instruction, perform the instruction referencing an address where the associated pmpcfg.W=0 and observe an access fault or not. +=> Foreach mode, perform instruction fetches to an address where the associated pmpcfg.X=0 and observe an access fault or not. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +=> Do the same for loads where pmpcfg.R=1 and pmpcfg.W=0 to make sure that the W bit only affects stores and AMOs. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +*/ +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_NA4_rw) +RVTEST_SIGBASE( x13,signature_x13_1) + + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP4_CFG_SHIFT 32 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg0 [7:0] value to configure address 0->RAM_LOCATION_FOR_TEST in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in NA4 Mode with RW enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_R|PMP_W|PMP_L|PMP_NA4)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(rvtest_code_end) +// in TOR Mode with RWX enabled +// ALSO NOTE THAT PMPREGION2 IS INSIDE THIS REGION, so this test will also check the priority order of PMP regions +#define PMPREGION3 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[39:32] value to configure address (rvtest_code_end)->(PMP_region_High) +// in TOR Mode with RWX enabled +#define PMPREGION4 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP4_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS0 RAM_LOCATION_FOR_TEST // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS1 TEST_FOR_EXECUTION +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of region3 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of region3 +#define PMPADDRESS3 rvtest_code_end +// PMPADDRESS4 = value to be loaded pmpaddr4 to declare upper address of region4 +#define PMPADDRESS4 PMP_region_High + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration +/* PMP is configure in the following order: +1. Address 0x0000 0000 to Address RAM_LOCATION_FOR_TEST => PMP TOR Region with RWX enabled. This region is the part of the code memory containing our code. For this purpose, pmpaddr0 has been given the value of RAM_LOCATION_FOR_TEST to declare the region from 0->RAM_LOCATION_FOR_TEST into a single PMP region. + +2. Address TEST_FOR_EXECUTION to Address RETURN_INSTRUCTION =====> This is the PMP region under test (A 4byte region == Granularity of Sail. This region has been declared by entering TEST_FOR_EXECUTION into pmpaddr1 and RETURN_INSTRUCTION into pmpaddr2. Then a PMP region is configure into NA4 mode by setting pmpcfg0[15:8]=((PMP_R|PMP_W|PMP_L|PMP_NA4)&0xFF) + +3. Address RAM_LOCATION_FOR_TEST to Address rvtest_code_end => Another PMP region under test. This region has been declared by entering rvtest_code_end into pmpaddr3 and RAM_LOCATION_FOR_TEST into pmpaddr2. configure pmpaddr2(RAM_LOCATION_FOR_TEST) to pmpaddr3(rvtest_code_end) into TOR mode by setting pmpcfg0[31:24]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) + +4. Address rvtest_code_end to address PMP_region_High => PMP TOR Region with RWX enabled. This region is the part of the code memory containing trap handler, epilogs, and other important macro definitions. For this purpose, configure pmpaddr3(rvtest_code_end) to pmpaddr4(PMP_region_High) into TOR mode by setting pmpcfg1[7:0]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)). This PMP Region is mandatory to access signature area in S,U mode */ + /* Assigning addresses to PMP address registers */ + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS4) // Value to be stored in pmpaddr4 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr4, x4 // Updated pmpaddr4 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1 | PMPREGION2 | PMPREGION3 | PMPREGION4) + // Value to be stored in pmpcfg register ; Setting Up PMP Region-1,2,3 + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 + .align 3 + +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-RWX.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-RWX.S new file mode 100644 index 000000000..5b98683b0 --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-RWX.S @@ -0,0 +1,255 @@ +// ----------- +// 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 +/* Test Name: pmp-NA4-RWX.S +// PMP Test in NA4 address matching mode +// Description: +=> Foreach mode in MPP (including M), for Load/store instruction, perform the instruction referencing an address where the associated pmpcfg.W=1 and observe an access fault or not. +=> Foreach mode, perform instruction fetches to an address where the associated pmpcfg.X=0 and observe an access fault or not. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +*/ +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_NA4_rwx) +RVTEST_SIGBASE( x13,signature_x13_1) + + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP4_CFG_SHIFT 32 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + csrc pmpcfgi , a5 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + +// pmpcfg0 [7:0] value to configure address 0->RAM_LOCATION_FOR_TEST in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in NA4 Mode with RW enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_NA4)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(rvtest_code_end) +// in TOR Mode with RWX enabled +// ALSO NOTE THAT PMPREGION2 IS INSIDE THIS REGION, so this test will also check the priority order of PMP regions +#define PMPREGION3 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[39:32] value to configure address (rvtest_code_end)->(PMP_region_High) +// in TOR Mode with RWX enabled +#define PMPREGION4 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP4_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS0 RAM_LOCATION_FOR_TEST // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS1 TEST_FOR_EXECUTION +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of region3 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of region3 +#define PMPADDRESS3 rvtest_code_end +// PMPADDRESS4 = value to be loaded pmpaddr4 to declare upper address of region4 +#define PMPADDRESS4 PMP_region_High + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration +/* PMP is configure in the following order: +1. Address 0x0000 0000 to Address RAM_LOCATION_FOR_TEST => PMP TOR Region with RWX enabled. +This region is the part of the code memory containing our code and the region between code_end to data_begin. +For this purpose, pmpaddr0 has been given the value of RAM_LOCATION_FOR_TEST to +declare the region from 0->RAM_LOCATION_FOR_TEST into a single PMP region. + +2. Address TEST_FOR_EXECUTION to Address RETURN_INSTRUCTION =====> This is the PMP region under test (A 4byte region == Granularity of Sail.) +This region has been declared by entering TEST_FOR_EXECUTION into pmpaddr1 and RETURN_INSTRUCTION into pmpaddr2. +Then a PMP region is configure into NA4 mode by setting pmpcfg0[15:8]=PMPREGION2 + +3. Address RAM_LOCATION_FOR_TEST to Address rvtest_code_end => Another PMP region under test. +This region has been declared by entering rvtest_code_end into pmpaddr3 and +RAM_LOCATION_FOR_TEST into pmpaddr2. configure pmpaddr2(RAM_LOCATION_FOR_TEST) +to pmpaddr3(rvtest_code_end) into TOR mode +by setting pmpcfg0[31:24]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) + +4. Address rvtest_code_end to address PMP_region_High => PMP TOR Region with RWX enabled. +This region is the part of the code memory containing trap handler, epilogs, and other important macro definitions. +For this purpose, configure pmpaddr3(rvtest_code_end) to pmpaddr4(PMP_region_High) +into TOR mode by setting pmpcfg1[7:0]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)). +This PMP Region is mandatory to access signature area in S,U mode */ + + /* Assigning addresses to PMP address registers */ + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS4) // Value to be stored in pmpaddr4 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr4, x4 // Updated pmpaddr4 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1 | PMPREGION2 | PMPREGION3 | PMPREGION4) + // Value to be stored in pmpcfg register ; Setting Up PMP Region-1,2,3 + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + nop + j exit +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 + .align 3 + +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-RX-priority-level-2.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-RX-priority-level-2.S new file mode 100644 index 000000000..403273b62 --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-RX-priority-level-2.S @@ -0,0 +1,233 @@ +// ----------- +// 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 +/* Test Name: pmp-TOR-priority-rx-level-2.S +// Tests the priority by assigning only R,X permissions to the highest priority while no permissions to high priority region and R-W-X to low priority region +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf +*/ + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_NA4_priority_rx_level_2) +RVTEST_SIGBASE( x13,signature_x13_1) + + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP7_CFG_SHIFT 56 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg2 [63:56] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled. This is the low priority region +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP7_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with nothing enabled +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION). This is the high priority region +// in TOR Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION3 ((((PMP_R|PMP_X|PMP_L|PMP_NA4)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +// PMPADDRESS14 = value to be loaded pmpaddr14 to declare lower address of Region-1 +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr14 to declare region1 +// PMPADDRESS15 = value to be loaded pmpaddr15 to declare upper address of Region-1 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of Region-2 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of Region-2 +#define PMPADDRESS3 RETURN_INSTRUCTION +// PMPADDRESS3 = value to be loaded pmpaddr1 to declare upper address of Region-3 +#define PMPADDRESS1 TEST_FOR_EXECUTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg2, x4 // Updated pmpcfg2 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION3) + // Value to be stored in pmpcfg register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 0*(XLEN/32),4,NOP + .align 3 + +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-RX-priority.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-RX-priority.S new file mode 100644 index 000000000..d7b16fa47 --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-RX-priority.S @@ -0,0 +1,214 @@ +// ----------- +// 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 +/* Test Name: pmp-NA4-priority-rx.S +// PMP Test in NA4 address matching mode +// Description: +// Tests the priority by assigning only R,X permissions to the high priority while R-W-X to low priority region +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf +*/ + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_NA4_priority_rx) +RVTEST_SIGBASE( x13,signature_x13_1) + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP7_CFG_SHIFT 56 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg2[63:56] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP7_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in NAPOT Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_R|PMP_X|PMP_NA4)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of region3 +#define PMPADDRESS2 TEST_FOR_EXECUTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg2, x4 // Updated pmpcfg2 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 + .align 3 + +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-RX.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-RX.S new file mode 100644 index 000000000..55d4a71b3 --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-RX.S @@ -0,0 +1,240 @@ +// ----------- +// 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 +/* Test Name: pmp-NA4-RX.S +// PMP Test in NA4 address matching mode +// Description: +=> Foreach mode in MPP (including M), for Load/store instruction, perform the instruction referencing an address where the associated pmpcfg.W=1 and observe an access fault or not. +=> Foreach mode, perform instruction fetches to an address where the associated pmpcfg.X=0 and observe an access fault or not. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +*/ +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_NA4_rx) +RVTEST_SIGBASE( x13,signature_x13_1) + + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP4_CFG_SHIFT 32 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg0 [7:0] value to configure address 0->RAM_LOCATION_FOR_TEST in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in NA4 Mode with RX enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_R|PMP_X|PMP_L|PMP_NA4)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(rvtest_code_end) +// in TOR Mode with RWX enabled +// ALSO NOTE THAT PMPREGION2 IS INSIDE THIS REGION, so this test will also check the priority order of PMP regions +#define PMPREGION3 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[39:32] value to configure address (rvtest_code_end)->(PMP_region_High) +// in TOR Mode with RWX enabled +#define PMPREGION4 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP4_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS0 RAM_LOCATION_FOR_TEST // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS1 TEST_FOR_EXECUTION +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of region3 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of region3 +#define PMPADDRESS3 rvtest_code_end +// PMPADDRESS4 = value to be loaded pmpaddr4 to declare upper address of region4 +#define PMPADDRESS4 PMP_region_High + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration +/* PMP is configure in the following order: +1. Address 0x0000 0000 to Address RAM_LOCATION_FOR_TEST => PMP TOR Region with RWX enabled. This region is the part of the code memory containing our code. For this purpose, pmpaddr0 has been given the value of RAM_LOCATION_FOR_TEST to declare the region from 0->RAM_LOCATION_FOR_TEST into a single PMP region. + +2. Address TEST_FOR_EXECUTION to Address RETURN_INSTRUCTION =====> This is the PMP region under test (A 4byte region == Granularity of Sail. This region has been declared by entering TEST_FOR_EXECUTION into pmpaddr1 and RETURN_INSTRUCTION into pmpaddr2. Then a PMP region is configure into NA4 mode by setting pmpcfg0[15:8]=PMPREGION2 + +3. Address RAM_LOCATION_FOR_TEST to Address rvtest_code_end => Another PMP region under test. This region has been declared by entering rvtest_code_end into pmpaddr3 and RAM_LOCATION_FOR_TEST into pmpaddr2. configure pmpaddr2(RAM_LOCATION_FOR_TEST) to pmpaddr3(rvtest_code_end) into TOR mode by setting pmpcfg0[31:24]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) + +4. Address rvtest_code_end to address PMP_region_High => PMP TOR Region with RWX enabled. This region is the part of the code memory containing trap handler, epilogs, and other important macro definitions. For this purpose, configure pmpaddr3(rvtest_code_end) to pmpaddr4(PMP_region_High) into TOR mode by setting pmpcfg1[7:0]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)). This PMP Region is mandatory to access signature area in S,U mode */ + /* Assigning addresses to PMP address registers */ + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS4) // Value to be stored in pmpaddr4 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr4, x4 // Updated pmpaddr4 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1 | PMPREGION2 | PMPREGION3 | PMPREGION4) + // Value to be stored in pmpcfg register ; Setting Up PMP Region-1,2,3 + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 + .align 3 + +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-X-priority-level-2.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-X-priority-level-2.S new file mode 100644 index 000000000..6d7c68faa --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-X-priority-level-2.S @@ -0,0 +1,234 @@ +// ----------- +// 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 +/* Test Name: pmp-TOR-priority-x-level-2.S +// Tests the priority by assigning only X permissions to the highest priority while no permissions to high priority region and R-W-X to low priority region +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf +*/ + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_NA4_priority_x_level_2) +RVTEST_SIGBASE( x13,signature_x13_1) + + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP7_CFG_SHIFT 56 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg2 [63:56] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled. This is the low priority region +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP7_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with nothing enabled +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION). This is the high priority region +// in TOR Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION3 ((((PMP_X|PMP_L|PMP_NA4)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +// PMPADDRESS14 = value to be loaded pmpaddr14 to declare lower address of Region-1 +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr14 to declare region1 +// PMPADDRESS15 = value to be loaded pmpaddr15 to declare upper address of Region-1 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of Region-2 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of Region-2 +#define PMPADDRESS3 RETURN_INSTRUCTION +// PMPADDRESS3 = value to be loaded pmpaddr1 to declare upper address of Region-3 +#define PMPADDRESS1 TEST_FOR_EXECUTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg2, x4 // Updated pmpcfg2 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION3) + // Value to be stored in pmpcfg register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 0*(XLEN/32),4,NOP + .align 3 + +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-X-priority.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-X-priority.S new file mode 100644 index 000000000..a9c4d0a9b --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-X-priority.S @@ -0,0 +1,214 @@ +// ----------- +// 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 +/* Test Name: pmp-NA4-priority-x.S +// PMP Test in NA4 address matching mode +// Description: +// Tests the priority by assigning only X permissions to the high priority while R-W-X to low priority region +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf +*/ + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_NA4_priority_x) +RVTEST_SIGBASE( x13,signature_x13_1) + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP7_CFG_SHIFT 56 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg2[63:56] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP7_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in NAPOT Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_X|PMP_NA4)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of region3 +#define PMPADDRESS2 TEST_FOR_EXECUTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg2, x4 // Updated pmpcfg2 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 4*(XLEN/32),8,0x12345678 + .align 3 + +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-X.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-X.S new file mode 100644 index 000000000..7eeffaa50 --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-NA4-X.S @@ -0,0 +1,239 @@ +// ----------- +// 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 +/* Test Name: pmp-NA4-X.S +// PMP Test in NA4 address matching mode +// Description: +=> Foreach mode in MPP (including M), for Load/store instruction, perform the instruction referencing an address where the associated pmpcfg.W=1 and observe an access fault or not. +=> Foreach mode, perform instruction fetches to an address where the associated pmpcfg.X=0 and observe an access fault or not. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +*/ +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_NA4_x) +RVTEST_SIGBASE( x13,signature_x13_1) + + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP4_CFG_SHIFT 32 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg0 [7:0] value to configure address 0->RAM_LOCATION_FOR_TEST in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in NA4 Mode with X enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_X|PMP_L|PMP_NA4)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(rvtest_code_end) +// in TOR Mode with RWX enabled +// ALSO NOTE THAT PMPREGION2 IS INSIDE THIS REGION, so this test will also check the priority order of PMP regions +#define PMPREGION3 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[39:32] value to configure address (rvtest_code_end)->(PMP_region_High) +// in TOR Mode with RWX enabled +#define PMPREGION4 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP4_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS0 RAM_LOCATION_FOR_TEST // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS1 TEST_FOR_EXECUTION +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of region3 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of region3 +#define PMPADDRESS3 rvtest_code_end +// PMPADDRESS4 = value to be loaded pmpaddr4 to declare upper address of region4 +#define PMPADDRESS4 PMP_region_High + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration +/* PMP is configure in the following order: +1. Address 0x0000 0000 to Address RAM_LOCATION_FOR_TEST => PMP TOR Region with RWX enabled. This region is the part of the code memory containing our code. For this purpose, pmpaddr0 has been given the value of RAM_LOCATION_FOR_TEST to declare the region from 0->RAM_LOCATION_FOR_TEST into a single PMP region. + +2. Address TEST_FOR_EXECUTION to Address RETURN_INSTRUCTION =====> This is the PMP region under test (A 4byte region == Granularity of Sail. This region has been declared by entering TEST_FOR_EXECUTION into pmpaddr1 and RETURN_INSTRUCTION into pmpaddr2. Then a PMP region is configure into NA4 mode by setting pmpcfg0[15:8]=PMPREGION2 + +3. Address RAM_LOCATION_FOR_TEST to Address rvtest_code_end => Another PMP region under test. This region has been declared by entering rvtest_code_end into pmpaddr3 and RAM_LOCATION_FOR_TEST into pmpaddr2. configure pmpaddr2(RAM_LOCATION_FOR_TEST) to pmpaddr3(rvtest_code_end) into TOR mode by setting pmpcfg0[31:24]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) + +4. Address rvtest_code_end to address PMP_region_High => PMP TOR Region with RWX enabled. This region is the part of the code memory containing trap handler, epilogs, and other important macro definitions. For this purpose, configure pmpaddr3(rvtest_code_end) to pmpaddr4(PMP_region_High) into TOR mode by setting pmpcfg1[7:0]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)). This PMP Region is mandatory to access signature area in S,U mode */ + /* Assigning addresses to PMP address registers */ + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS4) // Value to be stored in pmpaddr4 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr4, x4 // Updated pmpaddr4 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1 | PMPREGION2 | PMPREGION3 | PMPREGION4) + // Value to be stored in pmpcfg register ; Setting Up PMP Region-1,2,3 + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +.align 3 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-R-priority-level-2.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-R-priority-level-2.S new file mode 100644 index 000000000..63d4679cc --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-R-priority-level-2.S @@ -0,0 +1,233 @@ +// ----------- +// 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 +/* Test Name: pmp-NAPOT-priority-r-level-2.S +// Tests the priority by assigning only R permissions to the highest priority while no permissions to high priority region and R-W-X to low priority region +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf +*/ + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_NAPOT_priority_r_level_2) +RVTEST_SIGBASE( x13,signature_x13_1) + + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP7_CFG_SHIFT 56 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg2 [63:56] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled. This is the low priority region +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP7_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with nothing enabled +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION3 ((((PMP_R|PMP_L|PMP_NAPOT)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +// PMPADDRESS14 = value to be loaded pmpaddr14 to declare lower address of Region-1 +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr14 to declare region1 +// PMPADDRESS15 = value to be loaded pmpaddr15 to declare upper address of Region-1 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of Region-2 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of Region-2 +#define PMPADDRESS3 RETURN_INSTRUCTION +// PMPADDRESS3 = value to be loaded pmpaddr1 to declare upper address of Region-3 +#define PMPADDRESS1 TEST_FOR_EXECUTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg2, x4 // Updated pmpcfg2 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION3) + // Value to be stored in pmpcfg register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,NOP +.align 3 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-R-priority.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-R-priority.S new file mode 100644 index 000000000..8b7f641b1 --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-R-priority.S @@ -0,0 +1,213 @@ +// ----------- +// 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 +/* Test Name: pmp-NAPOT-priority-r.S +// PMP Test in NAPOT address matching mode +// Description: +// Tests the priority by assigning only R permissions to the high priority while R-W-X to low priority region +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf +*/ + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_NAPOT_priority_r) +RVTEST_SIGBASE( x13,signature_x13_1) + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP7_CFG_SHIFT 56 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg2[63:56] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP7_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in NAPOT Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_R|PMP_NAPOT)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of region3 +#define PMPADDRESS2 TEST_FOR_EXECUTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg2, x4 // Updated pmpcfg2 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +.align 3 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-R.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-R.S new file mode 100644 index 000000000..e72cb3802 --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-R.S @@ -0,0 +1,241 @@ +// ----------- +// 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 +/* Test Name: pmp-NAPOT-R.S +// PMP Test in NAPOT address matching mode +// Description: +=> Foreach mode in MPP (including M), for Load/store instruction, perform the instruction referencing an address where the associated pmpcfg.W=0 and observe an access fault or not. +=> Foreach mode, perform instruction fetches to an address where the associated pmpcfg.X=0 and observe an access fault or not. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +=> Do the same for loads where pmpcfg.R=1 and pmpcfg.W=0 to make sure that the W bit only affects stores and AMOs. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +*/ +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_NAPOT_r) +RVTEST_SIGBASE( x13,signature_x13_1) + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP4_CFG_SHIFT 32 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg0 [7:0] value to configure address 0->RAM_LOCATION_FOR_TEST in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in NAPOT Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_R|PMP_L|PMP_NAPOT)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(rvtest_code_end) +// in TOR Mode with RWX enabled +// ALSO NOTE THAT PMPREGION2 IS INSIDE THIS REGION, so this test will also check the priority order of PMP regions +#define PMPREGION3 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[39:32] value to configure address (rvtest_code_end)->(PMP_region_High) +// in TOR Mode with RWX enabled +#define PMPREGION4 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP4_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS0 RAM_LOCATION_FOR_TEST // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS1 TEST_FOR_EXECUTION +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of region3 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of region3 +#define PMPADDRESS3 rvtest_code_end +// PMPADDRESS4 = value to be loaded pmpaddr4 to declare upper address of region4 +#define PMPADDRESS4 PMP_region_High + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration +/* PMP is configure in the following order: +1. Address 0x0000 0000 to Address RAM_LOCATION_FOR_TEST => PMP TOR Region with RWX enabled. This region is the part of the code memory containing our code. For this purpose, pmpaddr0 has been given the value of RAM_LOCATION_FOR_TEST to declare the region from 0->RAM_LOCATION_FOR_TEST into a single PMP region. + +2. Address TEST_FOR_EXECUTION to Address RETURN_INSTRUCTION =====> This is the PMP region under test (A 4byte region == Granularity of Sail. This region has been declared by entering TEST_FOR_EXECUTION into pmpaddr1. Then a PMP region is configure into NAPOT mode by setting pmpcfg0[15:8]=PMPREGION2 + +3. Address RAM_LOCATION_FOR_TEST to Address rvtest_code_end => Another PMP region under test. This region has been declared by entering rvtest_code_end into pmpaddr3 and RAM_LOCATION_FOR_TEST into pmpaddr2. configure pmpaddr2(RAM_LOCATION_FOR_TEST) to pmpaddr3(rvtest_code_end) into TOR mode by setting pmpcfg0[31:24]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) + +4. Address rvtest_code_end to address PMP_region_High => PMP TOR Region with RWX enabled. This region is the part of the code memory containing trap handler, epilogs, and other important macro definitions. For this purpose, configure pmpaddr3(rvtest_code_end) to pmpaddr4(PMP_region_High) into TOR mode by setting pmpcfg1[7:0]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)). This PMP Region is mandatory to access signature area in S,U mode */ + /* Assigning addresses to PMP address registers */ + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS4) // Value to be stored in pmpaddr4 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr4, x4 // Updated pmpaddr4 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1 | PMPREGION2 | PMPREGION3 | PMPREGION4) + // Value to be stored in pmpcfg register ; Setting Up PMP Region-1,2,3 + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +.align 3 + +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-RW-priority-level-2.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-RW-priority-level-2.S new file mode 100644 index 000000000..225acf70b --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-RW-priority-level-2.S @@ -0,0 +1,233 @@ +// ----------- +// 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 +/* Test Name: pmp-NAPOT-priority-rw-level-2.S +// Tests the priority by assigning only R, w permissions to the highest priority while no permissions to high priority region and R-W-X to low priority region +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf +*/ + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_NAPOT_priority_rw_level_2) +RVTEST_SIGBASE( x13,signature_x13_1) + + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP7_CFG_SHIFT 56 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg2 [63:56] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled. This is the low priority region +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP7_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with nothing enabled +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION3 ((((PMP_R|PMP_W|PMP_L|PMP_NAPOT)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +// PMPADDRESS14 = value to be loaded pmpaddr14 to declare lower address of Region-1 +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr14 to declare region1 +// PMPADDRESS15 = value to be loaded pmpaddr15 to declare upper address of Region-1 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of Region-2 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of Region-2 +#define PMPADDRESS3 RETURN_INSTRUCTION +// PMPADDRESS3 = value to be loaded pmpaddr1 to declare upper address of Region-3 +#define PMPADDRESS1 TEST_FOR_EXECUTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg2, x4 // Updated pmpcfg2 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION3) + // Value to be stored in pmpcfg register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,NOP +.align 3 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-RW-priority.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-RW-priority.S new file mode 100644 index 000000000..0441e30db --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-RW-priority.S @@ -0,0 +1,213 @@ +// ----------- +// 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 +/* Test Name: pmp-NAPOT-priority-rw.S +// PMP Test in NAPOT address matching mode +// Description: +// Tests the priority by assigning only R,W permissions to the high priority while R-W-X to low priority region +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf +*/ + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_NAPOT_priority_rw) +RVTEST_SIGBASE( x13,signature_x13_1) + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP7_CFG_SHIFT 56 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg2[63:56] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP7_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in NAPOT Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_R|PMP_W|PMP_NAPOT)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of region3 +#define PMPADDRESS2 TEST_FOR_EXECUTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg2, x4 // Updated pmpcfg2 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +.align 3 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-RW.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-RW.S new file mode 100644 index 000000000..963a5436d --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-RW.S @@ -0,0 +1,240 @@ +// ----------- +// 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 +/* Test Name: pmp-NAPOT-RW.S +// PMP Test in NAPOT address matching mode +// Description: +=> Foreach mode in MPP (including M), for Load/store instruction, perform the instruction referencing an address where the associated pmpcfg.W=0 and observe an access fault or not. +=> Foreach mode, perform instruction fetches to an address where the associated pmpcfg.X=0 and observe an access fault or not. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +=> Do the same for loads where pmpcfg.R=1 and pmpcfg.W=0 to make sure that the W bit only affects stores and AMOs. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +*/ +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_NAPOT_rw) +RVTEST_SIGBASE( x13,signature_x13_1) + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP4_CFG_SHIFT 32 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg0 [7:0] value to configure address 0->RAM_LOCATION_FOR_TEST in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in NAPOT Mode with RW enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_R|PMP_W|PMP_L|PMP_NAPOT)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(rvtest_code_end) +// in TOR Mode with RWX enabled +// ALSO NOTE THAT PMPREGION2 IS INSIDE THIS REGION, so this test will also check the priority order of PMP regions +#define PMPREGION3 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[39:32] value to configure address (rvtest_code_end)->(PMP_region_High) +// in TOR Mode with RWX enabled +#define PMPREGION4 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP4_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS0 RAM_LOCATION_FOR_TEST // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS1 TEST_FOR_EXECUTION +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of region3 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of region3 +#define PMPADDRESS3 rvtest_code_end +// PMPADDRESS4 = value to be loaded pmpaddr4 to declare upper address of region4 +#define PMPADDRESS4 PMP_region_High + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration +/* PMP is configure in the following order: +1. Address 0x0000 0000 to Address RAM_LOCATION_FOR_TEST => PMP TOR Region with RWX enabled. This region is the part of the code memory containing our code. For this purpose, pmpaddr0 has been given the value of RAM_LOCATION_FOR_TEST to declare the region from 0->RAM_LOCATION_FOR_TEST into a single PMP region. + +2. Address TEST_FOR_EXECUTION to Address RETURN_INSTRUCTION =====> This is the PMP region under test (A 4byte region == Granularity of Sail. This region has been declared by entering TEST_FOR_EXECUTION into pmpaddr1 and RETURN_INSTRUCTION into pmpaddr2. Then a PMP region is configure into NA4 mode by setting pmpcfg0[15:8]=PMPREGION2 + +3. Address RAM_LOCATION_FOR_TEST to Address rvtest_code_end => Another PMP region under test. This region has been declared by entering rvtest_code_end into pmpaddr3 and RAM_LOCATION_FOR_TEST into pmpaddr2. configure pmpaddr2(RAM_LOCATION_FOR_TEST) to pmpaddr3(rvtest_code_end) into TOR mode by setting pmpcfg0[31:24]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) + +4. Address rvtest_code_end to address PMP_region_High => PMP TOR Region with RWX enabled. This region is the part of the code memory containing trap handler, epilogs, and other important macro definitions. For this purpose, configure pmpaddr3(rvtest_code_end) to pmpaddr4(PMP_region_High) into TOR mode by setting pmpcfg1[7:0]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)). This PMP Region is mandatory to access signature area in S,U mode */ + /* Assigning addresses to PMP address registers */ + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS4) // Value to be stored in pmpaddr4 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr4, x4 // Updated pmpaddr4 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1 | PMPREGION2 | PMPREGION3 | PMPREGION4) + // Value to be stored in pmpcfg register ; Setting Up PMP Region-1,2,3 + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +.align 3 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-RWX.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-RWX.S new file mode 100644 index 000000000..4d7885644 --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-RWX.S @@ -0,0 +1,240 @@ +// ----------- +// 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 +/* Test Name: pmp-NAPOT-RWX.S +// PMP Test in NAPOT address matching mode +// Description: +=> Foreach mode in MPP (including M), for Load/store instruction, perform the instruction referencing an address where the associated pmpcfg.W=0 and observe an access fault or not. +=> Foreach mode, perform instruction fetches to an address where the associated pmpcfg.X=0 and observe an access fault or not. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +=> Do the same for loads where pmpcfg.R=1 and pmpcfg.W=0 to make sure that the W bit only affects stores and AMOs. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +*/ +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_NAPOT_rwx) +RVTEST_SIGBASE( x13,signature_x13_1) + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP4_CFG_SHIFT 32 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg0 [7:0] value to configure address 0->RAM_LOCATION_FOR_TEST in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in NAPOT Mode with RWX enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_NAPOT)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(rvtest_code_end) +// in TOR Mode with RWX enabled +// ALSO NOTE THAT PMPREGION2 IS INSIDE THIS REGION, so this test will also check the priority order of PMP regions +#define PMPREGION3 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[39:32] value to configure address (rvtest_code_end)->(PMP_region_High) +// in TOR Mode with RWX enabled +#define PMPREGION4 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP4_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS0 RAM_LOCATION_FOR_TEST // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS1 TEST_FOR_EXECUTION +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of region3 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of region3 +#define PMPADDRESS3 rvtest_code_end +// PMPADDRESS4 = value to be loaded pmpaddr4 to declare upper address of region4 +#define PMPADDRESS4 PMP_region_High + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration +/* PMP is configure in the following order: +1. Address 0x0000 0000 to Address RAM_LOCATION_FOR_TEST => PMP TOR Region with RWX enabled. This region is the part of the code memory containing our code. For this purpose, pmpaddr0 has been given the value of RAM_LOCATION_FOR_TEST to declare the region from 0->RAM_LOCATION_FOR_TEST into a single PMP region. + +2. Address TEST_FOR_EXECUTION to Address RETURN_INSTRUCTION =====> This is the PMP region under test (A 4byte region == Granularity of Sail. This region has been declared by entering TEST_FOR_EXECUTION into pmpaddr1 and RETURN_INSTRUCTION into pmpaddr2. Then a PMP region is configure into NA4 mode by setting pmpcfg0[15:8]=PMPREGION2 + +3. Address RAM_LOCATION_FOR_TEST to Address rvtest_code_end => Another PMP region under test. This region has been declared by entering rvtest_code_end into pmpaddr3 and RAM_LOCATION_FOR_TEST into pmpaddr2. configure pmpaddr2(RAM_LOCATION_FOR_TEST) to pmpaddr3(rvtest_code_end) into TOR mode by setting pmpcfg0[31:24]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) + +4. Address rvtest_code_end to address PMP_region_High => PMP TOR Region with RWX enabled. This region is the part of the code memory containing trap handler, epilogs, and other important macro definitions. For this purpose, configure pmpaddr3(rvtest_code_end) to pmpaddr4(PMP_region_High) into TOR mode by setting pmpcfg1[7:0]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)). This PMP Region is mandatory to access signature area in S,U mode */ + /* Assigning addresses to PMP address registers */ + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS4) // Value to be stored in pmpaddr4 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr4, x4 // Updated pmpaddr4 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1 | PMPREGION2 | PMPREGION3 | PMPREGION4) + // Value to be stored in pmpcfg register ; Setting Up PMP Region-1,2,3 + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +.align 3 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-RX-priority-level-2.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-RX-priority-level-2.S new file mode 100644 index 000000000..d666f4e94 --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-RX-priority-level-2.S @@ -0,0 +1,233 @@ +// ----------- +// 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 +/* Test Name: pmp-NAPOT-priority-rx-level-2.S +// Tests the priority by assigning only R,X permissions to the highest priority while no permissions to high priority region and R-W-X to low priority region +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf +*/ + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_NAPOT_priority_rx_level_2) +RVTEST_SIGBASE( x13,signature_x13_1) + + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP7_CFG_SHIFT 56 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg2 [63:56] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled. This is the low priority region +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP7_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with nothing enabled +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION3 ((((PMP_R|PMP_X|PMP_L|PMP_NAPOT)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +// PMPADDRESS14 = value to be loaded pmpaddr14 to declare lower address of Region-1 +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr14 to declare region1 +// PMPADDRESS15 = value to be loaded pmpaddr15 to declare upper address of Region-1 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of Region-2 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of Region-2 +#define PMPADDRESS3 RETURN_INSTRUCTION +// PMPADDRESS3 = value to be loaded pmpaddr1 to declare upper address of Region-3 +#define PMPADDRESS1 TEST_FOR_EXECUTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg2, x4 // Updated pmpcfg2 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION3) + // Value to be stored in pmpcfg register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,NOP +.align 3 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-RX-priority.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-RX-priority.S new file mode 100644 index 000000000..1843d4d65 --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-RX-priority.S @@ -0,0 +1,213 @@ +// ----------- +// 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 +/* Test Name: pmp-NAPOT-priority-rx.S +// PMP Test in NAPOT address matching mode +// Description: +// Tests the priority by assigning only R,X permissions to the high priority while R-W-X to low priority region +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf +*/ + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_NAPOT_priority_rx) +RVTEST_SIGBASE( x13,signature_x13_1) + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP7_CFG_SHIFT 56 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg2[63:56] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP7_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in NAPOT Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_R|PMP_X|PMP_NAPOT)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of region3 +#define PMPADDRESS2 TEST_FOR_EXECUTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg2, x4 // Updated pmpcfg2 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +.align 3 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-RX.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-RX.S new file mode 100644 index 000000000..11b1eb837 --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-RX.S @@ -0,0 +1,240 @@ +// ----------- +// 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 +/* Test Name: pmp-NAPOT-RX.S +// PMP Test in NAPOT address matching mode +// Description: +=> Foreach mode in MPP (including M), for Load/store instruction, perform the instruction referencing an address where the associated pmpcfg.W=0 and observe an access fault or not. +=> Foreach mode, perform instruction fetches to an address where the associated pmpcfg.X=0 and observe an access fault or not. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +=> Do the same for loads where pmpcfg.R=1 and pmpcfg.W=0 to make sure that the W bit only affects stores and AMOs. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +*/ +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_NAPOT_rx) +RVTEST_SIGBASE( x13,signature_x13_1) + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP4_CFG_SHIFT 32 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg0 [7:0] value to configure address 0->RAM_LOCATION_FOR_TEST in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in NAPOT Mode with RX enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_R|PMP_X|PMP_L|PMP_NAPOT)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(rvtest_code_end) +// in TOR Mode with RWX enabled +// ALSO NOTE THAT PMPREGION2 IS INSIDE THIS REGION, so this test will also check the priority order of PMP regions +#define PMPREGION3 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[39:32] value to configure address (rvtest_code_end)->(PMP_region_High) +// in TOR Mode with RWX enabled +#define PMPREGION4 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP4_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS0 RAM_LOCATION_FOR_TEST // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS1 TEST_FOR_EXECUTION +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of region3 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of region3 +#define PMPADDRESS3 rvtest_code_end +// PMPADDRESS4 = value to be loaded pmpaddr4 to declare upper address of region4 +#define PMPADDRESS4 PMP_region_High + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration +/* PMP is configure in the following order: +1. Address 0x0000 0000 to Address RAM_LOCATION_FOR_TEST => PMP TOR Region with RWX enabled. This region is the part of the code memory containing our code. For this purpose, pmpaddr0 has been given the value of RAM_LOCATION_FOR_TEST to declare the region from 0->RAM_LOCATION_FOR_TEST into a single PMP region. + +2. Address TEST_FOR_EXECUTION to Address RETURN_INSTRUCTION =====> This is the PMP region under test (A 4byte region == Granularity of Sail. This region has been declared by entering TEST_FOR_EXECUTION into pmpaddr1 and RETURN_INSTRUCTION into pmpaddr2. Then a PMP region is configure into NA4 mode by setting pmpcfg0[15:8]=PMPREGION2 + +3. Address RAM_LOCATION_FOR_TEST to Address rvtest_code_end => Another PMP region under test. This region has been declared by entering rvtest_code_end into pmpaddr3 and RAM_LOCATION_FOR_TEST into pmpaddr2. configure pmpaddr2(RAM_LOCATION_FOR_TEST) to pmpaddr3(rvtest_code_end) into TOR mode by setting pmpcfg0[31:24]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) + +4. Address rvtest_code_end to address PMP_region_High => PMP TOR Region with RWX enabled. This region is the part of the code memory containing trap handler, epilogs, and other important macro definitions. For this purpose, configure pmpaddr3(rvtest_code_end) to pmpaddr4(PMP_region_High) into TOR mode by setting pmpcfg1[7:0]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)). This PMP Region is mandatory to access signature area in S,U mode */ + /* Assigning addresses to PMP address registers */ + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS4) // Value to be stored in pmpaddr4 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr4, x4 // Updated pmpaddr4 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1 | PMPREGION2 | PMPREGION3 | PMPREGION4) + // Value to be stored in pmpcfg register ; Setting Up PMP Region-1,2,3 + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +.align 3 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-X-priority-level-2.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-X-priority-level-2.S new file mode 100644 index 000000000..9d2e5ea1e --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-X-priority-level-2.S @@ -0,0 +1,233 @@ +// ----------- +// 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 +/* Test Name: pmp-NAPOT-priority-x-level-2.S +// Tests the priority by assigning only X permissions to the highest priority while no permissions to high priority region and R-W-X to low priority region +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf +*/ + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_NAPOT_priority_x_level_2) +RVTEST_SIGBASE( x13,signature_x13_1) + + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP7_CFG_SHIFT 56 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg2 [63:56] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled. This is the low priority region +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP7_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with nothing enabled +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION3 ((((PMP_X|PMP_L|PMP_NAPOT)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +// PMPADDRESS14 = value to be loaded pmpaddr14 to declare lower address of Region-1 +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr14 to declare region1 +// PMPADDRESS15 = value to be loaded pmpaddr15 to declare upper address of Region-1 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of Region-2 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of Region-2 +#define PMPADDRESS3 RETURN_INSTRUCTION +// PMPADDRESS3 = value to be loaded pmpaddr1 to declare upper address of Region-3 +#define PMPADDRESS1 TEST_FOR_EXECUTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg2, x4 // Updated pmpcfg2 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION3) + // Value to be stored in pmpcfg register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,NOP +.align 3 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-X-priority.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-X-priority.S new file mode 100644 index 000000000..e23b39e7f --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-X-priority.S @@ -0,0 +1,213 @@ +// ----------- +// 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 +/* Test Name: pmp-NAPOT-priority-x.S +// PMP Test in NAPOT address matching mode +// Description: +// Tests the priority by assigning only X permissions to the high priority while R-W-X to low priority region +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf +*/ + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_NAPOT_priority_x) +RVTEST_SIGBASE( x13,signature_x13_1) + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP7_CFG_SHIFT 56 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg2[63:56] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP7_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in NAPOT Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_X|PMP_NAPOT)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of region3 +#define PMPADDRESS2 TEST_FOR_EXECUTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg2, x4 // Updated pmpcfg2 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +.align 3 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-X.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-X.S new file mode 100644 index 000000000..a24570f8f --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-NAPOT-X.S @@ -0,0 +1,240 @@ +// ----------- +// 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 +/* Test Name: pmp-NAPOT-X.S +// PMP Test in NAPOT address matching mode +// Description: +=> Foreach mode in MPP (including M), for Load/store instruction, perform the instruction referencing an address where the associated pmpcfg.W=0 and observe an access fault or not. +=> Foreach mode, perform instruction fetches to an address where the associated pmpcfg.X=0 and observe an access fault or not. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +=> Do the same for loads where pmpcfg.R=1 and pmpcfg.W=0 to make sure that the W bit only affects stores and AMOs. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +*/ +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_NAPOT_x) +RVTEST_SIGBASE( x13,signature_x13_1) + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP4_CFG_SHIFT 32 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg0 [7:0] value to configure address 0->RAM_LOCATION_FOR_TEST in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in NAPOT Mode with X enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_X|PMP_L|PMP_NAPOT)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(rvtest_code_end) +// in TOR Mode with RWX enabled +// ALSO NOTE THAT PMPREGION2 IS INSIDE THIS REGION, so this test will also check the priority order of PMP regions +#define PMPREGION3 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[39:32] value to configure address (rvtest_code_end)->(PMP_region_High) +// in TOR Mode with RWX enabled +#define PMPREGION4 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP4_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS0 RAM_LOCATION_FOR_TEST // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS1 TEST_FOR_EXECUTION +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of region3 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of region3 +#define PMPADDRESS3 rvtest_code_end +// PMPADDRESS4 = value to be loaded pmpaddr4 to declare upper address of region4 +#define PMPADDRESS4 PMP_region_High + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration +/* PMP is configure in the following order: +1. Address 0x0000 0000 to Address RAM_LOCATION_FOR_TEST => PMP TOR Region with RWX enabled. This region is the part of the code memory containing our code. For this purpose, pmpaddr0 has been given the value of RAM_LOCATION_FOR_TEST to declare the region from 0->RAM_LOCATION_FOR_TEST into a single PMP region. + +2. Address TEST_FOR_EXECUTION to Address RETURN_INSTRUCTION =====> This is the PMP region under test (A 4byte region == Granularity of Sail. This region has been declared by entering TEST_FOR_EXECUTION into pmpaddr1 and RETURN_INSTRUCTION into pmpaddr2. Then a PMP region is configure into NA4 mode by setting pmpcfg0[15:8]=PMPREGION2 + +3. Address RAM_LOCATION_FOR_TEST to Address rvtest_code_end => Another PMP region under test. This region has been declared by entering rvtest_code_end into pmpaddr3 and RAM_LOCATION_FOR_TEST into pmpaddr2. configure pmpaddr2(RAM_LOCATION_FOR_TEST) to pmpaddr3(rvtest_code_end) into TOR mode by setting pmpcfg0[31:24]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) + +4. Address rvtest_code_end to address PMP_region_High => PMP TOR Region with RWX enabled. This region is the part of the code memory containing trap handler, epilogs, and other important macro definitions. For this purpose, configure pmpaddr3(rvtest_code_end) to pmpaddr4(PMP_region_High) into TOR mode by setting pmpcfg1[7:0]=((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)). This PMP Region is mandatory to access signature area in S,U mode */ + /* Assigning addresses to PMP address registers */ + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS4) // Value to be stored in pmpaddr4 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr4, x4 // Updated pmpaddr4 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1 | PMPREGION2 | PMPREGION3 | PMPREGION4) + // Value to be stored in pmpcfg register ; Setting Up PMP Region-1,2,3 + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +.align 3 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-R-priority-level-2.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-R-priority-level-2.S new file mode 100644 index 000000000..2967e6fd2 --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-R-priority-level-2.S @@ -0,0 +1,239 @@ +// ----------- +// 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 +/* Test Name: pmp-TOR-priority-r-level-2.S +// Tests the priority by assigning only R permissions to the highest priority while no permissions to high priority region and R-W-X to low priority region +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf +*/ + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_TOR_priority_r_level_2) +RVTEST_SIGBASE( x13,signature_x13_1) + + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP7_CFG_SHIFT 56 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg2 [63:56] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled. This is the low priority region +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP7_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with nothing enabled +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION3 ((((PMP_R|PMP_L|PMP_TOR)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +// PMPADDRESS14 = value to be loaded pmpaddr14 to declare lower address of Region-1 +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr14 to declare region1 +// PMPADDRESS15 = value to be loaded pmpaddr15 to declare upper address of Region-1 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of Region-2 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of Region-2 +#define PMPADDRESS3 RETURN_INSTRUCTION +// PMPADDRESS2 = value to be loaded pmpaddr0 to declare lower address of Region-3 +#define PMPADDRESS0 TEST_FOR_EXECUTION +// PMPADDRESS3 = value to be loaded pmpaddr1 to declare upper address of Region-3 +#define PMPADDRESS1 RETURN_INSTRUCTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg2, x4 // Updated pmpcfg2 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION3) + // Value to be stored in pmpcfg register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 0*(XLEN/32),4,NOP +.align 3 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-R-priority.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-R-priority.S new file mode 100644 index 000000000..4f299be98 --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-R-priority.S @@ -0,0 +1,218 @@ +// ----------- +// 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 +/* Test Name: pmp-TOR-priority-r.S +// Tests the priority by assigning only R permissions to the high priority while R-W-X to low priority region +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf +*/ + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_TOR_priority_r) +RVTEST_SIGBASE( x13,signature_x13_1) + + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP7_CFG_SHIFT 56 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg2 [63:56] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled. This is the low priority region +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP7_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_R|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +// PMPADDRESS14 = value to be loaded pmpaddr14 to declare lower address of Region-1 +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr14 to declare region1 +// PMPADDRESS15 = value to be loaded pmpaddr15 to declare upper address of Region-1 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr3 to declare lower address of Region-2 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of Region-2 +#define PMPADDRESS3 RETURN_INSTRUCTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg2, x4 // Updated pmpcfg2 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 0*(XLEN/32),4,NOP +.align 3 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-R.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-R.S new file mode 100644 index 000000000..a748d899d --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-R.S @@ -0,0 +1,248 @@ +// ----------- +// 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 +/* Test Name: pmp-tor-R.S +// PMP Test in TOR address matching mode +// Description: +=> Foreach mode in MPP (including M), for Load/store instruction, perform the instruction referencing an address where the associated pmpcfg.W=1 and observe an access fault or not. +=> Foreach mode, perform instruction fetches to an address where the associated pmpcfg.X=0 and observe an access fault or not. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +=> Do the same for loads where pmpcfg.R=1 and pmpcfg.W=0 to make sure that the W bit only affects stores and AMOs. +*/ +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_TOR_r) +RVTEST_SIGBASE( x13,signature_x13_1) + + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP4_CFG_SHIFT 32 +#define PMP5_CFG_SHIFT 40 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg0 [7:0] value to configure address 0->RAM_LOCATION_FOR_TEST in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[23:16] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in TOR Mode with X enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_R|PMP_L|PMP_TOR)&0xFF) << PMP2_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[39:32] value to configure address (RAM_LOCATION_FOR_TEST)->(rvtest_code_end) +// in TOR Mode with RW enabled +// ALSO NOTE THAT PMPREGION2 IS INSIDE THIS REGION, so this test will also check the priority order of PMP regions +#define PMPREGION3 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP4_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[47:40] value to configure address (rvtest_code_end)->(PMP_region_High) +// in TOR Mode with RWX enabled +#define PMPREGION4 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP5_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS0 RAM_LOCATION_FOR_TEST // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS1 TEST_FOR_EXECUTION +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare upper address of region2 +#define PMPADDRESS2 RETURN_INSTRUCTION +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare lower address of region3 +#define PMPADDRESS3 RAM_LOCATION_FOR_TEST +// PMPADDRESS4 = value to be loaded pmpaddr4 to declare upper address of region3 +#define PMPADDRESS4 rvtest_code_end +// PMPADDRESS5 = value to be loaded pmpaddr5 to declare upper address of region4 +#define PMPADDRESS5 PMP_region_High + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration +/* PMP is configure in the following order: +1. Address 0x8000 0000 to Address RAM_LOCATION_FOR_TEST => PMP TOR Region with RWX enabled. This region is the part of the code memory containing our code. For this purpose, pmpaddr0 has been given the value of RAM_LOCATION_FOR_TEST to declare the region from 0->RAM_LOCATION_FOR_TEST into a single PMP region. + +2. Address TEST_FOR_EXECUTION to Address RETURN_INSTRUCTION => PMP region under test. This region has been declared by entering TEST_FOR_EXECUTION into pmpaddr1 and rvtest_code_end into pmpaddr2. Then a PMP region is configure from pmpaddr2(RETURN_INSTRUCTION) to pmpaddr1(TEST_FOR_EXECUTION) into TOR mode by setting pmpcfg0[23:16]=PMPREGION2 + +3. Address RAM_LOCATION_FOR_TEST to Address rvtest_code_end => PMP region under test. This region has been declared by entering rvtest_code_end into pmpaddr4 and RAM_LOCATION_FOR_TEST into pmpaddr3. configure pmpaddr4(RAM_LOCATION_FOR_TEST) to pmpaddr5(rvtest_code_end) into TOR mode by setting pmpcfg1[15:8]=PMPREGION3 + +4. Address rvtest_code_end to address PMP_region_High => PMP TOR Region with RWX enabled. This region is the part of the code memory containing trap handler, epilogs, and other important macro definitions. For this purpose, configure pmpaddr4(rvtest_code_end) to pmpaddr5(PMP_region_High) into TOR mode by setting pmpcfg1[15:8]=PMPREGION4. This PMP Region is mandatory to access signature area in S,U mode */ + /* Assigning addresses to PMP address registers */ + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS4) // Value to be stored in pmpaddr4 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr4, x4 // Updated pmpaddr4 + nop // Added nop in case of trap + LA(x4, PMPADDRESS5) // Value to be stored in pmpaddr5 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr5, x4 // Updated pmpaddr5 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1 | PMPREGION2 | PMPREGION3 | PMPREGION4) + // Value to be stored in pmpcfg register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +.align 3 + +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-RW-priority-level-2..S b/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-RW-priority-level-2..S new file mode 100644 index 000000000..e79816a64 --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-RW-priority-level-2..S @@ -0,0 +1,240 @@ +// ----------- +// 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 +/* Test Name: pmp-TOR-priority-rw-level-2.S +// Tests the priority by assigning only R,W permissions to the highest priority while no permissions to high priority region and R-W-X to low priority region +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf +*/ + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_TOR_priority_rw_level_2) +RVTEST_SIGBASE( x13,signature_x13_1) + + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP7_CFG_SHIFT 56 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg2 [63:56] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled. This is the low priority region +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP7_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with nothing enabled +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with R,W enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION3 ((((PMP_R|PMP_W|PMP_L|PMP_TOR)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +// PMPADDRESS14 = value to be loaded pmpaddr14 to declare lower address of Region-1 +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr14 to declare region1 +// PMPADDRESS15 = value to be loaded pmpaddr15 to declare upper address of Region-1 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of Region-2 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of Region-2 +#define PMPADDRESS3 RETURN_INSTRUCTION +// PMPADDRESS2 = value to be loaded pmpaddr0 to declare lower address of Region-3 +#define PMPADDRESS0 TEST_FOR_EXECUTION +// PMPADDRESS3 = value to be loaded pmpaddr1 to declare upper address of Region-3 +#define PMPADDRESS1 RETURN_INSTRUCTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg2, x4 // Updated pmpcfg2 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION3) + // Value to be stored in pmpcfg register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 1*(XLEN/32),4,NOP //Single +.align 3 + +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-RW-priority.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-RW-priority.S new file mode 100644 index 000000000..076ffd6fb --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-RW-priority.S @@ -0,0 +1,218 @@ +// ----------- +// 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 +/* Test Name: pmp-TOR-priority-rw.S +// Tests the priority by assigning only rw permissions to the high priority while R-W-X to low priority region +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf +*/ + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_TOR_priority_rw) +RVTEST_SIGBASE( x13,signature_x13_1) + + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP7_CFG_SHIFT 56 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg2 [63:56] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled. This is the low priority region +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP7_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_R|PMP_W|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +// PMPADDRESS14 = value to be loaded pmpaddr14 to declare lower address of Region-1 +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr14 to declare region1 +// PMPADDRESS15 = value to be loaded pmpaddr15 to declare upper address of Region-1 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr3 to declare lower address of Region-2 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of Region-2 +#define PMPADDRESS3 RETURN_INSTRUCTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg2, x4 // Updated pmpcfg2 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 0*(XLEN/32),4,NOP +.align 3 +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-RW.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-RW.S new file mode 100644 index 000000000..e0d08d6ed --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-RW.S @@ -0,0 +1,248 @@ +// ----------- +// 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 +/* Test Name: pmp-tor-RW.S +// PMP Test in TOR address matching mode +// Description: +=> Foreach mode in MPP (including M), for Load/store instruction, perform the instruction referencing an address where the associated pmpcfg.W=1 and observe an access fault or not. +=> Foreach mode, perform instruction fetches to an address where the associated pmpcfg.X=0 and observe an access fault or not. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +=> Do the same for loads where pmpcfg.R=1 and pmpcfg.W=0 to make sure that the W bit only affects stores and AMOs. +*/ +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_TOR_rw) +RVTEST_SIGBASE( x13,signature_x13_1) + + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP4_CFG_SHIFT 32 +#define PMP5_CFG_SHIFT 40 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg0 [7:0] value to configure address 0->RAM_LOCATION_FOR_TEST in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[23:16] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in TOR Mode with X enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_R|PMP_W|PMP_L|PMP_TOR)&0xFF) << PMP2_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[39:32] value to configure address (RAM_LOCATION_FOR_TEST)->(rvtest_code_end) +// in TOR Mode with RW enabled +// ALSO NOTE THAT PMPREGION2 IS INSIDE THIS REGION, so this test will also check the priority order of PMP regions +#define PMPREGION3 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP4_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[47:40] value to configure address (rvtest_code_end)->(PMP_region_High) +// in TOR Mode with RWX enabled +#define PMPREGION4 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP5_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS0 RAM_LOCATION_FOR_TEST // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS1 TEST_FOR_EXECUTION +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare upper address of region2 +#define PMPADDRESS2 RETURN_INSTRUCTION +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare lower address of region3 +#define PMPADDRESS3 RAM_LOCATION_FOR_TEST +// PMPADDRESS4 = value to be loaded pmpaddr4 to declare upper address of region3 +#define PMPADDRESS4 rvtest_code_end +// PMPADDRESS5 = value to be loaded pmpaddr5 to declare upper address of region4 +#define PMPADDRESS5 PMP_region_High + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration +/* PMP is configure in the following order: +1. Address 0x8000 0000 to Address RAM_LOCATION_FOR_TEST => PMP TOR Region with RWX enabled. This region is the part of the code memory containing our code. For this purpose, pmpaddr0 has been given the value of RAM_LOCATION_FOR_TEST to declare the region from 0->RAM_LOCATION_FOR_TEST into a single PMP region. + +2. Address TEST_FOR_EXECUTION to Address RETURN_INSTRUCTION => PMP region under test. This region has been declared by entering TEST_FOR_EXECUTION into pmpaddr1 and rvtest_code_end into pmpaddr2. Then a PMP region is configure from pmpaddr2(RETURN_INSTRUCTION) to pmpaddr1(TEST_FOR_EXECUTION) into TOR mode by setting pmpcfg0[23:16]=PMPREGION2 + +3. Address RAM_LOCATION_FOR_TEST to Address rvtest_code_end => PMP region under test. This region has been declared by entering rvtest_code_end into pmpaddr4 and RAM_LOCATION_FOR_TEST into pmpaddr3. configure pmpaddr4(RAM_LOCATION_FOR_TEST) to pmpaddr5(rvtest_code_end) into TOR mode by setting pmpcfg1[15:8]=PMPREGION3 + +4. Address rvtest_code_end to address PMP_region_High => PMP TOR Region with RWX enabled. This region is the part of the code memory containing trap handler, epilogs, and other important macro definitions. For this purpose, configure pmpaddr4(rvtest_code_end) to pmpaddr5(PMP_region_High) into TOR mode by setting pmpcfg1[15:8]=PMPREGION4. This PMP Region is mandatory to access signature area in S,U mode */ + /* Assigning addresses to PMP address registers */ + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS4) // Value to be stored in pmpaddr4 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr4, x4 // Updated pmpaddr4 + nop // Added nop in case of trap + LA(x4, PMPADDRESS5) // Value to be stored in pmpaddr5 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr5, x4 // Updated pmpaddr5 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1 | PMPREGION2 | PMPREGION3 | PMPREGION4) + // Value to be stored in pmpcfg register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +.align 3 + +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-RWX.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-RWX.S new file mode 100644 index 000000000..1e9b313d3 --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-RWX.S @@ -0,0 +1,248 @@ +// ----------- +// 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 +/* Test Name: pmp-tor-RWX.S +// PMP Test in TOR address matching mode +// Description: +=> Foreach mode in MPP (including M), for Load/store instruction, perform the instruction referencing an address where the associated pmpcfg.W=1 and observe an access fault or not. +=> Foreach mode, perform instruction fetches to an address where the associated pmpcfg.X=0 and observe an access fault or not. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +=> Do the same for loads where pmpcfg.R=1 and pmpcfg.W=0 to make sure that the W bit only affects stores and AMOs. +*/ +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_TOR_rwx) +RVTEST_SIGBASE( x13,signature_x13_1) + + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP4_CFG_SHIFT 32 +#define PMP5_CFG_SHIFT 40 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg0 [7:0] value to configure address 0->RAM_LOCATION_FOR_TEST in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[23:16] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in TOR Mode with RWX enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP2_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[39:32] value to configure address (RAM_LOCATION_FOR_TEST)->(rvtest_code_end) +// in TOR Mode with RW enabled +// ALSO NOTE THAT PMPREGION2 IS INSIDE THIS REGION, so this test will also check the priority order of PMP regions +#define PMPREGION3 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP4_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg1[47:40] value to configure address (rvtest_code_end)->(PMP_region_High) +// in TOR Mode with RWX enabled +#define PMPREGION4 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP5_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS0 RAM_LOCATION_FOR_TEST // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS1 TEST_FOR_EXECUTION +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare upper address of region2 +#define PMPADDRESS2 RETURN_INSTRUCTION +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare lower address of region3 +#define PMPADDRESS3 RAM_LOCATION_FOR_TEST +// PMPADDRESS4 = value to be loaded pmpaddr4 to declare upper address of region3 +#define PMPADDRESS4 rvtest_code_end +// PMPADDRESS5 = value to be loaded pmpaddr5 to declare upper address of region4 +#define PMPADDRESS5 PMP_region_High + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration +/* PMP is configure in the following order: +1. Address 0x8000 0000 to Address RAM_LOCATION_FOR_TEST => PMP TOR Region with RWX enabled. This region is the part of the code memory containing our code. For this purpose, pmpaddr0 has been given the value of RAM_LOCATION_FOR_TEST to declare the region from 0->RAM_LOCATION_FOR_TEST into a single PMP region. + +2. Address TEST_FOR_EXECUTION to Address RETURN_INSTRUCTION => PMP region under test. This region has been declared by entering TEST_FOR_EXECUTION into pmpaddr1 and rvtest_code_end into pmpaddr2. Then a PMP region is configure from pmpaddr2(RETURN_INSTRUCTION) to pmpaddr1(TEST_FOR_EXECUTION) into TOR mode by setting pmpcfg0[23:16]=PMPREGION2 + +3. Address RAM_LOCATION_FOR_TEST to Address rvtest_code_end => PMP region under test. This region has been declared by entering rvtest_code_end into pmpaddr4 and RAM_LOCATION_FOR_TEST into pmpaddr3. configure pmpaddr4(RAM_LOCATION_FOR_TEST) to pmpaddr5(rvtest_code_end) into TOR mode by setting pmpcfg1[15:8]=PMPREGION3 + +4. Address rvtest_code_end to address PMP_region_High => PMP TOR Region with RWX enabled. This region is the part of the code memory containing trap handler, epilogs, and other important macro definitions. For this purpose, configure pmpaddr4(rvtest_code_end) to pmpaddr5(PMP_region_High) into TOR mode by setting pmpcfg1[15:8]=PMPREGION4. This PMP Region is mandatory to access signature area in S,U mode */ + /* Assigning addresses to PMP address registers */ + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS4) // Value to be stored in pmpaddr4 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr4, x4 // Updated pmpaddr4 + nop // Added nop in case of trap + LA(x4, PMPADDRESS5) // Value to be stored in pmpaddr5 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr5, x4 // Updated pmpaddr5 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1 | PMPREGION2 | PMPREGION3 | PMPREGION4) + // Value to be stored in pmpcfg register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +.align 3 + +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-RX-priority-level-2.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-RX-priority-level-2.S new file mode 100644 index 000000000..67ddb001d --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-RX-priority-level-2.S @@ -0,0 +1,240 @@ +// ----------- +// 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 +/* Test Name: pmp-TOR-priority-rx-level-2.S +// Tests the priority by assigning only R, X permissions to the highest priority while no permissions to high priority region and R-W-X to low priority region +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf +*/ + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_TOR_priority_rx_level_2) +RVTEST_SIGBASE( x13,signature_x13_1) + + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP7_CFG_SHIFT 56 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg2 [63:56] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled. This is the low priority region +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP7_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with nothing enabled +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with R,W enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION3 ((((PMP_R|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +// PMPADDRESS14 = value to be loaded pmpaddr14 to declare lower address of Region-1 +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr14 to declare region1 +// PMPADDRESS15 = value to be loaded pmpaddr15 to declare upper address of Region-1 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of Region-2 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of Region-2 +#define PMPADDRESS3 RETURN_INSTRUCTION +// PMPADDRESS2 = value to be loaded pmpaddr0 to declare lower address of Region-3 +#define PMPADDRESS0 TEST_FOR_EXECUTION +// PMPADDRESS3 = value to be loaded pmpaddr1 to declare upper address of Region-3 +#define PMPADDRESS1 RETURN_INSTRUCTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg2, x4 // Updated pmpcfg2 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION3) + // Value to be stored in pmpcfg register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 1*(XLEN/32),4,NOP //Single +.align 3 + +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-RX-priority.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-RX-priority.S new file mode 100644 index 000000000..eed06bab0 --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-RX-priority.S @@ -0,0 +1,219 @@ +// ----------- +// 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 +/* Test Name: pmp-TOR-priority-rx.S +// Tests the priority by assigning only rx permissions to the high priority while R-W-X to low priority region +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf +*/ + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_TOR_priority_rx) +RVTEST_SIGBASE( x13,signature_x13_1) + + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP7_CFG_SHIFT 56 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg2 [63:56] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled. This is the low priority region +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP7_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_R|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +// PMPADDRESS14 = value to be loaded pmpaddr14 to declare lower address of Region-1 +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr14 to declare region1 +// PMPADDRESS15 = value to be loaded pmpaddr15 to declare upper address of Region-1 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr3 to declare lower address of Region-2 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of Region-2 +#define PMPADDRESS3 RETURN_INSTRUCTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg2, x4 // Updated pmpcfg2 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 0*(XLEN/32),4,NOP +.align 3 + +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-RX.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-RX.S new file mode 100644 index 000000000..88c5649c3 --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-RX.S @@ -0,0 +1,248 @@ +// ----------- +// 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 +/* Test Name: pmp-tor-RX.S +// PMP Test in TOR address matching mode +// Description: +=> Foreach mode in MPP (including M), for Load/store instruction, perform the instruction referencing an address where the associated pmpcfg.W=1 and observe an access fault or not. +=> Foreach mode, perform instruction fetches to an address where the associated pmpcfg.X=0 and observe an access fault or not. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +=> Do the same for loads where pmpcfg.R=1 and pmpcfg.W=0 to make sure that the W bit only affects stores and AMOs. +*/ +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_TOR_rx) +RVTEST_SIGBASE( x13,signature_x13_1) + + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP4_CFG_SHIFT 32 +#define PMP5_CFG_SHIFT 40 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg0 [7:0] value to configure address 0->RAM_LOCATION_FOR_TEST in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[23:16] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in TOR Mode with RX enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_R|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP2_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[39:32] value to configure address (RAM_LOCATION_FOR_TEST)->(rvtest_code_end) +// in TOR Mode with RW enabled +// ALSO NOTE THAT PMPREGION2 IS INSIDE THIS REGION, so this test will also check the priority order of PMP regions +#define PMPREGION3 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP4_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[47:40] value to configure address (rvtest_code_end)->(PMP_region_High) +// in TOR Mode with RWX enabled +#define PMPREGION4 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP5_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS0 RAM_LOCATION_FOR_TEST // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS1 TEST_FOR_EXECUTION +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare upper address of region2 +#define PMPADDRESS2 RETURN_INSTRUCTION +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare lower address of region3 +#define PMPADDRESS3 RAM_LOCATION_FOR_TEST +// PMPADDRESS4 = value to be loaded pmpaddr4 to declare upper address of region3 +#define PMPADDRESS4 rvtest_code_end +// PMPADDRESS5 = value to be loaded pmpaddr5 to declare upper address of region4 +#define PMPADDRESS5 PMP_region_High + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration +/* PMP is configure in the following order: +1. Address 0x8000 0000 to Address RAM_LOCATION_FOR_TEST => PMP TOR Region with RWX enabled. This region is the part of the code memory containing our code. For this purpose, pmpaddr0 has been given the value of RAM_LOCATION_FOR_TEST to declare the region from 0->RAM_LOCATION_FOR_TEST into a single PMP region. + +2. Address TEST_FOR_EXECUTION to Address RETURN_INSTRUCTION => PMP region under test. This region has been declared by entering TEST_FOR_EXECUTION into pmpaddr1 and rvtest_code_end into pmpaddr2. Then a PMP region is configure from pmpaddr2(RETURN_INSTRUCTION) to pmpaddr1(TEST_FOR_EXECUTION) into TOR mode by setting pmpcfg0[23:16]=PMPREGION2 + +3. Address RAM_LOCATION_FOR_TEST to Address rvtest_code_end => PMP region under test. This region has been declared by entering rvtest_code_end into pmpaddr4 and RAM_LOCATION_FOR_TEST into pmpaddr3. configure pmpaddr4(RAM_LOCATION_FOR_TEST) to pmpaddr5(rvtest_code_end) into TOR mode by setting pmpcfg1[15:8]=PMPREGION3 + +4. Address rvtest_code_end to address PMP_region_High => PMP TOR Region with RWX enabled. This region is the part of the code memory containing trap handler, epilogs, and other important macro definitions. For this purpose, configure pmpaddr4(rvtest_code_end) to pmpaddr5(PMP_region_High) into TOR mode by setting pmpcfg1[15:8]=PMPREGION4. This PMP Region is mandatory to access signature area in S,U mode */ + /* Assigning addresses to PMP address registers */ + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS4) // Value to be stored in pmpaddr4 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr4, x4 // Updated pmpaddr4 + nop // Added nop in case of trap + LA(x4, PMPADDRESS5) // Value to be stored in pmpaddr5 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr5, x4 // Updated pmpaddr5 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1 | PMPREGION2 | PMPREGION3 | PMPREGION4) + // Value to be stored in pmpcfg register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +.align 3 + +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-X-priority-level-2.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-X-priority-level-2.S new file mode 100644 index 000000000..fe3550e5b --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-X-priority-level-2.S @@ -0,0 +1,240 @@ +// ----------- +// 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 +/* Test Name: pmp-TOR-priority-x-level-2.S +// Tests the priority by assigning only X permissions to the highest priority while no permissions to high priority region and R-W-X to low priority region +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf +*/ + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_TOR_priority_x_level_2) +RVTEST_SIGBASE( x13,signature_x13_1) + + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP7_CFG_SHIFT 56 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg2 [63:56] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled. This is the low priority region +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP7_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with nothing enabled +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[15:8] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with R,W enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION3 ((((PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP1_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +// PMPADDRESS14 = value to be loaded pmpaddr14 to declare lower address of Region-1 +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr14 to declare region1 +// PMPADDRESS15 = value to be loaded pmpaddr15 to declare upper address of Region-1 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare lower address of Region-2 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of Region-2 +#define PMPADDRESS3 RETURN_INSTRUCTION +// PMPADDRESS2 = value to be loaded pmpaddr0 to declare lower address of Region-3 +#define PMPADDRESS0 TEST_FOR_EXECUTION +// PMPADDRESS3 = value to be loaded pmpaddr1 to declare upper address of Region-3 +#define PMPADDRESS1 RETURN_INSTRUCTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg2, x4 // Updated pmpcfg2 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap + LI(x4, PMPREGION3) + // Value to be stored in pmpcfg register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 1*(XLEN/32),4,NOP //Single +.align 3 + +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-X-priority.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-X-priority.S new file mode 100644 index 000000000..17b1128c3 --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-X-priority.S @@ -0,0 +1,219 @@ +// ----------- +// 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 +/* Test Name: pmp-TOR-priority-x.S +// Tests the priority by assigning only X permissions to the high priority while R-W-X to low priority region +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf +*/ + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_TOR_priority_x) +RVTEST_SIGBASE( x13,signature_x13_1) + + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP7_CFG_SHIFT 56 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg2 [63:56] value to configure address 0->PMP_region_High in TOR Mode with RWX enabled. This is the low priority region +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP7_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[31:24] value to configure address (RAM_LOCATION_FOR_TEST)->(RETURN_INSTRUCTION). This is the high priority region +// in TOR Mode with R enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP3_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +// PMPADDRESS14 = value to be loaded pmpaddr14 to declare lower address of Region-1 +#define PMPADDRESS14 0x80000000 // value to be loaded pmpaddr14 to declare region1 +// PMPADDRESS15 = value to be loaded pmpaddr15 to declare upper address of Region-1 +#define PMPADDRESS15 PMP_region_High +// PMPADDRESS2 = value to be loaded pmpaddr3 to declare lower address of Region-2 +#define PMPADDRESS2 RAM_LOCATION_FOR_TEST +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare upper address of Region-2 +#define PMPADDRESS3 RETURN_INSTRUCTION + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration + + /* Assigning addresses to PMP address registers */ + LI(x4, PMPADDRESS14) // Value to be stored in pmpaddr14 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr14, x4 // Updated pmpaddr14 + nop // Added nop in case of trap + LA(x4, PMPADDRESS15) // Value to be stored in pmpaddr15 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr15, x4 // Updated pmpaddr15 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1) + // Value to be stored in pmpcfg register + csrs pmpcfg2, x4 // Updated pmpcfg2 + nop // Added nop in case of trap + LI(x4, PMPREGION2) + // Value to be stored in pmpcfg1 register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 0*(XLEN/32),4,NOP +.align 3 + +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END diff --git a/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-X.S b/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-X.S new file mode 100644 index 000000000..c2357734e --- /dev/null +++ b/riscv-test-suite/rv64i_m/pmp64/pmp64-TOR-X.S @@ -0,0 +1,248 @@ +// ----------- +// 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 +/* Test Name: pmp-tor-X.S +// PMP Test in TOR address matching mode +// Description: +=> Foreach mode in MPP (including M), for Load/store instruction, perform the instruction referencing an address where the associated pmpcfg.W=1 and observe an access fault or not. +=> Foreach mode, perform instruction fetches to an address where the associated pmpcfg.X=0 and observe an access fault or not. +=> Foreach mode in MPP (including M), Perform the instruction referencing an address where the associated pmpcfg.R=1 and observe an access fault or not. Do the same for stores where pmpcfg.R=1 and pmpcfg.W=1 to make sure that the R bit only affects loads while W bit only affect store. +=> Do the same for loads where pmpcfg.R=1 and pmpcfg.W=0 to make sure that the W bit only affects stores and AMOs. +*/ +// coverpoint definitions are given in coverage/pmp32_translated_coverpoints.cgf or coverage/pmp32_coverpoint_def_format.cgf + +#include "model_test.h" +#include "arch_test.h" +RVTEST_ISA("RV64I_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(.*64.*); 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_TOR_x) +RVTEST_SIGBASE( x13,signature_x13_1) + + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .align 3 + .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) +/* Define PMP Configuration Fields */ +#define PMP0_CFG_SHIFT 0 +#define PMP1_CFG_SHIFT 8 +#define PMP2_CFG_SHIFT 16 +#define PMP3_CFG_SHIFT 24 +#define PMP4_CFG_SHIFT 32 +#define PMP5_CFG_SHIFT 40 +#define NOP 0x13 +.macro VERIFICATION_RWX ADDRESS + LA(a5, \ADDRESS) // Fetch the address to be checked + LI(a4, NOP) // Load the new value (NOP Instruction ID) + sb a4,0(a5) // Store the new value (NOT TRAP => W enabled) + nop + nop + sh a4,0(a5) // store data + nop + nop + sw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + sd a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + lb a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) //verify that the data is stored successfuly + lh a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + lw a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + ld a4,0(a5) // Load data from it (CHECK FOR READ) ; (NOT TRAP => W enabled) + nop + nop + RVTEST_SIGUPD(x13,a4) + jal \ADDRESS // Test for execution, an instruction is placed at this address + nop + nop +jal \ADDRESS // Test for execution, an instruction is placed at this address + +.endm + +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 2 // START OF LOOP + + csrw pmpcfgi , x0 // Set all pmpcfg regs to zero (initial value) + .set pmpcfgi, pmpcfgi+2 // 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 + csrw pmpaddri, x0 // 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 + +// pmpcfg0 [7:0] value to configure address 0->RAM_LOCATION_FOR_TEST in TOR Mode with RWX enabled +#define PMPREGION1 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP0_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[23:16] value to configure address (TEST_FOR_EXECUTION)->(RETURN_INSTRUCTION) +// in TOR Mode with RX enabled =========> THIS IS OUR REGION UNDER OBSERVATION. +// THIS REGION CONSISTS OF ONLY ONE INSTRUCTION +#define PMPREGION2 ((((PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP2_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[39:32] value to configure address (RAM_LOCATION_FOR_TEST)->(rvtest_code_end) +// in TOR Mode with RW enabled +// ALSO NOTE THAT PMPREGION2 IS INSIDE THIS REGION, so this test will also check the priority order of PMP regions +#define PMPREGION3 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP4_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// pmpcfg0[47:40] value to configure address (rvtest_code_end)->(PMP_region_High) +// in TOR Mode with RWX enabled +#define PMPREGION4 ((((PMP_R|PMP_W|PMP_X|PMP_L|PMP_TOR)&0xFF) << PMP5_CFG_SHIFT)) +// ------------------------------------------------------------------------------------------------ +// MACROS TO DECLARE THE VALUES TO BE STORED IN PMPADDR registers +#define PMPADDRESS0 RAM_LOCATION_FOR_TEST // value to be loaded pmpaddr0 to declare region1 +// PMPADDRESS1 = value to be loaded pmpaddr1 to declare lower address of region2 +#define PMPADDRESS1 TEST_FOR_EXECUTION +// PMPADDRESS2 = value to be loaded pmpaddr2 to declare upper address of region2 +#define PMPADDRESS2 RETURN_INSTRUCTION +// PMPADDRESS3 = value to be loaded pmpaddr3 to declare lower address of region3 +#define PMPADDRESS3 RAM_LOCATION_FOR_TEST +// PMPADDRESS4 = value to be loaded pmpaddr4 to declare upper address of region3 +#define PMPADDRESS4 rvtest_code_end +// PMPADDRESS5 = value to be loaded pmpaddr5 to declare upper address of region4 +#define PMPADDRESS5 PMP_region_High + + /* SET UP DATA IN THE MEMORY */ + csrw satp, x0 // Disable Address Translation +// PMP Configuration +/* PMP is configure in the following order: +1. Address 0x8000 0000 to Address RAM_LOCATION_FOR_TEST => PMP TOR Region with RWX enabled. This region is the part of the code memory containing our code. For this purpose, pmpaddr0 has been given the value of RAM_LOCATION_FOR_TEST to declare the region from 0->RAM_LOCATION_FOR_TEST into a single PMP region. + +2. Address TEST_FOR_EXECUTION to Address RETURN_INSTRUCTION => PMP region under test. This region has been declared by entering TEST_FOR_EXECUTION into pmpaddr1 and rvtest_code_end into pmpaddr2. Then a PMP region is configure from pmpaddr2(RETURN_INSTRUCTION) to pmpaddr1(TEST_FOR_EXECUTION) into TOR mode by setting pmpcfg0[23:16]=PMPREGION2 + +3. Address RAM_LOCATION_FOR_TEST to Address rvtest_code_end => PMP region under test. This region has been declared by entering rvtest_code_end into pmpaddr4 and RAM_LOCATION_FOR_TEST into pmpaddr3. configure pmpaddr4(RAM_LOCATION_FOR_TEST) to pmpaddr5(rvtest_code_end) into TOR mode by setting pmpcfg1[15:8]=PMPREGION3 + +4. Address rvtest_code_end to address PMP_region_High => PMP TOR Region with RWX enabled. This region is the part of the code memory containing trap handler, epilogs, and other important macro definitions. For this purpose, configure pmpaddr4(rvtest_code_end) to pmpaddr5(PMP_region_High) into TOR mode by setting pmpcfg1[15:8]=PMPREGION4. This PMP Region is mandatory to access signature area in S,U mode */ + /* Assigning addresses to PMP address registers */ + LA(x4, PMPADDRESS0) // Value to be stored in pmpaddr0 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr0, x4 // Updated pmpaddr0 + nop // Added nop in case of trap + LA(x4, PMPADDRESS1) // Value to be stored in pmpaddr1 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr1, x4 // Updated pmpaddr1 + nop // Added nop in case of trap + LA(x4, PMPADDRESS2) // Value to be stored in pmpaddr2 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr2, x4 // Updated pmpaddr2 + nop // Added nop in case of trap + LA(x4, PMPADDRESS3) // Value to be stored in pmpaddr3 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr3, x4 // Updated pmpaddr3 + nop // Added nop in case of trap + LA(x4, PMPADDRESS4) // Value to be stored in pmpaddr4 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr4, x4 // Updated pmpaddr4 + nop // Added nop in case of trap + LA(x4, PMPADDRESS5) // Value to be stored in pmpaddr5 + srl x4, x4, PMP_SHIFT // Shift right by 2 times + csrw pmpaddr5, x4 // Updated pmpaddr5 + nop // Added nop in case of trap + /* Decalring pmp configuration register */ + LI(x4, PMPREGION1 | PMPREGION2 | PMPREGION3 | PMPREGION4) + // Value to be stored in pmpcfg register + csrs pmpcfg0, x4 // Updated pmpcfg0 + nop // Added nop in case of trap +//////////// ALL PMP REGIONS DECLARED ////////////////////////////////////////////// + /* VERIFICATION in M-mode */ + VERIFICATION_RWX TEST_FOR_EXECUTION +// VERIFICATION IN S-Mode + RVTEST_GOTO_LOWER_MODE Smode // SWITCH TO S-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + +/////////////////// Switch back to M-mode //////////////////////////////////////////// + RVTEST_GOTO_MMODE + csrr a4, mstatus // VERIFICATION of M-mode + nop // Added nop in case of trap +// VERIFICATION IN U-Mode + RVTEST_GOTO_LOWER_MODE Umode // SWITCH TO U-mode + VERIFICATION_RWX TEST_FOR_EXECUTION + j exit + +RAM_LOCATION_FOR_TEST: + .fill 3*(XLEN/32),4,0x12345678 +.align 3 + +TEST_FOR_EXECUTION: + addi x9,x9,0x01 // A TEST INSTRUCTION TO TEST THE EXECUTION CHECK ON PMP REGION + nop +RETURN_INSTRUCTION: + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + nop // Added nop in case of trap + jr ra +// AN instruction to bring back PC to the address where TEST_FOR_EXECUTION was called to check for execution. +exit: +#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 128*(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: +PMP_region_High: +RVMODEL_DATA_END \ No newline at end of file