Separate page faults from physical memory access exceptions
[riscv-tests.git] / isa / rv64si / dirty.S
index 78e333b62995714cccf891d4c5013a3fcf301840..86e4656059fb8ae395607c55c8c281a096d5bb07 100644 (file)
@@ -14,35 +14,40 @@ RVTEST_RV64M
 RVTEST_CODE_BEGIN
 
   # Turn on VM with superpage identity mapping
-  la a1, handler
-  csrw stvec, a1
+  li a0, (SPTBR_MODE & ~(SPTBR_MODE<<1)) * SPTBR_MODE_SV39
   la a1, page_table_1
+  srl a1, a1, RISCV_PGSHIFT
+  or a1, a1, a0
+  la a2, page_table_2
+  srl a2, a2, RISCV_PGSHIFT
+  or a2, a2, a0
   csrw sptbr, a1
-  sfence.vm
-  li a1, (MSTATUS_VM & ~(MSTATUS_VM<<1)) * VM_SV43
+  sfence.vma
+  li a1, ((MSTATUS_MPP & ~(MSTATUS_MPP<<1)) * PRV_S) | MSTATUS_SUM
   csrs mstatus, a1
-  la a1, 1f
+  la a1, 1f - DRAM_BASE
   csrw mepc, a1
-  eret
+  la a1, stvec_handler - DRAM_BASE
+  csrw stvec, a1
+  mret
 1:
 
   # Try a faulting store to make sure dirty bit is not set
   li TESTNUM, 2
   li t0, 1
-  sd t0, dummy, t1
+  sw t0, dummy, t1
 
   # Load new page table
   li TESTNUM, 3
-  la t0, page_table_2
-  csrw sptbr, t0
-  sfence.vm
+  csrw sptbr, a2
+  sfence.vma
 
   # Try a non-faulting store to make sure dirty bit is set
-  sd t0, dummy, t1
+  sw t0, dummy, t1
 
-  # Make sure R and D bits are set
+  # Make sure D bit is set
   lw t0, page_table_2
-  li t1, PTE_R | PTE_D
+  li t1, PTE_A | PTE_D
   and t0, t0, t1
   bne t0, t1, die
   
@@ -50,35 +55,49 @@ RVTEST_CODE_BEGIN
 
   TEST_PASSFAIL
 
-handler:
+  .align 2
+stvec_handler:
   csrr t0, scause
+  add t0, t0, -CAUSE_STORE_PAGE_FAULT
+  bnez t0, die
+
   li t1, 2
   bne TESTNUM, t1, 1f
-  # Make sure R bit is set
-  lw t0, page_table_1
-  li t1, PTE_R
-  and t0, t0, t1
-  bne t0, t1, die
-
   # Make sure D bit is clear
   lw t0, page_table_1
-  li t1, PTE_D
-  and t0, t0, t1
-  beq t0, t1, die
-
+  and t1, t0, PTE_D
+  bnez t1, die
+skip:
   csrr t0, sepc
   add t0, t0, 4
   csrw sepc, t0
   sret
 
+1:
+  li t1, 3
+  bne TESTNUM, t1, 1f
+  # The implementation doesn't appear to set D bits in HW.  Skip the test,
+  # after making sure the D bit is clear.
+  lw t0, page_table_2
+  and t1, t0, PTE_D
+  bnez t1, die
+  j pass
+
+1:
 die:
   RVTEST_FAIL
 
-.data
-.align 13
-page_table_1: .dword PTE_V | PTE_SX | PTE_SR
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+  TEST_DATA
+
+.align 12
+page_table_1: .dword (DRAM_BASE/RISCV_PGSIZE << PTE_PPN_SHIFT) | PTE_V | PTE_U | PTE_R | PTE_X | PTE_A
 dummy: .dword 0
-.align 13
-page_table_2: .dword PTE_V | PTE_SX | PTE_SR | PTE_SW
+.align 12
+page_table_2: .dword (DRAM_BASE/RISCV_PGSIZE << PTE_PPN_SHIFT) | PTE_V | PTE_U | PTE_R | PTE_X | PTE_W | PTE_A
 
-RVTEST_CODE_END
+RVTEST_DATA_END