aboutsummaryrefslogtreecommitdiff
path: root/mirai/boot/sequence/phases/memory.zig
blob: 3cd415255617ef29db407d13c196232a5766f807 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
//! Memory Phase

const pmm = @import("../../../pmm/pmm.zig");
const kagami = @import("../../../kagami/kagami.zig");
const serial = @import("../../../drivers/serial/serial.zig");
const types = @import("../types/types.zig");

const BootInfo = types.BootInfo;

pub fn execute(boot_info: *const BootInfo) bool {
    serial.printf("Detecting physical memory from Hikari bootloader\n", .{});

    const bitmap_location = find_bitmap_location(boot_info);
    if (bitmap_location == 0) {
        serial.printf("  Could not find suitable location for page bitmap\n", .{});
        return false;
    }

    pmm.initialize(boot_info.memory_map, boot_info.memory_map_count, bitmap_location);

    const stats = pmm.get_statistics();
    const total_mb = (stats.total_pages * 4096) / (1024 * 1024);
    const free_mb = (stats.free_pages * 4096) / (1024 * 1024);

    serial.printf("  Found %d pages (%d MB total)\n", .{ stats.total_pages, total_mb });
    serial.printf("  Available: %d pages (%d MB)\n", .{ stats.free_pages, free_mb });

    serial.printf("Setting up Kagami page table abstraction\n", .{});
    kagami.initialize(boot_info.pml4_physical);
    serial.printf("  Using PML4 at physical address %x\n", .{boot_info.pml4_physical});

    return true;
}

fn find_bitmap_location(boot_info: *const BootInfo) u64 {
    const bitmap_size = pmm.constants.bitmap_size_bytes;
    const required_pages = (bitmap_size + 4095) / 4096;

    var index: u64 = 0;
    while (index < boot_info.memory_map_count) : (index += 1) {
        const region = boot_info.memory_map[index];

        if (!region.is_usable()) continue;

        if (region.base_address < 0x100000) continue;

        if (region.base_address >= boot_info.kernel_physical_base and
            region.base_address < boot_info.kernel_physical_end)
        {
            continue;
        }

        const region_pages = region.page_count();
        if (region_pages >= required_pages) {
            return region.base_address;
        }
    }

    return 0;
}