mirror of
https://github.com/SerenityOS/serenity.git
synced 2026-11-07 04:29:30 -10:00
LibACPI: Add support for strings
Co-authored-by: RatcheT2497 <[email protected]>
This commit is contained in:
1 parent
afbe9b228c
commit
7150a99e75
6 files changed
+58
-3
No files matched your search
@@ -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: {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in new issue
Block a user