/* * Copyright (c) 2026, Chloe M. * Provided under the BSD-3 clause. * * Description: Boot protocol abstraction layer * Author: Chloe M. */ #include #include #include #include #define FRAMEBUFFER FbResp->framebuffers[0] #define DTRACE(Fmt, ...) \ TRACE("[ BPAL ]: " Fmt, ##__VA_ARGS__) /* Framebuffer request */ static struct limine_framebuffer_response *FbResp = NULL; static struct limine_framebuffer_request FbReq = { .id = LIMINE_FRAMEBUFFER_REQUEST_ID, .revision = 0 }; /* HHDM request */ static struct limine_hhdm_response *HHDMResp = NULL; static volatile struct limine_hhdm_request HHDMReq = { .id = LIMINE_HHDM_REQUEST_ID, .revision = 0 }; /* Bootloader information */ static struct limine_bootloader_info_response *LoaderInfoResp = NULL; static volatile struct limine_bootloader_info_request LoaderInfoReq = { .id = LIMINE_BOOTLOADER_INFO_REQUEST_ID, .revision = 0 }; /* Bootloader perf information */ static struct limine_bootloader_performance_response *LoaderPerfResp = NULL; static struct limine_bootloader_performance_request LoaderPerReq = { .id = LIMINE_BOOTLOADER_PERFORMANCE_REQUEST_ID, .revision = 0 }; /* Memory map request */ static struct limine_memmap_response *MapResp = NULL; static volatile struct limine_memmap_request MapReq = { .id = LIMINE_MEMMAP_REQUEST_ID, .revision = 0 }; /* Module request */ static struct limine_module_response *ModResp = NULL; static volatile struct limine_module_request ModReq = { .id = LIMINE_MODULE_REQUEST_ID, .revision = 0 }; /* Command line request */ static struct limine_executable_cmdline_response *CmdLineResp = NULL; static struct limine_executable_cmdline_request CmdLineReq = { .id = LIMINE_EXECUTABLE_CMDLINE_REQUEST_ID, .revision = 0 }; static ST_STATUS LimineModuleLookup(CHAR *Path, BPAL_MODULE *Result) { struct limine_file *Module; USIZE PathLen; if (Path == NULL || Result == NULL) { return STATUS_INVALID_PARAM; } if (ModResp == NULL) { return STATUS_NOT_FOUND; } PathLen = RtlStrLen(Path); for (USIZE Idx = 0; Idx < ModResp->module_count; ++Idx) { Module = ModResp->modules[Idx]; if (*Module->path != *Path) { continue; } if (RtlMemCmp(Module->path, Path, PathLen) == 0) { Result->Data = Module->address; Result->Length = Module->size; return STATUS_SUCCESS; } } return STATUS_NOT_FOUND; } VOID BpalInitFramebuffer(BPAL_HANDLE *Handle) { BPAL_FRAMEBUFFER *Framebuffer; if (Handle == NULL) { return; } Framebuffer = &Handle->Framebuffer; Framebuffer->Address = FRAMEBUFFER->address; Framebuffer->Width = FRAMEBUFFER->width; Framebuffer->Height = FRAMEBUFFER->height; Framebuffer->Pitch = FRAMEBUFFER->pitch; Framebuffer->RedMaskSize = FRAMEBUFFER->red_mask_size; Framebuffer->RedMaskShift = FRAMEBUFFER->red_mask_shift; Framebuffer->GreenMaskSize = FRAMEBUFFER->green_mask_size; Framebuffer->GreenMaskShift = FRAMEBUFFER->green_mask_shift; Framebuffer->BlueMaskSize = FRAMEBUFFER->blue_mask_size; Framebuffer->BlueMaskShift = FRAMEBUFFER->blue_mask_shift; } static ST_STATUS LimineMemEntryIdx(USIZE Idx, MEMMAP_ENTRY *Result) { struct limine_memmap_entry *Entry; if (Idx >= MapResp->entry_count) { return STATUS_NOT_FOUND; } Entry = MapResp->entries[Idx]; Result->Base = Entry->base; Result->Length = Entry->length; Result->Type = Entry->type; return STATUS_SUCCESS; } VOID KeBpalLimineInit(BPAL_HANDLE *Handle) { LoaderInfoResp = LoaderInfoReq.response; LoaderPerfResp = LoaderPerReq.response; HHDMResp = HHDMReq.response; ModResp = ModReq.response; FbResp = FbReq.response; MapResp = MapReq.response; CmdLineResp = CmdLineReq.response; DTRACE( "slut handed control by %s %s\n", LoaderInfoResp->name, LoaderInfoResp->version ); DTRACE( "loader took %d usec\n", LoaderPerfResp->init_usec ); DTRACE( "handoff took %d usec\n", LoaderPerfResp->exec_usec ); Handle->CommandLine = CmdLineResp->cmdline; DTRACE( "kernel parameters : %s\n", Handle->CommandLine ); BpalInitFramebuffer(Handle); Handle->KernelBase = HHDMResp->offset; Handle->MemEntryIdx = LimineMemEntryIdx; Handle->ModuleLookup = LimineModuleLookup; }