Kernel: Make ACPI \\_OSI return true for Linux

This commit is contained in:
Bananymous 2024-04-17 02:19:35 +03:00
parent 0ad7025a17
commit 45b9dc8be9
2 changed files with 32 additions and 16 deletions

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include <BAN/Function.h>
#include <kernel/ACPI/AML/Bytes.h> #include <kernel/ACPI/AML/Bytes.h>
#include <kernel/ACPI/AML/Namespace.h> #include <kernel/ACPI/AML/Namespace.h>
#include <kernel/ACPI/AML/ParseContext.h> #include <kernel/ACPI/AML/ParseContext.h>
@ -16,6 +17,7 @@ namespace Kernel::ACPI::AML
bool serialized; bool serialized;
uint8_t sync_level; uint8_t sync_level;
BAN::Function<BAN::RefPtr<AML::Node>(ParseContext&)> override_function;
BAN::ConstByteSpan term_list; BAN::ConstByteSpan term_list;
Method(AML::NameSeg name, uint8_t arg_count, bool serialized, uint8_t sync_level) Method(AML::NameSeg name, uint8_t arg_count, bool serialized, uint8_t sync_level)
@ -117,21 +119,26 @@ namespace Kernel::ACPI::AML
AML_DEBUG_PRINTLN("Evaluating {}", scope); AML_DEBUG_PRINTLN("Evaluating {}", scope);
#endif #endif
BAN::Optional<BAN::RefPtr<AML::Node>> return_value = BAN::RefPtr<AML::Node>(); BAN::Optional<BAN::RefPtr<AML::Node>> return_value = BAN::RefPtr<AML::Node>();
while (context.aml_data.size() > 0)
if (override_function)
return_value = override_function(context);
else
{ {
auto parse_result = AML::parse_object(context); while (context.aml_data.size() > 0)
if (parse_result.returned())
{ {
return_value = parse_result.node(); auto parse_result = AML::parse_object(context);
break; if (parse_result.returned())
} {
if (!parse_result.success()) return_value = parse_result.node();
{ break;
AML_ERROR("Method {} evaluate failed", scope); }
return_value = {}; if (!parse_result.success())
break; {
AML_ERROR("Method {} evaluate failed", scope);
return_value = {};
break;
}
} }
} }

View File

@ -4,6 +4,7 @@
#include <kernel/ACPI/AML/Namespace.h> #include <kernel/ACPI/AML/Namespace.h>
#include <kernel/ACPI/AML/ParseContext.h> #include <kernel/ACPI/AML/ParseContext.h>
#include <kernel/ACPI/AML/Region.h> #include <kernel/ACPI/AML/Region.h>
#include <kernel/ACPI/AML/String.h>
#include <kernel/Lock/LockGuard.h> #include <kernel/Lock/LockGuard.h>
namespace Kernel::ACPI namespace Kernel::ACPI
@ -211,11 +212,19 @@ namespace Kernel::ACPI
ADD_PREDEFIED_NAMESPACE("_TZ"sv); ADD_PREDEFIED_NAMESPACE("_TZ"sv);
#undef ADD_PREDEFIED_NAMESPACE #undef ADD_PREDEFIED_NAMESPACE
// Add dummy \_OSI // Add \_OSI that returns true for Linux compatibility
MUST(s_osi_aml_data.push_back(static_cast<uint8_t>(Byte::ReturnOp)));
MUST(s_osi_aml_data.push_back(static_cast<uint8_t>(Byte::ZeroOp)));
auto osi = MUST(BAN::RefPtr<AML::Method>::create(NameSeg("_OSI"sv), 1, false, 0)); auto osi = MUST(BAN::RefPtr<AML::Method>::create(NameSeg("_OSI"sv), 1, false, 0));
osi->term_list = s_osi_aml_data.span(); osi->override_function = [](AML::ParseContext& context) -> BAN::RefPtr<AML::Node> {
ASSERT(context.method_args[0]);
auto arg = context.method_args[0]->evaluate();
if (!arg || arg->type != AML::Node::Type::String)
{
AML_ERROR("Invalid _OSI argument");
return {};
}
auto string = static_cast<AML::String*>(arg.ptr());
return string->string == "Linux" ? AML::Integer::Constants::Ones : AML::Integer::Constants::Zero;
};
ASSERT(s_root_namespace->add_named_object(context, AML::NameString("\\_OSI"), osi)); ASSERT(s_root_namespace->add_named_object(context, AML::NameString("\\_OSI"), osi));
return s_root_namespace; return s_root_namespace;