forked from Bananymous/banan-os
Kernel: Make ACPI load all SSDT headers after DSDT is loaded
This commit is contained in:
parent
cdbdc1a822
commit
0ff68b7d66
|
@ -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();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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 {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue