From f97fb1b35db0633b837ff5188e00b4b66e994464 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Wed, 17 Apr 2024 00:52:57 +0300 Subject: [PATCH] Kernel: Evaluate _REG on devices for embedded controller if needed --- kernel/kernel/ACPI/AML/Scope.cpp | 44 ++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/kernel/kernel/ACPI/AML/Scope.cpp b/kernel/kernel/ACPI/AML/Scope.cpp index 5316d844..a53d4789 100644 --- a/kernel/kernel/ACPI/AML/Scope.cpp +++ b/kernel/kernel/ACPI/AML/Scope.cpp @@ -1,6 +1,8 @@ #include +#include #include #include +#include #include namespace Kernel::ACPI @@ -93,6 +95,48 @@ namespace Kernel::ACPI AML_DEBUG_PRINTLN("Initializing {}", scope->scope); #endif + if (auto reg = Namespace::root_namespace()->find_object(scope->scope, AML::NameString("_REG"sv), Namespace::FindMode::ForceAbsolute)) + { + bool embedded_controller = false; + Namespace::for_each_child(scope->scope, + [&](const auto&, auto& child) + { + if (child->type != AML::Node::Type::OpRegion) + return; + auto* region = static_cast(child.ptr()); + if (region->region_space == AML::OpRegion::RegionSpace::EmbeddedController) + embedded_controller = true; + } + ); + if (embedded_controller) + { + if (reg->type != AML::Node::Type::Method) + { + AML_ERROR("Object {}._REG is not a method", scope->scope); + return false; + } + + auto* method = static_cast(reg.ptr()); + if (method->arg_count != 2) + { + AML_ERROR("Method {}._REG has {} arguments, expected 2", scope->scope, method->arg_count); + return false; + } + + BAN::RefPtr embedded_controller = MUST(BAN::RefPtr::create(static_cast(AML::OpRegion::RegionSpace::EmbeddedController))); + + Method::Arguments arguments; + arguments[0] = MUST(BAN::RefPtr::create(embedded_controller)); + arguments[1] = MUST(BAN::RefPtr::create(AML::Integer::Constants::One)); + BAN::Vector sync_stack; + if (!method->evaluate(arguments, sync_stack).has_value()) + { + AML_ERROR("Failed to evaluate {}._REG(EmbeddedController, 1), ignoring device", scope->scope); + return false; + } + } + } + bool run_ini = true; bool init_children = true;