From 0ff68b7d660be49cb011ee25efc3e1609c9b2ff4 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Wed, 10 Apr 2024 15:03:54 +0300 Subject: [PATCH] Kernel: Make ACPI load all SSDT headers after DSDT is loaded --- kernel/include/kernel/ACPI/AML.h | 2 +- kernel/include/kernel/ACPI/AML/Namespace.h | 4 ++- kernel/kernel/ACPI/ACPI.cpp | 4 +-- kernel/kernel/ACPI/AML.cpp | 31 ++++++++++++++++------ kernel/kernel/ACPI/AML/Namespace.cpp | 21 ++++++++++++--- kernel/kernel/kernel.cpp | 6 ++--- 6 files changed, 48 insertions(+), 20 deletions(-) diff --git a/kernel/include/kernel/ACPI/AML.h b/kernel/include/kernel/ACPI/AML.h index 61e6c44c50..9c8be76487 100644 --- a/kernel/include/kernel/ACPI/AML.h +++ b/kernel/include/kernel/ACPI/AML.h @@ -6,6 +6,6 @@ namespace Kernel::ACPI::AML { - BAN::RefPtr initialize_namespace(const SDTHeader& header); + BAN::RefPtr initialize_namespace(); } diff --git a/kernel/include/kernel/ACPI/AML/Namespace.h b/kernel/include/kernel/ACPI/AML/Namespace.h index 21063d08a1..e795bb7040 100644 --- a/kernel/include/kernel/ACPI/AML/Namespace.h +++ b/kernel/include/kernel/ACPI/AML/Namespace.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include namespace Kernel::ACPI::AML @@ -14,7 +15,8 @@ namespace Kernel::ACPI::AML Namespace(NameSeg name) : AML::Scope(Node::Type::Namespace, name) {} - static BAN::RefPtr parse(BAN::ConstByteSpan aml); + static BAN::RefPtr create_root_namespace(); + bool parse(const SDTHeader& header); BAN::Optional resolve_path(const AML::NameString& relative_base, const AML::NameString& relative_path); diff --git a/kernel/kernel/ACPI/ACPI.cpp b/kernel/kernel/ACPI/ACPI.cpp index 2d8cee63cb..20ba94e014 100644 --- a/kernel/kernel/ACPI/ACPI.cpp +++ b/kernel/kernel/ACPI/ACPI.cpp @@ -36,9 +36,7 @@ namespace Kernel::ACPI return BAN::Error::from_errno(ENOMEM); TRY(s_instance->initialize_impl()); - auto dsdt = s_instance->get_header("DSDT", 0); - ASSERT(dsdt); - s_instance->m_namespace = AML::initialize_namespace(*dsdt); + s_instance->m_namespace = AML::initialize_namespace(); return {}; } diff --git a/kernel/kernel/ACPI/AML.cpp b/kernel/kernel/ACPI/AML.cpp index 73c66b4fbb..b71863e8f1 100644 --- a/kernel/kernel/ACPI/AML.cpp +++ b/kernel/kernel/ACPI/AML.cpp @@ -6,19 +6,34 @@ namespace Kernel::ACPI { - BAN::RefPtr AML::initialize_namespace(const SDTHeader& header) + BAN::RefPtr AML::initialize_namespace() { - dprintln("Parsing {}, {} bytes of AML", header, header.length); + auto ns = AML::Namespace::create_root_namespace(); - auto aml_raw = BAN::ConstByteSpan { reinterpret_cast(&header), header.length }; - aml_raw = aml_raw.slice(sizeof(header)); - - auto ns = AML::Namespace::parse(aml_raw); - if (!ns) + // Parse DSDT + auto* dsdt = ACPI::ACPI::get().get_header("DSDT", 0); + if (!dsdt) { - dwarnln("Failed to parse ACPI namespace"); + dwarnln("Failed to get DSDT"); return {}; } + if (!ns->parse(*dsdt)) + { + dwarnln("Failed to parse DSDT"); + return {}; + } + + for (uint32_t i = 0;; i++) + { + auto* ssdt = ACPI::ACPI::get().get_header("SSDT", i); + if (!ssdt) + break; + if (!ns->parse(*ssdt)) + { + dwarnln("Failed to parse SSDT"); + return {}; + } + } #if AML_DEBUG_LEVEL >= 1 ns->debug_print(0); diff --git a/kernel/kernel/ACPI/AML/Namespace.cpp b/kernel/kernel/ACPI/AML/Namespace.cpp index 86849ba146..b55f21e514 100644 --- a/kernel/kernel/ACPI/AML/Namespace.cpp +++ b/kernel/kernel/ACPI/AML/Namespace.cpp @@ -191,13 +191,13 @@ namespace Kernel::ACPI return true; } - BAN::RefPtr AML::Namespace::parse(BAN::ConstByteSpan aml_data) + BAN::RefPtr AML::Namespace::create_root_namespace() { + ASSERT(!s_root_namespace); s_root_namespace = MUST(BAN::RefPtr::create(NameSeg("\\"sv))); AML::ParseContext context; context.scope = AML::NameString("\\"sv); - context.aml_data = aml_data; // Add predefined namespaces #define ADD_PREDEFIED_NAMESPACE(NAME) \ @@ -209,17 +209,30 @@ namespace Kernel::ACPI ADD_PREDEFIED_NAMESPACE("_TZ"sv); #undef ADD_PREDEFIED_NAMESPACE + return s_root_namespace; + } + + bool AML::Namespace::parse(const SDTHeader& header) + { + ASSERT(this == s_root_namespace.ptr()); + + dprintln("Parsing {}, {} bytes of AML", header, header.length); + + AML::ParseContext context; + context.scope = AML::NameString("\\"sv); + context.aml_data = BAN::ConstByteSpan(reinterpret_cast(&header), header.length).slice(sizeof(header)); + while (context.aml_data.size() > 0) { auto result = AML::parse_object(context); if (!result.success()) { AML_ERROR("Failed to parse object"); - return {}; + return false; } } - return s_root_namespace; + return true; } } diff --git a/kernel/kernel/kernel.cpp b/kernel/kernel/kernel.cpp index 03f4c2ee84..1440e8853f 100644 --- a/kernel/kernel/kernel.cpp +++ b/kernel/kernel/kernel.cpp @@ -154,9 +154,6 @@ extern "C" void kernel_main(uint32_t boot_magic, uint32_t boot_info) dprintln("Virtual TTY initialized"); } - if (ACPI::ACPI::get().enter_acpi_mode(InterruptController::get().is_using_apic()).is_error()) - dprintln("Failed to enter ACPI mode"); - Random::initialize(); dprintln("RNG initialized"); @@ -181,6 +178,9 @@ static void init2(void*) ASSERT(console->is_tty()); ((TTY*)console.ptr())->set_as_current(); + if (ACPI::ACPI::get().enter_acpi_mode(InterruptController::get().is_using_apic()).is_error()) + dprintln("Failed to enter ACPI mode"); + DevFileSystem::get().initialize_device_updater(); #if 0