LibACPI: Add support for strings

Co-authored-by: RatcheT2497 <[email protected]>
This commit is contained in:
UndefineandRatcheT2497 authored and Sönke Holz committed 2026-11-01 15:08:28 +01:00
1 parent afbe9b228c
commit 7150a99e75
6 files changed
+58 -3

No files matched your search

+7 -1
View File
@@ -195,7 +195,7 @@ ErrorOr<Object> Interpreter::finalize_value_opcode(OpcodeFrame& frame)
case Opcode::WordPrefix:
case Opcode::DWordPrefix:
case Opcode::QWordPrefix:
VERIFY(frame.operand(0).is<u64>());
case Opcode::StringPrefix:
return frame.operand(0);
default:
@@ -315,6 +315,12 @@ ErrorOr<IterationDecision> Interpreter::read_operand(TableStream& stream, Operan
TRY(top_opcode_frame.finish_operand(value, stream.offset()));
return IterationDecision::Continue;
}
case OperandType::String: {
DEBUG_LOG("Reading string...");
auto value = TRY(stream.read_string());
TRY(top_opcode_frame.finish_operand(String(value), stream.offset()));
return IterationDecision::Continue;
}
// https://uefi.org/specs/ACPI/6.6/20_AML_Specification.html#fieldelement
case OperandType::FieldElement: {
+18 -2
View File
@@ -16,8 +16,21 @@
namespace ACPI::AML {
class String {
public:
String(ByteBuffer buffer)
: m_buffer(move(buffer))
{
}
ByteBuffer& buffer() { return m_buffer; }
private:
ByteBuffer m_buffer;
};
template<typename T>
concept IsNodeData = OneOf<T, u64, NameString>;
concept IsNodeData = OneOf<T, u64, String, NameString>;
class Object {
public:
@@ -50,7 +63,7 @@ public:
}
protected:
Variant<AK::Empty, u64, NameString> m_data;
Variant<AK::Empty, u64, String, NameString> m_data;
};
}
@@ -64,6 +77,9 @@ struct AK::Formatter<::ACPI::AML::Object> : AK::Formatter<FormatString> {
return AK::Formatter<FormatString>::format(builder, "(Decimal: {}, Hexadecimal: {:X})"sv, value, value);
}
if (object.is<::ACPI::AML::String>())
return AK::Formatter<FormatString>::format(builder, "'{}'"sv, StringView(MUST(object.as<::ACPI::AML::String>()).buffer()));
if (object.is<::ACPI::AML::NameString>())
return AK::Formatter<FormatString>::format(builder, "{}"sv, TRY(MUST(object.as<::ACPI::AML::NameString>()).to_string()));
@@ -25,6 +25,7 @@ constexpr static Array<OperandType, 2> BYTE_CONST_OPERANDS = { OperandType::Byte
constexpr static Array<OperandType, 2> WORD_CONST_OPERANDS = { OperandType::WordData, OperandType::End };
constexpr static Array<OperandType, 2> DWORD_CONST_OPERANDS = { OperandType::DWordData, OperandType::End };
constexpr static Array<OperandType, 2> QWORD_CONST_OPERANDS = { OperandType::QWordData, OperandType::End };
constexpr static Array<OperandType, 2> STRING_CONST_OPERANDS = { OperandType::String, OperandType::End };
constexpr static Array<OperandType, 4> METHOD_OPERANDS = {
OperandType::PackageLength,
@@ -68,6 +69,8 @@ static ErrorOr<ReadonlySpan<OperandType>> get_opcode_operand_template(Opcode opc
return DWORD_CONST_OPERANDS.span();
case Opcode::QWordPrefix:
return QWORD_CONST_OPERANDS.span();
case Opcode::StringPrefix:
return STRING_CONST_OPERANDS.span();
case Opcode::ScopeOp:
return SCOPE_OPERANDS.span();
@@ -123,6 +126,7 @@ bool OpcodeFrame::filter_opcode_for_next_operand(Opcode opcode)
case OperandType::WordData:
case OperandType::DWordData:
case OperandType::QWordData:
case OperandType::String:
case OperandType::FieldElement:
return false;
+1
View File
@@ -20,6 +20,7 @@ enum class OperandType : u8 {
WordData,
DWordData,
QWordData,
String,
FieldElement,
TermArg,
@@ -45,6 +45,33 @@ ErrorOr<u32> TableStream::read_package_length()
return value;
}
// https://uefi.org/specs/ACPI/6.6/20_AML_Specification.html#stringprefix
ErrorOr<ByteBuffer> TableStream::read_string()
{
size_t start = offset();
u8 b = TRY(read_value<u8>());
if (b == 0)
return ByteBuffer::create_uninitialized(0);
do {
if (b > 0x7f) {
warnln("Invalid character in string: {} at offset {}", b, offset());
return Error::from_string_view_or_print_error_and_return_errno("Invalid character in string!"sv, EINVAL);
}
b = TRY(read_value<u8>());
} while (b != 0);
size_t size = offset() - start;
TRY(seek(start));
auto span = TRY(read_in_place<u8 const>(size - 1));
// Skip over null byte so it doesn't end up in the buffer.
TRY(seek(1, SeekMode::FromCurrentPosition));
return ByteBuffer::copy(span);
}
// https://uefi.org/specs/ACPI/6.6/20_AML_Specification.html#namestring
ErrorOr<NameString> TableStream::read_name_string()
{
+1
View File
@@ -24,6 +24,7 @@ public:
ErrorOr<Opcode> read_opcode();
ErrorOr<u32> read_package_length();
ErrorOr<ByteBuffer> read_string();
ErrorOr<NameString> read_name_string();
ErrorOr<u8> peek_byte();