Skip to content

Commit d6786a2

Browse files
feat(physicalmem): respect memory reservations
Co-authored-by: Martin Kröning <[email protected]>
1 parent 7d8352a commit d6786a2

File tree

1 file changed

+56
-1
lines changed

1 file changed

+56
-1
lines changed

src/mm/physicalmem.rs

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use core::sync::atomic::{AtomicUsize, Ordering};
22

33
use align_address::Align;
4-
use free_list::{FreeList, PageRange};
4+
use free_list::{FreeList, PageRange, PageRangeError};
55
use hermit_sync::InterruptTicketMutex;
66
use memory_addresses::{PhysAddr, VirtAddr};
77

@@ -97,9 +97,64 @@ fn detect_from_fdt() -> Result<(), ()> {
9797
debug!("Claimed physical memory: {range:#x?}");
9898
}
9999

100+
let reserve = |reservation: PageRange| {
101+
debug!("Memory reservation: {reservation:#x?}");
102+
if let Ok(reserved) = PHYSICAL_FREE_LIST
103+
.lock()
104+
.allocate_with(|range| reservation.and(range))
105+
{
106+
debug!("Reserved {reserved:#x?}");
107+
}
108+
};
109+
110+
for reservation in fdt.memory_reservations() {
111+
let start = reservation.address().addr();
112+
let end = start + reservation.size();
113+
let reservation = PageRange::new(start, end).unwrap();
114+
reserve(reservation);
115+
}
116+
117+
let kernel_start = if env::is_uefi() {
118+
super::kernel_start_address().as_usize()
119+
} else {
120+
// FIXME: Memory before the kernel causes trouble on non-uefi systems.
121+
// It is unclear, which exact regions cause problems.
122+
0
123+
};
124+
let kernel_end = super::kernel_end_address().as_usize();
125+
let kernel_region = PageRange::new(kernel_start, kernel_end).unwrap();
126+
reserve(kernel_region);
127+
128+
let fdt_start = env::boot_info().hardware_info.device_tree.unwrap().get();
129+
let fdt_start = usize::try_from(fdt_start).unwrap();
130+
let fdt_end = fdt_start + fdt.total_size();
131+
let fdt_region = PageRange::containing(fdt_start, fdt_end).unwrap();
132+
reserve(fdt_region);
133+
100134
Ok(())
101135
}
102136

137+
// FIXME: upstream these
138+
trait PageRangeExt: Sized {
139+
fn containing(start: usize, end: usize) -> Result<Self, PageRangeError>;
140+
141+
fn and(self, rhs: Self) -> Option<Self>;
142+
}
143+
144+
impl PageRangeExt for PageRange {
145+
fn containing(start: usize, end: usize) -> Result<Self, PageRangeError> {
146+
let start = start.align_down(free_list::PAGE_SIZE);
147+
let end = end.align_up(free_list::PAGE_SIZE);
148+
Self::new(start, end)
149+
}
150+
151+
fn and(self, rhs: Self) -> Option<Self> {
152+
let start = self.start().max(rhs.start());
153+
let end = self.end().min(rhs.end());
154+
Self::new(start, end).ok()
155+
}
156+
}
157+
103158
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
104159
fn detect_from_limits() -> Result<(), ()> {
105160
let limit = crate::arch::kernel::get_limit();

0 commit comments

Comments
 (0)