From 32b8cb74be692b661bc77191b4a7fc6f2a2e33e5 Mon Sep 17 00:00:00 2001 From: Kristine Dosvik Date: Fri, 12 Jan 2024 08:20:52 +0100 Subject: [PATCH 1/4] added mepc minhv misalignement test Signed-off-by: Kristine Dosvik --- .../Simulation/interrupts/CV32E40SX_CLIC.csv | 2 + .../Simulation/interrupts/CV32E40SX_CLIC.json | 11 +++ .../Simulation/interrupts/CV32E40SX_CLIC.xlsx | Bin 38973 -> 39368 bytes cv32e40s/tests/programs/custom/clic/clic.c | 88 +++++++++++++++++- 4 files changed, 100 insertions(+), 1 deletion(-) diff --git a/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.csv b/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.csv index 5c9e6559a6..9d66f21808 100644 --- a/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.csv +++ b/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.csv @@ -305,6 +305,8 @@ Added assertion for formal coverage",Assertion Check,"ENV capability, not specif [clic_assert].a_mret_mie_mpie" CLIC 0.9-draft 4/11/2023,Return from handler,mret,"""If the hart is currently running at some privilege mode x, an MRET or SRET instruction that changes the privilege mode to a mode less privileged than x also sets xintthresh = 0.""","Use ""mret"" to enter U-mode. Check that ""mintthresh"" is written to zero upon executing the mret.",Assertion Check,"ENV capability, not specific test",Assertion Coverage,A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.clic_assert_i.gen_clic_assertions.a_mret_umode_clear_mintthresh +CLIC 0.9-draft 12/19/2023,Return from handler,mret minhv=1,"""If the xinhv bit is set, the hart resumes the trap handler memory access to retrieve the function pointer for vectoring with permissions corresponding to the previous privilege mode. The trap handler function address is obtained from the current privilege mode’s xepc with the low bits of the address cleared to force the access to be naturally aligned to an XLEN/8-byte table entry.""","Run mret when minhv is set. Check that the next instruction to be executed is the address pointed to by the mepc, and check that mepc gets naturally aligned to XLEN/8 byte.",Self Checking Test,Directed Self-Checking,Testcase,"DTC: clic :: mret_with_minhv +clic ::mret_with_minhv_and_unaligned_mepc" CLIC 0.9-draft 4/11/2023,Return from debug mode,dret,"""Likewise, if the RISC-V debug specification is implemented and the hart is currently running at some privilege mode x, a DRET instruction that changes the privilege mode to a mode less privileged than x also sets xintthresh = 0.""","Use ""dret"" to enter U-mode. Check that ""mintthresh"" is written to zero upon executing the dret.",Assertion Check,"ENV capability, not specific test",Assertion Coverage,Requirement removed CLIC 8675ec,WFI,Wakeup conditions,"A pending-and-enabled interrupt i causes the hart to resume execution if interrupt i diff --git a/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.json b/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.json index ed0491458a..2a1dc8b2e2 100644 --- a/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.json +++ b/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.json @@ -791,6 +791,17 @@ "Coverage Method": "Assertion Coverage", "Link to Coverage": "A: uvmt_cv32e40s_tb.dut_wrap.cv32e40s_wrapper_i.core_i.clic_assert_i.gen_clic_assertions.a_mret_umode_clear_mintthresh" }, + { + "Requirement Location": "CLIC 0.9-draft 12/19/2023", + "Feature": "Return from handler", + "Sub Feature": "mret minhv=1", + "Feature Description": "\"If the xinhv bit is set, the hart resumes the trap handler memory access to retrieve the function pointer for vectoring with permissions corresponding to the previous privilege mode. The trap handler function address is obtained from the current privilege mode\u2019s xepc with the low bits of the address cleared to force the access to be naturally aligned to an XLEN/8-byte table entry.\"", + "Verification Goal": "Run mret when minhv is set. Check that the next instruction to be executed is the address pointed to by the mepc, and check that mepc gets naturally aligned to XLEN/8 byte.", + "Pass/Fail Criteria": "Self Checking Test", + "Test Type": "Directed Self-Checking", + "Coverage Method": "Testcase", + "Link to Coverage": "DTC: clic :: mret_with_minhv\nclic ::mret_with_minhv_and_unaligned_mepc" + }, { "Requirement Location": "CLIC 0.9-draft 4/11/2023", "Feature": "Return from debug mode", diff --git a/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.xlsx b/cv32e40s/docs/VerifPlans/Simulation/interrupts/CV32E40SX_CLIC.xlsx index 9af84b66045a780ba6fbe47cbbc0a8d4896cd9b4..433283b78d26ec29fe7d87b5bdab8e4699295ed1 100644 GIT binary patch delta 23809 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 diff --git a/cv32e40s/tests/programs/custom/clic/clic.c b/cv32e40s/tests/programs/custom/clic/clic.c index 2a8e908972..e3db475f68 100644 --- a/cv32e40s/tests/programs/custom/clic/clic.c +++ b/cv32e40s/tests/programs/custom/clic/clic.c @@ -35,7 +35,7 @@ // MUST be 31 or less (bit position-1 in result array determines test pass/fail // status, thus we are limited to 31 tests with this construct. -#define NUM_TESTS 24 +#define NUM_TESTS 25 // Set which test index to start testing at (for quickly running specific tests during development) #define START_TEST_IDX 0 // Abort test at first self-check fail, useful for debugging. @@ -220,6 +220,8 @@ volatile uint32_t * volatile g_asserted_irq_lvl; volatile uint32_t * volatile g_irq_handler_reported_error; volatile uint32_t * volatile g_mepc_triggered; volatile uint32_t * volatile g_recovery_enable; +volatile uint32_t * volatile g_checker; + // --------------------------------------------------------------- // Test prototypes - should match // uint32_t (uint32_t index, uint8_t report_name) @@ -250,6 +252,7 @@ uint32_t mret_with_minhv(uint32_t index, uint8_t report_name); uint32_t mintthresh_higher(uint32_t index, uint8_t report_name); uint32_t mintthresh_lower(uint32_t index, uint8_t report_name); uint32_t mintthresh_equal(uint32_t index, uint8_t report_name); +uint32_t mret_with_minhv_and_unaligned_mepc(uint32_t index, uint8_t report_name); // --------------------------------------------------------------- // Generic test template: @@ -377,6 +380,7 @@ int main(int argc, char **argv){ g_irq_handler_reported_error = calloc(1, sizeof(uint32_t)); g_mepc_triggered = calloc(1, sizeof(uint32_t)); g_recovery_enable = calloc(1, sizeof(uint32_t)); + g_checker = calloc(1, sizeof(uint32_t)); // Add function pointers to new tests here tests[0] = mcause_mstatus_mirror_init; @@ -403,6 +407,7 @@ int main(int argc, char **argv){ tests[21] = mintthresh_lower; tests[22] = mintthresh_higher; tests[23] = mintthresh_equal; + tests[24] = mret_with_minhv_and_unaligned_mepc; // Run all tests in list above cvprintf(V_LOW, "\nCLIC Test start\n\n"); @@ -420,6 +425,7 @@ int main(int argc, char **argv){ free((void *)g_irq_handler_reported_error); free((void *)g_mepc_triggered ); free((void *)g_recovery_enable ); + free((void *)g_checker ); return retval; // Nonzero for failing tests } @@ -3052,6 +3058,7 @@ uint32_t mret_with_minhv(uint32_t index, uint8_t report_name) { mret addi %[check_val], zero, 42 jal zero, 2f + .align 4 1: .word(2f) .space 0x100, 0x0 2: addi %[result], %[check_val], 0 @@ -3326,6 +3333,75 @@ uint32_t mintthresh_equal(uint32_t index, uint8_t report_name) { return 0; } +// This function should cover corner cases encountered by broken code during +// test development that made the ISS and RTL deviate. After resolving issues, +// leave this function in place to ensure that these issues do not return. +uint32_t mret_with_minhv_and_unaligned_mepc(uint32_t index, uint8_t report_name) { + volatile uint8_t test_fail = 0; + volatile mcause_t mcause = { 0 }; + volatile uint32_t result = 0; + volatile uint32_t all_set = 0xFFFFFFFF; + + SET_FUNC_INFO + if (report_name) { + cvprintf(V_LOW, "\"%s\"", name); + return 0; + } + + *g_special_handler_idx = 7; + + __asm__ volatile ( R"( + csrrs %[rd1], mcause, zero + )":[rd1] "=r"(mcause.raw) + ::); + + mcause.clic.minhv = 1; + mcause.clic.mpp = 0x3; + mcause.clic.mpie = 0; + + *g_checker = 0; + + __asm__ volatile (R"( + csrrw zero, mcause, %[mcause] + la t0, 1f + lw t1, (t0) + csrrw zero, mepc, t0 + # Store instruction mepc aims to execute in mscratch register. + csrrw zero, mscratch, t1 + mret + + # Write 0xFFFF_FFFF to where g_checker points. + lw t2, g_checker + sw %[all_set], 0(t2) + + jal zero, 2f + .align 4 + .byte(0xFF) + .byte(0xFF) + 1: .word(2f) + .space 0x100, 0x0 + + 2: + # Fetch the value g_checker points to. + lw t2, g_checker + lw t2, 0(t2) + + addi %[result], t2, 0 + + )":[result] "=r"(result) + :[mcause] "r"(mcause.raw), [all_set] "r"(all_set) + :"t0", "t1", "t2"); + + test_fail += (result != 0); + + if (test_fail) { + cvprintf(V_LOW, "\nTest: \"%s\" FAIL!\n", name); + return index + 1; + } + cvprintf(V_MEDIUM, "\nTest: \"%s\" OK!\n", name); + return 0; +} + // ----------------------------------------------------------------------------- // Note that the following interrupt/exception handler is not generic and specific // to this test. @@ -3408,6 +3484,16 @@ __attribute__((interrupt("machine"))) void u_sw_irq_handler(void) { case 6: *g_irq_handler_reported_error = 1; vp_assert_irq(0, 0); + *g_special_handler_idx = 0; + return; + break; + case 7: + *g_special_handler_idx = 0; + //Write mscratch value to mepc + __asm__ volatile ( R"( + csrrw t0, mscratch, zero + csrrw zero, mepc, t0 + )"::: "t0"); return; break; } From abc843bc4bc88f917bf559574a92eb93e53901ae Mon Sep 17 00:00:00 2001 From: Kristine Dosvik Date: Fri, 12 Jan 2024 08:25:31 +0100 Subject: [PATCH 2/4] remove unnecessary comment Signed-off-by: Kristine Dosvik --- cv32e40s/tests/programs/custom/clic/clic.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cv32e40s/tests/programs/custom/clic/clic.c b/cv32e40s/tests/programs/custom/clic/clic.c index e3db475f68..3873b4c864 100644 --- a/cv32e40s/tests/programs/custom/clic/clic.c +++ b/cv32e40s/tests/programs/custom/clic/clic.c @@ -3333,9 +3333,7 @@ uint32_t mintthresh_equal(uint32_t index, uint8_t report_name) { return 0; } -// This function should cover corner cases encountered by broken code during -// test development that made the ISS and RTL deviate. After resolving issues, -// leave this function in place to ensure that these issues do not return. + uint32_t mret_with_minhv_and_unaligned_mepc(uint32_t index, uint8_t report_name) { volatile uint8_t test_fail = 0; volatile mcause_t mcause = { 0 }; From 4feff72978e3df1764ea71ab3753c2087e5e6480 Mon Sep 17 00:00:00 2001 From: Kristine Dosvik Date: Fri, 12 Jan 2024 10:32:45 +0100 Subject: [PATCH 3/4] Correct indent Signed-off-by: Kristine Dosvik --- cv32e40s/tests/programs/custom/clic/clic.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/cv32e40s/tests/programs/custom/clic/clic.c b/cv32e40s/tests/programs/custom/clic/clic.c index 3873b4c864..3659b23e86 100644 --- a/cv32e40s/tests/programs/custom/clic/clic.c +++ b/cv32e40s/tests/programs/custom/clic/clic.c @@ -3486,14 +3486,14 @@ __attribute__((interrupt("machine"))) void u_sw_irq_handler(void) { return; break; case 7: - *g_special_handler_idx = 0; - //Write mscratch value to mepc - __asm__ volatile ( R"( - csrrw t0, mscratch, zero - csrrw zero, mepc, t0 - )"::: "t0"); - return; - break; + *g_special_handler_idx = 0; + //Write mscratch value to mepc + __asm__ volatile ( R"( + csrrw t0, mscratch, zero + csrrw zero, mepc, t0 + )"::: "t0"); + return; + break; } if (mcause.clic.interrupt == 0 && mcause.clic.exccode == 2) { From 4a672547e8cd735a05ca417cbdae751887adbaca Mon Sep 17 00:00:00 2001 From: Kristine Dosvik Date: Fri, 12 Jan 2024 10:38:09 +0100 Subject: [PATCH 4/4] correct indent again Signed-off-by: Kristine Dosvik --- cv32e40s/tests/programs/custom/clic/clic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cv32e40s/tests/programs/custom/clic/clic.c b/cv32e40s/tests/programs/custom/clic/clic.c index 3659b23e86..543dccf2cf 100644 --- a/cv32e40s/tests/programs/custom/clic/clic.c +++ b/cv32e40s/tests/programs/custom/clic/clic.c @@ -3492,8 +3492,8 @@ __attribute__((interrupt("machine"))) void u_sw_irq_handler(void) { csrrw t0, mscratch, zero csrrw zero, mepc, t0 )"::: "t0"); - return; - break; + return; + break; } if (mcause.clic.interrupt == 0 && mcause.clic.exccode == 2) {