diff options
-rw-r--r-- | isa/rv64si/csr.S | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/isa/rv64si/csr.S b/isa/rv64si/csr.S index 26031bc..846a483 100644 --- a/isa/rv64si/csr.S +++ b/isa/rv64si/csr.S @@ -11,6 +11,11 @@ RVTEST_RV64S RVTEST_CODE_BEGIN + # Set up evec in case we trap. + la t0, evec + csrw evec, t0 + csrwi count, 0 + csrwi sup0, 3 TEST_CASE( 2, a0, 3, csrr a0, sup0); TEST_CASE( 3, a1, 3, csrrci a1, sup0, 1); @@ -21,8 +26,55 @@ RVTEST_CODE_BEGIN TEST_CASE( 8, a0, 0xbad0000, li a0, 0x000beef; csrrs a0, sup0, a0); TEST_CASE( 9, a0, 0xbadbeef, csrr a0, sup0); + # Make sure writing the cycle counter causes an exception. + TEST_CASE(10, a0, 255, li a0, 255; csrrw a0, cycle, x0); + + # Make sure reading status in user mode causes an exception. + csrci status, SR_S|SR_PS + TEST_CASE(11, a0, 255, li a0, 255; csrr a0, status); + + # Make sure rdcycle is legal in user mode. + TEST_CASE(12, x0, 0, rdcycle a0) + + # Exit by doing a syscall. + TEST_CASE(13, x0, 1, scall) + + # We should only fall through to this if scall failed. TEST_PASSFAIL +evec: + # Trapping on tests 10, 11, and 13 is usually good news. + # Note that since the test didn't finished, TESTNUM is smaller by 1. + li t0, 9 + beq TESTNUM, t0, privileged + li t0, 10 + beq TESTNUM, t0, privileged + li t0, 12 + beq TESTNUM, t0, syscall + + # Trapping on other tests is bad news. + j fail + +privileged: + # Make sure CAUSE indicates a lack of privilege. + csrr t0, cause + li t1, CAUSE_PRIVILEGED_INSTRUCTION + bne t0, t1, fail + # Return to user mode, but skip the trapping instruction. + csrr t0, epc + addi t0, t0, 4 + csrw epc, t0 + sret + +syscall: + # Make sure CAUSE indicates a syscall. + csrr t0, cause + li t1, CAUSE_SYSCALL + bne t0, t1, fail + + # We're done. + j pass + RVTEST_CODE_END .data |