Kernel: Start working on AML method evaluations

Also fix namespace lookup and scope creations.
This commit is contained in:
2024-04-09 18:37:51 +03:00
parent b16e65168f
commit 23fa39121c
15 changed files with 371 additions and 85 deletions

View File

@@ -1,5 +1,6 @@
#pragma once
#include <kernel/ACPI/AML/Method.h>
#include <kernel/ACPI/AML/ParseContext.h>
#include <kernel/ACPI/AML/Pkg.h>
#include <kernel/ACPI/AML/Scope.h>
@@ -9,7 +10,9 @@ namespace Kernel::ACPI::AML
struct Device : public AML::Scope
{
Device(NameSeg name) : Scope(name, Node::Type::Device) {}
Device(NameSeg name)
: Scope(Node::Type::Device, name)
{}
static ParseResult parse(ParseContext& context)
{
@@ -27,12 +30,65 @@ namespace Kernel::ACPI::AML
return ParseResult::Failure;
auto device = MUST(BAN::RefPtr<Device>::create(name_string->path.back()));
if (!context.root_namespace->add_named_object(context.scope.span(), name_string.value(), device))
if (!context.root_namespace->add_named_object(context, name_string.value(), device))
return ParseResult::Failure;
return device->enter_context_and_parse_term_list(context, name_string.value(), device_pkg.value());
}
void initialize(BAN::RefPtr<AML::Namespace> root_namespace)
{
bool run_ini = true;
bool init_children = true;
auto _sta = root_namespace->find_object(scope, NameString("_STA"sv));
if (_sta && _sta->type == Node::Type::Method)
{
auto* method = static_cast<Method*>(_sta.ptr());
auto result = method->evaluate(root_namespace);
if (!result.has_value())
{
AML_ERROR("Failed to evaluate {}._STA", scope);
return;
}
if (!result.value())
{
AML_ERROR("Failed to evaluate {}._STA, return value is null", scope);
return;
}
auto result_val = result.value()->as_integer();
if (!result_val.has_value())
{
AML_ERROR("Failed to evaluate {}._STA, return value could not be resolved to integer", scope);
return;
}
run_ini = (result_val.value() & 0x01);
init_children = run_ini || (result_val.value() & 0x02);
}
if (run_ini)
{
auto _ini = root_namespace->find_object(scope, NameString("_INI"sv));
if (_ini && _ini->type == Node::Type::Method)
{
auto* method = static_cast<Method*>(_ini.ptr());
method->evaluate(root_namespace);
}
}
if (init_children)
{
for (auto& [_, child] : objects)
{
if (child->type == Node::Type::Device)
{
auto* device = static_cast<Device*>(child.ptr());
device->initialize(root_namespace);
}
}
}
}
virtual void debug_print(int indent) const override
{
AML_DEBUG_PRINT_INDENT(indent);