From 956335e844324a398a0c6a21c5d04d85c2f7999e Mon Sep 17 00:00:00 2001 From: Bananymous Date: Wed, 17 Apr 2024 15:00:14 +0300 Subject: [PATCH] Kernel: Implement AML WhileOp --- kernel/include/kernel/ACPI/AML/While.h | 65 ++++++++++++++++++++++++++ kernel/kernel/ACPI/AML/Node.cpp | 3 ++ 2 files changed, 68 insertions(+) create mode 100644 kernel/include/kernel/ACPI/AML/While.h diff --git a/kernel/include/kernel/ACPI/AML/While.h b/kernel/include/kernel/ACPI/AML/While.h new file mode 100644 index 00000000..19c0bf3b --- /dev/null +++ b/kernel/include/kernel/ACPI/AML/While.h @@ -0,0 +1,65 @@ +#pragma once + +#include +#include +#include + +namespace Kernel::ACPI::AML +{ + + struct While + { + static ParseResult parse(ParseContext& context) + { + ASSERT(context.aml_data.size() >= 1); + ASSERT(static_cast(context.aml_data[0]) == Byte::WhileOp); + context.aml_data = context.aml_data.slice(1); + + auto while_pkg = AML::parse_pkg(context.aml_data); + if (!while_pkg.has_value()) + return ParseResult::Failure; + + auto outer_aml_data = context.aml_data; + + bool breaked = false; + while (!breaked) + { + context.aml_data = while_pkg.value(); + + auto predicate_result = AML::parse_object(context); + if (!predicate_result.success()) + return ParseResult::Failure; + auto predicate = predicate_result.node() ? predicate_result.node()->as_integer() : BAN::Optional(); + if (!predicate.has_value()) + { + AML_ERROR("While predicate is not an integer"); + return ParseResult::Failure; + } + + if (!predicate.value()) + break; + + while (context.aml_data.size() > 0) + { + // NOTE: we can just parse BreakOp here, since this is the only legal place for BreakOp + if (static_cast(context.aml_data[0]) == AML::Byte::BreakOp) + { + context.aml_data = context.aml_data.slice(1); + breaked = true; + break; + } + auto object_result = AML::parse_object(context); + if (object_result.returned()) + return ParseResult(ParseResult::Result::Returned, object_result.node()); + if (!object_result.success()) + return ParseResult::Failure; + } + } + + context.aml_data = outer_aml_data; + + return ParseResult::Success; + } + }; + +} diff --git a/kernel/kernel/ACPI/AML/Node.cpp b/kernel/kernel/ACPI/AML/Node.cpp index 227399e7..640cb00a 100644 --- a/kernel/kernel/ACPI/AML/Node.cpp +++ b/kernel/kernel/ACPI/AML/Node.cpp @@ -21,6 +21,7 @@ #include #include #include +#include namespace Kernel::ACPI { @@ -163,6 +164,8 @@ namespace Kernel::ACPI return AML::Scope::parse(context); case AML::Byte::IfOp: return AML::IfElse::parse(context); + case AML::Byte::WhileOp: + return AML::While::parse(context); case AML::Byte::StoreOp: return AML::Store::parse(context); case AML::Byte::DerefOfOp: