Kernel: Start working on AML method evaluations
Also fix namespace lookup and scope creations.
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user