chore: implement `HardwareAddressSpace::assert_valid`
Implement `assert_valid` for `HardwareAddressSpace` to ensure the address space is in a correct state. We should extend this to the bootstrapping phase to make sure that the address space is in a good state before switching on the MMU.
rough sketch:
```rust
struct IdentityMappingValidator<'a> {
root_pgtable: PhysicalAddress,
self_regions: &'a SelfRegions,
phys_off: VirtualAddress,
}
impl IdentityMappingValidator<'_> {
/// Verify all loader regions are correctly identity-mapped
fn validate(&self) -> Result<()> {
self.validate_region(
self.self_regions.executable.clone(),
PTEFlags::READ | PTEFlags::EXECUTE
)?;
self.validate_region(
self.self_regions.read_only.clone(),
PTEFlags::READ
)?;
self.validate_region(
self.self_regions.read_write.clone(),
PTEFlags::READ | PTEFlags::WRITE
)?;
// Validate current PC is mapped
self.validate_current_pc()?;
Ok(())
}
fn validate_region(&self, phys: Range<PhysicalAddress>, expected_flags: PTEFlags) -> Result<()> {
let virt = VirtualAddress::new(phys.start.get());
// Walk page tables to verify mapping exists
let (mapped_phys, flags) = self.walk_page_table(virt)?;
if mapped_phys != phys.start {
return Err(Error::InvalidMapping);
}
if !flags.contains(expected_flags) {
return Err(Error::IncorrectPermissions);
}
Ok(())
}
fn validate_current_pc(&self) -> Result<()> {
let pc: usize;
unsafe {
asm!("auipc {}, 0", out(reg) pc);
}
// Verify PC is in mapped region
// ...
Ok(())
}
}
```
0 条评论