diff options
-rw-r--r-- | isa/rv64si/Makefrag | 1 | ||||
-rw-r--r-- | isa/rv64si/napot.S | 172 |
2 files changed, 173 insertions, 0 deletions
diff --git a/isa/rv64si/Makefrag b/isa/rv64si/Makefrag index 604005c..dbd1d56 100644 --- a/isa/rv64si/Makefrag +++ b/isa/rv64si/Makefrag @@ -7,6 +7,7 @@ rv64si_sc_tests = \ dirty \ icache-alias \ ma_fetch \ + napot \ scall \ wfi \ sbreak \ diff --git a/isa/rv64si/napot.S b/isa/rv64si/napot.S new file mode 100644 index 0000000..3d62e6c --- /dev/null +++ b/isa/rv64si/napot.S @@ -0,0 +1,172 @@ +# See LICENSE for license details. + +#***************************************************************************** +# napot.S +#----------------------------------------------------------------------------- +# +# Test Svnapot +# + +#include "riscv_test.h" +#include "test_macros.h" + +#if (DRAM_BASE >> 30 << 30) != DRAM_BASE +# error This test requires DRAM_BASE be SV39 superpage-aligned +#endif + +#if __riscv_xlen != 64 +# error This test requires RV64 +#endif + +RVTEST_RV64M +RVTEST_CODE_BEGIN + + # Construct the page table + +#define MY_VA 0x40201010 + # VPN 2 == VPN 1 == VPN 0 == 0x1 + # Page offset == 0x10 + + #### + + # Level 0 PTE contents + + # PPN + la a0, my_data + srl a0, a0, 12 + + # adjust the PPN to be in NAPOT form + li a1, ~0xF + and a0, a0, a1 + ori a0, a0, 0x8 + + # attributes + sll a0, a0, PTE_PPN_SHIFT + li a1, PTE_V | PTE_U | PTE_R | PTE_W | PTE_X | PTE_A | PTE_D | PTE_N + or a0, a0, a1 + + # Level 0 PTE address + la a1, page_table + addi a1, a1, ((MY_VA >> 12) & 0x1FF) * 8 + + # Level 0 PTE store + sd a0, (a1) + + #### + + # Level 1 PTE contents + la a0, page_table + srl a0, a0, 12 + sll a0, a0, PTE_PPN_SHIFT + li a1, PTE_V | PTE_U + or a0, a0, a1 + + # Level 1 PTE address + la a1, page_table + addi a1, a1, ((MY_VA >> 21) & 0x1FF) * 8 + li a2, 1 << 12 + add a1, a1, a2 + + # Level 1 PTE store + sd a0, (a1) + + #### + + # Level 2 PTE contents + la a0, page_table + li a1, 1 << 12 + add a0, a0, a1 + srl a0, a0, 12 + sll a0, a0, PTE_PPN_SHIFT + li a1, PTE_V | PTE_U + or a0, a0, a1 + + # Level 2 PTE address + la a1, page_table + addi a1, a1, ((MY_VA >> 30) & 0x1FF) * 8 + li a2, 2 << 12 + add a1, a1, a2 + + # Level 2 PTE store + sd a0, (a1) + + #### + + # Do a load from the PA that would be written if the PTE were misinterpreted as non-NAPOT + la a0, my_data + li a1, ~0xFFFF + and a0, a0, a1 + li a1, 0x8000 | (MY_VA & 0xFFF) + or a3, a0, a1 + li a1, 0 + sw a1, (a3) + + #### + li TESTNUM, 1 + + ## Turn on VM + la a1, page_table + li a2, 2 << 12 + add a1, a1, a2 + srl a1, a1, 12 + li a0, (SATP_MODE & ~(SATP_MODE<<1)) * SATP_MODE_SV39 + or a0, a0, a1 + csrw satp, a0 + sfence.vma + + # Set up MPRV with MPP=S and SUM=1, so loads and stores use S-mode and S can access U pages + li a1, ((MSTATUS_MPP & ~(MSTATUS_MPP<<1)) * PRV_S) | MSTATUS_MPRV | MSTATUS_SUM + csrs mstatus, a1 + + # Do a store to MY_VA + li a0, MY_VA + li a1, 42 + sw a1, (a0) + + # Clear MPRV + li a1, MSTATUS_MPRV + csrc mstatus, a1 + + # Do a load from the PA that would be written if the PTE were misinterpreted as non-NAPOT + lw a1, (a3) + + # Check the result + li a0, 42 + beq a1, a0, die + + # Do a load from the PA for MY_VA + la a0, my_data + li a1, MY_VA & 0xFFFF + add a0, a0, a1 + lw a1, (a0) + li a2, 42 + + # Check the result + bne a1, a2, die + + #### + + RVTEST_PASS + + TEST_PASSFAIL + + .align 2 + .global mtvec_handler +mtvec_handler: +die: + RVTEST_FAIL + +RVTEST_CODE_END + + .data +RVTEST_DATA_BEGIN + + TEST_DATA + +.align 20 +page_table: .dword 0 + +.align 20 +my_data: .dword 0 + +RVTEST_DATA_END |