diff --git a/kernel/src/arch/riscv/vspace/utils.rs b/kernel/src/arch/riscv/vspace/utils.rs index 2962161..0790547 100644 --- a/kernel/src/arch/riscv/vspace/utils.rs +++ b/kernel/src/arch/riscv/vspace/utils.rs @@ -96,14 +96,40 @@ pub unsafe fn setup_kernel_paging(allocator: &mut RamBlock) { // map 4 GiB physical memory // TODO: walk fdt to get all memory region? - for addr in (0..(3 * GIB - 1 + GIB)).step_by(TableLevel::Level1.level_size()) { - let phys_addr = PhysAddr(addr); - map( - mmap_phys_to_virt(phys_addr), - phys_addr, - MapAttr::READABLE | MapAttr::WRITABLE, - TableLevel::Level1, - ); + { + #[cfg(feature = "legacy")] + let level = TableLevel::Level1; + #[cfg(not(feature = "legacy"))] + let level = TableLevel::Level2; + + let addr_end = PhysAddr(3 * GIB - 1 + GIB); + let mut phys_addr = PhysAddr(0); + let mut map_level = level; + + while phys_addr < addr_end { + let ok = map( + kernel_phys_to_virt(phys_addr), + phys_addr, + MapAttr::READABLE | MapAttr::WRITABLE, + map_level, + ); + + if ok || map_level.next().is_none() { + // map success or reach the end, move to next region + phys_addr += map_level.level_size(); + + // check whether we could raise the level + if let Some(prv) = map_level.previous() + && prv.is_aligned(phys_addr) + { + map_level = prv; + } + continue; + } + + // already mapped, try smaller level + map_level = map_level.next().unwrap(); + } } riscv::register::satp::set(riscv::register::satp::Mode::Sv39, 0, root_pt.to_ppn()); diff --git a/kernel/src/vspace/paging/table.rs b/kernel/src/vspace/paging/table.rs index b01d702..3d1993c 100644 --- a/kernel/src/vspace/paging/table.rs +++ b/kernel/src/vspace/paging/table.rs @@ -25,6 +25,18 @@ impl TableLevel { Self::Level4 => Some(Self::Level3), } } + + pub fn previous(&self) -> Option { + match self { + Self::Level0 => Some(Self::Level1), + Self::Level1 => Some(Self::Level2), + Self::Level2 => Some(Self::Level3), + #[cfg(not(feature = "legacy"))] + Self::Level3 => Some(Self::Level4), + #[cfg(not(feature = "legacy"))] + Self::Level4 => None, + } + } } #[derive(Debug)]