Kernel: AML add flag to force absolute lookup for ACPI namespace

This commit is contained in:
Bananymous 2024-04-16 17:37:08 +03:00
parent e667326df5
commit 7707e01352
9 changed files with 32 additions and 37 deletions

View File

@ -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);

View File

@ -15,7 +15,7 @@ namespace Kernel::ACPI::AML
template<typename F>
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<BAN::String> resolve_path(const AML::NameString& relative_base, const AML::NameString& relative_path, bool allow_nonexistent = false);
enum class FindMode
{
Normal,
ForceAbsolute,
};
BAN::Optional<BAN::String> 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<NamedObject> find_object(const AML::NameString& relative_base, const AML::NameString& relative_path);
BAN::RefPtr<NamedObject> 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<NamedObject> object);

View File

@ -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);

View File

@ -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
{

View File

@ -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<AML::Method*>(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<AML::Scope*>(_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<AML::Method*>(_pic.ptr());

View File

@ -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());

View File

@ -37,7 +37,7 @@ namespace Kernel::ACPI
}
BAN::Optional<BAN::String> AML::Namespace::resolve_path(const AML::NameString& relative_base, const AML::NameString& relative_path, bool allow_nonexistent)
BAN::Optional<BAN::String> 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::NamedObject> AML::Namespace::find_object(const AML::NameString& relative_base, const AML::NameString& relative_path)
BAN::RefPtr<AML::NamedObject> 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);

View File

@ -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());

View File

@ -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)