Kernel: Cleanup AML device initialization
_STA and _INI are now properly called on call devices
This commit is contained in:
parent
46b5a7697c
commit
89c4abc07a
|
@ -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
|
||||
|
|
|
@ -52,6 +52,4 @@ namespace Kernel::ACPI::AML
|
|||
}
|
||||
};
|
||||
|
||||
bool initialize_device(BAN::RefPtr<NamedObject> device);
|
||||
|
||||
}
|
||||
|
|
|
@ -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> scope);
|
||||
|
||||
}
|
||||
|
|
|
@ -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<AML::Method*>(_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<uint8_t> 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<AML::Scope*>(_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)
|
||||
|
|
|
@ -1,73 +0,0 @@
|
|||
#include <kernel/ACPI/AML/Device.h>
|
||||
|
||||
namespace Kernel::ACPI
|
||||
{
|
||||
|
||||
bool AML::initialize_device(BAN::RefPtr<AML::NamedObject> 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<Scope*>(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<Method*>(it->value.ptr());
|
||||
if (method->arg_count != 0)
|
||||
{
|
||||
AML_ERROR("Method {}._STA has {} arguments, expected 0", scope, method->arg_count);
|
||||
return false;
|
||||
}
|
||||
BAN::Vector<uint8_t> 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<Method*>(it->value.ptr());
|
||||
if (method->arg_count != 0)
|
||||
{
|
||||
AML_ERROR("Method {}._INI has {} arguments, expected 0", scope, method->arg_count);
|
||||
return false;
|
||||
}
|
||||
BAN::Vector<uint8_t> 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;
|
||||
}
|
||||
|
||||
}
|
|
@ -79,4 +79,77 @@ namespace Kernel::ACPI
|
|||
AML_DEBUG_PRINT("}");
|
||||
}
|
||||
|
||||
bool AML::initialize_scope(BAN::RefPtr<AML::Scope> 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<Method*>(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<uint8_t> 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<Method*>(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<uint8_t> 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<Scope*>(child.ptr());
|
||||
if (!initialize_scope(child_scope))
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue