112771Sqtt2@cornell.edu# See LICENSE for license details.
212771Sqtt2@cornell.edu
312771Sqtt2@cornell.edu#*****************************************************************************
412771Sqtt2@cornell.edu# dirty.S
512771Sqtt2@cornell.edu#-----------------------------------------------------------------------------
612771Sqtt2@cornell.edu#
712771Sqtt2@cornell.edu# Test VM referenced and dirty bits.
812771Sqtt2@cornell.edu#
912771Sqtt2@cornell.edu
1012771Sqtt2@cornell.edu#include "riscv_test.h"
1112771Sqtt2@cornell.edu#include "test_macros.h"
1212771Sqtt2@cornell.edu
1312771Sqtt2@cornell.eduRVTEST_RV64M
1412771Sqtt2@cornell.eduRVTEST_CODE_BEGIN
1512771Sqtt2@cornell.edu
1612771Sqtt2@cornell.edu  # Turn on VM
1712771Sqtt2@cornell.edu  li a0, (SATP_MODE & ~(SATP_MODE<<1)) * SATP_MODE_SV39
1812771Sqtt2@cornell.edu  la a1, page_table_1
1912771Sqtt2@cornell.edu  srl a1, a1, RISCV_PGSHIFT
2012771Sqtt2@cornell.edu  or a1, a1, a0
2112771Sqtt2@cornell.edu  csrw sptbr, a1
2212771Sqtt2@cornell.edu  sfence.vma
2312771Sqtt2@cornell.edu
2412771Sqtt2@cornell.edu  # Set up MPRV with MPP=S, so loads and stores use S-mode
2512771Sqtt2@cornell.edu  li a1, ((MSTATUS_MPP & ~(MSTATUS_MPP<<1)) * PRV_S) | MSTATUS_MPRV
2612771Sqtt2@cornell.edu  csrs mstatus, a1
2712771Sqtt2@cornell.edu
2812771Sqtt2@cornell.edu  # Try a faulting store to make sure dirty bit is not set
2912771Sqtt2@cornell.edu  li TESTNUM, 2
3012771Sqtt2@cornell.edu  li t2, 1
3112771Sqtt2@cornell.edu  sw t2, dummy - DRAM_BASE, a0
3212771Sqtt2@cornell.edu
3312771Sqtt2@cornell.edu  # Set SUM=1 so user memory access is permitted
3412771Sqtt2@cornell.edu  li TESTNUM, 3
3512771Sqtt2@cornell.edu  li a1, ((MSTATUS_MPP & ~(MSTATUS_MPP<<1)) * PRV_S) | MSTATUS_SUM
3612771Sqtt2@cornell.edu  csrs mstatus, a1
3712771Sqtt2@cornell.edu
3812771Sqtt2@cornell.edu  # Make sure SUM=1 works
3912771Sqtt2@cornell.edu  lw t0, dummy - DRAM_BASE
4012771Sqtt2@cornell.edu  bnez t0, die
4112771Sqtt2@cornell.edu
4212771Sqtt2@cornell.edu  # Try a non-faulting store to make sure dirty bit is set
4312771Sqtt2@cornell.edu  sw t2, dummy - DRAM_BASE, a0
4412771Sqtt2@cornell.edu
4512771Sqtt2@cornell.edu  # Make sure it succeeded
4612771Sqtt2@cornell.edu  lw t0, dummy - DRAM_BASE
4712771Sqtt2@cornell.edu  bne t0, t2, die
4812771Sqtt2@cornell.edu
4912771Sqtt2@cornell.edu  # Leave MPRV
5012771Sqtt2@cornell.edu  li t0, MSTATUS_MPRV
5112771Sqtt2@cornell.edu  csrc mstatus, t0
5212771Sqtt2@cornell.edu
5312771Sqtt2@cornell.edu  # Make sure D bit is set
5412771Sqtt2@cornell.edu  lw t0, page_table_1
5512771Sqtt2@cornell.edu  li a0, PTE_A | PTE_D
5612771Sqtt2@cornell.edu  and t0, t0, a0
5712771Sqtt2@cornell.edu  bne t0, a0, die
5812771Sqtt2@cornell.edu
5912771Sqtt2@cornell.edu  # Enter MPRV again
6012771Sqtt2@cornell.edu  li t0, MSTATUS_MPRV
6112771Sqtt2@cornell.edu  csrs mstatus, t0
6212771Sqtt2@cornell.edu
6312771Sqtt2@cornell.edu  # Make sure that superpage entries trap when PPN LSBs are set.
6412771Sqtt2@cornell.edu  li TESTNUM, 4
6512771Sqtt2@cornell.edu  lw a0, page_table_1 - DRAM_BASE
6612771Sqtt2@cornell.edu  or a0, a0, 1 << PTE_PPN_SHIFT
6712771Sqtt2@cornell.edu  sw a0, page_table_1 - DRAM_BASE, t0
6812771Sqtt2@cornell.edu  sfence.vma
6912771Sqtt2@cornell.edu  sw a0, page_table_1 - DRAM_BASE, t0
7012771Sqtt2@cornell.edu  j die
7112771Sqtt2@cornell.edu
7212771Sqtt2@cornell.edu  RVTEST_PASS
7312771Sqtt2@cornell.edu
7412771Sqtt2@cornell.edu  TEST_PASSFAIL
7512771Sqtt2@cornell.edu
7612771Sqtt2@cornell.edu  .align 2
7712771Sqtt2@cornell.edu  .global mtvec_handler
7812771Sqtt2@cornell.edumtvec_handler:
7912771Sqtt2@cornell.edu  csrr t0, mcause
8012771Sqtt2@cornell.edu  add t0, t0, -CAUSE_STORE_PAGE_FAULT
8112771Sqtt2@cornell.edu  bnez t0, die
8212771Sqtt2@cornell.edu
8312771Sqtt2@cornell.edu  li t1, 2
8412771Sqtt2@cornell.edu  bne TESTNUM, t1, 1f
8512771Sqtt2@cornell.edu  # Make sure D bit is clear
8612771Sqtt2@cornell.edu  lw t0, page_table_1
8712771Sqtt2@cornell.edu  and t1, t0, PTE_D
8812771Sqtt2@cornell.edu  bnez t1, die
8912771Sqtt2@cornell.eduskip:
9012771Sqtt2@cornell.edu  csrr t0, mepc
9112771Sqtt2@cornell.edu  add t0, t0, 4
9212771Sqtt2@cornell.edu  csrw mepc, t0
9312771Sqtt2@cornell.edu  mret
9412771Sqtt2@cornell.edu
9512771Sqtt2@cornell.edu1:
9612771Sqtt2@cornell.edu  li t1, 3
9712771Sqtt2@cornell.edu  bne TESTNUM, t1, 1f
9812771Sqtt2@cornell.edu  # The implementation doesn't appear to set D bits in HW.
9912771Sqtt2@cornell.edu  # Make sure the D bit really is clear.
10012771Sqtt2@cornell.edu  lw t0, page_table_1
10112771Sqtt2@cornell.edu  and t1, t0, PTE_D
10212771Sqtt2@cornell.edu  bnez t1, die
10312771Sqtt2@cornell.edu  # Set the D bit.
10412771Sqtt2@cornell.edu  or t0, t0, PTE_D
10512771Sqtt2@cornell.edu  sw t0, page_table_1, t1
10612771Sqtt2@cornell.edu  sfence.vma
10712771Sqtt2@cornell.edu  mret
10812771Sqtt2@cornell.edu
10912771Sqtt2@cornell.edu1:
11012771Sqtt2@cornell.edu  li t1, 4
11112771Sqtt2@cornell.edu  bne TESTNUM, t1, 1f
11212771Sqtt2@cornell.edu  j pass
11312771Sqtt2@cornell.edu
11412771Sqtt2@cornell.edu1:
11512771Sqtt2@cornell.edudie:
11612771Sqtt2@cornell.edu  RVTEST_FAIL
11712771Sqtt2@cornell.edu
11812771Sqtt2@cornell.eduRVTEST_CODE_END
11912771Sqtt2@cornell.edu
12012771Sqtt2@cornell.edu  .data
12112771Sqtt2@cornell.eduRVTEST_DATA_BEGIN
12212771Sqtt2@cornell.edu
12312771Sqtt2@cornell.edu  TEST_DATA
12412771Sqtt2@cornell.edu
12512771Sqtt2@cornell.edu.align 12
12612771Sqtt2@cornell.edupage_table_1: .dword (DRAM_BASE/RISCV_PGSIZE << PTE_PPN_SHIFT) | PTE_V | PTE_U | PTE_R | PTE_W | PTE_X | PTE_A
12712771Sqtt2@cornell.edudummy: .dword 0
12812771Sqtt2@cornell.edu
12912771Sqtt2@cornell.eduRVTEST_DATA_END
130