From 6bfe833aa5449f119e8a5a5dd21c23ba487b3229 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Fri, 26 Jan 2024 00:49:42 +0200 Subject: [PATCH] Kernel: Parse RSDP from multiboot headers if exists --- kernel/include/kernel/BootInfo.h | 4 +++- kernel/include/kernel/RSDP.h | 23 +++++++++++++++++++++++ kernel/kernel/ACPI.cpp | 28 ++++------------------------ kernel/kernel/BootInfo.cpp | 29 +++++++++++++++++++++-------- 4 files changed, 51 insertions(+), 33 deletions(-) create mode 100644 kernel/include/kernel/RSDP.h diff --git a/kernel/include/kernel/BootInfo.h b/kernel/include/kernel/BootInfo.h index 1f52b5a145..8ba370f0ef 100644 --- a/kernel/include/kernel/BootInfo.h +++ b/kernel/include/kernel/BootInfo.h @@ -3,6 +3,7 @@ #include #include #include +#include namespace Kernel { @@ -34,7 +35,8 @@ namespace Kernel struct BootInfo { BAN::String command_line; - FramebufferInfo framebuffer; + FramebufferInfo framebuffer {}; + RSDP rsdp {}; BAN::Vector memory_map_entries; }; diff --git a/kernel/include/kernel/RSDP.h b/kernel/include/kernel/RSDP.h new file mode 100644 index 0000000000..86e0d40351 --- /dev/null +++ b/kernel/include/kernel/RSDP.h @@ -0,0 +1,23 @@ +#pragma once + +#include + +namespace Kernel +{ + + struct RSDP + { + uint8_t signature[8]; + uint8_t checksum; + uint8_t oemid[6]; + uint8_t revision; + uint32_t rsdt_address; + + // only in revision >= 2 + uint32_t length; + uint64_t xsdt_address; + uint8_t extended_checksum; + uint8_t reserved[3]; + }; + +} diff --git a/kernel/kernel/ACPI.cpp b/kernel/kernel/ACPI.cpp index 263256d462..ff397d9763 100644 --- a/kernel/kernel/ACPI.cpp +++ b/kernel/kernel/ACPI.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -11,21 +12,6 @@ namespace Kernel { - struct RSDP - { - uint8_t signature[8]; - uint8_t checksum; - uint8_t oemid[6]; - uint8_t revision; - uint32_t rsdt_address; - - // only in revision >= 2 - uint32_t length; - uint64_t xsdt_address; - uint8_t extended_checksum; - uint8_t reserved[3]; - }; - struct RSDT : public ACPI::SDTHeader { uint32_t entries[]; @@ -84,19 +70,13 @@ namespace Kernel static const RSDP* locate_rsdp() { - // FIXME: add this back -#if 0 - // Check the multiboot headers - if (auto* rsdp_new = (multiboot2_rsdp_tag_t*)multiboot2_find_tag(MULTIBOOT2_TAG_NEW_RSDP)) - return (const RSDP*)rsdp_new->data; - if (auto* rsdp_old = (multiboot2_rsdp_tag_t*)multiboot2_find_tag(MULTIBOOT2_TAG_OLD_RSDP)) - return (const RSDP*)rsdp_old->data; -#endif + if (g_boot_info.rsdp.length) + return &g_boot_info.rsdp; // Look in main BIOS area below 1 MB for (uintptr_t addr = P2V(0x000E0000); addr < P2V(0x000FFFFF); addr += 16) if (is_rsdp(addr)) - return (const RSDP*)addr; + return reinterpret_cast(addr); return nullptr; } diff --git a/kernel/kernel/BootInfo.cpp b/kernel/kernel/BootInfo.cpp index 5545ba66c3..9a6ac1e817 100644 --- a/kernel/kernel/BootInfo.cpp +++ b/kernel/kernel/BootInfo.cpp @@ -7,7 +7,7 @@ namespace Kernel BootInfo g_boot_info; - void parse_boot_info_multiboot2(uint32_t info) + static void parse_boot_info_multiboot2(uint32_t info) { const auto& multiboot2_info = *reinterpret_cast(info); @@ -15,12 +15,12 @@ namespace Kernel { if (tag->type == MULTIBOOT2_TAG_CMDLINE) { - const auto& command_line_tag = *reinterpret_cast(tag); + const auto& command_line_tag = *static_cast(tag); MUST(g_boot_info.command_line.append(command_line_tag.cmdline)); } else if (tag->type == MULTIBOOT2_TAG_FRAMEBUFFER) { - const auto& framebuffer_tag = *reinterpret_cast(tag); + const auto& framebuffer_tag = *static_cast(tag); g_boot_info.framebuffer.address = framebuffer_tag.framebuffer_addr; g_boot_info.framebuffer.pitch = framebuffer_tag.framebuffer_pitch; g_boot_info.framebuffer.width = framebuffer_tag.framebuffer_width; @@ -33,7 +33,7 @@ namespace Kernel } else if (tag->type == MULTIBOOT2_TAG_MMAP) { - const auto& mmap_tag = *reinterpret_cast(tag); + const auto& mmap_tag = *static_cast(tag); const size_t entry_count = (mmap_tag.size - sizeof(multiboot2_mmap_tag_t)) / mmap_tag.entry_size; @@ -52,19 +52,32 @@ namespace Kernel g_boot_info.memory_map_entries[i].type = mmap_entry.type; } } + else if (tag->type == MULTIBOOT2_TAG_OLD_RSDP) + { + if (g_boot_info.rsdp.length == 0) + { + memcpy(&g_boot_info.rsdp, static_cast(tag)->data, 20); + g_boot_info.rsdp.length = 20; + } + } + else if (tag->type == MULTIBOOT2_TAG_NEW_RSDP) + { + const auto& rsdp = *reinterpret_cast(static_cast(tag)->data); + memcpy(&g_boot_info.rsdp, &rsdp, BAN::Math::min(rsdp.length, sizeof(g_boot_info.rsdp))); + } } } - BAN::StringView get_early_boot_command_line_multiboot2(uint32_t info) + static BAN::StringView get_early_boot_command_line_multiboot2(uint32_t info) { const auto& multiboot2_info = *reinterpret_cast(info); for (const auto* tag = multiboot2_info.tags; tag->type != MULTIBOOT2_TAG_END; tag = tag->next()) if (tag->type == MULTIBOOT2_TAG_CMDLINE) - return reinterpret_cast(tag)->cmdline; + return static_cast(tag)->cmdline; return {}; } - void parse_boot_info_banan_bootloader(uint32_t info) + static void parse_boot_info_banan_bootloader(uint32_t info) { const auto& banan_bootloader_info = *reinterpret_cast(info); @@ -93,7 +106,7 @@ namespace Kernel } } - BAN::StringView get_early_boot_command_line_banan_bootloader(uint32_t info) + static BAN::StringView get_early_boot_command_line_banan_bootloader(uint32_t info) { const auto& banan_bootloader_info = *reinterpret_cast(info); return reinterpret_cast(banan_bootloader_info.command_line_addr);