From 7d9ebf56ede6033744ebd6068f364d73ae37c339 Mon Sep 17 00:00:00 2001 From: Kip Macsai-Goren Date: Tue, 11 Apr 2023 18:46:37 -0700 Subject: [PATCH] renamed virt mem tests to include svadu --- .../WALLY-mmu-sv32-svadu-01.reference_output | 47 ++++ .../privilege/src/WALLY-mmu-sv32-svadu-01.S | 201 +++++++++++++++ .../WALLY-mmu-sv39-svadu-01.reference_output | 106 ++++++++ .../WALLY-mmu-sv48-svadu-01.reference_output | 114 +++++++++ .../privilege/src/WALLY-mmu-sv39-svadu-01.S | 215 ++++++++++++++++ .../privilege/src/WALLY-mmu-sv48-svadu-01.S | 232 ++++++++++++++++++ 6 files changed, 915 insertions(+) create mode 100644 tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-mmu-sv32-svadu-01.reference_output create mode 100644 tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-mmu-sv32-svadu-01.S create mode 100644 tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-mmu-sv39-svadu-01.reference_output create mode 100644 tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-mmu-sv48-svadu-01.reference_output create mode 100644 tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-mmu-sv39-svadu-01.S create mode 100644 tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-mmu-sv48-svadu-01.S diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-mmu-sv32-svadu-01.reference_output b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-mmu-sv32-svadu-01.reference_output new file mode 100644 index 00000000..aa60ea21 --- /dev/null +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-mmu-sv32-svadu-01.reference_output @@ -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 diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-mmu-sv32-svadu-01.S b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-mmu-sv32-svadu-01.S new file mode 100644 index 00000000..409fae18 --- /dev/null +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-mmu-sv32-svadu-01.S @@ -0,0 +1,201 @@ +/////////////////////////////////////////// +// +// WALLY-MMU +// +// Author: David_Harris@hmc.edu and Kip Macsai-Goren +// +// 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. + diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-mmu-sv39-svadu-01.reference_output b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-mmu-sv39-svadu-01.reference_output new file mode 100644 index 00000000..64b2e79d --- /dev/null +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-mmu-sv39-svadu-01.reference_output @@ -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 diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-mmu-sv48-svadu-01.reference_output b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-mmu-sv48-svadu-01.reference_output new file mode 100644 index 00000000..7982cdeb --- /dev/null +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-mmu-sv48-svadu-01.reference_output @@ -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 diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-mmu-sv39-svadu-01.S b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-mmu-sv39-svadu-01.S new file mode 100644 index 00000000..cd35b9a2 --- /dev/null +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-mmu-sv39-svadu-01.S @@ -0,0 +1,215 @@ +/////////////////////////////////////////// +// +// WALLY-MMU +// +// Author: David_Harris@hmc.edu and Kip Macsai-Goren +// +// 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. + diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-mmu-sv48-svadu-01.S b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-mmu-sv48-svadu-01.S new file mode 100644 index 00000000..702645b6 --- /dev/null +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-mmu-sv48-svadu-01.S @@ -0,0 +1,232 @@ +/////////////////////////////////////////// +// +// WALLY-MMU +// +// Author: David_Harris@hmc.edu and Kip Macsai-Goren +// +// 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. +