diff --git a/src/platform/boot/limine/entry.zig b/src/platform/boot/limine/entry.zig index d47ef56..77b8b5c 100644 --- a/src/platform/boot/limine/entry.zig +++ b/src/platform/boot/limine/entry.zig @@ -1,5 +1,6 @@ const b = @import("base"); const ksyms = @import("ksyms"); +const limine = @import("limine.zig"); const pl = b.pl; const ke = b.ke; @@ -12,8 +13,91 @@ const std = @import("std"); var boot_info: pl.BootInfo = undefined; +pub export var limine_base_revision: [3]u64 linksection(".limine_requests") = limine.base_revision(6); + +pub export var framebuffer_request: limine.FramebufferRequest linksection(".limine_requests") = .{ + .id = limine.framebuffer_request_id, + .revision = 0, + .response = null, +}; + +pub export var limine_requests_start_marker: [4]u64 linksection(".limine_requests_start") = limine.requests_start_marker; +pub export var limine_requests_end_marker: [2]u64 linksection(".limine_requests_end") = limine.requests_end_marker; + +pub export var memmap_request: limine.MemmapRequest linksection(".limine_requests") = .{ + .id = limine.memmap_request_id, + .revision = 0, + .response = null, +}; + +pub export var rsdp_request: limine.RsdpRequest linksection(".limine_requests") = .{ + .id = limine.rsdp_request_id, + .revision = 0, + .response = null, +}; + +pub export var cmdline_request: limine.CmdlineRequest linksection(".limine_requests") = .{ + .id = limine.cmdline_request_id, + .revision = 0, + .response = null, +}; + +pub export var kernel_address_request: limine.KernelAddressRequest linksection(".limine_requests") = .{ + .id = limine.kernel_address_request_id, + .revision = 0, + .response = null, +}; + +fn build_memory_map() void { + const memmap_response = memmap_request.response orelse { + @panic("Limine memmap request failed"); + }; + + boot_info.memory_map.entry_count = memmap_response.entry_count; + const entries = memmap_response.entries orelse { + @panic("Limine memmap response has no entries"); + }; + + for (0..memmap_response.entry_count) |i| { + const entry = entries[i]; + boot_info.memory_map.entries[i] = .{ + .base = entry.base, + .size = entry.length, + .type = switch (entry.type) { + .Usable => pl.BootInfo.MemMap.Entry.Type.Free, + .AcpiReclaimable => pl.BootInfo.MemMap.Entry.Type.AcpiReclaimable, + .AcpiNvs => pl.BootInfo.MemMap.Entry.Type.AcpiNvs, + .BootloaderReclaimable => pl.BootInfo.MemMap.Entry.Type.LoaderReclaimable, + .KernelAndModules => pl.BootInfo.MemMap.Entry.Type.Kernel, + else => pl.BootInfo.MemMap.Entry.Type.Reserved, + }, + }; + } +} + export fn kmain() callconv(.c) void { - boot_info.memory_map.entry_count = 0; + boot_info.cmdline = if (cmdline_request.response) |cmdline_response| { + cmdline_response.cmdline; + } else { + null; + }; + + boot_info.rsdp = if (rsdp_request.response) |rsdp_response| { + rsdp_response.rsdp; + } else { + 0; + }; + + boot_info.kernel_address = if (kernel_address_request.response) |ka_response| { + .{ + .physical_base = ka_response.kernel_address.physical_base, + .virtual_base = ka_response.kernel_address.virtual_base, + }; + } else { + .{ .physical_base = 0, .virtual_base = 0 }; + }; + + build_memory_map(); var cpus: [1]*ke.Cpu = .{&ke.private.bootstrap_cpu}; diff --git a/src/platform/boot/limine/limine.zig b/src/platform/boot/limine/limine.zig index 664f6c6..4d53d16 100644 --- a/src/platform/boot/limine/limine.zig +++ b/src/platform/boot/limine/limine.zig @@ -15,7 +15,7 @@ pub const requests_end_marker: [2]u64 = .{ 0x9572709f31764c62, }; -pub fn baseRevision(rev: u64) [3]u64 { +pub fn base_revision(rev: u64) [3]u64 { return .{ 0xf9562b2d5c95a6c8, 0x6a7b384944536bdc, @@ -23,11 +23,102 @@ pub fn baseRevision(rev: u64) [3]u64 { }; } -pub fn baseRevisionSupported(base_rev: *const [3]u64) bool { - // Limine will overwrite base_rev[2] with 0 if it supports the requested revision. +pub fn base_revision_supported(base_rev: *const [3]u64) bool { return base_rev[2] == 0; } +pub const memmap_request_id: [4]u64 = .{ + common_magic[0], + common_magic[1], + 0x67cf3d9d378a806f, + 0xe304acdfc50c3c62, +}; + +pub const MemmapRequest = extern struct { + id: [4]u64, + revision: u64, + response: ?*MemmapResponse, +}; + +pub const MemmapResponse = extern struct { + revision: u64, + entry_count: u64, + entries: ?[*]*MemmapEntry, +}; + +pub const MemmapEntryType = enum(u64) { + Usable = 0, + Reserved = 1, + AcpiReclaimable = 2, + AcpiNvs = 3, + BadMemory = 4, + BootloaderReclaimable = 5, + KernelAndModules = 6, + Framebuffer = 7, + ReservedMapped = 8, +}; + +pub const MemmapEntry = extern struct { + base: u64, + length: u64, + type: MemmapEntryType, +}; + +pub const rsdp_request_id: [4]u64 = .{ + common_magic[0], + common_magic[1], + 0xc5e77b6b397e7b43, + 0x27637845accdcf3c, +}; + +pub const RsdpRequest = extern struct { + id: [4]u64, + revision: u64, + response: ?*RsdpResponse, +}; + +pub const RsdpResponse = extern struct { + revision: u64, + rsdp_address: ?*anyopaque, +}; + +pub const cmdline_request_id: [4]u64 = .{ + common_magic[0], + common_magic[1], + 0x4b161536e598651e, + 0xb390ad4a2f1f303a, +}; + +pub const CmdlineRequest = extern struct { + id: [4]u64, + revision: u64, + response: ?*CmdlineResponse, +}; + +pub const CmdlineResponse = extern struct { + revision: u64, + cmdline: ?[*]u8, +}; + +pub const executable_address_request_id: [4]u64 = .{ + common_magic[0], + common_magic[1], + 0x71ba76863cc55f63, + 0xb2644a48c516a487, +}; + +pub const ExecutableAddressRequest = extern struct { + id: [4]u64, + revision: u64, + response: ?*ExecutableAddressResponse, +}; + +pub const ExecutableAddressResponse = extern struct { + revision: u64, + physical_base: u64, + virtual_base: u64, +}; + pub const framebuffer_request_id: [4]u64 = .{ common_magic[0], common_magic[1], @@ -63,8 +154,4 @@ pub const Framebuffer = extern struct { unused: [7]u8, edid_size: u64, edid: ?*anyopaque, - // Response revision 1 fields (ignored by this template). - mode_count: u64, - modes: ?[*]*anyopaque, }; -