Kernel: Simplify AML method invocation API

This commit is contained in:
Bananymous 2024-04-17 01:20:58 +03:00
parent a40ef610a2
commit 49b7467840
4 changed files with 48 additions and 25 deletions

View File

@ -11,9 +11,7 @@ namespace Kernel::ACPI::AML
struct Method : public AML::Scope
{
using Arguments = BAN::Array<BAN::RefPtr<AML::Register>, 7>;
Mutex mutex;
Kernel::Mutex mutex;
uint8_t arg_count;
bool serialized;
uint8_t sync_level;
@ -64,7 +62,30 @@ namespace Kernel::ACPI::AML
return ParseResult::Success;
}
BAN::Optional<BAN::RefPtr<AML::Node>> evaluate(Arguments args, BAN::Vector<uint8_t>& current_sync_stack)
BAN::Optional<BAN::RefPtr<AML::Node>> invoke(
BAN::RefPtr<AML::Node> arg0 = {},
BAN::RefPtr<AML::Node> arg1 = {},
BAN::RefPtr<AML::Node> arg2 = {},
BAN::RefPtr<AML::Node> arg3 = {},
BAN::RefPtr<AML::Node> arg4 = {},
BAN::RefPtr<AML::Node> arg5 = {},
BAN::RefPtr<AML::Node> arg6 = {}
)
{
BAN::Vector<uint8_t> sync_stack;
return invoke_with_sync_stack(sync_stack, arg0, arg1, arg2, arg3, arg4, arg5, arg6);
}
BAN::Optional<BAN::RefPtr<AML::Node>> invoke_with_sync_stack(
BAN::Vector<uint8_t>& current_sync_stack,
BAN::RefPtr<AML::Node> arg0 = {},
BAN::RefPtr<AML::Node> arg1 = {},
BAN::RefPtr<AML::Node> arg2 = {},
BAN::RefPtr<AML::Node> arg3 = {},
BAN::RefPtr<AML::Node> arg4 = {},
BAN::RefPtr<AML::Node> arg5 = {},
BAN::RefPtr<AML::Node> arg6 = {}
)
{
if (serialized && !current_sync_stack.empty() && sync_level < current_sync_stack.back())
{
@ -75,7 +96,13 @@ namespace Kernel::ACPI::AML
ParseContext context;
context.aml_data = term_list;
context.scope = scope;
context.method_args = args;
context.method_args[0] = MUST(BAN::RefPtr<AML::Register>::create(arg0));
context.method_args[1] = MUST(BAN::RefPtr<AML::Register>::create(arg1));
context.method_args[2] = MUST(BAN::RefPtr<AML::Register>::create(arg2));
context.method_args[3] = MUST(BAN::RefPtr<AML::Register>::create(arg3));
context.method_args[4] = MUST(BAN::RefPtr<AML::Register>::create(arg4));
context.method_args[5] = MUST(BAN::RefPtr<AML::Register>::create(arg5));
context.method_args[6] = MUST(BAN::RefPtr<AML::Register>::create(arg6));
context.sync_stack = BAN::move(current_sync_stack);
for (auto& local : context.method_locals)
local = MUST(BAN::RefPtr<AML::Register>::create());

View File

@ -396,10 +396,7 @@ acpi_release_global_lock:
return;
}
AML::Method::Arguments args;
args[0] = MUST(BAN::RefPtr<AML::Register>::create(MUST(BAN::RefPtr<AML::Integer>::create(5))));
BAN::Vector<uint8_t> sync_stack;
if (!method->evaluate(args, sync_stack).has_value())
if (!method->invoke(MUST(BAN::RefPtr<AML::Integer>::create(5))).has_value())
{
dwarnln("Failed to evaluate \\_PTS");
return;
@ -482,11 +479,7 @@ acpi_release_global_lock:
dwarnln("Method \\_PIC has {} arguments, expected 1", method->arg_count);
return BAN::Error::from_errno(EINVAL);
}
AML::Method::Arguments args;
args[0] = MUST(BAN::RefPtr<AML::Register>::create(MUST(BAN::RefPtr<AML::Integer>::create(mode))));
BAN::Vector<uint8_t> sync_stack;
method->evaluate(args, sync_stack);
method->invoke(MUST(BAN::RefPtr<AML::Integer>::create(mode)));
}
dprintln("Devices are initialized");

View File

@ -201,7 +201,7 @@ namespace Kernel::ACPI
{
auto* method = static_cast<AML::Method*>(aml_object.ptr());
Method::Arguments args;
BAN::Array<BAN::RefPtr<AML::Node>, 7> args;
for (uint8_t i = 0; i < method->arg_count; i++)
{
auto arg = AML::parse_object(context);
@ -213,7 +213,16 @@ namespace Kernel::ACPI
args[i] = MUST(BAN::RefPtr<AML::Register>::create(arg.node()));
}
auto result = method->evaluate(args, context.sync_stack);
auto result = method->invoke_with_sync_stack(
context.sync_stack,
args[0],
args[1],
args[2],
args[3],
args[4],
args[5],
args[6]
);
if (!result.has_value())
{
AML_ERROR("Failed to evaluate {}", name_string.value());

View File

@ -78,8 +78,7 @@ namespace Kernel::ACPI
return {};
}
BAN::Vector<uint8_t> sync_stack;
auto result = method->evaluate({}, sync_stack);
auto result = method->invoke();
if (!result.has_value())
{
AML_ERROR("Failed to evaluate method");
@ -125,11 +124,7 @@ namespace Kernel::ACPI
BAN::RefPtr<AML::Node> embedded_controller = MUST(BAN::RefPtr<AML::Integer>::create(static_cast<uint64_t>(AML::OpRegion::RegionSpace::EmbeddedController)));
Method::Arguments arguments;
arguments[0] = MUST(BAN::RefPtr<AML::Register>::create(embedded_controller));
arguments[1] = MUST(BAN::RefPtr<AML::Register>::create(AML::Integer::Constants::One));
BAN::Vector<uint8_t> sync_stack;
if (!method->evaluate(arguments, sync_stack).has_value())
if (!method->invoke(embedded_controller, AML::Integer::Constants::One).has_value())
{
AML_ERROR("Failed to evaluate {}._REG(EmbeddedController, 1), ignoring device", scope->scope);
return false;
@ -171,8 +166,7 @@ namespace Kernel::ACPI
return false;
}
BAN::Vector<uint8_t> sync_stack;
auto result = method->evaluate({}, sync_stack);
auto result = method->invoke();
if (!result.has_value())
{
AML_ERROR("Failed to evaluate {}._INI, ignoring device", scope->scope);