diff --git a/kernel/include/kernel/ACPI/AML/Alias.h b/kernel/include/kernel/ACPI/AML/Alias.h new file mode 100644 index 00000000..61520343 --- /dev/null +++ b/kernel/include/kernel/ACPI/AML/Alias.h @@ -0,0 +1,74 @@ +#pragma once + +#include +#include +#include + +namespace Kernel::ACPI::AML +{ + + struct Alias : public AML::NamedObject + { + BAN::RefPtr target; + + Alias(NameSeg name, BAN::RefPtr target) + : NamedObject(Node::Type::Alias, name) + , target(target) + {} + + bool is_scope() const override { return target->is_scope(); } + + BAN::RefPtr copy() override { return target->copy(); } + + BAN::RefPtr as_buffer() override { return target->as_buffer(); } + BAN::RefPtr as_integer() override { return target->as_integer(); } + BAN::RefPtr as_string() override { return target->as_string(); } + + BAN::RefPtr evaluate() override { return target->evaluate(); } + bool store(BAN::RefPtr node) override { return target->store(node); } + + static ParseResult parse(ParseContext& context) + { + ASSERT(context.aml_data.size() >= 1); + ASSERT(static_cast(context.aml_data[0]) == Byte::AliasOp); + context.aml_data = context.aml_data.slice(1); + + auto source_string = AML::NameString::parse(context.aml_data); + if (!source_string.has_value()) + return ParseResult::Failure; + + auto source_object = AML::Namespace::root_namespace()->find_object(context.scope, source_string.value(), AML::Namespace::FindMode::Normal); + if (!source_object) + { + AML_ERROR("Alias target could not be found"); + return ParseResult::Failure; + } + + auto alias_string = AML::NameString::parse(context.aml_data); + if (!alias_string.has_value()) + return ParseResult::Failure; + + auto alias = MUST(BAN::RefPtr::create(alias_string.value().path.back(), source_object)); + if (!Namespace::root_namespace()->add_named_object(context, alias_string.value(), alias)) + return ParseResult::Success; + + #if AML_DEBUG_LEVEL >= 2 + alias->debug_print(0); + AML_DEBUG_PRINTLN(""); + #endif + + return ParseResult::Success; + } + + void debug_print(int indent) const override + { + AML_DEBUG_PRINT_INDENT(indent); + AML_DEBUG_PRINTLN("Alias {} { ", name); + target->debug_print(indent + 1); + AML_DEBUG_PRINTLN(""); + AML_DEBUG_PRINT_INDENT(indent); + AML_DEBUG_PRINT("}"); + } + }; + +} diff --git a/kernel/include/kernel/ACPI/AML/Node.h b/kernel/include/kernel/ACPI/AML/Node.h index 2e82f6ed..df451474 100644 --- a/kernel/include/kernel/ACPI/AML/Node.h +++ b/kernel/include/kernel/ACPI/AML/Node.h @@ -19,10 +19,11 @@ namespace Kernel::ACPI::AML enum class Type { - Debug, + Alias, BankFieldElement, Buffer, BufferField, + Debug, Device, FieldElement, IndexFieldElement, diff --git a/kernel/kernel/ACPI/AML/Node.cpp b/kernel/kernel/ACPI/AML/Node.cpp index 288dd764..fb2854ef 100644 --- a/kernel/kernel/ACPI/AML/Node.cpp +++ b/kernel/kernel/ACPI/AML/Node.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -165,6 +166,8 @@ namespace Kernel::ACPI case AML::Byte::CreateDWordFieldOp: case AML::Byte::CreateQWordFieldOp: return AML::BufferField::parse(context); + case AML::Byte::AliasOp: + return AML::Alias::parse(context); case AML::Byte::NameOp: return AML::Name::parse(context); case AML::Byte::PackageOp: