Kernel: Make ACPI load all SSDT headers after DSDT is loaded

This commit is contained in:
Bananymous 2024-04-10 15:03:54 +03:00
parent cdbdc1a822
commit 0ff68b7d66
6 changed files with 48 additions and 20 deletions

View File

@ -6,6 +6,6 @@
namespace Kernel::ACPI::AML namespace Kernel::ACPI::AML
{ {
BAN::RefPtr<AML::Namespace> initialize_namespace(const SDTHeader& header); BAN::RefPtr<AML::Namespace> initialize_namespace();
} }

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <kernel/ACPI/AML/Scope.h> #include <kernel/ACPI/AML/Scope.h>
#include <kernel/ACPI/Headers.h>
#include <kernel/Lock/Mutex.h> #include <kernel/Lock/Mutex.h>
namespace Kernel::ACPI::AML namespace Kernel::ACPI::AML
@ -14,7 +15,8 @@ namespace Kernel::ACPI::AML
Namespace(NameSeg name) : AML::Scope(Node::Type::Namespace, name) {} Namespace(NameSeg name) : AML::Scope(Node::Type::Namespace, name) {}
static BAN::RefPtr<Namespace> parse(BAN::ConstByteSpan aml); static BAN::RefPtr<AML::Namespace> create_root_namespace();
bool parse(const SDTHeader& header);
BAN::Optional<AML::NameString> resolve_path(const AML::NameString& relative_base, const AML::NameString& relative_path); BAN::Optional<AML::NameString> resolve_path(const AML::NameString& relative_base, const AML::NameString& relative_path);

View File

@ -36,9 +36,7 @@ namespace Kernel::ACPI
return BAN::Error::from_errno(ENOMEM); return BAN::Error::from_errno(ENOMEM);
TRY(s_instance->initialize_impl()); TRY(s_instance->initialize_impl());
auto dsdt = s_instance->get_header("DSDT", 0); s_instance->m_namespace = AML::initialize_namespace();
ASSERT(dsdt);
s_instance->m_namespace = AML::initialize_namespace(*dsdt);
return {}; return {};
} }

View File

@ -6,19 +6,34 @@
namespace Kernel::ACPI namespace Kernel::ACPI
{ {
BAN::RefPtr<AML::Namespace> AML::initialize_namespace(const SDTHeader& header) BAN::RefPtr<AML::Namespace> 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<const uint8_t*>(&header), header.length }; // Parse DSDT
aml_raw = aml_raw.slice(sizeof(header)); auto* dsdt = ACPI::ACPI::get().get_header("DSDT", 0);
if (!dsdt)
auto ns = AML::Namespace::parse(aml_raw);
if (!ns)
{ {
dwarnln("Failed to parse ACPI namespace"); dwarnln("Failed to get DSDT");
return {}; 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 #if AML_DEBUG_LEVEL >= 1
ns->debug_print(0); ns->debug_print(0);

View File

@ -191,13 +191,13 @@ namespace Kernel::ACPI
return true; return true;
} }
BAN::RefPtr<AML::Namespace> AML::Namespace::parse(BAN::ConstByteSpan aml_data) BAN::RefPtr<AML::Namespace> AML::Namespace::create_root_namespace()
{ {
ASSERT(!s_root_namespace);
s_root_namespace = MUST(BAN::RefPtr<Namespace>::create(NameSeg("\\"sv))); s_root_namespace = MUST(BAN::RefPtr<Namespace>::create(NameSeg("\\"sv)));
AML::ParseContext context; AML::ParseContext context;
context.scope = AML::NameString("\\"sv); context.scope = AML::NameString("\\"sv);
context.aml_data = aml_data;
// Add predefined namespaces // Add predefined namespaces
#define ADD_PREDEFIED_NAMESPACE(NAME) \ #define ADD_PREDEFIED_NAMESPACE(NAME) \
@ -209,17 +209,30 @@ namespace Kernel::ACPI
ADD_PREDEFIED_NAMESPACE("_TZ"sv); ADD_PREDEFIED_NAMESPACE("_TZ"sv);
#undef ADD_PREDEFIED_NAMESPACE #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<const uint8_t*>(&header), header.length).slice(sizeof(header));
while (context.aml_data.size() > 0) while (context.aml_data.size() > 0)
{ {
auto result = AML::parse_object(context); auto result = AML::parse_object(context);
if (!result.success()) if (!result.success())
{ {
AML_ERROR("Failed to parse object"); AML_ERROR("Failed to parse object");
return {}; return false;
} }
} }
return s_root_namespace; return true;
} }
} }

View File

@ -154,9 +154,6 @@ extern "C" void kernel_main(uint32_t boot_magic, uint32_t boot_info)
dprintln("Virtual TTY initialized"); 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(); Random::initialize();
dprintln("RNG initialized"); dprintln("RNG initialized");
@ -181,6 +178,9 @@ static void init2(void*)
ASSERT(console->is_tty()); ASSERT(console->is_tty());
((TTY*)console.ptr())->set_as_current(); ((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(); DevFileSystem::get().initialize_device_updater();
#if 0 #if 0