mirror of
https://github.com/openhwgroup/cvw.git
synced 2025-04-24 22:07:12 -04:00
fixed arch tests to pass make, added 32 bit tests, addded all make-passing tests to tests.vh.
This commit is contained in:
parent
5218533ddc
commit
46b0cb810d
14 changed files with 4999 additions and 5110 deletions
|
@ -1488,9 +1488,9 @@ string imperas32f[] = '{
|
||||||
string wally64priv[] = '{
|
string wally64priv[] = '{
|
||||||
`WALLYTEST,
|
`WALLYTEST,
|
||||||
"rv64i_m/privilege/WALLY-MMU-SV39", "30A0",
|
"rv64i_m/privilege/WALLY-MMU-SV39", "30A0",
|
||||||
"rv64i_m/privilege/WALLY-MMU-SV48", "30A0"
|
"rv64i_m/privilege/WALLY-MMU-SV48", "30A0",
|
||||||
|
"rv64i_m/privilege/WALLY-PMP", "30A0"
|
||||||
// "rv64i_m/privilege/WALLY-PMA", "30A0",
|
// "rv64i_m/privilege/WALLY-PMA", "30A0",
|
||||||
// "rv64i_m/privilege/WALLY-PMP", "30A0"
|
|
||||||
};
|
};
|
||||||
|
|
||||||
string wally64periph[] = '{
|
string wally64periph[] = '{
|
||||||
|
@ -1505,8 +1505,8 @@ string wally32i[] = '{
|
||||||
string wally32priv[] = '{
|
string wally32priv[] = '{
|
||||||
`WALLYTEST,
|
`WALLYTEST,
|
||||||
"rv32i_m/privilege/WALLY-MMU-SV32", "3080",
|
"rv32i_m/privilege/WALLY-MMU-SV32", "3080",
|
||||||
"rv32i_m/privilege/WALLY-PMA", "3080",
|
|
||||||
"rv32i_m/privilege/WALLY-PMP", "3080"
|
"rv32i_m/privilege/WALLY-PMP", "3080"
|
||||||
|
// "rv32i_m/privilege/WALLY-PMA", "3080"
|
||||||
};
|
};
|
||||||
|
|
||||||
string wally32periph[] = '{
|
string wally32periph[] = '{
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -46,12 +46,12 @@
|
||||||
# Level 1 page table, situated at 0x8000D000
|
# Level 1 page table, situated at 0x8000D000
|
||||||
.4byte 0x8000D000, 0x20004C01, 0x0 # points to level 0 page table A
|
.4byte 0x8000D000, 0x20004C01, 0x0 # points to level 0 page table A
|
||||||
.4byte 0x8000D004, 0x200000CB, 0x0 # Vaddr 0x400000 Paddr 0x80000000: aligned megapage, W=0, used for execute tests
|
.4byte 0x8000D004, 0x200000CB, 0x0 # Vaddr 0x400000 Paddr 0x80000000: aligned megapage, W=0, used for execute tests
|
||||||
.4byte 0x8000D008, 0x20005421, 0x0 # points to level 0 page table B
|
.4byte 0x8000D008, 0x20005401, 0x0 # points to level 0 page table B
|
||||||
.4byte 0x8000D00C, 0x000800C7, 0x0 # Vaddr 0xC00000: misaligned megapage
|
.4byte 0x8000D00C, 0x000800C7, 0x0 # Vaddr 0xC00000: misaligned megapage
|
||||||
.4byte 0x8000D800, 0x200000CF, 0x0 # Vaddr 0x80000000 Paddr 0x80000000: aligned megapage (program and data memory)
|
.4byte 0x8000D800, 0x200000CF, 0x0 # Vaddr 0x80000000 Paddr 0x80000000: aligned megapage (program and data memory)
|
||||||
.4byte 0x8000D804, 0x200000DF, 0x0 # Vaddr 0x80400000 Paddr 0x80000000: aligned megapage, U=1 (aliased with program and data memory)
|
.4byte 0x8000D804, 0x200000DF, 0x0 # Vaddr 0x80400000 Paddr 0x80000000: aligned megapage, U=1 (aliased with program and data memory)
|
||||||
# Level 0 page table A
|
# Level 0 page table A
|
||||||
.4byte 0x80013000, 0x20007011, 0x0 # Vaddr 0x0000: bad PTE points to level -1 table
|
.4byte 0x80013000, 0x20007001, 0x0 # Vaddr 0x0000: bad PTE points to level -1 table
|
||||||
.4byte 0x80013004, 0x202000DF, 0x0 # Vaddr 0x1000 Paddr 0x80800000: aligned kilopage, U=1
|
.4byte 0x80013004, 0x202000DF, 0x0 # Vaddr 0x1000 Paddr 0x80800000: aligned kilopage, U=1
|
||||||
.4byte 0x80013008, 0x202010D5, 0x0 # Vaddr 0x2000: pad PTE has W but not R
|
.4byte 0x80013008, 0x202010D5, 0x0 # Vaddr 0x2000: pad PTE has W but not R
|
||||||
.4byte 0x8001300C, 0x20200817, 0x0 # Vaddr 0x3000: A=0, should cause read fault
|
.4byte 0x8001300C, 0x20200817, 0x0 # Vaddr 0x3000: A=0, should cause read fault
|
||||||
|
@ -59,7 +59,8 @@
|
||||||
.4byte 0x80013014, 0x202014C9, 0x0 # Vaddr 0x5000 Paddr 80805000: aligned kilopage, W=R=0
|
.4byte 0x80013014, 0x202014C9, 0x0 # Vaddr 0x5000 Paddr 80805000: aligned kilopage, W=R=0
|
||||||
.4byte 0x80013018, 0x0, 0x0 # Vaddr 0x6000: invalid page
|
.4byte 0x80013018, 0x0, 0x0 # Vaddr 0x6000: invalid page
|
||||||
# Level 0 page table B
|
# Level 0 page table B
|
||||||
.4byte 0x80015FFC, 0x202004CF, 0x0 # Vaddr 0x00BFF000 Paddr 0x80801000: aligned kilopage
|
.4byte 0x80015FFC, 0x202004C7, 0x0 # Vaddr 0xBFF000 Paddr 0x80801000: aligned kilopage with X=0, U=0
|
||||||
|
|
||||||
|
|
||||||
# test 12.3.1.1.2 write values to Paddrs in each page
|
# test 12.3.1.1.2 write values to Paddrs in each page
|
||||||
# each of these values is used for 12.3.1.1.3 and some other tests, specified in the comments.
|
# each of these values is used for 12.3.1.1.3 and some other tests, specified in the comments.
|
||||||
|
@ -70,6 +71,10 @@
|
||||||
.4byte 0x808017E0, 0xBEEF0099, 0x0 # 12.3.1.1.4 kilopage
|
.4byte 0x808017E0, 0xBEEF0099, 0x0 # 12.3.1.1.4 kilopage
|
||||||
.4byte 0x80805EA0, 0xBEEF0440, 0x0 # 12.3.1.3.3
|
.4byte 0x80805EA0, 0xBEEF0440, 0x0 # 12.3.1.3.3
|
||||||
.4byte 0x80803AA0, 0xBEEF0BB0, 0x0 # 12.3.1.3.7
|
.4byte 0x80803AA0, 0xBEEF0BB0, 0x0 # 12.3.1.3.7
|
||||||
|
.4byte 0x8000FFA0, 0x11100393, 0x0 # write executable code for "li x7, 0x111; ret" to executable region.
|
||||||
|
.4byte 0x8000FFA4, 0x00008067, 0x0 # Used for 12.3.1.3.1, 12.3.1.3.2
|
||||||
|
.4byte 0x80801DE0, 0x11100393, 0x0 # write executable code for "li x7, 0x111; ret" to NON-executable region.
|
||||||
|
.4byte 0x80801DE4, 0x00008067, 0x0 # Used for 12.3.1.3.5
|
||||||
|
|
||||||
# test 12.3.1.1.3 read values back from Paddrs without translation (this also verifies the previous test)
|
# test 12.3.1.1.3 read values back from Paddrs without translation (this also verifies the previous test)
|
||||||
.4byte 0x0, 0x0, 0x4 # satp.MODE = baremetal / no translation.
|
.4byte 0x0, 0x0, 0x4 # satp.MODE = baremetal / no translation.
|
||||||
|
@ -80,9 +85,13 @@
|
||||||
.4byte 0x808017E0, 0xBEEF0099, 0x1
|
.4byte 0x808017E0, 0xBEEF0099, 0x1
|
||||||
.4byte 0x80805EA0, 0xBEEF0440, 0x1
|
.4byte 0x80805EA0, 0xBEEF0440, 0x1
|
||||||
.4byte 0x80803AA0, 0xBEEF0BB0, 0x1
|
.4byte 0x80803AA0, 0xBEEF0BB0, 0x1
|
||||||
|
.4byte 0x8000FFA0, 0x11100393, 0x1
|
||||||
|
.4byte 0x8000FFA4, 0x00008067, 0x1
|
||||||
|
.4byte 0x80801DE0, 0x11100393, 0x1
|
||||||
|
.4byte 0x80801DE4, 0x00008067, 0x1
|
||||||
|
|
||||||
# test 12.3.1.1.4 check translation works in sv48, read the same values from previous tests, this time with Vaddrs
|
# test 12.3.1.1.4 check translation works in sv48, read the same values from previous tests, this time with Vaddrs
|
||||||
.4byte 0x0, 0x0, 0x5 # satp.MODE = sv48, Nothing written to output
|
.4byte 0x0, 0x0, 0x5 # satp.MODE = sv32, Nothing written to output
|
||||||
.4byte 0x4AAAA8, 0xBEEF0055, 0x1 # megapage at Vaddr 0x400000, Paddr 0x80000000
|
.4byte 0x4AAAA8, 0xBEEF0055, 0x1 # megapage at Vaddr 0x400000, Paddr 0x80000000
|
||||||
.4byte 0xBFF7E0, 0xBEEF0099, 0x1 # kilopage at Vaddr 0xBFF000, Paddr 0x80201000
|
.4byte 0xBFF7E0, 0xBEEF0099, 0x1 # kilopage at Vaddr 0xBFF000, Paddr 0x80201000
|
||||||
|
|
||||||
|
@ -105,25 +114,19 @@
|
||||||
|
|
||||||
# =========== test 12.3.1.3 PTE Protection flags ===========
|
# =========== test 12.3.1.3 PTE Protection flags ===========
|
||||||
|
|
||||||
// *** 16 July 2021: Execution tests commented out because they rely on some memory that's written in 12.3.1.1.2. this memory is written but stays in the dcache without being synced into memory
|
|
||||||
// Then the ifu tries to fetch the same address, but it's working with the unsynced memory, NOT the value stored in the dcache
|
|
||||||
// Until we have some fence instructions or another way of modifying the code implemented, these tests are ignored.
|
|
||||||
|
|
||||||
# test 12.3.1.3.1 User flag == 0
|
# test 12.3.1.3.1 User flag == 0
|
||||||
# *** reads on pages with U=0 already tested in 12.3.1.1.4
|
# *** reads on pages with U=0 already tested in 12.3.1.1.4
|
||||||
.4byte 0x400000, 0x1, 0x2 # fetch success when U=0, priv=S
|
.4byte 0x40FFA0, 0x111, 0x2 # fetch success when U=0, priv=S
|
||||||
.4byte 0x201, 0x11, 0xA # go to U mode, return to megapage VPN at [513] where PTE.U = 1. 0x9 written to output
|
.4byte 0x80400000, 0x1, 0xA # go to U mode, return to VPN 0x80400000 where PTE.U = 1. 0x9 written to output
|
||||||
.4byte 0xBFFC80, 0xBEEF0550, 0x1 # load page fault when U=0, priv=U
|
.4byte 0xBFFC80, 0xBEEF0550, 0x1 # load page fault when U=0, priv=U
|
||||||
.4byte 0x400000, 0x1, 0x2 # instr page fault when U=0, priv=U
|
.4byte 0x40FFA0, 0xbad, 0x2 # instr page fault when U=0, priv=U
|
||||||
|
|
||||||
# test 12.3.1.3.2 User flag == 1
|
# test 12.3.1.3.2 User flag == 1
|
||||||
.4byte 0x804FFAC0, 0xBEEF0033, 0x1 # read success when U=1, priv=U
|
.4byte 0x804FFAC0, 0xBEEF0033, 0x1 # read success when U=1, priv=U
|
||||||
.4byte 0x200, 0x11, 0x9 # go back to S mode, return to megapage VPN at [512] where PTE.U = 0. 0x8 written to output
|
.4byte 0x80000000, 0x1, 0x9 # go back to S mode, return to VPN 0x80000000 where PTE.U = 0. 0x8 written to output
|
||||||
.4byte 0x0, 0x3, 0x7 # set sstatus.[MXR, SUM] = 11
|
.4byte 0x0, 0x3, 0x7 # set sstatus.[MXR, SUM] = 11
|
||||||
.4byte 0x804E3130, 0xBEEF0077, 0x1 # read success when U=1, priv=S, sstatus.SUM=1
|
.4byte 0x804E3130, 0xBEEF0077, 0x1 # read success when U=1, priv=S, sstatus.SUM=1
|
||||||
.4byte 0x0, 0x400000, 0x10 # push to stack virtual address corresponfding to the PTE about to be changed.
|
.4byte 0x8040FFA0, 0xbad, 0x2 # instr page fault when U=1, priv=S (with any sstatus.SUM)
|
||||||
.4byte 0x8000D004, 0x200000DB, 0xF # Edit execution PTE so U=1
|
|
||||||
.4byte 0x400000, 0x1, 0x2 # instr page fault when U=1, priv=S (with any sstatus.SUM)
|
|
||||||
.4byte 0x0, 0x2, 0x7 # set sstatus.[MXR, SUM] = 10.
|
.4byte 0x0, 0x2, 0x7 # set sstatus.[MXR, SUM] = 10.
|
||||||
.4byte 0x804FFAC0, 0xBEEF0033, 0x1 # load page fault when U-1, priv=S, sstatus.SUM=0
|
.4byte 0x804FFAC0, 0xBEEF0033, 0x1 # load page fault when U-1, priv=S, sstatus.SUM=0
|
||||||
|
|
||||||
|
@ -141,9 +144,7 @@
|
||||||
|
|
||||||
# test 12.3.1.3.5 eXecute flag
|
# test 12.3.1.3.5 eXecute flag
|
||||||
# *** fetches on pages with X = 1 already tested in 12.3.1.3.1
|
# *** fetches on pages with X = 1 already tested in 12.3.1.3.1
|
||||||
.4byte 0x0, 0x400000, 0x10 # push to stack virtual address corresponfding to the PTE about to be changed.
|
.4byte 0xBFFDE0, 0xbad, 0x2 # instr page fault when X=0
|
||||||
.4byte 0x8000D004, 0x200000C7, 0xF # Edit execution PTE so U=0, X=0
|
|
||||||
.4byte 0x400000, 0x0, 0x2 # instr page fault when X=0
|
|
||||||
|
|
||||||
# test 12.3.1.3.6 Accessed flag == 0
|
# test 12.3.1.3.6 Accessed flag == 0
|
||||||
.4byte 0x3020, 0xBEEF0770, 0x0 # store page fault when A=0
|
.4byte 0x3020, 0xBEEF0770, 0x0 # store page fault when A=0
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
#include "WALLY-TEST-LIB-32.S"
|
#include "WALLY-TEST-LIB-32.S"
|
||||||
// Test library includes and handler for each type of test, a trap handler, imperas compliance instructions
|
// Test library includes and handler for each type of test, a trap handler, imperas compliance instructions
|
||||||
// Ideally this should mean that a test can be written by simply adding .8byte statements as below.
|
// Ideally this should mean that a test can be written by simply adding .4byte statements as below.
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------------------------
|
||||||
# Test Contents
|
# Test Contents
|
||||||
|
@ -31,9 +31,9 @@
|
||||||
# Here is where the actual tests are held, or rather, what the actual tests do.
|
# 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:
|
# each entry consists of 3 values that will be read in as follows:
|
||||||
#
|
#
|
||||||
# '.8byte [x28 Value], [x29 Value], [x30 value]'
|
# '.4byte [x28 Value], [x29 Value], [x30 value]'
|
||||||
# or
|
# or
|
||||||
# '.8byte [address], [value], [test type]'
|
# '.4byte [address], [value], [test type]'
|
||||||
#
|
#
|
||||||
# The encoding for x30 test type values can be found in the test handler in the framework file
|
# The encoding for x30 test type values can be found in the test handler in the framework file
|
||||||
#
|
#
|
||||||
|
@ -43,69 +43,72 @@
|
||||||
# =========== test 12.3.2.2 PMPs ===========
|
# =========== test 12.3.2.2 PMPs ===========
|
||||||
|
|
||||||
# Test 12.3.2.2.1 Config: Write known values and set PMP config according to table 12.4 in the *** riscv book, copied below
|
# Test 12.3.2.2.1 Config: Write known values and set PMP config according to table 12.4 in the *** riscv book, copied below
|
||||||
.8byte 0x0, 0x0018900C0009001F, 0xD # write pmpcfg0, output 0x0018900C0009001F
|
|
||||||
.8byte 0x2, 0x1F00000000000000, 0xD # write pmpcfg2, output 0x1F00000000000000
|
|
||||||
|
|
||||||
# write pmpaddr regs
|
# write pmpaddr regs. These should produce no outputs. *** consider replacing if a test needs to see the outputs of this.
|
||||||
# | Reg | pmpaddr | pmpcfg | L | A | X | W | R | Comments |
|
# | Reg | pmpaddr | pmpcfg | L | A | X | W | R | Comments |
|
||||||
.8byte 0x0, 0x0FFFFFFF, 0xE # | 0 | 0FFFFFFF | 1F | 0 | NAPOT | 0 | 1 | 1 | I/O 00000000-7FFFFFFF RW |
|
.4byte 0x0, 0x0FFFFFFF, 0xE # | 0 | 0x0FFFFFFF | 1F | 0 | NAPOT | 0 | 1 | 1 | I/O 00000000-7FFFFFFF RW |
|
||||||
.8byte 0x1, 0x80100000, 0xE # | 1 | 80100000 | 00 | 0 | OFF | 0 | 0 | 0 | |
|
.4byte 0x1, 0x20040000, 0xE # | 1 | 0x20040000 | 00 | 0 | OFF | 0 | 0 | 0 | |
|
||||||
.8byte 0x2, 0x801000FF, 0xE # | 2 | 801000FF | 09 | 0 | TOR | 0 | 0 | 1 | 80100000-801000FF R |
|
.4byte 0x2, 0x2004003F, 0xE # | 2 | 0x2004003F | 09 | 0 | TOR | 0 | 0 | 1 | 80100000-801000FF R |
|
||||||
.8byte 0x3, 0x80100200, 0xE # | 3 | 80100200 | 00 | 0 | OFF | 0 | 0 | 0 | |
|
.4byte 0x3, 0x20040080, 0xE # | 3 | 0x20040080 | 00 | 0 | OFF | 0 | 0 | 0 | |
|
||||||
.8byte 0x4, 0x80100210, 0xE # | 4 | 80100210 | 0C | 0 | TOR | 1 | 0 | 0 | 80100200-80100210 X |
|
.4byte 0x4, 0x20040084, 0xE # | 4 | 0x20040084 | 0C | 0 | TOR | 1 | 0 | 0 | 80100200-80100210 X |
|
||||||
.8byte 0x5, 0x80100300, 0xE # | 5 | 80100300 | 90 | 1 | NA4 | 0 | 0 | 0 | 80100300-80100303 locked out |
|
.4byte 0x5, 0x200400C0, 0xE # | 5 | 0x200400C0 | 90 | 1 | NA4 | 0 | 0 | 0 | 80100300-80100303 locked out |
|
||||||
.8byte 0x6, 0x2004013F, 0xE # | 6 | 2004013F | 18 | 0 | NAPOT | 0 | 0 | 0 | 80100400-801004FF no access |
|
.4byte 0x6, 0x2004013F, 0xE # | 6 | 0x2004013F | 18 | 0 | NAPOT | 0 | 0 | 0 | 80100400-801004FF no access |
|
||||||
# Pmpaddr 7-14 are all zeroed out in this test, so they don't need writes.
|
# Pmpaddr 7-14 are all zeroed out in this test, so they don't need writes.
|
||||||
.8byte 0xF, 0x8FFFFFFF, 0xE # | 15 | 8FFFFFFF | 1F | 0 | NAPOT | 1 | 1 | 1 | Main mem 80000000-FFFFFFFF RWX |
|
.4byte 0xF, 0x2FFFFFFF, 0xE # | 15 | 0x2FFFFFFF | 1F | 0 | NAPOT | 1 | 1 | 1 | Main mem 80000000-FFFFFFFF RWX|
|
||||||
|
|
||||||
|
# write pmpcfg regs with the information in the table above. this should also write the value of these registers to the output.
|
||||||
|
.4byte 0x0, 0x0009001F, 0xD # write pmpcfg0, output 0x0009001F
|
||||||
|
.4byte 0x1, 0x0018900C, 0xD # write pmpcfg1, output 0x0018900C
|
||||||
|
# .4byte 0x2, 0x00000000, 0xD # write pmpcfg2, output 0x00000000
|
||||||
|
.4byte 0x3, 0x1F000000, 0xD # write pmpcfg3, output 0x1F000000
|
||||||
|
|
||||||
# write known values to memory where W=0. This should be possible since we're in machine mode.
|
# write known values to memory where W=0. This should be possible since we're in machine mode.
|
||||||
.8byte 0x80100010, 0x600DAA, 0x0 # write to pmpaddr 1-2 range
|
.4byte 0x80100010, 0x600DAA, 0x0 # write to pmpaddr 1-2 range
|
||||||
.8byte 0x80100400, 0x600DBB, 0x0 # write to pmpaddr 6 range
|
.4byte 0x80100400, 0x600DBB, 0x0 # write to pmpaddr 6 range
|
||||||
|
|
||||||
# Write RET to regions where X = 0, 1 in main memory
|
# Write executable code to regions where X = 0, 1 in main memory
|
||||||
# *** This is currently impossible due to the fact that writing ret gets put into the datacache but
|
.4byte 0x80100200, 0x11100393, 0x0 # write executable code for "li x7, 0x111; ret" to region with X=1 (PMP4)
|
||||||
# The values in datacache never get synced with icache values so when we try to fetch the written ret,
|
.4byte 0x80100204, 0x00008067, 0x0
|
||||||
# We get an instr of all 0x0
|
.4byte 0x80100020, 0x11100393, 0x0 # write same executable code to region with X=0 (PMP2)
|
||||||
# It may also be impossible to do the exe tests version from the library since we have no way to guarantee that theyll be
|
.4byte 0x80100024, 0x00008067, 0x0
|
||||||
# compiled into in the address range with the right permissions.
|
|
||||||
|
|
||||||
# attempt to write to pmpcfg5 after lockout
|
|
||||||
.8byte 0x0, 0x0018EE0C0009001F, 0xD # instruction ignored, output 0x0018900C0009001F, NOT 0x0018EE0C0009001F
|
|
||||||
|
|
||||||
|
|
||||||
|
# attempt to write to pmpaddr5 and pmp5cfg after lockout
|
||||||
|
.4byte 0x1, 0x0018FF0C, 0xD # attempt to edit only pmp5cfg (pmpcfg1[8:15]) after lockout.
|
||||||
|
# instruction ignored, output is 0x0018900C, NOT 0x0018FF0C
|
||||||
|
.4byte 0x5, 0xFFFFFFFF, 0xE # attempt to edit pmpaddr5 after lockout.
|
||||||
|
# instruction ignored, output is 0x200400C0, NOT 0xFFFFFFFF
|
||||||
|
|
||||||
# Test 12.3.2.2.2 Machine mode access
|
# Test 12.3.2.2.2 Machine mode access
|
||||||
.8byte 0x80100300, 0x0, 0x1 # access fault to region with L=1, R=0
|
|
||||||
.8byte 0x80100400, 0x0, 0x1 # successful access to region with L=X=W=R=0
|
|
||||||
|
|
||||||
|
|
||||||
|
.4byte 0x80100300, 0x0, 0x1 # access fault to region with L=1, R=0. This one writes 0x5 as the mcause, not 0xd.
|
||||||
|
.4byte 0x80100400, 0x0, 0x1 # successful access to region with L=X=W=R=0
|
||||||
|
|
||||||
# Test 12.3.2.2.3 System mode access
|
# Test 12.3.2.2.3 System mode access
|
||||||
.8byte 0x0, 0x0, 0x9 # go to S mode. 0xb written to output
|
|
||||||
|
.4byte 0x0, 0x0, 0x9 # go to S mode. 0xb written to output
|
||||||
# test a write followed by a read to each region with R=W=1
|
# test a write followed by a read to each region with R=W=1
|
||||||
.8byte 0x80200000, 0x600D15, 0x0 # Write "good value" to RW range (PMP15)
|
.4byte 0x80200000, 0x600D15, 0x0 # Write "good value" to RW range (PMP15)
|
||||||
.8byte 0x80200000, 0x600D15, 0x1 # confirm write with read
|
.4byte 0x80200000, 0x600D15, 0x1 # confirm write with read
|
||||||
|
|
||||||
# test a write followed by a read on the edges of a read-only range
|
# test a write followed by a read on the edges of a read-only range
|
||||||
.8byte 0x800FFFF8, 0x600D02, 0x0 # Write "good value" just below read-only range (PMP2)
|
.4byte 0x800FFFF8, 0x600D02, 0x0 # Write "good value" just below read-only range (PMP2)
|
||||||
.8byte 0x800FFFF8, 0x600D02, 0x1 # confirm write with read
|
.4byte 0x800FFFF8, 0x600D02, 0x1 # confirm write with read
|
||||||
.8byte 0x80100100, 0x600D12, 0x0 # Write "good value" just above read-only range (PMP2)
|
.4byte 0x80100100, 0x600D12, 0x0 # Write "good value" just above read-only range (PMP2)
|
||||||
.8byte 0x80100100, 0x600D12, 0x1 # confirm write with read
|
.4byte 0x80100100, 0x600D12, 0x1 # confirm write with read
|
||||||
|
|
||||||
# test a read from each read only range verify a write causes an access fault
|
# test a read from each read only range verify a write causes an access fault
|
||||||
.8byte 0x80100010, 0xBAD, 0x0 # Write fault in read-only range (PMP2)
|
.4byte 0x80100010, 0xBAD, 0x0 # Write fault in read-only range (PMP2)
|
||||||
.8byte 0x80100010, 0x600DAA, 0x1 # read correct value out
|
.4byte 0x80100010, 0x600DAA, 0x1 # read correct value out
|
||||||
|
|
||||||
# test read and write fault on region with no access
|
# test read and write fault on region with no access
|
||||||
.8byte 0x80100208, 0x600D15, 0x0 # Write fault on no-access range (PMP6)
|
.4byte 0x80100208, 0x600D15, 0x0 # Write fault on no-access range (PMP6)
|
||||||
.8byte 0x80100208, 0x600D15, 0x1 # read fault on no-access range (PMP6)
|
.4byte 0x80100208, 0x600D15, 0x1 # read fault on no-access range (PMP6)
|
||||||
|
|
||||||
# test jalr to region with X=0 causes access fault
|
# test jalr to region with X=0 causes access fault
|
||||||
.8byte 0x80100400, 0xF, 0x2 # instr fault on no-execute range (PMP6)
|
.4byte 0x80100020, 0xbad, 0x2 # execute fault on no-execute range (PMP2)
|
||||||
|
|
||||||
# test jalr to region with X=1 returns successfully
|
# test jalr to region with X=1 returns successfully
|
||||||
# *** This has the same problem as the note above where we want actual instructions to be in this range,
|
.4byte 0x80100200, 0x111, 0x2 # execute success when X=1
|
||||||
# but it's difficult to make sure the exe_code in the library will compile into the right pmp range for this to work
|
|
||||||
|
|
||||||
.8byte 0x0, 0x0, 0x3 // terminate tests
|
.4byte 0x0, 0x0, 0x3 // terminate tests
|
||||||
|
|
|
@ -31,10 +31,7 @@ rvtest_entry_point:
|
||||||
RVMODEL_BOOT
|
RVMODEL_BOOT
|
||||||
RVTEST_CODE_BEGIN
|
RVTEST_CODE_BEGIN
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------------------------
|
|
||||||
# Initialization Overview:
|
# Initialization Overview:
|
||||||
#
|
#
|
||||||
# Initialize x6 as a virtual pointer to the test results
|
# Initialize x6 as a virtual pointer to the test results
|
||||||
|
@ -52,9 +49,14 @@ RVTEST_CODE_BEGIN
|
||||||
# address for stack
|
# address for stack
|
||||||
la sp, top_of_stack
|
la sp, top_of_stack
|
||||||
|
|
||||||
# address for trap handler
|
# trap handler setup
|
||||||
la x1, machine_trap_handler
|
la x1, machine_trap_handler
|
||||||
csrrw x4, mtvec, x1 # x4 reserved for "default" trap handler address that needs to be restored before halting this test.
|
csrrw x4, mtvec, x1 # x4 reserved for "default" trap handler address that needs to be restored before halting this test.
|
||||||
|
li a0, 0
|
||||||
|
li a1, 0
|
||||||
|
li a2, 0 # reset trap handler inputs to zero
|
||||||
|
|
||||||
|
# go to first test!
|
||||||
j test_setup
|
j test_setup
|
||||||
|
|
||||||
|
|
||||||
|
@ -76,21 +78,18 @@ RVTEST_CODE_BEGIN
|
||||||
# 4: go to user mode
|
# 4: go to user mode
|
||||||
# others: do nothing
|
# others: do nothing
|
||||||
#
|
#
|
||||||
# a1 (x11): Upper bits of change of return address after trap
|
# a1 (x11):
|
||||||
# Put it in the bottom bits of a1.
|
# VPN for return address after changing privilege mode.
|
||||||
#
|
# This should be the base VPN with no offset.
|
||||||
# Default : 0x0 (defaults to the next instruction in the same location as the return address)
|
# 0x0 : defaults to next instruction on the same page the trap was called on.
|
||||||
# Megapage: returnAddr[END-1:22]
|
|
||||||
# Kilopage: returnAddr[END-1:12] (this value also works for baremetal)
|
|
||||||
#
|
#
|
||||||
# a2 (x12): Pagetype for change of return address after trap
|
# a2 (x12):
|
||||||
# Put the Source page in a2[7:4] and Dest page in a2[3:0]
|
# Pagetype of the current address VPN before changing privilge mode
|
||||||
# Ex: giga -> mega a2=0x21
|
# Used so that we can know how many bits of the adress are the offset.
|
||||||
#
|
# Ignored if a1 == 0x0
|
||||||
# Default : Ignored if a1 == 0x0
|
# 0: Kilopage
|
||||||
# Megapage: 1
|
# 1: Megapage
|
||||||
# Kilopage: 0
|
#
|
||||||
#
|
|
||||||
# --------------------------------------------------------------------------------------------
|
# --------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
@ -150,53 +149,42 @@ trapreturn:
|
||||||
# addi x1, x1, 4 # add 4 to find the next instruction
|
# addi x1, x1, 4 # add 4 to find the next instruction
|
||||||
|
|
||||||
trapreturn_specified:
|
trapreturn_specified:
|
||||||
# update mepc and stack (x1 and x5) to have new virtual addresses.
|
# reset the necessary pointers and registers (x1, x5, x6, and the return address going to mepc)
|
||||||
|
# so that when we return to a new virtual address, they're all in the right spot as well.
|
||||||
|
|
||||||
beqz a1, trapreturn_finished # either update values, of go to default return address.
|
beqz a1, trapreturn_finished # either update values, of go to default return address.
|
||||||
|
|
||||||
# Get Mask Bits
|
|
||||||
la x5, trap_return_pagetype_table
|
la x5, trap_return_pagetype_table
|
||||||
mv x7, a2
|
|
||||||
li x28, 0xF0 # mask bits for current pagetype
|
|
||||||
and x7, x28, x7
|
|
||||||
srli x7, x7, 2
|
|
||||||
add x5, x5, x7
|
|
||||||
lw x7, 0(x5) # x7 = number of offset bits in current page type
|
|
||||||
|
|
||||||
la x5, trap_return_pagetype_table
|
|
||||||
li x28, 0xF # mask bits for new pagetype
|
|
||||||
and a2, x28, a2
|
|
||||||
slli a2, a2, 2
|
slli a2, a2, 2
|
||||||
add x5, x5, a2
|
add x5, x5, a2
|
||||||
lw a2, 0(x5) # a2 = number of offset bits in new page type
|
lw a2, 0(x5) # a2 = number of offset bits in current page type
|
||||||
|
|
||||||
li x5, 1
|
li x5, 1
|
||||||
sll x5, x5, x7
|
sll x5, x5, a2
|
||||||
addi x5, x5, -1 # x5 = mask bits for offset into current pagetype
|
addi x5, x5, -1 # x5 = mask bits for offset into current pagetype
|
||||||
|
|
||||||
sll a1, a1, a2 # a1 = the VPN of the new return page.
|
# reset the top of the stack, x1
|
||||||
|
lw x7, -4(sp)
|
||||||
# set x1 stack spot
|
|
||||||
lw x7, -4(sp)
|
|
||||||
and x7, x5, x7 # x7 = offset for x1
|
and x7, x5, x7 # x7 = offset for x1
|
||||||
add x7, x7, a1 # x7 = new address for x1
|
add x7, x7, a1 # x7 = new address for x1
|
||||||
sw x7, -4(sp)
|
sw x7, -4(sp)
|
||||||
|
|
||||||
# set x5 stack spot
|
# reset the second spot in the stack, x5
|
||||||
lw x7, -8(sp)
|
lw x7, -8(sp)
|
||||||
and x7, x5, x7 # x7 = offset for x5
|
and x7, x5, x7 # x7 = offset for x5
|
||||||
add x7, x7, a1 # x7 = new address for x5
|
add x7, x7, a1 # x7 = new address for x5
|
||||||
sw x7, -8(sp)
|
sw x7, -8(sp)
|
||||||
|
|
||||||
# set x6
|
# reset x6, the pointer for the virtual address of the output of the tests
|
||||||
and x7, x5, x6 # x7 = offset for the result pointer (x6)
|
and x7, x5, x6 # x7 = offset for x6
|
||||||
add x6, x7, a1 # x6 = new address for the result pointer
|
add x6, x7, a1 # x6 = new address for the result pointer
|
||||||
|
|
||||||
# set return address
|
# set return address, stored temporarily in x1, to the next instruction, but in the new virtual page.
|
||||||
and x1, x5, x1 # x1 = offset for the return address
|
and x1, x5, x1 # x1 = offset for the return address
|
||||||
add x1, x1, a1 # x1 = new return address.
|
add x1, x1, a1 # x1 = new return address.
|
||||||
|
|
||||||
li a1, 0
|
li a1, 0
|
||||||
li a2, 0 # reset inputs
|
li a2, 0 # reset trapreturn inputs to the trap handler
|
||||||
|
|
||||||
trapreturn_finished:
|
trapreturn_finished:
|
||||||
csrw mepc, x1 # update the mepc with address of next instruction
|
csrw mepc, x1 # update the mepc with address of next instruction
|
||||||
|
@ -310,18 +298,10 @@ test_loop:
|
||||||
beq x30, x7, write_test # 0x0 : Write to address : 0xf : None
|
beq x30, x7, write_test # 0x0 : Write to address : 0xf : None
|
||||||
li x7, 0x1 # : : :
|
li x7, 0x1 # : : :
|
||||||
beq x30, x7, read_test # 0x1 : Read from address : 0xd, 0xbad : readvalue in hex
|
beq x30, x7, read_test # 0x1 : Read from address : 0xd, 0xbad : readvalue in hex
|
||||||
li x7, 0xB # : : :
|
|
||||||
beq x30, x7, access_test # 0xB : Mem access at any width (see table) : 0x1, 0x5, or 0x7 : 0x32001608, 0x32001608, 0x1608, 0x08, // *** Execute, cahceable, etc values
|
|
||||||
li x7, 0xC # : : :
|
|
||||||
beq x30, x7, access_denied_test # 0xC : Access memory regions with no device : 0x7, 0x5, 0x1, 0x600d : 0xbad, 0x3
|
|
||||||
li x7, 0x2 # : : :
|
li x7, 0x2 # : : :
|
||||||
beq x30, x7, executable_test # 0x2 : test executable at address : 0xc, 0xbad : leading 12 bits of the li instr written to address. (be sure to also write a return instruction)
|
beq x30, x7, executable_test # 0x2 : test executable at address : 0xc, 0xbad : leading 12 bits of the li instr written to address. In general this is 0x111. (be sure to also write a return instruction)
|
||||||
li x7, 0x3 # : : :
|
li x7, 0x3 # : : :
|
||||||
beq x30, x7, terminate_test # 0x3 : terminate tests : mcause value for fault : from M 0xb, from S 0x9, from U 0x8
|
beq x30, x7, terminate_test # 0x3 : terminate tests : mcause value for fault : from M 0xb, from S 0x9, from U 0x8
|
||||||
li x7, 0xF # : : :
|
|
||||||
beq x30, x7, edit_pte # 0xF : edit an already instantiated pte : None : None
|
|
||||||
li x7, 0x10 # : : :
|
|
||||||
beq x30, x7, push_to_stack # 0x10 : put a value onto the top of the stack : None : None
|
|
||||||
li x7, 0x4 # : : :
|
li x7, 0x4 # : : :
|
||||||
beq x30, x7, goto_baremetal # 0x4 : satp.MODE = bare metal : None : None
|
beq x30, x7, goto_baremetal # 0x4 : satp.MODE = bare metal : None : None
|
||||||
li x7, 0x5 # : : :
|
li x7, 0x5 # : : :
|
||||||
|
@ -436,184 +416,120 @@ write_pmpcfg_end:
|
||||||
|
|
||||||
write_pmpaddr_0:
|
write_pmpaddr_0:
|
||||||
# writes the value in x29 to the pmpaddr register specified in x28.
|
# writes the value in x29 to the pmpaddr register specified in x28.
|
||||||
|
# then writes the final value of pmpaddrX to the output.
|
||||||
li x7, 0x0
|
li x7, 0x0
|
||||||
bne x7, x28, write_pmpaddr_1
|
bne x7, x28, write_pmpaddr_1
|
||||||
csrw pmpaddr0, x29
|
csrw pmpaddr0, x29
|
||||||
|
csrr x30, pmpaddr0
|
||||||
|
j write_pmpaddr_end
|
||||||
write_pmpaddr_1:
|
write_pmpaddr_1:
|
||||||
li x7, 0x1
|
li x7, 0x1
|
||||||
bne x7, x28, write_pmpaddr_2
|
bne x7, x28, write_pmpaddr_2
|
||||||
csrw pmpaddr1, x29
|
csrw pmpaddr1, x29
|
||||||
|
csrr x30, pmpaddr1
|
||||||
|
j write_pmpaddr_end
|
||||||
write_pmpaddr_2:
|
write_pmpaddr_2:
|
||||||
li x7, 0x2
|
li x7, 0x2
|
||||||
bne x7, x28, write_pmpaddr_3
|
bne x7, x28, write_pmpaddr_3
|
||||||
csrw pmpaddr2, x29
|
csrw pmpaddr2, x29
|
||||||
|
csrr x30, pmpaddr2
|
||||||
|
j write_pmpaddr_end
|
||||||
write_pmpaddr_3:
|
write_pmpaddr_3:
|
||||||
li x7, 0x3
|
li x7, 0x3
|
||||||
bne x7, x28, write_pmpaddr_4
|
bne x7, x28, write_pmpaddr_4
|
||||||
csrw pmpaddr3, x29
|
csrw pmpaddr3, x29
|
||||||
|
csrr x30, pmpaddr3
|
||||||
|
j write_pmpaddr_end
|
||||||
write_pmpaddr_4:
|
write_pmpaddr_4:
|
||||||
li x7, 0x4
|
li x7, 0x4
|
||||||
bne x7, x28, write_pmpaddr_5
|
bne x7, x28, write_pmpaddr_5
|
||||||
csrw pmpaddr4, x29
|
csrw pmpaddr4, x29
|
||||||
|
csrr x30, pmpaddr4
|
||||||
|
j write_pmpaddr_end
|
||||||
write_pmpaddr_5:
|
write_pmpaddr_5:
|
||||||
li x7, 0x5
|
li x7, 0x5
|
||||||
bne x7, x28, write_pmpaddr_6
|
bne x7, x28, write_pmpaddr_6
|
||||||
csrw pmpaddr5, x29
|
csrw pmpaddr5, x29
|
||||||
|
csrr x30, pmpaddr5
|
||||||
|
j write_pmpaddr_end
|
||||||
write_pmpaddr_6:
|
write_pmpaddr_6:
|
||||||
li x7, 0x6
|
li x7, 0x6
|
||||||
bne x7, x28, write_pmpaddr_7
|
bne x7, x28, write_pmpaddr_7
|
||||||
csrw pmpaddr6, x29
|
csrw pmpaddr6, x29
|
||||||
|
csrr x30, pmpaddr6
|
||||||
|
j write_pmpaddr_end
|
||||||
write_pmpaddr_7:
|
write_pmpaddr_7:
|
||||||
li x7, 0x7
|
li x7, 0x7
|
||||||
bne x7, x28, write_pmpaddr_8
|
bne x7, x28, write_pmpaddr_8
|
||||||
csrw pmpaddr7, x29
|
csrw pmpaddr7, x29
|
||||||
|
csrr x30, pmpaddr7
|
||||||
|
j write_pmpaddr_end
|
||||||
write_pmpaddr_8:
|
write_pmpaddr_8:
|
||||||
li x7, 0x8
|
li x7, 0x8
|
||||||
bne x7, x28, write_pmpaddr_9
|
bne x7, x28, write_pmpaddr_9
|
||||||
csrw pmpaddr8, x29
|
csrw pmpaddr8, x29
|
||||||
|
csrr x30, pmpaddr8
|
||||||
|
j write_pmpaddr_end
|
||||||
write_pmpaddr_9:
|
write_pmpaddr_9:
|
||||||
li x7, 0x9
|
li x7, 0x9
|
||||||
bne x7, x28, write_pmpaddr_10
|
bne x7, x28, write_pmpaddr_10
|
||||||
csrw pmpaddr9, x29
|
csrw pmpaddr9, x29
|
||||||
|
csrr x30, pmpaddr9
|
||||||
|
j write_pmpaddr_end
|
||||||
write_pmpaddr_10:
|
write_pmpaddr_10:
|
||||||
li x7, 0xA
|
li x7, 0xA
|
||||||
bne x7, x28, write_pmpaddr_11
|
bne x7, x28, write_pmpaddr_11
|
||||||
csrw pmpaddr10, x29
|
csrw pmpaddr10, x29
|
||||||
|
csrr x30, pmpaddr10
|
||||||
|
j write_pmpaddr_end
|
||||||
write_pmpaddr_11:
|
write_pmpaddr_11:
|
||||||
li x7, 0xB
|
li x7, 0xB
|
||||||
bne x7, x28, write_pmpaddr_12
|
bne x7, x28, write_pmpaddr_12
|
||||||
csrw pmpaddr11, x29
|
csrw pmpaddr11, x29
|
||||||
|
csrr x30, pmpaddr11
|
||||||
|
j write_pmpaddr_end
|
||||||
write_pmpaddr_12:
|
write_pmpaddr_12:
|
||||||
li x7, 0xC
|
li x7, 0xC
|
||||||
bne x7, x28, write_pmpaddr_13
|
bne x7, x28, write_pmpaddr_13
|
||||||
csrw pmpaddr12, x29
|
csrw pmpaddr12, x29
|
||||||
|
csrr x30, pmpaddr12
|
||||||
|
j write_pmpaddr_end
|
||||||
write_pmpaddr_13:
|
write_pmpaddr_13:
|
||||||
li x7, 0xD
|
li x7, 0xD
|
||||||
bne x7, x28, write_pmpaddr_14
|
bne x7, x28, write_pmpaddr_14
|
||||||
csrw pmpaddr13, x29
|
csrw pmpaddr13, x29
|
||||||
|
csrr x30, pmpaddr13
|
||||||
|
j write_pmpaddr_end
|
||||||
write_pmpaddr_14:
|
write_pmpaddr_14:
|
||||||
li x7, 0xE
|
li x7, 0xE
|
||||||
bne x7, x28, write_pmpaddr_15
|
bne x7, x28, write_pmpaddr_15
|
||||||
csrw pmpaddr14, x29
|
csrw pmpaddr14, x29
|
||||||
|
csrr x30, pmpaddr14
|
||||||
|
j write_pmpaddr_end
|
||||||
write_pmpaddr_15:
|
write_pmpaddr_15:
|
||||||
li x7, 0xF
|
li x7, 0xF
|
||||||
bne x7, x28, write_pmpaddr_end
|
bne x7, x28, write_pmpaddr_end
|
||||||
csrw pmpaddr15, x29
|
csrw pmpaddr15, x29
|
||||||
|
csrr x30, pmpaddr15
|
||||||
|
j write_pmpaddr_end
|
||||||
write_pmpaddr_end:
|
write_pmpaddr_end:
|
||||||
j test_loop
|
sw x30, 0(x6)
|
||||||
|
|
||||||
executable_test:
|
|
||||||
# using a virtual page number in x28, and the page type in x29, test execution on that virtual page
|
|
||||||
# note: that x28 page must point to program and data memory
|
|
||||||
# Another unfortunate case of not being able to use a little table like above, again because of the virtual addressing problem
|
|
||||||
|
|
||||||
li x7, 0x0
|
|
||||||
beq x7, x29, exe_kilopage
|
|
||||||
li x7, 0x1
|
|
||||||
beq x7, x29, exe_megapage
|
|
||||||
li x7, 0xF
|
|
||||||
beq x7, x29, exe_physical
|
|
||||||
|
|
||||||
exe_kilopage:
|
|
||||||
li x7, 0xFFFFF000
|
|
||||||
and x28, x28, x7 # x28 = virtual page number
|
|
||||||
li x29, 0xFFF
|
|
||||||
j exe_combine_and_test
|
|
||||||
|
|
||||||
exe_megapage:
|
|
||||||
li x7, 0xFFE00000
|
|
||||||
and x28, x28, x7 # x28 = virtual page number
|
|
||||||
li x29, 0x1FFFFF
|
|
||||||
j exe_combine_and_test
|
|
||||||
|
|
||||||
exe_combine_and_test: # at this point x28 is the VPN and x29 physical offset mask bits
|
|
||||||
la x7, exe_code
|
|
||||||
and x7, x7, x29
|
|
||||||
or x28, x28, x7 # x28 = full virtual address for executable_code
|
|
||||||
|
|
||||||
exe_physical:
|
|
||||||
li x7, 0xBAD # load a bad value into x7 in case this fetch doesnt work.
|
|
||||||
jalr x28 # jump to executable code virtual address
|
|
||||||
sw x7, 0(x6)
|
|
||||||
addi x6, x6, 4
|
addi x6, x6, 4
|
||||||
addi x16, x16, 4
|
addi x16, x16, 4
|
||||||
j test_loop
|
j test_loop
|
||||||
|
|
||||||
exe_code:
|
executable_test:
|
||||||
li x7, 0xE600D
|
# Execute the code at the address in x28, returning the value in x7.
|
||||||
ret #jumps back to the original virtual PC and continues with this program.
|
# Assumes the code modifies x7, to become the value stored in x29 for this test.
|
||||||
|
fence.i # forces cache and main memory to sync so execution code written by the program can run.
|
||||||
access_test:
|
|
||||||
# test write, read, and *** Execute permissions on the region of memory beginning at the address in x28
|
|
||||||
|
|
||||||
|
|
||||||
# Load output: (None) if pass, (0x7) if fail
|
|
||||||
# Store output: (0x600DXX) if pass, (0x5, 0xBAD) if fail
|
|
||||||
# execute output: *** N/A
|
|
||||||
# *** idempotent, atomic, etc...
|
|
||||||
|
|
||||||
# *** unfortunately, there's no guarantee that this write will work since the access width applies to writes and reads
|
|
||||||
# So I'm sorry, but I'm going to have to do loads and stores at all widths. its either that or have a test for every width
|
|
||||||
li x7, 0x32001608
|
|
||||||
sw x7, 0(x28) # test 32 bit write
|
|
||||||
sh x7, 4(x28) # test 16 bit write
|
|
||||||
sb x7, 12(x28) # test 8 bit write
|
|
||||||
|
|
||||||
# *** Double unfortunately, there are cases where we aren't allowed to write a known value to the range of addresses
|
|
||||||
# so instead I have to do all this work to check if ANY value get read out of memory, but I can't verfy the value in the output necessarily.
|
|
||||||
li x7, 0xBAD
|
li x7, 0xBAD
|
||||||
access_32:
|
jalr x28
|
||||||
li x29, 0xBAD
|
sw x7, 0(x6)
|
||||||
lw x29, 0(x28)
|
addi x6, x6, 4
|
||||||
beq x29, x7, access_16
|
addi x16, x16, 4
|
||||||
li x29, 0x600D32
|
|
||||||
access_16:
|
|
||||||
sw x29, 0(x6)
|
|
||||||
|
|
||||||
li x29, 0xBAD
|
|
||||||
lh x29, 4(x28)
|
|
||||||
beq x29, x7, access_08
|
|
||||||
li x29, 0x600D16
|
|
||||||
access_08:
|
|
||||||
sw x29, 4(x6)
|
|
||||||
|
|
||||||
li x29, 0xBAD
|
|
||||||
lb x29, 8(x28)
|
|
||||||
beq x29, x7, access_end
|
|
||||||
li x29, 0x600D08
|
|
||||||
access_end:
|
|
||||||
sw x29, 8(x6)
|
|
||||||
|
|
||||||
/* *** EXECUTE, idempotent atomic, etc tests. how do we do it? */
|
|
||||||
|
|
||||||
addi x6, x6, 12
|
|
||||||
addi x16, x16, 12
|
|
||||||
j test_loop
|
j test_loop
|
||||||
|
|
||||||
access_denied_test:
|
|
||||||
# check that lw, sw and jalr all cause faults in a memory region (beginning at x28 address) where no device is intantiated.
|
|
||||||
lw x7, 0(x28) # cause a load access fault
|
|
||||||
|
|
||||||
li x7, 0xBADBAD // *** Necessary?
|
|
||||||
sw x7, 0(x28) # cause a store access fault
|
|
||||||
jalr x7, 0(x28) # cause an instruction access fault
|
|
||||||
j test_loop
|
|
||||||
|
|
||||||
edit_pte:
|
|
||||||
# write the PTE (value in x29) to address x28. This is different from a normal write since it includes an sfence.vma
|
|
||||||
sw x29, 0(x28)
|
|
||||||
lw x30, 0(sp) # the sfence.vma requires a virtual address within the page, it needs to be loaded into the stack.
|
|
||||||
addi sp, sp, 4 # put the stack pointer one value down, effectively popping this value by allowing it to be overwritten.
|
|
||||||
sfence.vma x0, x30
|
|
||||||
j test_loop
|
|
||||||
|
|
||||||
push_to_stack:
|
|
||||||
# write the value in x29 to the stack address pointed to by sp. update sp.
|
|
||||||
# this for those handy times when address, value, test type isn't enough info and you need more so you put it on the stack.
|
|
||||||
# any test that uses this info is also respnsible for removing the value or moving the stack pointer back.
|
|
||||||
sw x29, -4(sp)
|
|
||||||
addi sp, sp, -4
|
|
||||||
j test_loop
|
|
||||||
|
|
||||||
terminate_test:
|
terminate_test:
|
||||||
|
|
||||||
|
@ -633,7 +549,7 @@ RVTEST_DATA_END
|
||||||
|
|
||||||
.align 2 # align stack to 4 byte boundary
|
.align 2 # align stack to 4 byte boundary
|
||||||
bottom_of_stack:
|
bottom_of_stack:
|
||||||
.fill 1024, 4, -1
|
.fill 1024, 4, 0xdeadbeef
|
||||||
top_of_stack:
|
top_of_stack:
|
||||||
|
|
||||||
|
|
||||||
|
@ -642,7 +558,7 @@ RVMODEL_DATA_BEGIN
|
||||||
|
|
||||||
// next lines through test cases copied over from old framework
|
// next lines through test cases copied over from old framework
|
||||||
test_1_res:
|
test_1_res:
|
||||||
.fill 1024, 4, -1
|
.fill 1024, 4, 0xdeadbeef
|
||||||
|
|
||||||
RVMODEL_DATA_END
|
RVMODEL_DATA_END
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
rv64i_sc_tests = \
|
rv64i_sc_tests = \
|
||||||
WALLY-MMU-SV39 \
|
WALLY-MMU-SV39 \
|
||||||
WALLY-MMU-SV48 \
|
WALLY-MMU-SV48 \
|
||||||
# WALLY-PMP
|
WALLY-PMP
|
||||||
# WALLY-PMA \
|
# WALLY-PMA \
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -22,9 +22,6 @@
|
||||||
///////////////////////////////////////////
|
///////////////////////////////////////////
|
||||||
|
|
||||||
#include "WALLY-TEST-LIB-64.S"
|
#include "WALLY-TEST-LIB-64.S"
|
||||||
|
|
||||||
// *** new line
|
|
||||||
test_contents:
|
|
||||||
// Test library includes and handler for each type of test, a trap handler, imperas compliance instructions
|
// Test library includes and handler for each type of test, a trap handler, imperas compliance instructions
|
||||||
// Ideally this should mean that a test can be written by simply adding .8byte statements as below.
|
// Ideally this should mean that a test can be written by simply adding .8byte statements as below.
|
||||||
|
|
||||||
|
@ -48,12 +45,14 @@ test_contents:
|
||||||
# sv39 page table (See Figure 12.12***):
|
# sv39 page table (See Figure 12.12***):
|
||||||
# Level 2 page table, situated at 0x8000D000
|
# Level 2 page table, situated at 0x8000D000
|
||||||
.8byte 0x000000008000D000, 0x0000000020004C01, 0x0 # points to level 1 page table A
|
.8byte 0x000000008000D000, 0x0000000020004C01, 0x0 # points to level 1 page table A
|
||||||
.8byte 0x000000008000D008, 0x0000000020005001, 0x0 # points to level 1 page table B
|
.8byte 0x000000008000D008, 0x0000000020005001, 0x0 # points to level 1 page table B #*** replacing all the pointers DAU bits with 0.
|
||||||
.8byte 0x000000008000D010, 0x00000000200000CF, 0x0 # Vaddr 0x8000_0000, Paddr 0x80000000: aligned gigapage (program and data memory)
|
.8byte 0x000000008000D010, 0x00000000200000CF, 0x0 # Vaddr 0x8000_0000, Paddr 0x80000000: aligned gigapage (program and data memory)
|
||||||
.8byte 0x000000008000D018, 0x00004000004000C7, 0x0 # Vaddr 0xC000_0000: misaligned gigapage
|
.8byte 0x000000008000D018, 0x00004000004000C7, 0x0 # Vaddr 0xC000_0000: misaligned gigapage
|
||||||
.8byte 0x000000008000DFF8, 0x0000000020005421, 0x0 # points to level 1 page table C
|
.8byte 0x000000008000DFF8, 0x0000000020005401, 0x0 # points to level 1 page table C
|
||||||
|
|
||||||
# Level 1 page table A
|
# Level 1 page table A
|
||||||
.8byte 0x0000000080013000, 0x0000000020006001, 0x0 # points to level 0 page table A
|
.8byte 0x0000000080013000, 0x0000000020006001, 0x0 # points to level 0 page table A
|
||||||
|
|
||||||
# Level 1 page table B
|
# Level 1 page table B
|
||||||
.8byte 0x0000000080014000, 0x00000000200000CB, 0x0 # Vaddr 0x4000_0000, Paddr 0x80000000: aligned megapage, W=0, used for execution tests
|
.8byte 0x0000000080014000, 0x00000000200000CB, 0x0 # Vaddr 0x4000_0000, Paddr 0x80000000: aligned megapage, W=0, used for execution tests
|
||||||
.8byte 0x0000000080014008, 0x00000400000080C3, 0x0 # Vaddr 0x4020_0000: misaligned megapage
|
.8byte 0x0000000080014008, 0x00000400000080C3, 0x0 # Vaddr 0x4020_0000: misaligned megapage
|
||||||
|
@ -61,8 +60,9 @@ test_contents:
|
||||||
.8byte 0x0000000080014018, 0x00000000210800C9, 0x0 # Vaddr 0x4060_0000, Paddr 0x84200000: R=0, reads should fault
|
.8byte 0x0000000080014018, 0x00000000210800C9, 0x0 # Vaddr 0x4060_0000, Paddr 0x84200000: R=0, reads should fault
|
||||||
# Level 1 page table C
|
# Level 1 page table C
|
||||||
.8byte 0x0000000080015FF8, 0x0000000020005801, 0x0 # points to level 0 page table B
|
.8byte 0x0000000080015FF8, 0x0000000020005801, 0x0 # points to level 0 page table B
|
||||||
|
|
||||||
# Level 0 page table A
|
# Level 0 page table A
|
||||||
.8byte 0x0000000080018000, 0x0000000020007001, 0x0 # Vaddr 0x0000: bad PTE points to level -1 table
|
.8byte 0x0000000080018000, 0x00000000200070D1, 0x0 # Vaddr 0x0000: bad PTE points to level -1 table
|
||||||
.8byte 0x0000000080018008, 0x00000000200800DF, 0x0 # Vaddr 0x1000, Paddr = 0x80200000: aligned kilopage
|
.8byte 0x0000000080018008, 0x00000000200800DF, 0x0 # Vaddr 0x1000, Paddr = 0x80200000: aligned kilopage
|
||||||
.8byte 0x0000000080018010, 0x00000000200810D5, 0x0 # Vaddr 0x2000: bad PTE has W but not R
|
.8byte 0x0000000080018010, 0x00000000200810D5, 0x0 # Vaddr 0x2000: bad PTE has W but not R
|
||||||
.8byte 0x0000000080018018, 0x0000000020080817, 0x0 # Vaddr 0x3000 Paddr 0x80202000: A=0, should cause read fault
|
.8byte 0x0000000080018018, 0x0000000020080817, 0x0 # Vaddr 0x3000 Paddr 0x80202000: A=0, should cause read fault
|
||||||
|
@ -97,7 +97,7 @@ test_contents:
|
||||||
.8byte 0x80203AA0, 0x0440DEADBEEF0BB0, 0x1
|
.8byte 0x80203AA0, 0x0440DEADBEEF0BB0, 0x1
|
||||||
|
|
||||||
# test 12.3.1.1.4 check translation works in sv39, read the same values from previous tests, this time with Vaddrs
|
# test 12.3.1.1.4 check translation works in sv39, read the same values from previous tests, this time with Vaddrs
|
||||||
.8byte 0x0, 0x0, 0x5 # satp.MODE = sv39, Nothing written to output
|
.8byte 0x0, 0x0, 0x5 # satp.MODE = sv39, current VPN: gigapage at 0x80000000. Nothing written to output
|
||||||
.8byte 0x80200AB0, 0x0000DEADBEEF0000, 0x1 # gigapage at Vaddr 0x80000000, Paddr 0x80000000
|
.8byte 0x80200AB0, 0x0000DEADBEEF0000, 0x1 # gigapage at Vaddr 0x80000000, Paddr 0x80000000
|
||||||
.8byte 0x400FFAB8, 0x0880DEADBEEF0055, 0x1 # megapage at Vaddr 0x40400000, Paddr 0x80000000
|
.8byte 0x400FFAB8, 0x0880DEADBEEF0055, 0x1 # megapage at Vaddr 0x40400000, Paddr 0x80000000
|
||||||
.8byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, 0x1 # kilopage at Vaddr 0xFFFFFFFFFFFFF000, Paddr 0x80201000
|
.8byte 0xFFFFFFFFFFFFF888, 0x0220DEADBEEF0099, 0x1 # kilopage at Vaddr 0xFFFFFFFFFFFFF000, Paddr 0x80201000
|
||||||
|
@ -127,13 +127,13 @@ test_contents:
|
||||||
# test 12.3.1.3.1 User flag == 0
|
# test 12.3.1.3.1 User flag == 0
|
||||||
# *** reads on pages with U=0 already tested in 12.3.1.1.4
|
# *** reads on pages with U=0 already tested in 12.3.1.1.4
|
||||||
.8byte 0x40099000, 0x111, 0x2 # execute success when U=0, priv=S
|
.8byte 0x40099000, 0x111, 0x2 # execute success when U=0, priv=S
|
||||||
.8byte 0x202, 0x21, 0xA # go to U mode, return to megapgage at 0x40400000 where U = 1. 0x9 written to output
|
.8byte 0x40400000, 0x2, 0xA # go to U mode, return to megapage at 0x40400000 where U = 1. 0x9 written to output
|
||||||
.8byte 0xFFFFFFFFFFFFFC80, 0x0880DEADBEEF0550, 0x1 # load page fault when U=0, priv=U
|
.8byte 0xFFFFFFFFFFFFFC80, 0x0880DEADBEEF0550, 0x1 # load page fault when U=0, priv=U
|
||||||
.8byte 0x40099000, 0xbad, 0x2 # execute fault when U=0, priv=U
|
.8byte 0x40099000, 0xbad, 0x2 # execute fault when U=0, priv=U
|
||||||
|
|
||||||
# test 12.3.1.3.2 User flag == 1
|
# test 12.3.1.3.2 User flag == 1
|
||||||
.8byte 0x1AC0, 0x0990DEADBEEF0033, 0x1 # read success when U=1, priv=U
|
.8byte 0x1AC0, 0x0990DEADBEEF0033, 0x1 # read success when U=1, priv=U
|
||||||
.8byte 0x2, 0x12, 0x9 # go back to S mode, return to gigapage at 0x80000000 where U = 0. 0x8 written to output
|
.8byte 0x80000000, 0x1, 0x9 # go back to S mode, return to gigapage at 0x80000000 where U = 0. 0x8 written to output
|
||||||
.8byte 0x0, 0x3, 0x7 # set sstatus.[MXR, SUM] = 11
|
.8byte 0x0, 0x3, 0x7 # set sstatus.[MXR, SUM] = 11
|
||||||
.8byte 0x4130, 0x0110DEADBEEF0077, 0x1 # read success when U=1, priv=S, sstatus.SUM=1
|
.8byte 0x4130, 0x0110DEADBEEF0077, 0x1 # read success when U=1, priv=S, sstatus.SUM=1
|
||||||
.8byte 0x40499000, 0xbad, 0x2 # instr page fault when U=1, priv=S (with any sstatus.SUM)
|
.8byte 0x40499000, 0xbad, 0x2 # instr page fault when U=1, priv=S (with any sstatus.SUM)
|
||||||
|
|
|
@ -47,18 +47,21 @@
|
||||||
# sv48 page table (See Figure 12.12***):
|
# sv48 page table (See Figure 12.12***):
|
||||||
# Level 3 page table, situated at 0x8000D000
|
# Level 3 page table, situated at 0x8000D000
|
||||||
.8byte 0x000000008000D000, 0x0000000020004C01, 0x0 # points to level 2 page table A
|
.8byte 0x000000008000D000, 0x0000000020004C01, 0x0 # points to level 2 page table A
|
||||||
.8byte 0x000000008000D008, 0x0000000020005001, 0x0 # points to level 2 page table B
|
.8byte 0x000000008000D008, 0x0000000020005001, 0x0 # points to level 2 page table B # Changing DAU bits of each pointer to zero
|
||||||
.8byte 0x000000008000D010, 0x00000000000000C7, 0x0 # Vaddr 0x010000000000, Paddr 0x00000000: aligned terapage
|
.8byte 0x000000008000D010, 0x00000000000000C7, 0x0 # Vaddr 0x010000000000, Paddr 0x00000000: aligned terapage
|
||||||
.8byte 0x000000008000D018, 0x00004000004000C7, 0x0 # Vaddr 0x018000000000, misaligned terapage
|
.8byte 0x000000008000D018, 0x00004000004000C7, 0x0 # Vaddr 0x018000000000, misaligned terapage
|
||||||
.8byte 0x000000008000DFF8, 0x0000000020005421, 0x0 # points to level 2 page table C
|
.8byte 0x000000008000DFF8, 0x0000000020005401, 0x0 # points to level 2 page table C
|
||||||
|
|
||||||
# Level 2 page table A
|
# Level 2 page table A
|
||||||
.8byte 0x0000000080013010, 0x0000000020006001, 0x0 # points to level 1 page table A
|
.8byte 0x0000000080013010, 0x0000000020006001, 0x0 # points to level 1 page table A
|
||||||
|
|
||||||
# Level 2 page table B
|
# Level 2 page table B
|
||||||
.8byte 0x0000000080014000, 0x00000000200000CB, 0x0 # Vaddr 0x008000000000, Paddr 0x80000000: aligned gigapage used for execution tests
|
.8byte 0x0000000080014000, 0x00000000200000CB, 0x0 # Vaddr 0x008000000000, Paddr 0x80000000: aligned gigapage used for execution tests
|
||||||
.8byte 0x0000000080014008, 0x00000000200000DF, 0x0 # Vaddr 0x008040000000, Paddr 0x80000000: aligned gigapage (aliased with data and instr memory) U bit set.
|
.8byte 0x0000000080014008, 0x00000000200000DF, 0x0 # Vaddr 0x008040000000, Paddr 0x80000000: aligned gigapage (aliased with data and instr memory) U bit set.
|
||||||
.8byte 0x0000000080014010, 0x00000400080000C3, 0x0 # Vaddr 0x008080000000, misaligned gigapage
|
.8byte 0x0000000080014010, 0x00000400080000C3, 0x0 # Vaddr 0x008080000000, misaligned gigapage
|
||||||
# Level 2 page table C
|
# Level 2 page table C
|
||||||
.8byte 0x0000000080015FF8, 0x0000000020005801, 0x0 # points to level 1 page table B
|
.8byte 0x0000000080015FF8, 0x0000000020005801, 0x0 # points to level 1 page table B
|
||||||
|
|
||||||
# Level 1 page table A
|
# Level 1 page table A
|
||||||
.8byte 0x0000000080018000, 0x00000000200000CF, 0x0 # Vaddr 0x80000000, Paddr 0x80000000: aligned megapage (data and instr memory)
|
.8byte 0x0000000080018000, 0x00000000200000CF, 0x0 # Vaddr 0x80000000, Paddr 0x80000000: aligned megapage (data and instr memory)
|
||||||
.8byte 0x0000000080018008, 0x0000000020006401, 0x0 # points to level 0 page table A
|
.8byte 0x0000000080018008, 0x0000000020006401, 0x0 # points to level 0 page table A
|
||||||
|
@ -66,8 +69,9 @@
|
||||||
.8byte 0x0000000080018018, 0x00000000214800C9, 0x0 # Vaddr 0x80600000, Paddr 0x85200000: aligned megapage, R=0
|
.8byte 0x0000000080018018, 0x00000000214800C9, 0x0 # Vaddr 0x80600000, Paddr 0x85200000: aligned megapage, R=0
|
||||||
# Level 1 page table B
|
# Level 1 page table B
|
||||||
.8byte 0x0000000080016FF8, 0x0000000020006801, 0x0 # points to level 0 page table B
|
.8byte 0x0000000080016FF8, 0x0000000020006801, 0x0 # points to level 0 page table B
|
||||||
|
|
||||||
# Level 0 page table A
|
# Level 0 page table A
|
||||||
.8byte 0x0000000080019000, 0x0000000020007001, 0x0 # Vaddr 0x80200000, Paddr 0x8001C000: bad PTE points to level -1 table
|
.8byte 0x0000000080019000, 0x00000000200070D1, 0x0 # Vaddr 0x80200000, Paddr 0x8001C000: bad PTE points to level -1 table
|
||||||
.8byte 0x0000000080019008, 0x00000000200800DF, 0x0 # Vaddr 0x80201000, Paddr 0x80200000: aligned kilopage
|
.8byte 0x0000000080019008, 0x00000000200800DF, 0x0 # Vaddr 0x80201000, Paddr 0x80200000: aligned kilopage
|
||||||
.8byte 0x0000000080019010, 0x00000000200810DF, 0x0 # Vaddr 0x80202000, Paddr 0x80204000: bad PTE has W but not R
|
.8byte 0x0000000080019010, 0x00000000200810DF, 0x0 # Vaddr 0x80202000, Paddr 0x80204000: bad PTE has W but not R
|
||||||
.8byte 0x0000000080019018, 0x0000000020080817, 0x0 # Vaddr 0x80203000, Paddr 0x80202000: A=0, should cause read fault
|
.8byte 0x0000000080019018, 0x0000000020080817, 0x0 # Vaddr 0x80203000, Paddr 0x80202000: A=0, should cause read fault
|
||||||
|
@ -104,7 +108,7 @@
|
||||||
.8byte 0x80203AA0, 0x0440DEADBEEF0BB0, 0x1
|
.8byte 0x80203AA0, 0x0440DEADBEEF0BB0, 0x1
|
||||||
|
|
||||||
# test 12.3.1.1.4 check translation works in sv48, read the same values from previous tests, this time with Vaddrs
|
# test 12.3.1.1.4 check translation works in sv48, read the same values from previous tests, this time with Vaddrs
|
||||||
.8byte 0x0, 0x0, 0x6 # satp.MODE = sv48, Nothing written to output
|
.8byte 0x0, 0x0, 0x6 # satp.MODE = sv48, current VPN: megapage at 0x80000000. Nothing written to output
|
||||||
.8byte 0x10082777778, 0x0EE0DEADBEEF0CC0, 0x1 # terapage at Vaddr 0x010000000000, Paddr 0x0
|
.8byte 0x10082777778, 0x0EE0DEADBEEF0CC0, 0x1 # terapage at Vaddr 0x010000000000, Paddr 0x0
|
||||||
.8byte 0x8005BC0AB0, 0x0000DEADBEEF0000, 0x1 # gigapage at Vaddr 0x008000000000, Paddr 0x80000000
|
.8byte 0x8005BC0AB0, 0x0000DEADBEEF0000, 0x1 # gigapage at Vaddr 0x008000000000, Paddr 0x80000000
|
||||||
.8byte 0x800F0AB8, 0x0880DEADBEEF0055, 0x1 # megapage at Vaddr 0x80000000, Paddr 0x80000000
|
.8byte 0x800F0AB8, 0x0880DEADBEEF0055, 0x1 # megapage at Vaddr 0x80000000, Paddr 0x80000000
|
||||||
|
@ -135,13 +139,13 @@
|
||||||
# test 12.3.1.3.1 User flag == 0
|
# test 12.3.1.3.1 User flag == 0
|
||||||
# reads on pages with U=0 already tested in 12.3.1.1.4
|
# reads on pages with U=0 already tested in 12.3.1.1.4
|
||||||
.8byte 0x008000099000, 0x111, 0x2 # execute success when U=0, priv=S
|
.8byte 0x008000099000, 0x111, 0x2 # execute success when U=0, priv=S
|
||||||
.8byte 0x201, 0x12, 0xA # go to U mode, return to gigapage at 0x008040000000 where PTE.U = 1. 0x9 written to output
|
.8byte 0x008040000000, 0x1, 0xA # go to U mode, return to gigapage at 0x008040000000 where PTE.U = 1. 0x9 written to output
|
||||||
.8byte 0xFFFFFFFFFFFFFC80, 0x0880DEADBEEF0550, 0x1 # read fault when U=0, priv=U
|
.8byte 0xFFFFFFFFFFFFFC80, 0x0880DEADBEEF0550, 0x1 # read fault when U=0, priv=U
|
||||||
.8byte 0x008000099000, 0xbad, 0x2 # execute fault when U=0, priv=U
|
.8byte 0x008000099000, 0xbad, 0x2 # execute fault when U=0, priv=U
|
||||||
|
|
||||||
# test 12.3.1.3.2 User flag == 1
|
# test 12.3.1.3.2 User flag == 1
|
||||||
.8byte 0x80201AC0, 0x0990DEADBEEF0033, 0x1 # read success when U=1, priv=U
|
.8byte 0x80201AC0, 0x0990DEADBEEF0033, 0x1 # read success when U=1, priv=U
|
||||||
.8byte 0x400, 0x21, 0x9 # go back to S mode, return to megapage at 0x80000000 where PTE.U = 0. 0x8 written to output
|
.8byte 0x80000000, 0x2, 0x9 # go back to S mode, return to megapage at 0x80000000 where PTE.U = 0. 0x8 written to output
|
||||||
.8byte 0x0, 0x3, 0x7 # set sstatus.[MXR, SUM] = 11
|
.8byte 0x0, 0x3, 0x7 # set sstatus.[MXR, SUM] = 11
|
||||||
.8byte 0x80201130, 0x0110DEADBEEF0077, 0x1 # read success when U=1, priv=S, sstatus.SUM=1
|
.8byte 0x80201130, 0x0110DEADBEEF0077, 0x1 # read success when U=1, priv=S, sstatus.SUM=1
|
||||||
.8byte 0x80201400, 0xbad, 0x2 # execute fault when U=1, priv=S (with any sstatus.SUM)
|
.8byte 0x80201400, 0xbad, 0x2 # execute fault when U=1, priv=S (with any sstatus.SUM)
|
||||||
|
@ -158,7 +162,7 @@
|
||||||
# test 12.3.1.3.4 Write flag
|
# test 12.3.1.3.4 Write flag
|
||||||
.8byte 0x10080BCDED8, 0x0440DEADBEEF0110, 0x0 # write success when W=1 (corresponding Paddr = 0x80BCDED8)
|
.8byte 0x10080BCDED8, 0x0440DEADBEEF0110, 0x0 # write success when W=1 (corresponding Paddr = 0x80BCDED8)
|
||||||
.8byte 0x10080BCDED8, 0x0440DEADBEEF0110, 0x1 # check write success by reading value back
|
.8byte 0x10080BCDED8, 0x0440DEADBEEF0110, 0x1 # check write success by reading value back
|
||||||
.8byte 0x80C0009E88, 0x0220DEADBEEF0BB0, 0x0 # write fault when W=0
|
.8byte 0x8000009E88, 0x0220DEADBEEF0BB0, 0x0 # write fault when W=0
|
||||||
|
|
||||||
# test 12.3.1.3.5 eXecute flag
|
# test 12.3.1.3.5 eXecute flag
|
||||||
# executes on pages with X = 1 already tested in 12.3.1.3.1
|
# executes on pages with X = 1 already tested in 12.3.1.3.1
|
||||||
|
|
|
@ -60,7 +60,6 @@
|
||||||
.8byte 0x0, 0x0018900C0009001F, 0xD # write pmpcfg0, output 0x0018900C0009001F
|
.8byte 0x0, 0x0018900C0009001F, 0xD # write pmpcfg0, output 0x0018900C0009001F
|
||||||
.8byte 0x2, 0x1F00000000000000, 0xD # write pmpcfg2, output 0x1F00000000000000
|
.8byte 0x2, 0x1F00000000000000, 0xD # write pmpcfg2, output 0x1F00000000000000
|
||||||
|
|
||||||
|
|
||||||
# write known values to memory where W=0. This should be possible since we're in machine mode.
|
# write known values to memory where W=0. This should be possible since we're in machine mode.
|
||||||
.8byte 0x80100010, 0x600DAA, 0x0 # write to pmpaddr 1-2 range
|
.8byte 0x80100010, 0x600DAA, 0x0 # write to pmpaddr 1-2 range
|
||||||
.8byte 0x80100400, 0x600DBB, 0x0 # write to pmpaddr 6 range
|
.8byte 0x80100400, 0x600DBB, 0x0 # write to pmpaddr 6 range
|
||||||
|
@ -101,12 +100,10 @@
|
||||||
.8byte 0x80100208, 0x600D15, 0x0 # Write fault on no-access range (PMP6)
|
.8byte 0x80100208, 0x600D15, 0x0 # Write fault on no-access range (PMP6)
|
||||||
.8byte 0x80100208, 0x600D15, 0x1 # read fault on no-access range (PMP6)
|
.8byte 0x80100208, 0x600D15, 0x1 # read fault on no-access range (PMP6)
|
||||||
|
|
||||||
############## *********** Test works up to here. Adding in these tests somehow exes out the regions of memory where we wrote the original pmpaddr values to it.
|
# test jalr to region with X=0 causes access fault
|
||||||
|
.8byte 0x80100020, 0xbad, 0x2 # execute fault on no-execute range (PMP2)
|
||||||
|
|
||||||
# # test jalr to region with X=0 causes access fault
|
# test jalr to region with X=1 returns successfully
|
||||||
# .8byte 0x80100020, 0xbad, 0x2 # execute fault on no-execute range (PMP2)
|
.8byte 0x80100200, 0x111, 0x2 # execute success when X=1
|
||||||
|
|
||||||
# # test jalr to region with X=1 returns successfully
|
|
||||||
# .8byte 0x80100200, 0x111, 0x2 # execute success when X=1
|
|
||||||
|
|
||||||
.8byte 0x0, 0x0, 0x3 // terminate tests
|
.8byte 0x0, 0x0, 0x3 // terminate tests
|
||||||
|
|
|
@ -31,26 +31,7 @@ rvtest_entry_point:
|
||||||
RVMODEL_BOOT
|
RVMODEL_BOOT
|
||||||
RVTEST_CODE_BEGIN
|
RVTEST_CODE_BEGIN
|
||||||
|
|
||||||
/*
|
# ---------------------------------------------------------------------------------------------
|
||||||
#include "riscv_test_macros.h"
|
|
||||||
#include "compliance_test.h"
|
|
||||||
#include "compliance_io.h"
|
|
||||||
|
|
||||||
RV_COMPLIANCE_RV64M
|
|
||||||
|
|
||||||
RV_COMPLIANCE_CODE_BEGIN
|
|
||||||
|
|
||||||
|
|
||||||
RVTEST_IO_INIT
|
|
||||||
RVTEST_IO_ASSERT_GPR_EQ(x31, x0, 0x00000000)
|
|
||||||
RVTEST_IO_WRITE_STR(x31, "Test Begin\n")
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
RVTEST_IO_WRITE_STR(x31, "# Test group 1\n")
|
|
||||||
*/
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------------------------
|
|
||||||
# Initialization Overview:
|
# Initialization Overview:
|
||||||
#
|
#
|
||||||
# Initialize x6 as a virtual pointer to the test results
|
# Initialize x6 as a virtual pointer to the test results
|
||||||
|
@ -68,9 +49,14 @@ RV_COMPLIANCE_CODE_BEGIN
|
||||||
# address for stack
|
# address for stack
|
||||||
la sp, top_of_stack
|
la sp, top_of_stack
|
||||||
|
|
||||||
# address for trap handler
|
# trap handler setup
|
||||||
la x1, machine_trap_handler
|
la x1, machine_trap_handler
|
||||||
csrrw x4, mtvec, x1 # x4 reserved for "default" trap handler address that needs to be restored before halting this test.
|
csrrw x4, mtvec, x1 # x4 reserved for "default" trap handler address that needs to be restored before halting this test.
|
||||||
|
li a0, 0
|
||||||
|
li a1, 0
|
||||||
|
li a2, 0 # reset trap handler inputs to zero
|
||||||
|
|
||||||
|
# go to first test!
|
||||||
j test_setup
|
j test_setup
|
||||||
|
|
||||||
|
|
||||||
|
@ -92,23 +78,19 @@ RV_COMPLIANCE_CODE_BEGIN
|
||||||
# 4: go to user mode
|
# 4: go to user mode
|
||||||
# others: do nothing
|
# others: do nothing
|
||||||
#
|
#
|
||||||
# a1 (x11): Upper bits of change of return address after trap
|
# a1 (x11):
|
||||||
# Put it in the bottom bits of a1. *** soon to be changed to just the base address of the return page.
|
# VPN for return address after changing privilege mode.
|
||||||
# Default : 0x0 (defaults to the next instruction in the same location as the return address)
|
# This should be the base VPN with no offset.
|
||||||
# Terapage: returnAddr[END-1:39]
|
# 0x0 : defaults to next instruction on the same page the trap was called on.
|
||||||
# Gigapage: returnAddr[END-1:30]
|
|
||||||
# Megapage: returnAddr[END-1:21]
|
|
||||||
# Kilopage: returnAddr[END-1:12] (this value also works for baremetal)
|
|
||||||
|
|
||||||
# a2 (x12): Pagetype for change of return address after trap
|
|
||||||
# Put the Source page in a2[7:4] and Dest page in a2[3:0]
|
|
||||||
# Ex: giga -> mega a2=0x21
|
|
||||||
#
|
#
|
||||||
# Default : Ignored if a1 == 0x0
|
# a2 (x12):
|
||||||
# Terapage: 3
|
# Pagetype of the current address VPN before changing privilge mode
|
||||||
# Gigapage: 2
|
# Used so that we can know how many bits of the adress are the offset.
|
||||||
# Megapage: 1
|
# Ignored if a1 == 0x0
|
||||||
# Kilopage: 0
|
# 0: Kilopage
|
||||||
|
# 1: Megapage
|
||||||
|
# 2: Gigapage
|
||||||
|
# 3: Terapage
|
||||||
#
|
#
|
||||||
# --------------------------------------------------------------------------------------------
|
# --------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -174,51 +156,37 @@ trapreturn_specified:
|
||||||
|
|
||||||
beqz a1, trapreturn_finished # either update values, of go to default return address.
|
beqz a1, trapreturn_finished # either update values, of go to default return address.
|
||||||
|
|
||||||
# Get Mask Bits
|
|
||||||
la x5, trap_return_pagetype_table
|
la x5, trap_return_pagetype_table
|
||||||
mv x7, a2
|
|
||||||
li x28, 0xF0 # mask bits for current pagetype
|
|
||||||
and x7, x28, x7
|
|
||||||
srli x7, x7, 1
|
|
||||||
add x5, x5, x7
|
|
||||||
ld x7, 0(x5) # x7 = number of offset bits in current page type
|
|
||||||
|
|
||||||
la x5, trap_return_pagetype_table
|
|
||||||
li x28, 0xF # mask bits for new pagetype
|
|
||||||
and a2, x28, a2
|
|
||||||
slli a2, a2, 3
|
slli a2, a2, 3
|
||||||
add x5, x5, a2
|
add x5, x5, a2
|
||||||
ld a2, 0(x5) # a2 = number of offset bits in new page type
|
ld a2, 0(x5) # a2 = number of offset bits in current page type
|
||||||
|
|
||||||
li x5, 1
|
li x5, 1
|
||||||
sll x5, x5, x7
|
sll x5, x5, a2
|
||||||
addi x5, x5, -1 # x5 = mask bits for offset into current pagetype
|
addi x5, x5, -1 # x5 = mask bits for offset into current pagetype
|
||||||
|
|
||||||
# *** This shoulf be removed
|
# reset the top of the stack, x1
|
||||||
sll a1, a1, a2 # a1 = the VPN of the new return page.
|
ld x7, -8(sp)
|
||||||
|
|
||||||
# set x1, the stack pointer, to the new virtual address
|
|
||||||
ld x7, -8(sp)
|
|
||||||
and x7, x5, x7 # x7 = offset for x1
|
and x7, x5, x7 # x7 = offset for x1
|
||||||
add x7, x7, a1 # x7 = new address for x1
|
add x7, x7, a1 # x7 = new address for x1
|
||||||
sd x7, -8(sp)
|
sd x7, -8(sp)
|
||||||
|
|
||||||
# set x5, the pointer for where we are in the test cases, to the new virtual address
|
# reset the second spot in the stack, x5
|
||||||
ld x7, -16(sp)
|
ld x7, -16(sp)
|
||||||
and x7, x5, x7 # x7 = offset for x5
|
and x7, x5, x7 # x7 = offset for x5
|
||||||
add x7, x7, a1 # x7 = new address for x5
|
add x7, x7, a1 # x7 = new address for x5
|
||||||
sd x7, -16(sp)
|
sd x7, -16(sp)
|
||||||
|
|
||||||
# set x6, the pointer for the virtual address of the output of the tests, to the new virtual address
|
# reset x6, the pointer for the virtual address of the output of the tests
|
||||||
and x7, x5, x6 # x7 = offset for x6
|
and x7, x5, x6 # x7 = offset for x6
|
||||||
add x6, x7, a1 # x6 = new address for the result pointer
|
add x6, x7, a1 # x6 = new address for the result pointer
|
||||||
|
|
||||||
# set return address to the next instruction, but in the new virtual page.
|
# set return address, stored temporarily in x1, to the next instruction, but in the new virtual page.
|
||||||
and x1, x5, x1 # x1 = offset for the return address
|
and x1, x5, x1 # x1 = offset for the return address
|
||||||
add x1, x1, a1 # x1 = new return address.
|
add x1, x1, a1 # x1 = new return address.
|
||||||
|
|
||||||
li a1, 0
|
li a1, 0
|
||||||
li a2, 0 # reset inputs to the trap handler
|
li a2, 0 # reset trapreturn inputs to the trap handler
|
||||||
|
|
||||||
trapreturn_finished:
|
trapreturn_finished:
|
||||||
csrw mepc, x1 # update the mepc with address of next instruction
|
csrw mepc, x1 # update the mepc with address of next instruction
|
||||||
|
@ -640,14 +608,14 @@ RVTEST_DATA_END
|
||||||
|
|
||||||
.align 3 # align stack to 8 byte boundary
|
.align 3 # align stack to 8 byte boundary
|
||||||
bottom_of_stack:
|
bottom_of_stack:
|
||||||
.fill 1024, 4, -1
|
.fill 1024, 4, 0xdeadbeef
|
||||||
top_of_stack:
|
top_of_stack:
|
||||||
|
|
||||||
|
|
||||||
RVMODEL_DATA_BEGIN
|
RVMODEL_DATA_BEGIN
|
||||||
|
|
||||||
test_1_res:
|
test_1_res:
|
||||||
.fill 1024, 4, -1
|
.fill 1024, 4, 0xdeadbeef
|
||||||
|
|
||||||
RVMODEL_DATA_END
|
RVMODEL_DATA_END
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue