From 7707e01352d5507f7107ea93906f832a939a84c8 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Tue, 16 Apr 2024 17:37:08 +0300 Subject: [PATCH] Kernel: AML add flag to force absolute lookup for ACPI namespace --- kernel/include/kernel/ACPI/AML/Method.h | 5 ----- kernel/include/kernel/ACPI/AML/Namespace.h | 11 ++++++++--- kernel/include/kernel/ACPI/AML/Package.h | 2 +- kernel/include/kernel/ACPI/AML/Reference.h | 2 +- kernel/kernel/ACPI/ACPI.cpp | 8 ++++---- kernel/kernel/ACPI/AML/Field.cpp | 10 +++++----- kernel/kernel/ACPI/AML/Namespace.cpp | 21 ++++++++------------- kernel/kernel/ACPI/AML/Node.cpp | 2 +- kernel/kernel/ACPI/AML/Scope.cpp | 8 ++++---- 9 files changed, 32 insertions(+), 37 deletions(-) diff --git a/kernel/include/kernel/ACPI/AML/Method.h b/kernel/include/kernel/ACPI/AML/Method.h index 605973e4..11967fa2 100644 --- a/kernel/include/kernel/ACPI/AML/Method.h +++ b/kernel/include/kernel/ACPI/AML/Method.h @@ -54,12 +54,7 @@ namespace Kernel::ACPI::AML )); if (!Namespace::root_namespace()->add_named_object(context, name_string.value(), method)) return ParseResult::Failure; - - auto method_scope = Namespace::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 = AML::NameString(method_scope.release_value()); #if AML_DEBUG_LEVEL >= 2 method->debug_print(0); diff --git a/kernel/include/kernel/ACPI/AML/Namespace.h b/kernel/include/kernel/ACPI/AML/Namespace.h index cf6dbe7f..66a65654 100644 --- a/kernel/include/kernel/ACPI/AML/Namespace.h +++ b/kernel/include/kernel/ACPI/AML/Namespace.h @@ -15,7 +15,7 @@ namespace Kernel::ACPI::AML template static void for_each_child(const AML::NameString& scope, const F& callback) { - auto canonical_path = root_namespace()->resolve_path({}, scope); + auto canonical_path = root_namespace()->resolve_path(scope, {}, FindMode::ForceAbsolute); ASSERT(canonical_path.has_value()); for (auto& [path, child] : root_namespace()->m_objects) @@ -39,10 +39,15 @@ namespace Kernel::ACPI::AML void debug_print(int indent) const override; - BAN::Optional resolve_path(const AML::NameString& relative_base, const AML::NameString& relative_path, bool allow_nonexistent = false); + enum class FindMode + { + Normal, + ForceAbsolute, + }; + BAN::Optional resolve_path(const AML::NameString& relative_base, const AML::NameString& relative_path, FindMode mode, bool check_existence = true) const; // Find an object in the namespace. Returns nullptr if the object is not found. - BAN::RefPtr find_object(const AML::NameString& relative_base, const AML::NameString& relative_path); + BAN::RefPtr find_object(const AML::NameString& relative_base, const AML::NameString& relative_path, FindMode mode); // Add an object to the namespace. Returns false if the parent object could not be added. bool add_named_object(ParseContext&, const AML::NameString& object_path, BAN::RefPtr object); diff --git a/kernel/include/kernel/ACPI/AML/Package.h b/kernel/include/kernel/ACPI/AML/Package.h index 3fd627cb..e9899f92 100644 --- a/kernel/include/kernel/ACPI/AML/Package.h +++ b/kernel/include/kernel/ACPI/AML/Package.h @@ -32,7 +32,7 @@ namespace Kernel::ACPI::AML // resolve references for (auto& reference : unresolved_references) { - auto object = Namespace::root_namespace()->find_object(scope, reference.name); + auto object = Namespace::root_namespace()->find_object(scope, reference.name, Namespace::FindMode::Normal); if (!object) { AML_ERROR("Failed to resolve reference {} in package", reference.name); diff --git a/kernel/include/kernel/ACPI/AML/Reference.h b/kernel/include/kernel/ACPI/AML/Reference.h index 50112b15..38f34c6b 100644 --- a/kernel/include/kernel/ACPI/AML/Reference.h +++ b/kernel/include/kernel/ACPI/AML/Reference.h @@ -54,7 +54,7 @@ namespace Kernel::ACPI::AML auto name = NameString::parse(context.aml_data); if (!name.has_value()) return ParseResult::Failure; - object = Namespace::root_namespace()->find_object(context.scope, name.value()); + object = Namespace::root_namespace()->find_object(context.scope, name.value(), Namespace::FindMode::Normal); } else { diff --git a/kernel/kernel/ACPI/ACPI.cpp b/kernel/kernel/ACPI/ACPI.cpp index 08368ee7..1326c1cd 100644 --- a/kernel/kernel/ACPI/ACPI.cpp +++ b/kernel/kernel/ACPI/ACPI.cpp @@ -354,7 +354,7 @@ acpi_release_global_lock: return; } - auto s5_object = m_namespace->find_object({}, AML::NameString("\\_S5")); + auto s5_object = m_namespace->find_object({}, AML::NameString("_S5"), AML::Namespace::FindMode::ForceAbsolute); if (!s5_object) { dwarnln("\\_S5 not found"); @@ -386,7 +386,7 @@ acpi_release_global_lock: return; } - auto pts_object = m_namespace->find_object({}, AML::NameString("\\_PTS")); + auto pts_object = m_namespace->find_object({}, AML::NameString("_PTS"), AML::Namespace::FindMode::ForceAbsolute); if (pts_object && pts_object->type == AML::Node::Type::Method) { auto* method = static_cast(pts_object.ptr()); @@ -465,7 +465,7 @@ acpi_release_global_lock: dprintln("Initializing devices"); // Initialize \\_SB - auto _sb = m_namespace->find_object({}, AML::NameString("\\_SB")); + auto _sb = m_namespace->find_object({}, AML::NameString("_SB"), AML::Namespace::FindMode::ForceAbsolute); if (_sb && _sb->is_scope()) { auto* scope = static_cast(_sb.ptr()); @@ -473,7 +473,7 @@ acpi_release_global_lock: } // Evaluate \\_PIC (mode) - auto _pic = m_namespace->find_object({}, AML::NameString("\\_PIC")); + auto _pic = m_namespace->find_object({}, AML::NameString("_PIC"), AML::Namespace::FindMode::ForceAbsolute); if (_pic && _pic->type == AML::Node::Type::Method) { auto* method = static_cast(_pic.ptr()); diff --git a/kernel/kernel/ACPI/AML/Field.cpp b/kernel/kernel/ACPI/AML/Field.cpp index d0addd82..d164ae4b 100644 --- a/kernel/kernel/ACPI/AML/Field.cpp +++ b/kernel/kernel/ACPI/AML/Field.cpp @@ -404,7 +404,7 @@ namespace Kernel::ACPI if (!name_string.has_value()) return ParseResult::Failure; - auto op_region = Namespace::root_namespace()->find_object(context.scope, name_string.value()); + auto op_region = Namespace::root_namespace()->find_object(context.scope, name_string.value(), Namespace::FindMode::Normal); if (!op_region || op_region->type != AML::Node::Type::OpRegion) { AML_ERROR("FieldOp: {} does not name a valid OpRegion", name_string.value()); @@ -532,7 +532,7 @@ namespace Kernel::ACPI auto index_field_element_name = NameString::parse(field_pkg); if (!index_field_element_name.has_value()) return ParseResult::Failure; - auto index_field_element = Namespace::root_namespace()->find_object(context.scope, index_field_element_name.value()); + auto index_field_element = Namespace::root_namespace()->find_object(context.scope, index_field_element_name.value(), Namespace::FindMode::Normal); if (!index_field_element || index_field_element->type != AML::Node::Type::FieldElement) { AML_ERROR("IndexField IndexName does not name a valid FieldElement"); @@ -542,7 +542,7 @@ namespace Kernel::ACPI auto data_field_element_name = NameString::parse(field_pkg); if (!data_field_element_name.has_value()) return ParseResult::Failure; - auto data_field_element = Namespace::root_namespace()->find_object(context.scope, data_field_element_name.value()); + auto data_field_element = Namespace::root_namespace()->find_object(context.scope, data_field_element_name.value(), Namespace::FindMode::Normal); if (!data_field_element || data_field_element->type != AML::Node::Type::FieldElement) { AML_ERROR("IndexField DataName does not name a valid FieldElement"); @@ -694,7 +694,7 @@ namespace Kernel::ACPI auto op_region_name = NameString::parse(field_pkg); if (!op_region_name.has_value()) return ParseResult::Failure; - auto op_region = Namespace::root_namespace()->find_object(context.scope, op_region_name.value()); + auto op_region = Namespace::root_namespace()->find_object(context.scope, op_region_name.value(), Namespace::FindMode::Normal); if (!op_region || op_region->type != AML::Node::Type::OpRegion) { AML_ERROR("BankField RegionName {} does not name a valid OpRegion", op_region_name.value()); @@ -704,7 +704,7 @@ namespace Kernel::ACPI auto bank_selector_name = NameString::parse(field_pkg); if (!bank_selector_name.has_value()) return ParseResult::Failure; - auto bank_selector = Namespace::root_namespace()->find_object(context.scope, bank_selector_name.value()); + auto bank_selector = Namespace::root_namespace()->find_object(context.scope, bank_selector_name.value(), Namespace::FindMode::Normal); if (!bank_selector) { AML_ERROR("BankField BankSelector {} does not name a valid object", bank_selector_name.value()); diff --git a/kernel/kernel/ACPI/AML/Namespace.cpp b/kernel/kernel/ACPI/AML/Namespace.cpp index 18015c4d..793d4300 100644 --- a/kernel/kernel/ACPI/AML/Namespace.cpp +++ b/kernel/kernel/ACPI/AML/Namespace.cpp @@ -37,7 +37,7 @@ namespace Kernel::ACPI } - BAN::Optional AML::Namespace::resolve_path(const AML::NameString& relative_base, const AML::NameString& relative_path, bool allow_nonexistent) + BAN::Optional AML::Namespace::resolve_path(const AML::NameString& relative_base, const AML::NameString& relative_path, FindMode mode, bool check_existence) const { LockGuard _(m_object_mutex); @@ -45,7 +45,7 @@ namespace Kernel::ACPI ASSERT(relative_base.prefix == "\\"sv || relative_base.path.empty()); // Do absolute path lookup - if (!relative_path.prefix.empty() || relative_path.path.size() != 1 || allow_nonexistent) + if (!relative_path.prefix.empty() || relative_path.path.size() != 1 || mode == FindMode::ForceAbsolute) { BAN::String absolute_path; MUST(absolute_path.push_back('\\')); @@ -77,7 +77,7 @@ namespace Kernel::ACPI if (absolute_path.back() == '.') absolute_path.pop_back(); - if (allow_nonexistent || m_objects.contains(absolute_path)) + if (!check_existence || m_objects.contains(absolute_path)) return absolute_path; return {}; } @@ -118,11 +118,11 @@ namespace Kernel::ACPI return {}; } - BAN::RefPtr AML::Namespace::find_object(const AML::NameString& relative_base, const AML::NameString& relative_path) + BAN::RefPtr AML::Namespace::find_object(const AML::NameString& relative_base, const AML::NameString& relative_path, FindMode mode) { LockGuard _(m_object_mutex); - auto canonical_path = resolve_path(relative_base, relative_path); + auto canonical_path = resolve_path(relative_base, relative_path, mode); if (!canonical_path.has_value()) return nullptr; @@ -139,14 +139,9 @@ namespace Kernel::ACPI ASSERT(!object_path.path.empty()); ASSERT(object_path.path.back() == object->name); - auto canonical_path = resolve_path(parse_context.scope, object_path, true); + auto canonical_path = resolve_path(parse_context.scope, object_path, FindMode::ForceAbsolute, false); ASSERT(canonical_path.has_value()); - - if (canonical_path->empty()) - { - AML_ERROR("Trying to add root namespace"); - return false; - } + ASSERT(!canonical_path->empty()); if (m_objects.contains(canonical_path.value())) { @@ -172,7 +167,7 @@ namespace Kernel::ACPI { LockGuard _(m_object_mutex); - auto canonical_path = resolve_path({}, absolute_path); + auto canonical_path = resolve_path({}, absolute_path, FindMode::ForceAbsolute); if (!canonical_path.has_value()) { AML_ERROR("Trying to delete non-existent object '{}'", absolute_path); diff --git a/kernel/kernel/ACPI/AML/Node.cpp b/kernel/kernel/ACPI/AML/Node.cpp index ccf5474f..300de514 100644 --- a/kernel/kernel/ACPI/AML/Node.cpp +++ b/kernel/kernel/ACPI/AML/Node.cpp @@ -191,7 +191,7 @@ namespace Kernel::ACPI auto name_string = AML::NameString::parse(context.aml_data); if (!name_string.has_value()) return ParseResult::Failure; - auto aml_object = Namespace::root_namespace()->find_object(context.scope, name_string.value()); + auto aml_object = Namespace::root_namespace()->find_object(context.scope, name_string.value(), Namespace::FindMode::Normal); if (!aml_object) { AML_ERROR("NameString {} not found in namespace", name_string.value()); diff --git a/kernel/kernel/ACPI/AML/Scope.cpp b/kernel/kernel/ACPI/AML/Scope.cpp index 690fc4c2..5316d844 100644 --- a/kernel/kernel/ACPI/AML/Scope.cpp +++ b/kernel/kernel/ACPI/AML/Scope.cpp @@ -20,7 +20,7 @@ namespace Kernel::ACPI if (!name_string.has_value()) return ParseResult::Failure; - auto named_object = Namespace::root_namespace()->find_object(context.scope, name_string.value()); + auto named_object = Namespace::root_namespace()->find_object(context.scope, name_string.value(), Namespace::FindMode::Normal); if (!named_object) { AML_ERROR("Scope '{}' not found in namespace", name_string.value()); @@ -38,7 +38,7 @@ namespace Kernel::ACPI AML::ParseResult AML::Scope::enter_context_and_parse_term_list(ParseContext& outer_context, const AML::NameString& name_string, BAN::ConstByteSpan aml_data) { - auto resolved_scope = Namespace::root_namespace()->resolve_path(outer_context.scope, name_string); + auto resolved_scope = Namespace::root_namespace()->resolve_path(outer_context.scope, name_string, Namespace::FindMode::Normal); if (!resolved_scope.has_value()) return ParseResult::Failure; @@ -96,7 +96,7 @@ namespace Kernel::ACPI bool run_ini = true; bool init_children = true; - if (auto sta = Namespace::root_namespace()->find_object(scope->scope, AML::NameString("_STA"sv))) + if (auto sta = Namespace::root_namespace()->find_object(scope->scope, AML::NameString("_STA"sv), Namespace::FindMode::ForceAbsolute)) { auto result = evaluate_or_invoke(sta); if (!result.has_value()) @@ -111,7 +111,7 @@ namespace Kernel::ACPI if (run_ini) { - auto ini = Namespace::root_namespace()->find_object(scope->scope, AML::NameString("_INI"sv)); + auto ini = Namespace::root_namespace()->find_object(scope->scope, AML::NameString("_INI"sv), Namespace::FindMode::ForceAbsolute); if (ini) { if (ini->type != AML::Node::Type::Method)