mirror of
https://github.com/panpaul/tiny_os
synced 2024-09-20 09:45:19 +08:00
fix: some parts of physical memory is not mapped
This commit is contained in:
parent
1d026d8053
commit
774cabc513
@ -96,14 +96,40 @@ pub unsafe fn setup_kernel_paging<const N: usize>(allocator: &mut RamBlock<N>) {
|
|||||||
|
|
||||||
// map 4 GiB physical memory
|
// map 4 GiB physical memory
|
||||||
// TODO: walk fdt to get all memory region?
|
// 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);
|
#[cfg(feature = "legacy")]
|
||||||
map(
|
let level = TableLevel::Level1;
|
||||||
mmap_phys_to_virt(phys_addr),
|
#[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,
|
phys_addr,
|
||||||
MapAttr::READABLE | MapAttr::WRITABLE,
|
MapAttr::READABLE | MapAttr::WRITABLE,
|
||||||
TableLevel::Level1,
|
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());
|
riscv::register::satp::set(riscv::register::satp::Mode::Sv39, 0, root_pt.to_ppn());
|
||||||
|
@ -25,6 +25,18 @@ impl TableLevel {
|
|||||||
Self::Level4 => Some(Self::Level3),
|
Self::Level4 => Some(Self::Level3),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn previous(&self) -> Option<Self> {
|
||||||
|
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)]
|
#[derive(Debug)]
|
||||||
|
Loading…
Reference in New Issue
Block a user