Kernel: Implement AML To{Buffer,Integer,String}Op

This commit is contained in:
Bananymous 2024-08-14 20:28:32 +03:00
parent 17b7e9e772
commit 44d5c8c4b4
2 changed files with 97 additions and 0 deletions

View File

@ -0,0 +1,92 @@
#pragma once
#include <kernel/ACPI/AML/Buffer.h>
#include <kernel/ACPI/AML/Integer.h>
#include <kernel/ACPI/AML/ParseContext.h>
#include <kernel/ACPI/AML/String.h>
namespace Kernel::ACPI::AML
{
struct Conversion
{
static ParseResult parse(AML::ParseContext& context)
{
const auto opcode = static_cast<AML::Byte>(context.aml_data[0]);
context.aml_data = context.aml_data.slice(1);
switch (opcode)
{
case AML::Byte::ToIntegerOp:
case AML::Byte::ToBufferOp:
case AML::Byte::ToStringOp:
break;
default:
ASSERT_NOT_REACHED();
}
auto data_result = AML::parse_object(context);
if (!data_result.success())
return ParseResult::Failure;
auto data_node = data_result.node();
if (!data_node)
{
AML_ERROR("Conversion {2H} data could not be evaluated", static_cast<uint8_t>(opcode));
return ParseResult::Failure;
}
if (context.aml_data.size() < 1)
{
AML_ERROR("Conversion {2H} missing target", static_cast<uint8_t>(opcode));
return ParseResult::Failure;
}
BAN::RefPtr<AML::Node> target_node;
if (context.aml_data[0] == 0x00)
context.aml_data = context.aml_data.slice(1);
else
{
auto target_result = AML::parse_object(context);
if (!target_result.success())
return ParseResult::Failure;
target_node = target_result.node();
if (!target_node)
{
AML_ERROR("Conversion {2H} target invalid", static_cast<uint8_t>(opcode));
return ParseResult::Failure;
}
}
BAN::RefPtr<AML::Node> converted;
switch (opcode)
{
case AML::Byte::ToBufferOp:
converted = data_node->as_buffer();
break;
case AML::Byte::ToIntegerOp:
converted = data_node->as_integer();
break;
case AML::Byte::ToStringOp:
converted = data_node->as_string();
break;
default:
ASSERT_NOT_REACHED();
}
if (!converted)
{
AML_ERROR("Conversion {2H} could not convert from node type {}", static_cast<uint8_t>(opcode), static_cast<uint8_t>(data_node->type));
return ParseResult::Failure;
}
if (target_node && !target_node->store(converted))
{
AML_ERROR("Conversion {2H} failed to store converted value", static_cast<uint8_t>(opcode));
return ParseResult::Failure;
}
return ParseResult(converted);
}
};
}

View File

@ -1,6 +1,7 @@
#include <kernel/ACPI/AML/Alias.h>
#include <kernel/ACPI/AML/Buffer.h>
#include <kernel/ACPI/AML/Bytes.h>
#include <kernel/ACPI/AML/Conversion.h>
#include <kernel/ACPI/AML/Device.h>
#include <kernel/ACPI/AML/Expression.h>
#include <kernel/ACPI/AML/Event.h>
@ -166,6 +167,10 @@ namespace Kernel::ACPI
case AML::Byte::SubtractOp:
case AML::Byte::XorOp:
return AML::Expression::parse(context);
case AML::Byte::ToBufferOp:
case AML::Byte::ToIntegerOp:
case AML::Byte::ToStringOp:
return AML::Conversion::parse(context);
case AML::Byte::CreateBitFieldOp:
case AML::Byte::CreateByteFieldOp:
case AML::Byte::CreateWordFieldOp: