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
|
font/prefs.psf.o
|
||||||
kernel/ACPI/ACPI.cpp
|
kernel/ACPI/ACPI.cpp
|
||||||
kernel/ACPI/AML.cpp
|
kernel/ACPI/AML.cpp
|
||||||
kernel/ACPI/AML/Device.cpp
|
|
||||||
kernel/ACPI/AML/Field.cpp
|
kernel/ACPI/AML/Field.cpp
|
||||||
kernel/ACPI/AML/NamedObject.cpp
|
kernel/ACPI/AML/NamedObject.cpp
|
||||||
kernel/ACPI/AML/Namespace.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);
|
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");
|
dprintln("Initializing devices");
|
||||||
|
|
||||||
// Evaluate \\_SB._INI
|
// Initialize \\_SB
|
||||||
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
|
|
||||||
auto _sb = m_namespace->find_object({}, AML::NameString("\\_SB"));
|
auto _sb = m_namespace->find_object({}, AML::NameString("\\_SB"));
|
||||||
if (_sb && _sb->is_scope())
|
if (_sb && _sb->is_scope())
|
||||||
{
|
{
|
||||||
auto* scope = static_cast<AML::Scope*>(_sb.ptr());
|
auto* scope = static_cast<AML::Scope*>(_sb.ptr());
|
||||||
for (auto& [name, object] : scope->objects)
|
AML::initialize_scope(scope);
|
||||||
if (object->type == AML::Node::Type::Device || object->type == AML::Node::Type::Processor)
|
|
||||||
AML::initialize_device(object);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate \\_PIC (mode)
|
// 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("}");
|
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