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,14 +1,15 @@
#pragma once
#include <kernel/ACPI/AML/Bytes.h>
#include <kernel/ACPI/AML/NamedObject.h>
#include <kernel/ACPI/AML/Namespace.h>
#include <kernel/ACPI/AML/ParseContext.h>
#include <kernel/ACPI/AML/Pkg.h>
#include <kernel/ACPI/AML/Scope.h>
namespace Kernel::ACPI::AML
{
struct Method : public AML::NamedObject
struct Method : public AML::Scope
{
uint8_t arg_count;
bool serialized;
@@ -16,12 +17,11 @@ namespace Kernel::ACPI::AML
BAN::ConstByteSpan term_list;
Method(AML::NameSeg name, uint8_t arg_count, bool serialized, uint8_t sync_level, BAN::ConstByteSpan term_list)
: AML::NamedObject(Node::Type::Method, name)
Method(AML::NameSeg name, uint8_t arg_count, bool serialized, uint8_t sync_level)
: AML::Scope(Node::Type::Method, name)
, arg_count(arg_count)
, serialized(serialized)
, sync_level(sync_level)
, term_list(term_list)
{}
static ParseResult parse(AML::ParseContext& context)
@@ -47,13 +47,17 @@ namespace Kernel::ACPI::AML
name_string.value().path.back(),
method_flags & 0x07,
(method_flags >> 3) & 0x01,
method_flags >> 4,
method_pkg.value()
method_flags >> 4
));
if (!context.root_namespace->add_named_object(context.scope.span(), name_string.value(), method))
if (!context.root_namespace->add_named_object(context, name_string.value(), method))
return ParseResult::Failure;
auto method_scope = context.root_namespace->resolve_path(context.scope, name_string.value());
if (!method_scope.has_value())
return ParseResult::Failure;
method->term_list = method_pkg.value();
method->scope = method_scope.release_value();
#if AML_DEBUG_LEVEL >= 2
method->debug_print(0);
AML_DEBUG_PRINTLN("");
@@ -62,6 +66,43 @@ namespace Kernel::ACPI::AML
return ParseResult::Success;
}
BAN::Optional<BAN::RefPtr<AML::Node>> evaluate(BAN::RefPtr<AML::Namespace> root_namespace)
{
ParseContext context;
context.root_namespace = root_namespace.ptr();
context.aml_data = term_list;
context.scope = scope;
AML_DEBUG_PRINTLN("Evaluating method {}", scope);
BAN::Optional<BAN::RefPtr<AML::Node>> return_value;
ASSERT(arg_count == 0);
while (context.aml_data.size() > 0)
{
if (static_cast<AML::Byte>(context.aml_data[0]) == AML::Byte::ReturnOp)
{
context.aml_data = context.aml_data.slice(1);
auto result = AML::parse_object(context);
if (result.success())
return_value = result.node();
break;
}
auto object_result = AML::parse_object(context);
if (!object_result.success())
break;
}
while (!context.created_objects.empty())
{
root_namespace->remove_named_object(context.created_objects.back());
context.created_objects.pop_back();
}
return return_value;
}
virtual void debug_print(int indent) const override
{
AML_DEBUG_PRINT_INDENT(indent);