Files
Toooba/Tests/isa/PageRead.S
2026-03-05 15:45:05 +00:00

231 lines
5.9 KiB
ArmAsm

.option norvc
.option norelax
# ==================================================
# Text section
# ==================================================
.section .text
.globl _start
.globl vm_boot
_start:
vm_boot:
# --------------------------------------------------
# Only hart 0 runs
# --------------------------------------------------
csrr a0, mhartid
bnez a0, hang
# --------------------------------------------------
# Build page tables
# --------------------------------------------------
#
# Page table setup (Sv39) binary + hex example
#
# Purpose:
# Build a VALID page table entry (PTE) in the root page table
# that points to the next-level page table (l1_pt).
#
# Assume:
# l1_pt physical address =
# binary: 00000000 10000000 01000000 00110000 00000000
# hex: 0x0000000080403000
# (page aligned, lower 12 bits = 0)
#
# Step-by-step instruction meaning:
#
# la t0, l1_pt
# Load physical address of l1_pt.
#
# t0 =
# binary: 00000000 10000000 01000000 00110000 00000000
# hex: 0x0000000080403000
#
# srli t0, t0, 12
# Drop 12-bit page offset extract Physical Page Number (PPN).
#
# t0 (PPN) =
# binary: 00000000 00000000 10000000 01000000 0011
# hex: 0x0000000000080403
#
# slli t0, t0, 10
# Shift PPN into PTE bit positions [63:10].
# Bits [9:0] are flags.
#
# t0 =
# binary: 00000000 00000000 10000000 01000000 0011 0000000000
# hex: 0x0000000020100C00
#
# ori t0, t0, 1
# Set bit 0 (V = Valid).
#
# t0 (final PTE) =
# binary: 00000000 00000000 10000000 01000000 0011 0000000001
# hex: 0x0000000020100C01
#
# Memory effect:
#
# root_pt[0] =
# bit index:
# 63 10 9 0
# +----------------------------------+----------+
# | PPN = 0x0000000000080403 | V = 1 |
# +----------------------------------+----------+
#
# binary: 00000000 00000000 10000000 01000000 0011 0000000001
# hex: 0x0000000020100C01
#
# Result:
# Root page table entry 0 is VALID and points to l1_pt.
# The MMU uses this entry to continue the Sv39 page-table walk.
#
# root_pt[0] -> l1_pt
la t0, l1_pt
srli t0, t0, 12 # PPN
slli t0, t0, 10 # PTE format
ori t0, t0, 0x1 # V
la t1, root_pt
sd t0, 0(t1)
# l1_pt[0] -> l0_pt
la t0, l0_pt
srli t0, t0, 12
slli t0, t0, 10
ori t0, t0, 0x1 # V
la t1, l1_pt
sd t0, 0(t1)
# l0_pt[0] -> identity mapping (RWX)
li t0, (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<6) # V R W X A
la t1, l0_pt
sd t0, 0(t1)
# --------------------------------------------------
# Enable Sv39 paging
# --------------------------------------------------
# Enable virtual memory (Sv39) SATP setup diagram (binary)
#
# Assume:
# root_pt physical address =
# 00000000 10000000 01000000 00010000 00000000
# (4 KB aligned, lower 12 bits = 0)
#
# Instruction flow:
#
# la t0, root_pt
# t0 =
# 00000000 10000000 01000000 00010000 00000000
#
# srli t0, t0, 12 ; extract PPN
# t0 (PPN) =
# 00000000 00000000 10000000 01000000 0001
#
# li t1, (8 << 60) ; MODE = Sv39
# t1 =
# 1000 0000000000000000000000000000000000000000000000000000
# ^^^^
# MODE[63:60] = 1000 (Sv39)
#
# or t0, t0, t1
# satp value =
# 1000 0000000000000000000000000000000010000000010000000001
# |<-- MODE -->|<----------- ASID ---------->|<---- PPN ---->|
#
# csrw satp, t0
# satp register loaded:
#
# 63 60 59 44 43 0
# +------+----------------------------------+----------------+
# |1000 |0000000000000000 |0000000010000000010000000001|
# +------+----------------------------------+----------------+
# MODE=Sv39 ASID=0 root_pt PPN
#
# sfence.vma zero, zero
# Flush all TLB entries so new page tables are used
#
# Meaning:
# - Virtual memory enabled in Sv39 mode
# - Root page table base = root_pt
# - ASID = 0
# - MMU now performs 3-level page table walks
#
la t0, root_pt
srli t0, t0, 12
li t1, (8 << 60) # MODE=Sv39
or t0, t0, t1
csrw satp, t0
sfence.vma zero, zero
# --------------------------------------------------
# Write data to memory (safe area)
# --------------------------------------------------
la t2, test_buf
li t3, 0x1122334455667788
sd t3, 0(t2)
# --------------------------------------------------
# Read data back
# --------------------------------------------------
ld t4, 0(t2)
# Optional check (simple)
bne t3, t4, hang
# --------------------------------------------------
# Signal success
# --------------------------------------------------
la t0, tohost
li t1, 1
sd t1, 0(t0)
hang:
wfi
j hang
# ==================================================
# Required test symbol
# ==================================================
.globl exit
exit:
j exit
# ==================================================
# Data section
# ==================================================
.section .data
.align 3
.globl tohost
.globl fromhost
tohost:
.dword 0
fromhost:
.dword 0
# --------------------------------------------------
# Test buffer (safe data memory)
# --------------------------------------------------
.align 3
test_buf:
.zero 16
# --------------------------------------------------
# Page tables (must be 4 KiB each)
# --------------------------------------------------
.align 12
root_pt:
.zero 4096
.align 12
l1_pt:
.zero 4096
.align 12
l0_pt:
.zero 4096