diff --git a/kernel/include/kernel/ACPI/AML/Node.h b/kernel/include/kernel/ACPI/AML/Node.h index b28e4ea7..814f0cef 100644 --- a/kernel/include/kernel/ACPI/AML/Node.h +++ b/kernel/include/kernel/ACPI/AML/Node.h @@ -306,6 +306,8 @@ namespace Kernel::ACPI::AML // If method has no return, it will return BAN::ErrorOr method_call(const Scope& scope, const Node& method, BAN::Array&& args, uint32_t call_depth = 0); + BAN::ErrorOr method_call(const Scope& scope, const Node& method, + Node&& arg0 = {}, Node&& arg1 = {}, Node&& arg2 = {}, Node&& arg3 = {}, Node&& arg4 = {}, Node&& arg5 = {}, Node&& arg6 = {}); } diff --git a/kernel/kernel/ACPI/ACPI.cpp b/kernel/kernel/ACPI/ACPI.cpp index 116becf0..031ec63f 100644 --- a/kernel/kernel/ACPI/ACPI.cpp +++ b/kernel/kernel/ACPI/ACPI.cpp @@ -819,7 +819,7 @@ acpi_release_global_lock: auto index = i * 8 + (pending & ~(pending - 1)); if (m_gpe_methods[index]) - if (auto ret = AML::method_call(m_gpe_scope, m_gpe_methods[index]->node, {}); ret.is_error()) + if (auto ret = AML::method_call(m_gpe_scope, m_gpe_methods[index]->node, BAN::Array{}); ret.is_error()) dwarnln("Failed to evaluate _GPE {}: ", index, ret.error()); handled_event = true; diff --git a/kernel/kernel/ACPI/AML/Node.cpp b/kernel/kernel/ACPI/AML/Node.cpp index 04094260..b581a00e 100644 --- a/kernel/kernel/ACPI/AML/Node.cpp +++ b/kernel/kernel/ACPI/AML/Node.cpp @@ -2571,7 +2571,7 @@ namespace Kernel::ACPI::AML case Node::Type::Method: if (node.as.method.arg_count != 0) return BAN::Error::from_errno(EFAULT); - return TRY(method_call(node_path, node, {})); + return TRY(method_call(node_path, node, BAN::Array{})); } dwarnln("evaluate {}", node); @@ -2680,6 +2680,33 @@ namespace Kernel::ACPI::AML return result; } + BAN::ErrorOr method_call(const Scope& scope, const Node& method, Node&& arg0, Node&& arg1, Node&& arg2, Node&& arg3, Node&& arg4, Node&& arg5, Node&& arg6) + { + BAN::Array args(nullptr); + +#define INIT_ARGn(n) \ + if (arg ## n.type != Node::Type::Uninitialized) \ + { \ + args[n] = new Reference(); \ + if (args[n] == nullptr) \ + return BAN::Error::from_errno(ENOMEM); \ + args[n]->ref_count = 1; \ + args[n]->node = BAN::move(arg ## n); \ + } + + INIT_ARGn(0); + INIT_ARGn(1); + INIT_ARGn(2); + INIT_ARGn(3); + INIT_ARGn(4); + INIT_ARGn(5); + INIT_ARGn(6); +#undef INIT_ARGn + + return method_call(scope, method, BAN::move(args)); + } + + BAN::ErrorOr parse_node(ParseContext& context, bool return_ref) { if (context.aml_data.empty()) diff --git a/kernel/kernel/ACPI/BatterySystem.cpp b/kernel/kernel/ACPI/BatterySystem.cpp index 8bb2ee3a..8feb299b 100644 --- a/kernel/kernel/ACPI/BatterySystem.cpp +++ b/kernel/kernel/ACPI/BatterySystem.cpp @@ -41,7 +41,7 @@ namespace Kernel::ACPI if (method_ref == nullptr) return BAN::Error::from_errno(EFAULT); - auto result = TRY(AML::method_call(method_path, method_ref->node, {})); + auto result = TRY(AML::method_call(method_path, method_ref->node, BAN::Array{})); if (result.type != AML::Node::Type::Package || result.as.package->num_elements < m_result_index) return BAN::Error::from_errno(EFAULT);