summaryrefslogtreecommitdiffstats
path: root/rsnix/src/memory.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--rsnix/src/memory.rs35
1 files changed, 33 insertions, 2 deletions
diff --git a/rsnix/src/memory.rs b/rsnix/src/memory.rs
index e03af8b..a947c53 100644
--- a/rsnix/src/memory.rs
+++ b/rsnix/src/memory.rs
@@ -354,14 +354,29 @@ pub unsafe fn refresh_and_exit(bs: &BootServices, image_handle: Handle) -> Resul
354 354
355fn init_heap() { 355fn init_heap() {
356 unsafe { 356 unsafe {
357 // Region the firmware maps for the GOP framebuffer, if known —
358 // exclude it even when the memory map lists it as conventional
359 // (some real firmware does exactly that, which would let heap
360 // allocations overwrite the display).
361 let fb = crate::gop::framebuffer_region();
357 let mut best_start = 0usize; 362 let mut best_start = 0usize;
358 let mut best_size = 0usize; 363 let mut best_size = 0usize;
359 for i in 0..MAP_ENTRIES { 364 for i in 0..MAP_ENTRIES {
360 let d = &MEMORY_MAP[i]; 365 let d = &MEMORY_MAP[i];
361 if d.kind == MEMORY_TYPE_CONVENTIONAL { 366 if d.kind == MEMORY_TYPE_CONVENTIONAL {
362 let sz = d.number_of_pages as usize * 4096; 367 let s = d.physical_start as usize;
368 let e = s + d.number_of_pages as usize * 4096;
369 // Subtract any overlap with the framebuffer region.
370 let (cs, ce) = match fb {
371 Some((b, sz)) if e > b && s < b + sz => (s.max(b), e.min(b + sz)),
372 _ => (e, s), // no overlap → empty range
373 };
374 let mut sz = e - s;
375 if ce > cs {
376 sz -= ce - cs;
377 }
363 if sz > best_size { 378 if sz > best_size {
364 best_start = d.physical_start as usize; 379 best_start = s;
365 best_size = sz; 380 best_size = sz;
366 } 381 }
367 } 382 }
@@ -634,6 +649,22 @@ pub fn init_page_allocator() -> bool {
634 } 649 }
635 } 650 }
636 651
652 // Reserve the GOP framebuffer region even if the map lists it as
653 // conventional — kernel allocations (stacks, DMA buffers) must
654 // never land on the display.
655 if let Some((fbase, fsize)) = crate::gop::framebuffer_region()
656 && fsize > 0
657 {
658 let s = fbase / PAGE_SIZE;
659 let e = (fbase + fsize).div_ceil(PAGE_SIZE);
660 for p in s..e {
661 let idx = p - base_page;
662 if idx < span_pages {
663 *bm.add(idx / 8) |= 1 << (idx % 8);
664 }
665 }
666 }
667
637 // Never hand out page 0 (the null-pointer trap page). 668 // Never hand out page 0 (the null-pointer trap page).
638 if base_page == 0 { 669 if base_page == 0 {
639 *bm |= 0x01; 670 *bm |= 0x01;