aboutsummaryrefslogtreecommitdiff
path: root/mirai/memory/pmm.zig
diff options
context:
space:
mode:
Diffstat (limited to 'mirai/memory/pmm.zig')
-rw-r--r--mirai/memory/pmm.zig53
1 files changed, 48 insertions, 5 deletions
diff --git a/mirai/memory/pmm.zig b/mirai/memory/pmm.zig
index 8207387..cf66855 100644
--- a/mirai/memory/pmm.zig
+++ b/mirai/memory/pmm.zig
@@ -12,6 +12,8 @@ const HIGHER_HALF = memory_const.HIGHER_HALF_START;
var bitmap: [*]u8 = undefined;
var bitmap_size: usize = 0;
+var bitmap_phys_start: u64 = 0;
+var bitmap_phys_end: u64 = 0;
var total_pages: u64 = 0;
var used_pages: u64 = 0;
var initialized: bool = false;
@@ -21,6 +23,14 @@ pub const MemoryInfo = struct {
used: u64,
};
+pub fn get_bitmap_range() struct { start: u64, end: u64 } {
+ return .{ .start = bitmap_phys_start, .end = bitmap_phys_end };
+}
+
+pub fn is_in_bitmap(phys: u64) bool {
+ return phys >= bitmap_phys_start and phys < bitmap_phys_end;
+}
+
pub fn init(kernel_end_phys: u64, memory_map: []multiboot.MemoryEntry) void {
serial.print("\n=== PMM ===\n");
@@ -39,8 +49,12 @@ pub fn init(kernel_end_phys: u64, memory_map: []multiboot.MemoryEntry) void {
serial.printf("Memory: {} MB, {} pages\n", .{ highest_addr / (1024 * 1024), total_pages });
- const bitmap_phys = align_up(kernel_end_phys, PAGE_SIZE);
- bitmap = @ptrFromInt(bitmap_phys + HIGHER_HALF);
+ bitmap_phys_start = align_up(kernel_end_phys, PAGE_SIZE);
+ bitmap = @ptrFromInt(bitmap_phys_start + HIGHER_HALF);
+
+ const bitmap_pages = (bitmap_size + PAGE_SIZE - 1) / PAGE_SIZE;
+ bitmap_phys_end = bitmap_phys_start + bitmap_pages * PAGE_SIZE;
+ serial.printf("Bitmap: phys={x}-{x} size={x} pages={d}\n", .{ bitmap_phys_start, bitmap_phys_end, bitmap_size, bitmap_pages });
for (0..bitmap_size) |i| {
bitmap[i] = pmm_const.BITMAP_MARK_USED;
@@ -54,11 +68,10 @@ pub fn init(kernel_end_phys: u64, memory_map: []multiboot.MemoryEntry) void {
}
const kernel_size = kernel_end_phys - pmm_const.KERNEL_BASE;
- const bitmap_pages = (bitmap_size + PAGE_SIZE - 1) / PAGE_SIZE;
reserve_region(0, pmm_const.FIRST_MB);
reserve_region(pmm_const.KERNEL_BASE, kernel_size);
- reserve_region(bitmap_phys, bitmap_pages * PAGE_SIZE);
+ reserve_region(bitmap_phys_start, bitmap_phys_end - bitmap_phys_start);
reserve_region(pmm_const.MMIO_PCI_BASE, pmm_const.MMIO_PCI_SIZE);
reserve_region(pmm_const.MMIO_FRAMEBUFFER_BASE, pmm_const.MMIO_FRAMEBUFFER_SIZE);
@@ -70,13 +83,40 @@ pub fn init(kernel_end_phys: u64, memory_map: []multiboot.MemoryEntry) void {
initialized = true;
}
+pub var ash_pd_phys: u64 = 0;
+
+pub fn set_ash_pd(phys: u64) void {
+ ash_pd_phys = phys;
+ serial.printf("PMM: Tracking Ash PD at {x}\n", .{phys});
+
+ // Verify it's marked as used
+ const page = phys / PAGE_SIZE;
+ if (is_page_used(page)) {
+ serial.printf("PMM: Ash PD page {x} is correctly marked USED\n", .{phys});
+ } else {
+ serial.printf("PMM: BUG! Ash PD page {x} is marked FREE!\n", .{phys});
+ }
+}
+
+pub fn check_ash_pd_status() void {
+ if (ash_pd_phys == 0) return;
+ const page = ash_pd_phys / PAGE_SIZE;
+ if (!is_page_used(page)) {
+ serial.printf("PMM: Ash PD {x} became FREE!\n", .{ash_pd_phys});
+ }
+}
+
pub fn alloc_page() ?u64 {
if (!initialized) return null;
for (0..total_pages) |i| {
if (!is_page_used(i)) {
+ const phys = i * PAGE_SIZE;
+ if (ash_pd_phys != 0 and phys == ash_pd_phys) {
+ serial.printf("PMM: ALLOCATING Ash's PD {x}! BUG - should be marked used!\n", .{phys});
+ }
set_page_used(i);
- return i * PAGE_SIZE;
+ return phys;
}
}
return null;
@@ -87,6 +127,9 @@ pub fn free_page(phys_addr: u64) void {
const page = phys_addr / PAGE_SIZE;
if (page < total_pages) {
+ if (ash_pd_phys != 0 and phys_addr == ash_pd_phys) {
+ serial.printf("PMM: FREEING Ash's PD {x}!\n", .{phys_addr});
+ }
set_page_free(page);
}
}