code wiki / _hdl_build / rv64im_min_mmu.nx

rv64im_min_mmu.nx

buildroot/runtime/_hdl_build/rv64im_min_mmu.nx

8859 B176 linesdepth 3pulls 3 transitivereach 45 importersview sourcekind librarytopic rv64im
docsdependenciesstructsconstsfunctions

about

rv64im_min_mmu.nx -- the Sv39 PAGE-TABLE-WALK device (virtual-memory-paging-mmu). The genuine hard core of paging: a SOVEREIGN Sv39 multi-level address-translation datapath. On a doorbell the device reads satp (root page-table PPN + MODE) and a virtual address, WALKS the 3-level Sv39 page table in guest RAM (level 2->1->0, checking each PTE's Valid bit and detecting a leaf via the R/W/X bits, assembling the physical address with the right page size for the leaf level -- gigapage/megapage/4K), and latches the translated PADDR + a FAULT flag (set on an invalid PTE or a walk that reaches no leaf). This is the MMU's translation algorithm, exercised end-to-end by a driver (emitted by nx_drv_proto_emit) -- the same MMIO+doorbell pattern as the virtio/nndev devices. Wiring translation transparently into the CPU's load/store datapath + privilege modes + page-fault traps is the documented follow-on rung (this proves the WALK). Register window @ NX_MMU_BASE (256 bytes), independent instance (other devices untouched): 0x00 SATP_LO (WO) low 32 bits of satp (root PPN) 0x04 SATP_HI (WO) high 32 bits of satp (MODE in bits 31:28 -> satp bits 63:60; 8 = Sv39) 0x08 VADDR (WO) the (low 32 of the) virtual address to translate 0x0C DOORBELL (WO) write 1 -> walk the page table in guest RAM, latch PADDR + FAULT 0x10 PADDR (RO) translated physical address (low 32) from the last walk 0x14 FAULT (RO) 0 = translated OK; 1 = page fault (invalid PTE / no leaf) Status: SEED 2026-06-13 (virtual-memory-paging-mmu, Sv39 walk). license_tier: ORIGINAL

dependencies 2 imports · 8 importers

nx_syscalls.nx nishi_hdl_primitives.nx rv64im_min_mmu.nx nx_nxc_baremetal.nx nx_nxc_run.nx nx_rv64_kernel_gate.nx nx_rv64_mmu_oracle.nx nx_rv64_realc_gate.nx nx_rv64_run_bin.nx nx_rv64_timer_oracle.nx rv64im_min_sim.nx

imports: nx_syscalls.nxnishi_hdl_primitives.nx

imported by: nx_nxc_baremetal.nxnx_nxc_run.nxnx_rv64_kernel_gate.nxnx_rv64_mmu_oracle.nxnx_rv64_realc_gate.nxnx_rv64_run_bin.nxnx_rv64_timer_oracle.nxrv64im_min_sim.nx

structs

51struct NxMmu

consts

25const NX_MMU_BASE: i64 = 0x10006000
26const NX_MMU_END: i64 = 0x10006100
28const NX_MMU_OFF_SATPLO: i64 = 0x00
29const NX_MMU_OFF_SATPHI: i64 = 0x04
30const NX_MMU_OFF_VADDR: i64 = 0x08
31const NX_MMU_OFF_DOORBELL: i64 = 0x0C
32const NX_MMU_OFF_PADDR: i64 = 0x10
33const NX_MMU_OFF_FAULT: i64 = 0x14
35const NX_MMU_SLOT_SATPLO: i64 = 0
36const NX_MMU_SLOT_SATPHI: i64 = 1
37const NX_MMU_SLOT_VADDR: i64 = 2
38const NX_MMU_SLOT_PADDR: i64 = 3
39const NX_MMU_SLOT_FAULT: i64 = 4
40const NX_MMU_SLOT_N: i64 = 5
42const NX_MMU_OK: i64 = 0
43const NX_MMU_ADDR_OUT_OF_RANGE: i64 = 1
46const NX_SV39_MODE: i64 = 8
47const NX_PTE_V: i64 = 1 // Valid
48const NX_PTE_RWX: i64 = 0xE // R|W|X (bits 3:1); any set => leaf
49const NX_PPN_MASK: i64 = 0xFFFFFFFFFFF // 44-bit PPN

functions

57func nx_mmu_reset(storage: *i64) -> i64
called by 1: nx_mmu_init
66func nx_mmu_init(d: *NxMmu, storage: *i64) -> i64
called by 2: bootcap_runmain calls 1: nx_mmu_reset
76func nx_mmu_in_range(d: *NxMmu, addr: i64) -> i64
82func nx_mmu_read32(d: *NxMmu, addr: i64, value_out: *i64) -> i64
93func nx_mmu_write32(d: *NxMmu, addr: i64, value: i64) -> i64
105func nx_mmu_rd64(mem_buf: *u8, off: i64) -> i64
112func nx_mmu_wr64(mem_buf: *u8, off: i64, v: i64) -> i64
called by 1: nx_rv64im_xlate
117func nx_mmu_inrange(off: i64, w: i64, mem_size: i64) -> i64 { if off < 0 { return 0 } if off > mem_size - w { return 0 } return 1 }
128func nx_sv39_walk(satp: i64, mem_buf: *u8, mem_base: i64, mem_size: i64, vaddr: i64, fault_out: *i64, perm_out: *i64, pte_addr_out: *i64) -> i64
164func nx_mmu_doorbell_walk(d: *NxMmu, mem_buf: *u8, mem_base: i64, mem_size: i64) -> i64