Skip to content

Commit bc32933

Browse files
nemecadjdupak
authored andcommitted
Tests: add integration test for SV32 page-table and TLB
Add a set of small assembly tests that exercise the SV32 page-table walker, SATP enablement and the new TLB code. The tests create a root page table and map a virtual page at 0xC4000000, then exercise several scenarios. The tests verify page-table walker behaviour, SATP switching and TLB caching/flush logic. Tests were written based on the consultation.
1 parent 14153a3 commit bc32933

File tree

6 files changed

+637
-1
lines changed

6 files changed

+637
-1
lines changed

tests/cli/stalls/stdout.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ Machine stopped on BREAK exception.
22
Machine state report:
33
PC:0x00000244
44
R0:0x00000000 R1:0x00000011 R2:0x00000022 R3:0x00000033 R4:0x00000000 R5:0x00000055 R6:0x00000000 R7:0x00000000 R8:0x00000000 R9:0x00000000 R10:0x00000000 R11:0x00000000 R12:0x00000000 R13:0x00000000 R14:0x00000000 R15:0x00000000 R16:0x00000000 R17:0x00000000 R18:0x00000000 R19:0x00000000 R20:0x00000000 R21:0x00000011 R22:0x00000022 R23:0x00000033 R24:0x00000044 R25:0x00000055 R26:0x00000000 R27:0x00000000 R28:0x00000000 R29:0x00000000 R30:0x00000000 R31:0x00000000
5-
cycle: 0x0000000c mvendorid: 0x00000000 marchid: 0x00000000 mimpid: 0x00000000 mhardid: 0x00000000 mstatus: 0x00000000 misa: 0x40001111 mie: 0x00000000 mtvec: 0x00000000 mscratch: 0x00000000 mepc: 0x00000240 mcause: 0x00000003 mtval: 0x00000000 mip: 0x00000000 mtinst: 0x00000000 mtval2: 0x00000000 mcycle: 0x0000000c minstret: 0x0000000b
5+
cycle: 0x0000000c mvendorid: 0x00000000 marchid: 0x00000000 mimpid: 0x00000000 mhardid: 0x00000000 mstatus: 0x00000000 misa: 0x40001111 mie: 0x00000000 mtvec: 0x00000000 mscratch: 0x00000000 mepc: 0x00000240 mcause: 0x00000003 mtval: 0x00000000 mip: 0x00000000 mtinst: 0x00000000 mtval2: 0x00000000 mcycle: 0x0000000c minstret: 0x0000000b sstatus: 0x00000000 stvec: 0x00000000 sscratch: 0x00000000 sepc: 0x00000000 scause: 0x00000000 stval: 0x00000000 satp: 0x00000000

tests/vm_assmebly/vm_template.s

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
// Test template: Sets up a page table, enables virtual memory, and prints "Hello world" via serial port.
2+
3+
.globl _start
4+
.option norelax
5+
6+
// Serial port/terminal registers
7+
.equ SERIAL_PORT_BASE, 0xffffc000 // base address of serial port region
8+
.equ SERP_RX_ST_REG_o, 0x0000 // Offset of RX_ST_REG
9+
.equ SERP_RX_DATA_REG_o, 0x0004 // Offset of RX_DATA_REG
10+
.equ SERP_TX_ST_REG_o, 0x0008 // Offset of TX_ST_REG
11+
.equ SERP_TX_ST_REG_READY_m,0x1 // Transmitter can accept next byte
12+
.equ SERP_TX_DATA_REG_o, 0x000c // Offset of TX_DATA_REG
13+
14+
.equ ROOT_PT_PHYS, 0x1000
15+
.equ MAP_VA, 0xC4000000
16+
17+
// PTE flags: 0xCF = 11001111
18+
// bit0 V = 1 (Valid)
19+
// bit1 R = 1 (Readable)
20+
// bit2 W = 1 Writable)
21+
// bit3 X = 1 (Executable)
22+
// bit4 U = 0 (NOT user-accessible)
23+
// bit5 G = 0 (NOT global)
24+
// bit6 A = 1 (Accessed)
25+
// bit7 D = 1 (Dirty)
26+
.equ PTE_FLAGS_FULL, 0xCF
27+
28+
// mstatus MPP manipulation masks (for preparing mret to change privilege)
29+
.equ MSTATUS_MPP_CLEAR, 0x1000 // mask to clear MPP[12] (set bit 12 -> will be cleared via csrrc)
30+
.equ MSTATUS_MPP_SET, 0x800 // mask to set MPP[11] (set bit 11 -> will be set via csrrs)
31+
32+
.equ SATP_ENABLE, 0x80000001 // satp value to enable paging (implementation-specific)
33+
34+
.org 0x00000200
35+
.text
36+
_start:
37+
// t0 = physical address of root page table
38+
li t0, ROOT_PT_PHYS
39+
40+
// t4 = virtual address we want to map (MAP_VA)
41+
li t4, MAP_VA
42+
43+
// Build a leaf PTE value in t1:
44+
// Take VA >> 12 (remove page offset) then shift left 10 to position PPN bits for a PTE,
45+
// then OR in the PTE flags.
46+
srli t1, t4, 12 // t1 = MAP_VA >> 12 (page number)
47+
slli t1, t1, 10 // t1 <<= 10 to position as PPN bits for a PTE entry
48+
li t6, PTE_FLAGS_FULL // t6 = flags
49+
or t1, t1, t6 // t1 = (PPN << 10) | PTE_FLAGS_FULL
50+
51+
// Calculate the root page table entry index for the high VPN (VPN[1]):
52+
// t5 = MAP_VA >> 22 (VPN[1])
53+
// t2 = t5 << 2 (multiply by 4 bytes per PTE to get byte offset)
54+
// t3 = root_pt_phys + offset (address of PTE in root page table)
55+
srli t5, t4, 22
56+
slli t2, t5, 2
57+
add t3, t0, t2
58+
59+
// Store the constructed PTE into the root page table (making a mapping)
60+
sw t1, 0(t3)
61+
fence
62+
63+
// Ensure satp is cleared before setting new value (flush previous translations)
64+
li t0, 0
65+
csrw satp, t0
66+
67+
// Enable the MMU by writing SATP; this switches address translation on
68+
li t0, SATP_ENABLE
69+
csrw satp, t0
70+
fence
71+
72+
// Prepare mstatus MPP so that mret will return to Supervisor mode:
73+
// Clear MPP[12] bit then set MPP[11] bit (resulting MPP=01 => Supervisor).
74+
li t0, MSTATUS_MPP_CLEAR
75+
csrrc zero, mstatus, t0 // clear bit 12 of mstatus.MPP
76+
li t0, MSTATUS_MPP_SET
77+
csrrs zero, mstatus, t0 // set bit 11 of mstatus.MPP
78+
79+
// Set mepc to the virtual address of vm_entry and return from machine mode to
80+
// the prepared privilege level (Supervisor) using mret.
81+
la t0, vm_entry // load address of vm_entry (virtual address after mapping)
82+
csrw mepc, t0
83+
mret
84+
85+
.org 0xC4000000
86+
.text
87+
vm_entry:
88+
li a0, SERIAL_PORT_BASE
89+
la a1, hello_str
90+
91+
print_next_char:
92+
// Load next byte from string; if zero (end), branch to done
93+
lb t1, 0(a1)
94+
beq t1, zero, print_done
95+
addi a1, a1, 1 // advance to next character
96+
97+
wait_tx_ready:
98+
// Poll transmit status register until TX ready bit is set
99+
lw t0, SERP_TX_ST_REG_o(a0)
100+
andi t0, t0, SERP_TX_ST_REG_READY_m
101+
beq t0, zero, wait_tx_ready
102+
103+
// Write byte to transmit-data register and loop for next char
104+
sw t1, SERP_TX_DATA_REG_o(a0)
105+
jal zero, print_next_char
106+
107+
print_done:
108+
ebreak
109+
110+
1: auipc t0, 0
111+
jalr zero, 0(t0)
112+
113+
.data
114+
.org 0xC4000100
115+
hello_str:
116+
.asciz "Hello world.\n"

tests/vm_assmebly/vm_test_dtlb.s

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
// D-TLB test — map data pages at MAP_VA; write 'A'..'H' to the first byte of eight pages and read/print them.
2+
3+
.globl _start
4+
.option norelax
5+
6+
// Serial port/terminal registers
7+
.equ SERIAL_PORT_BASE, 0xffffc000 // base address of serial port region
8+
.equ SERP_RX_ST_REG_o, 0x0000 // Offset of RX_ST_REG
9+
.equ SERP_RX_DATA_REG_o, 0x0004 // Offset of RX_DATA_REG
10+
.equ SERP_TX_ST_REG_o, 0x0008 // Offset of TX_ST_REG
11+
.equ SERP_TX_ST_REG_READY_m,0x1 // Transmitter can accept next byte
12+
.equ SERP_TX_DATA_REG_o, 0x000c // Offset of TX_DATA_REG
13+
14+
.equ ROOT_PT_PHYS, 0x1000
15+
.equ MAP_VA, 0xC4000000
16+
17+
// PTE flags: 0xCF = 11001111
18+
// bit0 V = 1 (Valid)
19+
// bit1 R = 1 (Readable)
20+
// bit2 W = 1 Writable)
21+
// bit3 X = 1 (Executable)
22+
// bit4 U = 0 (NOT user-accessible)
23+
// bit5 G = 0 (NOT global)
24+
// bit6 A = 1 (Accessed)
25+
// bit7 D = 1 (Dirty)
26+
.equ PTE_FLAGS_FULL, 0xCF
27+
28+
// mstatus MPP manipulation masks (for preparing mret to change privilege)
29+
.equ MSTATUS_MPP_CLEAR, 0x1000 // mask to clear MPP[12] (set bit 12 -> will be cleared via csrrc)
30+
.equ MSTATUS_MPP_SET, 0x800 // mask to set MPP[11] (set bit 11 -> will be set via csrrs)
31+
32+
.equ SATP_ENABLE, 0x80000001 // satp value to enable paging (implementation-specific)
33+
34+
.org 0x00000200
35+
.text
36+
_start:
37+
// t0 = physical address of root page table
38+
li t0, ROOT_PT_PHYS
39+
40+
// t4 = virtual address we want to map (MAP_VA)
41+
li t4, MAP_VA
42+
43+
// Compute level-1 table index for MAP_VA and form address of PTE in root page table.
44+
// srli/slli extracts bits for index and scales by 4 (word-sized PTEs).
45+
srli t3, t2, 22
46+
slli t3, t3, 2
47+
add t4, t0, t3
48+
49+
// Build leaf PTE: physical page number (vpn->ppn shift) | flags.
50+
// srli/slli moves MAP_VA to form the physical page number field in the PTE.
51+
srli t5, t2, 12
52+
slli t5, t5, 10
53+
li t6, PTE_FLAGS_FULL
54+
or t5, t5, t6
55+
sw t5, 0(t4)
56+
fence
57+
58+
// Enable paging: write SATP with implementation-specific value.
59+
li t0, 0
60+
csrw satp, t0
61+
li t0, SATP_ENABLE
62+
csrw satp, t0
63+
fence
64+
65+
// Prepare mstatus.MPP so mret will return to Supervisor (set bits appropriately).
66+
li t0, MSTATUS_MPP_CLEAR
67+
csrrc zero, mstatus, t0
68+
li t0, MSTATUS_MPP_SET
69+
csrrs zero, mstatus, t0
70+
71+
// Set mepc to vm_entry and enter Supervisor with mret.
72+
la t0, vm_entry
73+
csrw mepc, t0
74+
mret
75+
76+
.org 0xC4000000
77+
.text
78+
vm_entry:
79+
li t0, SERIAL_PORT_BASE
80+
la t1, MAP_VA // pointer to start of mapped virtual region
81+
li t2, 0 // page counter
82+
li t3, 8 // number of pages to write/read (A..H)
83+
li t4, 65 // ASCII 'A'
84+
li t5, 0x1000 // page size (4KB)
85+
86+
// write_pages_loop: write one byte (A..H) at the start of each mapped page.
87+
write_pages_loop:
88+
sb t4, 0(t1)
89+
add t1, t1, t5
90+
addi t4, t4, 1
91+
addi t2, t2, 1
92+
blt t2, t3, write_pages_loop
93+
94+
// Reset pointer and counter to read back and print the first byte of each page.
95+
la t1, MAP_VA
96+
li t2, 0
97+
98+
read_print_loop:
99+
lb t6, 0(t1) // load the byte stored at start of current page
100+
101+
// wait_tx: poll transmitter status until ready, then write byte to TX data reg.
102+
wait_tx:
103+
lw t4, SERP_TX_ST_REG_o(t0)
104+
andi t4, t4, SERP_TX_ST_REG_READY_m
105+
beq t4, zero, wait_tx
106+
sw t6, SERP_TX_DATA_REG_o(t0)
107+
108+
add t1, t1, t5
109+
addi t2, t2, 1
110+
blt t2, t3, read_print_loop
111+
112+
ebreak
113+
114+
1: auipc t0, 0
115+
jalr zero, 0(t0)

tests/vm_assmebly/vm_test_exec.s

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// Place a tiny function in the mapped virtual page and jump to it (tests X bit).
2+
3+
.globl _start
4+
.option norelax
5+
6+
// Serial port/terminal registers
7+
.equ SERIAL_PORT_BASE, 0xffffc000 // base address of serial port region
8+
.equ SERP_RX_ST_REG_o, 0x0000 // Offset of RX_ST_REG
9+
.equ SERP_RX_DATA_REG_o, 0x0004 // Offset of RX_DATA_REG
10+
.equ SERP_TX_ST_REG_o, 0x0008 // Offset of TX_ST_REG
11+
.equ SERP_TX_ST_REG_READY_m,0x1 // Transmitter can accept next byte
12+
.equ SERP_TX_DATA_REG_o, 0x000c // Offset of TX_DATA_REG
13+
14+
.equ ROOT_PT_PHYS, 0x1000
15+
.equ MAP_VA, 0xC4000000
16+
17+
// PTE flags: 0xCF = 11001111
18+
// bit0 V = 1 (Valid)
19+
// bit1 R = 1 (Readable)
20+
// bit2 W = 1 Writable)
21+
// bit3 X = 1 (Executable)
22+
// bit4 U = 0 (NOT user-accessible)
23+
// bit5 G = 0 (NOT global)
24+
// bit6 A = 1 (Accessed)
25+
// bit7 D = 1 (Dirty)
26+
.equ PTE_FLAGS_FULL, 0xCF
27+
28+
// mstatus MPP manipulation masks (for preparing mret to change privilege)
29+
.equ MSTATUS_MPP_CLEAR, 0x1000 // mask to clear MPP[12] (set bit 12 -> will be cleared via csrrc)
30+
.equ MSTATUS_MPP_SET, 0x800 // mask to set MPP[11] (set bit 11 -> will be set via csrrs)
31+
32+
.equ SATP_ENABLE, 0x80000001 // satp value to enable paging (implementation-specific)
33+
34+
.org 0x00000200
35+
.text
36+
_start:
37+
// t0 = physical address of root page table
38+
li t0, ROOT_PT_PHYS
39+
40+
// t4 = virtual address we want to map (MAP_VA)
41+
li t4, MAP_VA
42+
43+
// Build leaf PTE
44+
srli t1, t4, 12
45+
slli t1, t1, 10
46+
li t6, PTE_FLAGS_FULL
47+
or t1, t1, t6
48+
49+
srli t5, t4, 22
50+
slli t2, t5, 2
51+
add t3, t0, t2
52+
sw t1, 0(t3)
53+
fence
54+
55+
// Enable SATP
56+
li t0, 0
57+
csrw satp, t0
58+
li t0, SATP_ENABLE
59+
csrw satp, t0
60+
fence
61+
62+
// Prepare mstatus.MPP to return to Supervisor
63+
li t0, MSTATUS_MPP_CLEAR
64+
csrrc zero, mstatus, t0
65+
li t0, MSTATUS_MPP_SET
66+
csrrs zero, mstatus, t0
67+
68+
la t0, vm_entry
69+
csrw mepc, t0
70+
mret
71+
72+
.org 0xC4000000
73+
.text
74+
vm_entry:
75+
li a0, SERIAL_PORT_BASE
76+
77+
// Call the function placed in the same mapped page
78+
la t0, mapped_function
79+
jalr zero, 0(t0)
80+
81+
ebreak
82+
83+
// small function placed in the mapped page
84+
.org 0xC4000100
85+
mapped_function:
86+
li a0, SERIAL_PORT_BASE
87+
li t1, 88
88+
wait_tx:
89+
lw t0, SERP_TX_ST_REG_o(a0)
90+
andi t0, t0, SERP_TX_ST_REG_READY_m
91+
beq t0, zero, wait_tx
92+
sw t1, SERP_TX_DATA_REG_o(a0)
93+
ebreak

0 commit comments

Comments
 (0)