Kernel: Rewrite whole AML parser

Now AML parsing is actually done while respecting namespaces and
scopes. I implemented the minimal functionality to parse qemu's AML.

Next step is to implement AML interpreting and then we can drop lai
as a dependency.
This commit is contained in:
2024-04-09 01:16:07 +03:00
parent 090a294017
commit b16e65168f
38 changed files with 1891 additions and 2412 deletions

View File

@@ -0,0 +1,78 @@
#pragma once
#include <kernel/ACPI/AML/Bytes.h>
#include <kernel/ACPI/AML/NamedObject.h>
#include <kernel/ACPI/AML/ParseContext.h>
#include <kernel/ACPI/AML/Pkg.h>
namespace Kernel::ACPI::AML
{
struct Method : public AML::NamedObject
{
uint8_t arg_count;
bool serialized;
uint8_t sync_level;
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)
, arg_count(arg_count)
, serialized(serialized)
, sync_level(sync_level)
, term_list(term_list)
{}
static ParseResult parse(AML::ParseContext& context)
{
ASSERT(context.aml_data.size() >= 1);
ASSERT(static_cast<Byte>(context.aml_data[0]) == Byte::MethodOp);
context.aml_data = context.aml_data.slice(1);
auto method_pkg = AML::parse_pkg(context.aml_data);
if (!method_pkg.has_value())
return ParseResult::Failure;
auto name_string = AML::NameString::parse(method_pkg.value());
if (!name_string.has_value())
return ParseResult::Failure;
if (method_pkg->size() < 1)
return ParseResult::Failure;
auto method_flags = method_pkg.value()[0];
method_pkg = method_pkg.value().slice(1);
auto method = MUST(BAN::RefPtr<Method>::create(
name_string.value().path.back(),
method_flags & 0x07,
(method_flags >> 3) & 0x01,
method_flags >> 4,
method_pkg.value()
));
if (!context.root_namespace->add_named_object(context.scope.span(), name_string.value(), method))
return ParseResult::Failure;
#if AML_DEBUG_LEVEL >= 2
method->debug_print(0);
AML_DEBUG_PRINTLN("");
#endif
return ParseResult::Success;
}
virtual void debug_print(int indent) const override
{
AML_DEBUG_PRINT_INDENT(indent);
AML_DEBUG_PRINT("Method ");
name.debug_print();
AML_DEBUG_PRINTLN("({} args, {}Serialized, 0x{H}) {", arg_count, serialized ? "" : "Not", sync_level);
AML_DEBUG_PRINT_INDENT(indent + 1);
AML_DEBUG_PRINTLN("TermList: {} bytes", term_list.size());
AML_DEBUG_PRINT_INDENT(indent);
AML_DEBUG_PRINT("}");
}
};
}