diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 6d47346d..f0c14178 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -12,7 +12,6 @@ set(KERNEL_SOURCES font/prefs.psf.o kernel/ACPI/ACPI.cpp kernel/ACPI/AML.cpp - kernel/ACPI/AML/Device.cpp kernel/ACPI/AML/Field.cpp kernel/ACPI/AML/NamedObject.cpp kernel/ACPI/AML/Namespace.cpp diff --git a/kernel/include/kernel/ACPI/AML/Device.h b/kernel/include/kernel/ACPI/AML/Device.h index 225c3bf5..02b62d6c 100644 --- a/kernel/include/kernel/ACPI/AML/Device.h +++ b/kernel/include/kernel/ACPI/AML/Device.h @@ -52,6 +52,4 @@ namespace Kernel::ACPI::AML } }; - bool initialize_device(BAN::RefPtr device); - } diff --git a/kernel/include/kernel/ACPI/AML/Scope.h b/kernel/include/kernel/ACPI/AML/Scope.h index b1a5498b..dd47cf00 100644 --- a/kernel/include/kernel/ACPI/AML/Scope.h +++ b/kernel/include/kernel/ACPI/AML/Scope.h @@ -25,4 +25,6 @@ namespace Kernel::ACPI::AML ParseResult enter_context_and_parse_term_list(ParseContext& outer_context, const AML::NameString& name, BAN::ConstByteSpan aml_data); }; + bool initialize_scope(BAN::RefPtr scope); + } diff --git a/kernel/kernel/ACPI/ACPI.cpp b/kernel/kernel/ACPI/ACPI.cpp index 1761f96c..ab8e9303 100644 --- a/kernel/kernel/ACPI/ACPI.cpp +++ b/kernel/kernel/ACPI/ACPI.cpp @@ -462,28 +462,12 @@ acpi_release_global_lock: dprintln("Initializing devices"); - // Evaluate \\_SB._INI - auto _sb_ini = m_namespace->find_object({}, AML::NameString("\\_SB._INI")); - if (_sb_ini && _sb_ini->type == AML::Node::Type::Method) - { - auto* method = static_cast(_sb_ini.ptr()); - if (method->arg_count != 0) - { - dwarnln("Method \\_SB._INI has {} arguments, expected 0", method->arg_count); - return BAN::Error::from_errno(EINVAL); - } - BAN::Vector sync_stack; - method->evaluate({}, sync_stack); - } - - // Initialize devices + // Initialize \\_SB auto _sb = m_namespace->find_object({}, AML::NameString("\\_SB")); if (_sb && _sb->is_scope()) { auto* scope = static_cast(_sb.ptr()); - for (auto& [name, object] : scope->objects) - if (object->type == AML::Node::Type::Device || object->type == AML::Node::Type::Processor) - AML::initialize_device(object); + AML::initialize_scope(scope); } // Evaluate \\_PIC (mode) diff --git a/kernel/kernel/ACPI/AML/Device.cpp b/kernel/kernel/ACPI/AML/Device.cpp deleted file mode 100644 index efbfc2a0..00000000 --- a/kernel/kernel/ACPI/AML/Device.cpp +++ /dev/null @@ -1,73 +0,0 @@ -#include - -namespace Kernel::ACPI -{ - - bool AML::initialize_device(BAN::RefPtr device) - { - bool run_ini = true; - bool init_children = true; - - ASSERT(device->type == Node::Type::Device || device->type == Node::Type::Processor); - ASSERT(device->is_scope()); - auto* scope = static_cast(device.ptr()); - - auto it = scope->objects.find(NameSeg("_STA"sv)); - if (it != scope->objects.end() && it->value->type == Node::Type::Method) - { - auto* method = static_cast(it->value.ptr()); - if (method->arg_count != 0) - { - AML_ERROR("Method {}._STA has {} arguments, expected 0", scope, method->arg_count); - return false; - } - BAN::Vector sync_stack; - auto result = method->evaluate({}, sync_stack); - if (!result.has_value()) - { - AML_ERROR("Failed to evaluate {}._STA", scope); - return false; - } - if (!result.value()) - { - AML_ERROR("Failed to evaluate {}._STA, return value is null", scope); - return false; - } - 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); - AML_ERROR(" Return value: "); - result.value()->debug_print(0); - return false; - } - run_ini = (result_val.value() & 0x01); - init_children = run_ini || (result_val.value() & 0x02); - } - - if (run_ini) - { - auto it = scope->objects.find(NameSeg("_STA"sv)); - if (it != scope->objects.end() && it->value->type == Node::Type::Method) - { - auto* method = static_cast(it->value.ptr()); - if (method->arg_count != 0) - { - AML_ERROR("Method {}._INI has {} arguments, expected 0", scope, method->arg_count); - return false; - } - BAN::Vector sync_stack; - method->evaluate({}, sync_stack); - } - } - - bool success = true; - if (init_children) - for (auto& [_, child] : scope->objects) - if (child->type == Node::Type::Device || child->type == Node::Type::Processor) - if (!initialize_device(child)) - success = false; - return success; - } - -} diff --git a/kernel/kernel/ACPI/AML/Scope.cpp b/kernel/kernel/ACPI/AML/Scope.cpp index 3aa1846b..a4a1328f 100644 --- a/kernel/kernel/ACPI/AML/Scope.cpp +++ b/kernel/kernel/ACPI/AML/Scope.cpp @@ -79,4 +79,77 @@ namespace Kernel::ACPI AML_DEBUG_PRINT("}"); } + bool AML::initialize_scope(BAN::RefPtr scope) + { +#if AML_DEBUG_LEVEL >= 2 + AML_DEBUG_PRINTLN("Initializing {}", scope->scope); +#endif + + bool run_ini = true; + bool init_children = true; + + auto it = scope->objects.find(NameSeg("_STA"sv)); + if (scope->type != AML::Node::Type::Namespace && it != scope->objects.end() && it->value->type == Node::Type::Method) + { + auto* method = static_cast(it->value.ptr()); + if (method->arg_count != 0) + { + AML_ERROR("Method {}._STA has {} arguments, expected 0", scope->scope, method->arg_count); + return false; + } + BAN::Vector sync_stack; + auto result = method->evaluate({}, sync_stack); + if (!result.has_value()) + { + AML_ERROR("Failed to evaluate {}._STA", scope->scope); + return false; + } + if (!result.value()) + { + AML_ERROR("Failed to evaluate {}._STA, return value is null", scope->scope); + return false; + } + 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->scope); + AML_ERROR(" Return value: "); + result.value()->debug_print(0); + return false; + } + run_ini = (result_val.value() & 0x01); + init_children = run_ini || (result_val.value() & 0x02); + } + + if (run_ini) + { + auto it = scope->objects.find(NameSeg("_STA"sv)); + if (it != scope->objects.end() && it->value->type == Node::Type::Method) + { + auto* method = static_cast(it->value.ptr()); + if (method->arg_count != 0) + { + AML_ERROR("Method {}._INI has {} arguments, expected 0", scope->scope, method->arg_count); + return false; + } + BAN::Vector sync_stack; + method->evaluate({}, sync_stack); + } + } + + bool success = true; + if (init_children) + { + for (auto& [_, child] : scope->objects) + { + if (!child->is_scope()) + continue; + auto* child_scope = static_cast(child.ptr()); + if (!initialize_scope(child_scope)) + success = false; + } + } + return success; + } + }