renamed virt mem tests to include svadu

This commit is contained in:
Kip Macsai-Goren 2023-04-11 18:46:37 -07:00
parent cf50d04a21
commit 7d9ebf56ed
6 changed files with 915 additions and 0 deletions

View File

@ -0,0 +1,47 @@
0000000b
beef0055
beef0033
beef0077
beef0099
beef0440
11100393
00008067
beef0055
beef0099
0000000d
00000bad
0000000f
0000000d
00000bad
0000000d
00000bad
00000111
00000009
0000000d
00000bad
0000000c
00000bad
beef0033
00000008
beef0077
0000000c
00000bad
0000000d
00000bad
0000000d
00000bad
beef0440
beef0110
0000000f
0000000c
00000bad
beef0770 # Test 8.3.1.3.5: check successful read/write when A=0 and SVADU=1
beef0aa0 # Test 8.3.1.3.6: check successful read/write when D=0 and SVADU=1
beef0077 # Test 12.3.1.4.1: successful read back of saved value with new memory mapping
00000009 # Test 12.3.1.5.1: ecall from going to m mode from s mode
00000000 # previous value of mprv before being set
beef0099 # Read success from translated address when mprv=1, mpp=S and priv mode = m
0000000b # Test 12.3.1.5.2: ecall from going to S mode from m mode
00000009 # ecall from going straight back to m mode to access mstatus
00000000 # previous zeroed out value of mprv
0000000b # ecall from terminating tests in m mode

View File

@ -0,0 +1,201 @@
///////////////////////////////////////////
//
// WALLY-MMU
//
// Author: David_Harris@hmc.edu and Kip Macsai-Goren <kmacsaigoren@g.hmc.edu>
//
// Created 2021-06-15
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
///////////////////////////////////////////
#include "WALLY-TEST-LIB-32.h"
RVTEST_ISA("RV32I")
RVTEST_CASE(0,"//check ISA:=regex(.*32.*);check ISA:=regex(.*I.*); def Drvtest_mtrap_routine=True;def TEST_CASE_1=True; def NO_SAIL=True;",mmu)
INIT_TESTS
TRAP_HANDLER m
j run_test_loop // begin test loop/table tests instead of executing inline code.
INIT_TEST_TABLE
TEST_STACK_AND_DATA
.align 2
test_cases:
# ---------------------------------------------------------------------------------------------
# Test Contents
#
# Here is where the actual tests are held, or rather, what the actual tests do.
# each entry consists of 3 values that will be read in as follows:
#
# '.4byte [x28 Value], [x29 Value], [x30 value]'
# or
# '.4byte [address], [value], [test type]'
#
# The encoding for x30 test type values can be found in the test handler in the framework file
#
# ---------------------------------------------------------------------------------------------
# =========== test 8.3.1.1 Page Table Translation ===========
# test 8.3.1.1.1 write page tables / entries to phyiscal memory
# sv32 Page table (See Figure 12.12***):
# Level 1 page table, situated at 0x8000D000
.4byte 0x8000D000, 0x20004C01, write32_test # points to level 0 page table A
.4byte 0x8000D004, 0x200000CB, write32_test # Vaddr 0x400000 Paddr 0x80000000: aligned megapage, W=0, used for execute tests
.4byte 0x8000D008, 0x20005401, write32_test # points to level 0 page table B
.4byte 0x8000D00C, 0x000800C7, write32_test # Vaddr 0xC00000: misaligned megapage
.4byte 0x8000D800, 0x200000CF, write32_test # Vaddr 0x80000000 Paddr 0x80000000: aligned megapage (program and data memory)
.4byte 0x8000D804, 0x200000DF, write32_test # Vaddr 0x80400000 Paddr 0x80000000: aligned megapage, U=1 (aliased with program and data memory)
# Level 0 page table A
.4byte 0x80013000, 0x20007001, write32_test # Vaddr 0x0000: bad PTE points to level -1 table
.4byte 0x80013004, 0x202000DF, write32_test # Vaddr 0x1000 Paddr 0x80800000: aligned kilopage, U=1
.4byte 0x80013008, 0x202010D5, write32_test # Vaddr 0x2000: pad PTE has W but not R
.4byte 0x8001300C, 0x20200817, write32_test # Vaddr 0x3000: A=0, should cause read fault
.4byte 0x80013010, 0x20200C57, write32_test # Vaddr 0x4000: D=0, should cause write fault
.4byte 0x80013014, 0x202014C9, write32_test # Vaddr 0x5000 Paddr 80805000: aligned kilopage, W=R=0
.4byte 0x80013018, 0x0, write32_test # Vaddr 0x6000: invalid page
# Level 0 page table B
.4byte 0x80015FFC, 0x202004C7, write32_test # Vaddr 0xBFF000 Paddr 0x80801000: aligned kilopage with X=0, U=0
# second page table to check context switches with satp
.4byte 0x8000F000, 0x200000CF, write32_test # Vaddr 0x0 Paddr 0x80000000: aligned megapage
.4byte 0x8000F800, 0x200000CF, write32_test # Vaddr 0x80000000 Paddr 0x80000000: aligned megapage (program and data memory)
# test 8.3.1.1.2 write values to Paddrs in each page
# each of these values is used for 8.3.1.1.3 and some other tests, specified in the comments.
# when a test is supposed to fault, nothing is written into where it'll be reading/executing since it should fault before getting there.
.4byte 0x800AAAA8, 0xBEEF0055, write32_test # 8.3.1.1.4 megapage
.4byte 0x800FFAC0, 0xBEEF0033, write32_test # 8.3.1.3.2
.4byte 0x800E3130, 0xBEEF0077, write32_test # 8.3.1.3.2
.4byte 0x808017E0, 0xBEEF0099, write32_test # 8.3.1.1.4 kilopage
.4byte 0x80805EA0, 0xBEEF0440, write32_test # 8.3.1.3.3
.4byte 0x8000FFA0, 0x11100393, write32_test # write executable code for "li x7, 0x111; ret" to executable region.
.4byte 0x8000FFA4, 0x00008067, write32_test # Used for 8.3.1.3.1, 8.3.1.3.2
# test 8.3.1.1.3 read values back from Paddrs without translation (this also verifies the previous test)
.4byte 0x0, 0x0, goto_baremetal # satp.MODE = baremetal / no translation.
.4byte 0x0, 0x0, goto_s_mode # change to S mode, 0xb written to output
.4byte 0x800AAAA8, 0xBEEF0055, read32_test
.4byte 0x800FFAC0, 0xBEEF0033, read32_test
.4byte 0x800E3130, 0xBEEF0077, read32_test
.4byte 0x808017E0, 0xBEEF0099, read32_test
.4byte 0x80805EA0, 0xBEEF0440, read32_test
.4byte 0x8000FFA0, 0x11100393, read32_test
.4byte 0x8000FFA4, 0x00008067, read32_test
# test 8.3.1.1.4 check translation works in sv48, read the same values from previous tests, this time with Vaddrs
.4byte 0x8000D, 0x0, goto_sv32 # satp.MODE = sv32, Nothing written to output
.4byte 0x4AAAA8, 0xBEEF0055, read32_test # megapage at Vaddr 0x400000, Paddr 0x80000000
.4byte 0xBFF7E0, 0xBEEF0099, read32_test # kilopage at Vaddr 0xBFF000, Paddr 0x80201000
# =========== test 8.3.1.2 page fault tests ===========
# test 8.3.1.2.1 load page fault if upper bits of Vaddr are not the same
# Not tested in rv32/sv32
# test 8.3.1.2.2 load page fault when reading an address where the valid flag is zero
.4byte 0x6000, 0x0, read32_test
# test 8.3.1.2.3 store page fault if PTE has W and ~R flags set
.4byte 0x2000, 0x0, write32_test
# test 8.3.1.2.4 Fault if last level PTE is a pointer
.4byte 0x0200, 0x0, read32_test
# test 8.3.1.2.5 load page fault on misaligned pages
.4byte 0xC00000, 0x0, read32_test # misaligned megapage
# =========== test 8.3.1.3 PTE Protection flags ===========
# test 8.3.1.3.1 User flag == 0
# *** reads on pages with U=0 already tested in 8.3.1.1.4
.4byte 0x40FFA0, 0x111, executable_test # fetch success when U=0, priv=S
.4byte 0x80400000, 0x1, goto_u_mode # go to U mode, return to VPN 0x80400000 where PTE.U = 1. 0x9 written to output
.4byte 0xBFFC80, 0xBEEF0550, read32_test # load page fault when U=0, priv=U
.4byte 0x40FFA0, 0xbad, executable_test # instr page fault when U=0, priv=U
# test 8.3.1.3.2 User flag == 1
.4byte 0x804FFAC0, 0xBEEF0033, read32_test # read success when U=1, priv=U
.4byte 0x80000000, 0x1, goto_s_mode # go back to S mode, return to VPN 0x80000000 where PTE.U = 0. 0x8 written to output
.4byte 0x0, 0x3, write_mxr_sum # set sstatus.[MXR, SUM] = 11
.4byte 0x804E3130, 0xBEEF0077, read32_test # read success when U=1, priv=S, sstatus.SUM=1
.4byte 0x8040FFA0, 0xbad, executable_test # instr page fault when U=1, priv=S (with any sstatus.SUM)
.4byte 0x0, 0x2, write_mxr_sum # set sstatus.[MXR, SUM] = 10.
.4byte 0x804FFAC0, 0xBEEF0033, read32_test # load page fault when U-1, priv=S, sstatus.SUM=0
# test 8.3.1.3.3 Read flag
# *** reads on pages with R=1 already tested in 8.3.1.1.4
.4byte 0x0, 0x1, write_mxr_sum # set sstatus.[MXR, SUM] = 01.
.4byte 0x5EA0, 0xBEEF0440, read32_test # load page fault when R=0, sstatus.MXR=0
.4byte 0x0, 0x3, write_mxr_sum # set sstatus.[MXR, SUM] = 11.
.4byte 0x5EA0, 0xBEEF0440, read32_test # read success when R=0, MXR=1, X=1
# test 8.3.1.3.4 Write flag
.4byte 0xBFF290, 0xBEEF0110, write32_test # write success when W=1
.4byte 0xBFF290, 0xBEEF0110, read32_test # check write success by reading
.4byte 0x5B78, 0xBEEF0CC0, write32_test # store page fault when W=0
# test 8.3.1.3.5 eXecute flag
# *** fetches on pages with X = 1 already tested in 8.3.1.3.1
.4byte 0xBFFDE0, 0xbad, executable_test # instr page fault when X=0
# In the following two tests, SVADU is supported, so the hardware handles the A/D bits
# Since SVADU is 1, there are no faults when A/D=0
# test 8.3.1.3.6 Accessed flag == 0
.4byte 0x3020, 0xBEEF0770, write32_test # Write success when A=0 and SVADU is enabled
.4byte 0x3020, 0xBEEF0770, read32_test # Read success when A=0 and SVADU is enabled
# test 8.3.1.3.7 Dirty flag == 0
.4byte 0x4658, 0xBEEF0AA0, write32_test # write successs when D=0 and SVADU is enabled
.4byte 0x4658, 0xBEEF0AA0, read32_test # read success when D=0
# =========== test 8.3.1.4 SATP Register ===========
# test 8.3.1.4.1 SATP ASID and PPN fields (test having two page tables with different ASID)
// *** .4byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, write32_test # write identical value to global PTE to make sure it's still in the TLB
.4byte 0x8000F, 0x11, goto_sv32 # go to SV39 on a second, very minimal page table
.4byte 0xE3130, 0xBEEF0077, read32_test # Read success of old written value from a new page table mapping
# test 8.3.1.4.2 Test Global mapping
// ***.4byte 0x7FFFFFF888, 0x0220DEADBEEF0099, read32_test # read success of global PTE undefined in current mapping.
# =========== test 8.3.1.5 STATUS Registers ===========
# test 8.3.1.5.1 mstatus.mprv translation
# *** mstatus.mprv = 0 tested on every one of the translated reads and writes before this.
.4byte 0x8000D, 0x0, goto_sv32 // go back to old, extensive page table
.4byte 0x80000000, 0x1, goto_m_mode // go to m mode to be able to write mstatus
.4byte 0x1, 0x1, read_write_mprv // write 1 to mstatus.mprv and set mstatus.mpp to be 01=S
.4byte 0xBFF7E0, 0xBEEF0099, read32_test // read test succeeds with translation even though we're in M mode since MPP=S and MPRV=1
# test 8.3.1.5.2 mstatus.mprv clearing
# mstatus.mprv is already 1 from the last test so going to S mode should clear it with the mret
.4byte 0x80000000, 0x1, goto_s_mode // This should zero out the mprv bit but now to read and write mstatus, we have to
.4byte 0x80000000, 0x1, goto_m_mode // go back to m mode to allow us to reread mstatus.
.4byte 0x0, 0x0, read_write_mprv // read what should be a zeroed out mprv value and then force it back to zero.
# test 8.3.1.5.3 sstatus.mxr read
# this bitfield already tested in 8.3.1.3.3
# terminate tests
.4byte 0x0, 0x0, terminate_test # brings us back into machine mode with a final ecall, writing 0x9 to the output.

View File

@ -0,0 +1,106 @@
0000000b # Test 12.3.1.1.3: ecall from going to S mode from M mode
00000000
beef0000 # Read test success from confirming writes of known values
0000dead
beef0055 # Read test success from confirming writes of known values
0880dead
beef0033 # Read test success from confirming writes of known values
0990dead
beef0077 # Read test success from confirming writes of known values
0110dead
beef0099 # Read test success from confirming writes of known values
0220dead
beef0440 # Read test success from confirming writes of known values
0330dead
beef0000 # Test 12.3.1.1.4: Read test success from checking translation works
0000dead
beef0055 # Read test success from checking translation works
0880dead
beef0099 # Read test success from checking translation works
0220dead
0000000d # Test 12.3.1.2.1: Read test with page fault from upper vaddr bits not the same
00000000
00000bad
00000000
0000000d # Read test with page fault from upper vaddr bits not the same
00000000
00000bad
00000000
0000000d # Test 12.3.1.2.2: read test with page fault
00000000
00000bad
00000000
0000000f # Test 12.3.1.2.3: write test with page fault
00000000
0000000d # Test 12.3.1.2.4: read test with page fault
00000000
00000bad
00000000
0000000d # Test 12.3.1.2.5: 2 read tests with page faults
00000000
00000bad
00000000
0000000d # read 2
00000000
00000bad
00000000
00000111 # Test 12.3.1.3.1: execute test success
00000000
00000009 # ecall from going to U mode from S mode
00000000
0000000d # read test with page fault
00000000
00000bad
00000000
0000000c # execute test with page fault
00000000
00000bad
00000000
beef0033 # Test 12.3.1.3.2: read test success
0990dead
00000008 # ecall from going to S mode from U mode
00000000
beef0077 # read test success
0110dead
0000000c # execute test with page fault
00000000
00000bad
00000000
0000000d # read test with page fault
00000000
00000bad
00000000
0000000d # Test 12.3.1.3.3: read test with page fault
00000000
00000bad
00000000
beef0440 # read test success
0330dead
beef0110 # Test 12.3.1.3.4: read test success
0440dead
0000000f # write test with page fault
00000000
0000000c # Test 12.3.1.3.5: execute test with page fault
00000000
00000bad
00000000
beef0770 # Test 8.3.1.3.5: check successful read/write when A=0 and SVADU=1
0990dead
beef0aa0 # Test 8.3.1.3.6: check successful read/write when D=0 and SVADU=1
0440dead
beef0000 # Test 12.3.1.4.1: read test success from new page table mapping
0000dead
00000009 # Test 12.3.1.5.1: ecall from going to m mode from s mode
00000000
00000000 # previous mprv value before writing 1 to it.
00000000
beef0099 # Read test success when mprv=1 So translation should occur
0220dead # even though we're in M mode with translation off
0000000b # Test 12.3.1.5.2 ecall from going to s mode from m mode (zeroing mprv)
00000000
00000009 # ecall from going to m mode from s mode (so we can access mstatus)
00000000
00000000 # previous mprv value zeroed out from mret after going to s mode.
00000000
0000000b # ecall from test termination from M mode
00000000

View File

@ -0,0 +1,114 @@
0000000b # Test 12.3.1.1.3: ecall from going to S mode from M mode
00000000
beef0cc0 # 8 read test successes
0ee0dead
beef0000 # read 2
0000dead
beef0055 # read 3
0880dead
beef0033 # read 4
0990dead
beef0077 # read 5
0110dead
beef0099 # read 6
0220dead
beef0440 # read 7
0330dead
beef0cc0 # Test 12.3.1.1.4: 4 read test successes
0ee0dead
beef0000 # read 2
0000dead
beef0055 # read 3
0880dead
beef0099 # read 4
0220dead
0000000d # Test 12.3.1.2.1: 2 read tests with page fault
00000000
00000bad
00000000
0000000d # read 2
00000000
00000bad
00000000
0000000d # Test 12.3.1.2.2: read test with page fault
00000000
00000bad
00000000
0000000f # Test 12.3.1.2.3: write test with page fault
00000000
0000000d # Test 12.3.1.2.4: read test with page fault
00000000
00000bad
00000000
0000000d # Test 12.3.1.2.5: 3 read tests with page fault
00000000
00000bad
00000000
0000000d # read 2
00000000
00000bad
00000000
0000000d # read 3
00000000
00000bad
00000000
00000111 # Test 12.3.1.3.1: Execute test success
00000000
00000009 # ecall from going to U mode from S mode
00000000
0000000d # read test with page fault
00000000
00000bad
00000000
0000000c # execute test with page fault
00000000
00000bad
00000000
beef0033 # Test 12.3.1.3.2: read test success
0990dead
00000008 # ecall from going to S mode from U mode
00000000
beef0077 # read test success
0110dead
0000000c # execute test with page fault
00000000
00000bad
00000000
0000000d # read test with page fault`
00000000
00000bad
00000000
0000000d # Test 12.3.1.3.3: read test with page fault
00000000
00000bad
00000000
beef0440 # read test success
0330dead
beef0110 # Test 12.3.1.3.4: read test success
0440dead
0000000f # write test with page fault
00000000
0000000c # Test 12.3.1.3.5: executable test with page fault
00000000
00000bad
00000000
beef0770 # Test 8.3.1.3.5: check successful read/write when A=0 and SVADU=1
0990dead
beef0aa0 # Test 8.3.1.3.6: check successful read/write when D=0 and SVADU=1
0440dead
beef0000 # Test 12.3.1.4.1: read test success on new page table mapping
0000dead
00000009 # Test 12.3.1.5.1: ecall from going to m mode from s mode
00000000
00000000 # previous value of mprv before write
00000000
beef0099 # Read test success when mprv=1 So translation should occur
0220dead # even though we're in M mode with translation off
0000000b # Test 12.3.1.5.2 ecall from going to s mode from m mode (zeroing mprv)
00000000
00000009 # ecall from going to m mode from s mode (so we can access mstatus)
00000000
00000000 # previous mprv value zeroed out from mret after going to s mode.
00000000
0000000b # ecall from test termination in S mode.
00000000

View File

@ -0,0 +1,215 @@
///////////////////////////////////////////
//
// WALLY-MMU
//
// Author: David_Harris@hmc.edu and Kip Macsai-Goren <kmacsaigoren@g.hmc.edu>
//
// Created 2021-06-15
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
///////////////////////////////////////////
#include "WALLY-TEST-LIB-64.h"
RVTEST_ISA("RV64I")
RVTEST_CASE(0,"//check ISA:=regex(.*64.*);check ISA:=regex(.*I.*);def TEST_CASE_1=True;def NO_SAIL=True",mmu-sv39)
INIT_TESTS
TRAP_HANDLER m
j run_test_loop // begin test loop/table tests instead of executing inline code.
INIT_TEST_TABLE
TEST_STACK_AND_DATA
.align 3
test_cases:
# ---------------------------------------------------------------------------------------------
# Test Contents
#
# Here is where the actual tests are held, or rather, what the actual tests do.
# each entry consists of 3 values that will be read in as follows:
#
# '.8byte [x28 Value], [x29 Value], [x30 value]'
# or
# '.8byte [address], [value], [test type]'
#
# The encoding for x30 test type values can be found in the test handler
#
# ---------------------------------------------------------------------------------------------
# =========== test 8.3.1.1 Page Table Translation ===========
# test 8.3.1.1.1 write page tables / entries to phyiscal memory
# sv39 page table (See Figure 12.12***):
# Level 2 page table, situated at 0x8000D000
.8byte 0x000000008000D000, 0x0000000020004C01, write64_test# points to level 1 page table A
.8byte 0x000000008000D008, 0x0000000020005001, write64_test# points to level 1 page table B #*** replacing all the pointers DAU bits with 0.
.8byte 0x000000008000D010, 0x00000000200000CF, write64_test# Vaddr 0x8000_0000, Paddr 0x80000000: aligned gigapage (program and data memory)
.8byte 0x000000008000D018, 0x00004000004000C7, write64_test# Vaddr 0xC000_0000: misaligned gigapage
.8byte 0x000000008000DFF8, 0x0000000020005401, write64_test # points to level 1 page table C
# Level 1 page table A
.8byte 0x0000000080013000, 0x0000000020006001, write64_test# points to level 0 page table A
# Level 1 page table B
.8byte 0x0000000080014000, 0x00000000200000CB, write64_test# Vaddr 0x4000_0000, Paddr 0x80000000: aligned megapage, W=0, used for execution tests
.8byte 0x0000000080014008, 0x00000400000080C3, write64_test# Vaddr 0x4020_0000: misaligned megapage
.8byte 0x0000000080014010, 0x00000000200000DF, write64_test# Vaddr 0x4040_0000, Paddr 0x80000000: aligned megapage, aliased with program, U=1
.8byte 0x0000000080014018, 0x00000000210800C9, write64_test# Vaddr 0x4060_0000, Paddr 0x84200000: R=0, reads should fault
# Level 1 page table C
.8byte 0x0000000080015FF8, 0x0000000020005801, write64_test# points to level 0 page table B
# Level 0 page table A
.8byte 0x0000000080018000, 0x00000000200070D1, write64_test# Vaddr 0x0000: bad PTE points to level -1 table
.8byte 0x0000000080018008, 0x00000000200800DF, write64_test# Vaddr 0x1000, Paddr = 0x80200000: aligned kilopage
.8byte 0x0000000080018010, 0x00000000200810D5, write64_test# Vaddr 0x2000: bad PTE has W but not R
.8byte 0x0000000080018018, 0x0000000020080817, write64_test# Vaddr 0x3000 Paddr 0x80202000: A=0, should cause read fault
.8byte 0x0000000080018020, 0x0000000020080C57, write64_test# Vaddr 0x4000 Paddr 0x80203000: D=0, should cause write fault
.8byte 0x0000000080018028, 0x00000000200814C7, write64_test# Vaddr 0x5000 Paddr 0x80205000: X=0, fetches should fault
.8byte 0x0000000080018030, 0x00000000200814C0, write64_test# Vaddr 0x6000: invalid page
# Level 0 page table B
.8byte 0x0000000080016FF8, 0x00000000200804CF, write64_test# Vaddr 0xFFFFFFFFFFFFF000, Paddr 0x80201000 aligned kilopage
# second page table to check context switches with satp
.8byte 0x8FFFF000, 0x200000CF, write64_test# Vaddr 0x0, Paddr 0x80000000 aligned gigapage
.8byte 0x8FFFF010, 0x200000CF, write64_test# Vaddr 0x8000_0000, Paddr 0x80000000: aligned gigapage (program and data memory so we can execute without jumping around)
# test 8.3.1.1.2 write values to Paddrs in each page
# each of these values is used for 8.3.1.1.3 and some other tests, specified in the comments.
# when a test is supposed to fault, nothing is written into where it'll be reading/executing since it shuold fault before getting there.
.8byte 0x80200AB0, 0x0000DEADBEEF0000, write64_test# 8.3.1.1.4 and 8.3.1.4.1
.8byte 0x800FFAB8, 0x0880DEADBEEF0055, write64_test# 8.3.1.1.4
.8byte 0x80200AC0, 0x0990DEADBEEF0033, write64_test# 8.3.1.3.2
.8byte 0x80203130, 0x0110DEADBEEF0077, write64_test# 8.3.1.3.2
.8byte 0x80099000, 0x0000806711100393, write64_test# 8.3.1.3.1 and 8.3.1.3.2 write executable code for "li x7, 0x111; ret"
.8byte 0x80205AA0, 0x0000806711100393, write64_test# 8.3.1.3.5 write same executable code
.8byte 0x80201888, 0x0220DEADBEEF0099, write64_test# 8.3.1.1.4
.8byte 0x84212348, 0x0330DEADBEEF0440, write64_test# 8.3.1.3.3
# test 8.3.1.1.3 read values back from Paddrs without translation (this also verifies the previous test)
.8byte 0x0, 0x0, goto_baremetal# satp.MODE = baremetal / no translation.
.8byte 0x0, 0x0, goto_s_mode # change to S mode, 0xb written to output
.8byte 0x80200AB0, 0x0000DEADBEEF0000, read64_test
.8byte 0x800FFAB8, 0x0880DEADBEEF0055, read64_test
.8byte 0x80200AC0, 0x0990DEADBEEF0033, read64_test
.8byte 0x80203130, 0x0110DEADBEEF0077, read64_test
.8byte 0x80201888, 0x0220DEADBEEF0099, read64_test
.8byte 0x84212348, 0x0330DEADBEEF0440, read64_test
# test 8.3.1.1.4 check translation works in sv39, read the same values from previous tests, this time with Vaddrs
.8byte 0x8000D, 0x0, goto_sv39 # satp.MODE = sv39, with base page table PPN = 0x8000D and ASID = 0. current VPN: gigapage at 0x80000000.
.8byte 0x80200AB0, 0x0000DEADBEEF0000, read64_test # gigapage at Vaddr 0x80000000, Paddr 0x80000000
.8byte 0x400FFAB8, 0x0880DEADBEEF0055, read64_test # megapage at Vaddr 0x40400000, Paddr 0x80000000
.8byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, read64_test # kilopage at Vaddr 0xFFFFFFFFFFFFF000, Paddr 0x80201000
# =========== test 8.3.1.2 page fault tests ===========
# test 8.3.1.2.1 load page fault if upper bits of Vaddr are not the same
.8byte 0x0010000080000AB0, 0x0, read64_test# gigapage at Vaddr 0x80000000, Paddr 0x80000000, bad 1 in upper bits
.8byte 0xFF0FFFFFFFFFF888, 0x0, read64_test# kilopage at Vaddr 0xFFFFFFFFFFFFF000, Paddr 0x80201000, bad 0000 in upper bits
# test 8.3.1.2.2 load page fault when reading an address where the valid flag is zero
.8byte 0x6000, 0x0, read64_test
# test 8.3.1.2.3 store page fault if PTE has W and ~R flags set
.8byte 0x2000, 0x0, write64_test
# test 8.3.1.2.4 Fault if last level PTE is a pointer
.8byte 0x0020, 0x0, read64_test
# test 8.3.1.2.5 load page fault on misaligned pages
.8byte 0xC0000000, 0x0, read64_test# misaligned gigapage
.8byte 0x40200000, 0x0, read64_test# misaligned megapage
# =========== test 8.3.1.3 PTE Protection flags ===========
# test 8.3.1.3.1 User flag == 0
# *** reads on pages with U=0 already tested in 8.3.1.1.4
.8byte 0x40099000, 0x111, executable_test # execute success when U=0, priv=S
.8byte 0x40400000, 0x2, goto_u_mode # go to U mode, return to megapage at 0x40400000 where U = 1. 0x9 written to output
.8byte 0xFFFFFFFFFFFFFC80, 0x0880DEADBEEF0550, read64_test # load page fault when U=0, priv=U
.8byte 0x40099000, 0xbad, executable_test # execute fault when U=0, priv=U
# test 8.3.1.3.2 User flag == 1
.8byte 0x1AC0, 0x0990DEADBEEF0033, read64_test # read success when U=1, priv=U
.8byte 0x80000000, 0x1, goto_s_mode # go back to S mode, return to gigapage at 0x80000000 where U = 0. 0x8 written to output
.8byte 0x0, 0x3, write_mxr_sum # set sstatus.[MXR, SUM] = 11
.8byte 0x4130, 0x0110DEADBEEF0077, read64_test # read success when U=1, priv=S, sstatus.SUM=1
.8byte 0x40499000, 0xbad, executable_test # instr page fault when U=1, priv=S (with any sstatus.SUM)
.8byte 0x0, 0x2, write_mxr_sum # set sstatus.[MXR, SUM] = 10.
.8byte 0x1AC0, 0x0990DEADBEEF0033, read64_test # load page fault when U-1, priv=S, sstatus.SUM=0
# test 8.3.1.3.3 Read flag
# *** reads on pages with R=1 already tested in 8.3.1.1.4
.8byte 0x0, 0x1, write_mxr_sum # set sstatus.[MXR, SUM] = 01.
.8byte 0x40612348, 0x0330DEADBEEF0440, read64_test # load page fault when R=0, sstatus.MXR=0
.8byte 0x0, 0x3, write_mxr_sum # set sstatus.[MXR, SUM] = 11.
.8byte 0x40612348, 0x0330DEADBEEF0440, read64_test # read success when MXR=1, X=1
# test 8.3.1.3.4 Write flag
.8byte 0x80AAAAA0, 0x0440DEADBEEF0110, write64_test# write success when W=1
.8byte 0x80AAAAA0, 0x0440DEADBEEF0110, read64_test# check write success by reading the same address
.8byte 0x40000000, 0x0220DEADBEEF0BB0, write64_test# store page fault when W=0
# test 8.3.1.3.5 eXecute flag
# *** fetches on pages with X = 1 already tested in 8.3.1.3.1
.8byte 0x5AA0, 0x1, executable_test # instr page fault when X=0
# In the following two tests, SVADU is supported, so the hardware handles the A/D bits
# Since SVADU is 1, there are no faults when A/D=0
# test 8.3.1.3.6 Accessed flag == 0
.8byte 0x36D0, 0x0990DEADBEEF0770, write64_test # Write success when A=0 and SVADU is enabled
.8byte 0x36D0, 0x0990DEADBEEF0770, read64_test # Read success when A=0 and SVADU is enabled
# test 8.3.1.3.7 Dirty flag == 0
.8byte 0x4658, 0x0440DEADBEEF0AA0, write64_test # Write success when D=0 and SVADU is enabled
.8byte 0x4658, 0x0440DEADBEEF0AA0, read64_test # read success when D=0
# =========== test 8.3.1.4 SATP Register ===========
# test 8.3.1.4.1 SATP ASID and PPN fields (test having two page tables with different ASID)
// *** .8byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, write64_test # write identical value to global PTE to make sure it's still in the TLB
.8byte 0x8FFFF, 0x11, goto_sv39 # go to SV39 on a second, very minimal page table
.8byte 0x200AB0, 0x0000DEADBEEF0000, read64_test # Read success of old written value from a new page table mapping
# test 8.3.1.4.2 Test Global mapping
// ***.8byte 0x7FFFFFF888, 0x0220DEADBEEF0099, read64_test # read success of global PTE undefined in current mapping.
# =========== test 8.3.1.5 STATUS Registers ===========
# test 8.3.1.5.1 mstatus.mprv translation
# *** mstatus.mprv = 0 tested on every one of the translated reads and writes before this.
.8byte 0x8000D, 0x0, goto_sv39 // go back to old, extensive page table
.8byte 0x80000000, 0x1, goto_m_mode // go to m mode to be able to write mstatus
.8byte 0x1, 0x1, read_write_mprv // write 1 to mstatus.mprv and set mstatus.mpp to be 01=S
.8byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, read64_test // read test succeeds with translation even though we're in M mode since MPP=S and MPRV=1
# test 8.3.1.5.2 mstatus.mprv clearing
# mstatus.mprv is already 1 from the last test so going to S mode should clear it with the mret
.8byte 0x80000000, 0x1, goto_s_mode // This should zero out the mprv bit but now to read and write mstatus, we have to
.8byte 0x80000000, 0x1, goto_m_mode // go back to m mode to allow us to reread mstatus.
.8byte 0x0, 0x0, read_write_mprv // read what should be a zeroed out mprv value and then force it back to zero.
# test 8.3.1.5.3 sstatus.mxr read
# this bitfield already tested in 8.3.1.3.3
# terminate tests
.8byte 0x0, 0x0, terminate_test # brings us back into machine mode with a final ecall, writing 0x9 to the output.

View File

@ -0,0 +1,232 @@
///////////////////////////////////////////
//
// WALLY-MMU
//
// Author: David_Harris@hmc.edu and Kip Macsai-Goren <kmacsaigoren@g.hmc.edu>
//
// Created 2021-06-15
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
///////////////////////////////////////////
#include "WALLY-TEST-LIB-64.h"
RVTEST_ISA("RV64I")
RVTEST_CASE(0,"//check ISA:=regex(.*64.*);check ISA:=regex(.*I.*);def TEST_CASE_1=True;def NO_SAIL=True",sv48)
INIT_TESTS
TRAP_HANDLER m
j run_test_loop // begin test loop/table tests instead of executing inline code.
INIT_TEST_TABLE
TEST_STACK_AND_DATA
# These tests follow the testing plan in Chapter 12 of the riscv-wally textbook
.align 3
test_cases:
# ---------------------------------------------------------------------------------------------
# Test Contents
#
# Here is where the actual tests are held, or rather, what the actual tests do.
# each entry consists of 3 values that will be read in as follows:
#
# '.8byte [x28 Value], [x29 Value], [x30 value]'
# or
# '.8byte [address], [value], [test type]'
#
# The encoding for x30 test type values can be found in the test handler in the framework file
#
# ---------------------------------------------------------------------------------------------
# =========== test 8.3.1.1 Page Table Translation ===========
# test 8.3.1.1.1 write page tables / entries to phyiscal memory
# sv48 page table (See Figure 12.12***):
# Level 3 page table, situated at 0x8000D000
.8byte 0x000000008000D000, 0x0000000020004C01, write64_test # points to level 2 page table A
.8byte 0x000000008000D008, 0x0000000020005001, write64_test # points to level 2 page table B # Changing DAU bits of each pointer to zero
.8byte 0x000000008000D010, 0x00000000000000C7, write64_test # Vaddr 0x010000000000, Paddr 0x00000000: aligned terapage
.8byte 0x000000008000D018, 0x00004000004000C7, write64_test # Vaddr 0x018000000000, misaligned terapage
.8byte 0x000000008000DFF8, 0x0000000020005401, write64_test # points to level 2 page table C
# Level 2 page table A
.8byte 0x0000000080013010, 0x0000000020006001, write64_test # points to level 1 page table A
# Level 2 page table B
.8byte 0x0000000080014000, 0x00000000200000CB, write64_test # Vaddr 0x008000000000, Paddr 0x80000000: aligned gigapage used for execution tests
.8byte 0x0000000080014008, 0x00000000200000DF, write64_test # Vaddr 0x008040000000, Paddr 0x80000000: aligned gigapage (aliased with data and instr memory) U bit set.
.8byte 0x0000000080014010, 0x00000400080000C3, write64_test # Vaddr 0x008080000000, misaligned gigapage
# Level 2 page table C
.8byte 0x0000000080015FF8, 0x0000000020005801, write64_test # points to level 1 page table B
# Level 1 page table A
.8byte 0x0000000080018000, 0x00000000200000CF, write64_test # Vaddr 0x80000000, Paddr 0x80000000: aligned megapage (data and instr memory)
.8byte 0x0000000080018008, 0x0000000020006401, write64_test # points to level 0 page table A
.8byte 0x0000000080018010, 0x000000C0000400CF, write64_test # Vaddr 0x80400000, misaligned megapage
.8byte 0x0000000080018018, 0x00000000214800C9, write64_test # Vaddr 0x80600000, Paddr 0x85200000: aligned megapage, R=0
# Level 1 page table B
.8byte 0x0000000080016FF8, 0x0000000020006801, write64_test # points to level 0 page table B
# Level 0 page table A
.8byte 0x0000000080019000, 0x00000000200070D1, write64_test # Vaddr 0x80200000, Paddr 0x8001C000: bad PTE points to level -1 table
.8byte 0x0000000080019008, 0x00000000200800DF, write64_test # Vaddr 0x80201000, Paddr 0x80200000: aligned kilopage
.8byte 0x0000000080019010, 0x00000000200810DF, write64_test # Vaddr 0x80202000, Paddr 0x80204000: bad PTE has W but not R
.8byte 0x0000000080019018, 0x0000000020080817, write64_test # Vaddr 0x80203000, Paddr 0x80202000: A=0, should cause read fault
.8byte 0x0000000080019020, 0x0000000020080C57, write64_test # Vaddr 0x80204000, Paddr 0x80203000: D=0, should cause write fault
.8byte 0x0000000080019028, 0x0000000020333000, write64_test # Vaddr 0x80205000, Paddr 0x80CCC000, invalid page.
# Level 0 page table B
.8byte 0x000000008001AFF8, 0x00000000200804CF, write64_test # Vaddr 0xFFFFFFFFF000, Paddr 0x80201000: aligned kilopage
# second page table to check context switches with satp
# Level 3 page table A
.8byte 0x8000F000, 0x2000BC01, write64_test # points to level 2 page table A
# Level 2 page table A
.8byte 0x8002F000, 0x200000CF, write64_test # Vaddr 0x0, Paddr 0x80000000: aligned gigapage
.8byte 0x8002F010, 0x200000CF, write64_test # Vaddr 0x80000000, Paddr 0x80000000: aligned gigapage (data and instr memory)
# test 8.3.1.1.2 write values to Paddrs in each page
# each of these values is used for 8.3.1.1.3 and some other tests, specified in the comments.
# when a test is supposed to fault, nothing is written into where it'll be reading/executing since it should fault before getting there.
.8byte 0x82777778, 0x0EE0DEADBEEF0CC0, write64_test # 8.3.1.1.4 terapage
.8byte 0x85BC0AB0, 0x0000DEADBEEF0000, write64_test # 8.3.1.1.4 gigapage
.8byte 0x800F0AB8, 0x0880DEADBEEF0055, write64_test # 8.3.1.1.4 megapage
.8byte 0x80201888, 0x0220DEADBEEF0099, write64_test # 8.3.1.1.4 kilopage
.8byte 0x80099000, 0x0000806711100393, write64_test # 8.3.1.3.1 write executable code for "li x7, 0x111; ret"
.8byte 0x80200400, 0x0000806711100393, write64_test # 8.3.1.3.2 write same executable code
.8byte 0x80200AC0, 0x0990DEADBEEF0033, write64_test # 8.3.1.3.2
.8byte 0x80200130, 0x0110DEADBEEF0077, write64_test # 8.3.1.3.2
.8byte 0x85212348, 0x0330DEADBEEF0440, write64_test # 8.3.1.3.3
.8byte 0x88888000, 0x0000806711100393, write64_test # 8.3.1.3.5 write same executable code
# test 8.3.1.1.3 read values back from Paddrs without translation (this also verifies the previous test)
.8byte 0x0, 0x0, goto_baremetal # satp.MODE = baremetal / no translation.
.8byte 0x0, 0x0, goto_s_mode # change to S mode, 0xb written to output
.8byte 0x82777778, 0x0EE0DEADBEEF0CC0, read64_test
.8byte 0x85BC0AB0, 0x0000DEADBEEF0000, read64_test
.8byte 0x800F0AB8, 0x0880DEADBEEF0055, read64_test
.8byte 0x80200AC0, 0x0990DEADBEEF0033, read64_test
.8byte 0x80200130, 0x0110DEADBEEF0077, read64_test
.8byte 0x80201888, 0x0220DEADBEEF0099, read64_test
.8byte 0x85212348, 0x0330DEADBEEF0440, read64_test
# test 8.3.1.1.4 check translation works in sv48, read the same values from previous tests, this time with Vaddrs
.8byte 0x8000D, 0x0, goto_sv48 # satp.MODE = sv48, with base page table PPN = 0x8000D and ASID = 0. current VPN: megapage at 0x80000000. Nothing written to output
.8byte 0x10082777778, 0x0EE0DEADBEEF0CC0, read64_test # terapage at Vaddr 0x010000000000, Paddr 0x0
.8byte 0x8005BC0AB0, 0x0000DEADBEEF0000, read64_test # gigapage at Vaddr 0x008000000000, Paddr 0x80000000
.8byte 0x800F0AB8, 0x0880DEADBEEF0055, read64_test # megapage at Vaddr 0x80000000, Paddr 0x80000000
.8byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, read64_test # kilopage at Vaddr 0xFFFFFFFFFFFFF000, Paddr 0x80201000
# =========== test 8.3.1.2 page fault tests ===========
# test 8.3.1.2.1 page fault if upper bits of Vaddr are not the same
.8byte 0x001000800ABC0AB0, 0x0, read64_test# gigapage at Vaddr 0x008000000000, Paddr 0x80000000, bad 1 in upper bits
.8byte 0xFF0FFFFFFFFFF888, 0x0, read64_test# kilopage at Vaddr 0xFFFFFFFFFFFFF000, Paddr 0x80201000, bad 0000 in upper bits
# test 8.3.1.2.2 read fault when reading an address where the valid flag is zero
.8byte 0x80205000, 0x0, read64_test
# test 8.3.1.2.3 write fault if PTE has W and ~R flags set
.8byte 0x80202000, 0x0, write64_test
# test 8.3.1.2.4 Fault if last level PTE is a pointer
.8byte 0x80200000, 0x0, read64_test
# test 8.3.1.2.5 read fault on misaligned pages
.8byte 0x18000000000, 0x0, read64_test # misaligned terapage
.8byte 0x8080000000, 0x0, read64_test # misaligned gigapage
.8byte 0x80400000, 0x0, read64_test # misaligned megapage
# =========== test 8.3.1.3 PTE Protection flags ===========
# test 8.3.1.3.1 User flag == 0
# reads on pages with U=0 already tested in 8.3.1.1.4
.8byte 0x008000099000, 0x111, executable_test # execute success when U=0, priv=S
.8byte 0x008040000000, 0x1, goto_u_mode # go to U mode, return to gigapage at 0x008040000000 where PTE.U = 1. 0x9 written to output
.8byte 0xFFFFFFFFFFFFFC80, 0x0880DEADBEEF0550, read64_test # read fault when U=0, priv=U
.8byte 0x008000099000, 0xbad, executable_test # execute fault when U=0, priv=U
# test 8.3.1.3.2 User flag == 1
.8byte 0x80201AC0, 0x0990DEADBEEF0033, read64_test # read success when U=1, priv=U
.8byte 0x80000000, 0x2, goto_s_mode
.8byte 0x0, 0x3, write_mxr_sum # set sstatus.[MXR, SUM] = 11
.8byte 0x80201130, 0x0110DEADBEEF0077, read64_test # read success when U=1, priv=S, sstatus.SUM=1
.8byte 0x80201400, 0xbad, executable_test # execute fault when U=1, priv=S (with any sstatus.SUM)
.8byte 0x0, 0x2, write_mxr_sum # set sstatus.[MXR, SUM] = 10.
.8byte 0x80201AC0, 0x0990DEADBEEF0033, read64_test # read fault when U=1, priv=S, sstatus.SUM=0
# test 8.3.1.3.3 Read flag
# reads on pages with R=1 already tested in 8.3.1.1.4
.8byte 0x0, 0x1, write_mxr_sum # set sstatus.[MXR, SUM] = 01.
.8byte 0x80612348, 0x0330DEADBEEF0440, read64_test # read fault when R=0, sstatus.MXR=0
.8byte 0x0, 0x3, write_mxr_sum # set sstatus.[MXR, SUM] = 11.
.8byte 0x80612348, 0x0330DEADBEEF0440, read64_test # read success when MXR=1, X=1
# test 8.3.1.3.4 Write flag
.8byte 0x10080BCDED8, 0x0440DEADBEEF0110, write64_test # write success when W=1 (corresponding Paddr = 0x80BCDED8)
.8byte 0x10080BCDED8, 0x0440DEADBEEF0110, read64_test # check write success by reading value back
.8byte 0x8000009E88, 0x0220DEADBEEF0BB0, write64_test # write fault when W=0
# test 8.3.1.3.5 eXecute flag
# executes on pages with X = 1 already tested in 8.3.1.3.1
.8byte 0x010088888000, 0x2, executable_test # execute fault when X=0
# In the following two tests, SVADU is supported, so the hardware handles the A/D bits
# Since SVADU is 1, there are no faults when A/D=0
# test 8.3.1.3.6 Accessed flag == 0
.8byte 0x802036D0, 0x0990DEADBEEF0770, write64_test # Write success when A=0 and SVADU is enabled
.8byte 0x802036D0, 0x0990DEADBEEF0770, read64_test # Read success when A=0 and SVADU is enabled
# test 8.3.1.3.7 Dirty flag == 0
.8byte 0x80204658, 0x0440DEADBEEF0AA0, write64_test # Write success when D=0 and SVADU is enabled
.8byte 0x80204658, 0x0440DEADBEEF0AA0, read64_test # read success when D=0
# =========== test 8.3.1.4 SATP Register ===========
# test 8.3.1.4.1 SATP ASID and PPN fields (test having two page tables with different ASID)
// *** .8byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, write64_test # write identical value to global PTE to make sure it's still in the TLB
.8byte 0x8000F, 0x11, goto_sv48 # go to SV39 on a second, very minimal page table
.8byte 0x5BC0AB0, 0x0000DEADBEEF0000, read64_test # Read success of old written value from a new page table mapping
# test 8.3.1.4.2 Test Global mapping
// ***.8byte 0x7FFFFFF888, 0x0220DEADBEEF0099, read64_test # read success of global PTE undefined in current mapping.
# =========== test 8.3.1.5 STATUS Registers ===========
# test 8.3.1.5.1 mstatus.mprv translation
# *** mstatus.mprv = 0 tested on every one of the translated reads and writes before this.
.8byte 0x8000D, 0x0, goto_sv48 // go back to old, extensive page table
.8byte 0x80000000, 0x1, goto_m_mode // go to m mode to be able to write mstatus
.8byte 0x1, 0x1, read_write_mprv // write 1 to mstatus.mprv and set mstatus.mpp to be 01=S
.8byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, read64_test // read test succeeds with translation even though we're in M mode since MPP=S and MPRV=1
# test 8.3.1.5.2 mstatus.mprv clearing
# mstatus.mprv is already 1 from the last test so going to S mode should clear it with the mret
.8byte 0x80000000, 0x1, goto_s_mode // This should zero out the mprv bit but now to read and write mstatus, we have to
.8byte 0x80000000, 0x1, goto_m_mode // go back to m mode to allow us to reread mstatus.
.8byte 0x0, 0x0, read_write_mprv // read what should be a zeroed out mprv value and then force it back to zero.
# test 8.3.1.5.3 sstatus.mxr read
# this bitfield already tested in 8.3.1.3.3
# terminate tests
.8byte 0x0, 0x0, terminate_test # brings us back into machine mode with a final ecall, writing 0x9 to the output.