Hello all;
I've been working with bare-metal Rust for the Pi 400 and have tried for the past week (Maybe two, time has melded together with this project) to enable the MMU and I have made next to no progress. I've dropped down to EL1 successfully, and I have a non-UART binary debugging method in place where, if it works, it hangs, and if it doesn't, it uses the watchdog to reboot. That said, whenever I try to generate the page tables, a synchronous exception is thrown. I'm not exactly sure what exact synchronous exception is thrown, but I've narrowed it down that much. The error is caused when I call a Rust function that generates page tables, specifically when it writes to the L1 table. The relevant code and comments are listed below.
Any advice or assistance would be greatly appreciated. Thank you all in advance!
(P.S. If you need any further code, I would be more than happy to oblige.)
I've been working with bare-metal Rust for the Pi 400 and have tried for the past week (Maybe two, time has melded together with this project) to enable the MMU and I have made next to no progress. I've dropped down to EL1 successfully, and I have a non-UART binary debugging method in place where, if it works, it hangs, and if it doesn't, it uses the watchdog to reboot. That said, whenever I try to generate the page tables, a synchronous exception is thrown. I'm not exactly sure what exact synchronous exception is thrown, but I've narrowed it down that much. The error is caused when I call a Rust function that generates page tables, specifically when it writes to the L1 table. The relevant code and comments are listed below.
Code:
// Constantsconst UNPRIV_EX_ON: u64 = 0 << 54;const UNPRIV_EX_OFF: u64 = 1 << 54;const PRIV_EX_ON: u64 = 0 << 53;const PRIV_EX_OFF: u64 = 1 << 53;const AF_INIT: u64 = 1 << 10;const SHAREABILITY_INNER: u64 = 0b11 << 8;const SHAREABILITY_OUTER: u64 = 0b10 << 8;const SHAREABILITY_NON: u64 = 0b00 << 8;const DATA_ACCESS_PERMS: u64 = 0b00 << 6;const NOT_SECURE: u64 = 1 << 5;const ATTR_IDX_RAM: u64 = 0b00 << 0;const ATTR_IDX_MMIO: u64 = 0b01 << 0;const IS_BLOCK: u64 = 0 << 1;const IS_TABLE: u64 = 1 << 1;const IS_VALID: u64 = 1 << 0;const TABLE_ADDR_MASK: u64 = 0x0000_FFFF_FFFF_F000;const L2_BLOCK_ADDR_MASK: u64 = 0x0000_FFFF_FFE0_0000;// Create an array of [u64; 512]s that I can use as my page tables.// The section is linked properly, and I can verify it from an objdump of my ELF.#[unsafe(link_section = ".page_tables")]static mut PAGE_TABLES: [[u64; 512]; 4096] = [ [0; 512]; 4096];static mut INDEX: usize = 0;// Generates the block descriptor given its PA and whether or not it's device memory.fn generate_block_descriptor(addr: u64, is_device: bool) -> u64 { IS_BLOCK | IS_VALID | if is_device {UNPRIV_EX_OFF} else {UNPRIV_EX_ON} | if is_device {PRIV_EX_OFF} else {PRIV_EX_ON} | (addr & L2_BLOCK_ADDR_MASK) | AF_INIT | if is_device {SHAREABILITY_NON} else {SHAREABILITY_INNER} | DATA_ACCESS_PERMS | NOT_SECURE | if is_device {ATTR_IDX_MMIO} else {ATTR_IDX_RAM}}// Generates the table descriptor from the PA of the tablefn generate_table_descriptor(addr: u64) -> u64 { IS_TABLE | IS_VALID | (addr & TABLE_ADDR_MASK)}fn generate_page_tables(level: u8) -> u64 { match level { 0 => { let l0 = unsafe { &raw mut PAGE_TABLES[INDEX] }; unsafe { INDEX = INDEX + 1; (*l0)[0] = generate_page_tables(1); } l0 as u64 } 1 => { let l1 = unsafe { &raw mut PAGE_TABLES[INDEX] }; for l1_idx in 0..4 { let l2 = unsafe { &raw mut PAGE_TABLES[INDEX] }; for l2_idx in 0..512 { let pa = (l1_idx * 0x4000_0000) + (l2_idx * 0x0020_0000); let block_end = pa + 0x0020_0000 - 1; let is_device = block_end >= MMIO_START && pa <= MMIO_END; let block = generate_block_descriptor(pa, is_device); unsafe { (*l2)[l2_idx as usize] = block; } // This code executes just fine } let table = generate_table_descriptor(l2 as u64); // This also executes just fine unsafe { (*l1)[l1_idx as usize] = table; } // CPU gets turned into a brick here if l1_idx == 0 {unsafe{loop{asm!("wfe")}}}; // This code is never reached } generate_table_descriptor(l1 as u64) } _ => 0 }}(P.S. If you need any further code, I would be more than happy to oblige.)
Statistics: Posted by OhOne — Tue Feb 17, 2026 11:23 pm