forked from Bananymous/banan-os
Kernel: Implement more features for AML parser/interpreter
Added - BankField - BufferField - PowerResource - ThermalZone - Reference - Package element forward declare
This commit is contained in:
parent
93ddee5956
commit
afb1d7ef0c
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <kernel/ACPI/AML/Bytes.h>
|
#include <kernel/ACPI/AML/Bytes.h>
|
||||||
|
#include <kernel/ACPI/AML/Integer.h>
|
||||||
#include <kernel/ACPI/AML/Node.h>
|
#include <kernel/ACPI/AML/Node.h>
|
||||||
#include <kernel/ACPI/AML/ParseContext.h>
|
#include <kernel/ACPI/AML/ParseContext.h>
|
||||||
#include <kernel/ACPI/AML/Pkg.h>
|
#include <kernel/ACPI/AML/Pkg.h>
|
||||||
|
@ -12,7 +13,14 @@ namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
BAN::Vector<uint8_t> buffer;
|
BAN::Vector<uint8_t> buffer;
|
||||||
|
|
||||||
Buffer() : AML::Node(Node::Type::Buffer) {}
|
Buffer()
|
||||||
|
: AML::Node(Node::Type::Buffer)
|
||||||
|
{}
|
||||||
|
|
||||||
|
BAN::RefPtr<AML::Node> evaluate() override
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
static ParseResult parse(AML::ParseContext& context)
|
static ParseResult parse(AML::ParseContext& context)
|
||||||
{
|
{
|
||||||
|
@ -57,4 +65,147 @@ namespace Kernel::ACPI::AML
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct BufferField : AML::NamedObject
|
||||||
|
{
|
||||||
|
BAN::RefPtr<Buffer> buffer;
|
||||||
|
size_t field_bit_offset;
|
||||||
|
size_t field_bit_size;
|
||||||
|
|
||||||
|
BufferField(AML::NameSeg name, BAN::RefPtr<Buffer> buffer, size_t field_bit_offset, size_t field_bit_size)
|
||||||
|
: AML::NamedObject(Node::Type::BufferField, name)
|
||||||
|
, buffer(buffer)
|
||||||
|
, field_bit_offset(field_bit_offset)
|
||||||
|
, field_bit_size(field_bit_size)
|
||||||
|
{}
|
||||||
|
|
||||||
|
BAN::RefPtr<AML::Node> evaluate() override
|
||||||
|
{
|
||||||
|
ASSERT(buffer);
|
||||||
|
ASSERT(field_bit_offset + field_bit_size <= buffer->buffer.size() * 8);
|
||||||
|
|
||||||
|
uint64_t value = 0;
|
||||||
|
if (field_bit_size == 1)
|
||||||
|
{
|
||||||
|
size_t byte_offset = field_bit_offset / 8;
|
||||||
|
size_t bit_offset = field_bit_offset % 8;
|
||||||
|
value = (buffer->buffer[byte_offset] >> bit_offset) & 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ASSERT(field_bit_size % 8 == 0);
|
||||||
|
for (size_t byte = 0; byte < field_bit_size / 8; byte++)
|
||||||
|
value |= buffer->buffer[byte] << byte;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MUST(BAN::RefPtr<AML::Integer>::create(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool store(BAN::RefPtr<AML::Node> node) override
|
||||||
|
{
|
||||||
|
ASSERT(buffer);
|
||||||
|
ASSERT(field_bit_offset + field_bit_size <= buffer->buffer.size() * 8);
|
||||||
|
|
||||||
|
auto value = node->as_integer();
|
||||||
|
if (!value.has_value())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (field_bit_size == 1)
|
||||||
|
{
|
||||||
|
size_t byte_offset = field_bit_offset / 8;
|
||||||
|
size_t bit_offset = field_bit_offset % 8;
|
||||||
|
buffer->buffer[byte_offset] &= ~(1 << bit_offset);
|
||||||
|
buffer->buffer[byte_offset] |= (value.value() & 1) << bit_offset;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ASSERT(field_bit_size % 8 == 0);
|
||||||
|
for (size_t byte = 0; byte < field_bit_size / 8; byte++)
|
||||||
|
buffer->buffer[byte] = (value.value() >> (byte * 8)) & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ParseResult parse(AML::ParseContext& context)
|
||||||
|
{
|
||||||
|
ASSERT(context.aml_data.size() >= 1);
|
||||||
|
|
||||||
|
size_t field_bit_size = 0;
|
||||||
|
switch (static_cast<Byte>(context.aml_data[0]))
|
||||||
|
{
|
||||||
|
case AML::Byte::CreateBitFieldOp:
|
||||||
|
field_bit_size = 1;
|
||||||
|
break;
|
||||||
|
case AML::Byte::CreateByteFieldOp:
|
||||||
|
field_bit_size = 8;
|
||||||
|
break;
|
||||||
|
case AML::Byte::CreateWordFieldOp:
|
||||||
|
field_bit_size = 16;
|
||||||
|
break;
|
||||||
|
case AML::Byte::CreateDWordFieldOp:
|
||||||
|
field_bit_size = 32;
|
||||||
|
break;
|
||||||
|
case AML::Byte::CreateQWordFieldOp:
|
||||||
|
field_bit_size = 64;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
}
|
||||||
|
context.aml_data = context.aml_data.slice(1);
|
||||||
|
|
||||||
|
auto buffer_result = AML::parse_object(context);
|
||||||
|
if (!buffer_result.success())
|
||||||
|
return ParseResult::Failure;
|
||||||
|
auto buffer_node = buffer_result.node() ? buffer_result.node()->evaluate() : nullptr;
|
||||||
|
if (!buffer_node || buffer_node->type != Node::Type::Buffer)
|
||||||
|
{
|
||||||
|
AML_ERROR("Buffer source does not evaluate to a Buffer");
|
||||||
|
return ParseResult::Failure;
|
||||||
|
}
|
||||||
|
auto buffer = static_cast<Buffer*>(buffer_node.ptr());
|
||||||
|
|
||||||
|
auto index_result = AML::parse_object(context);
|
||||||
|
if (!index_result.success())
|
||||||
|
return ParseResult::Failure;
|
||||||
|
auto index = index_result.node() ? index_result.node()->as_integer() : BAN::Optional<uint64_t>();
|
||||||
|
if (!index.has_value())
|
||||||
|
{
|
||||||
|
AML_ERROR("Failed to parse index for BufferField");
|
||||||
|
return ParseResult::Failure;
|
||||||
|
}
|
||||||
|
size_t field_bit_offset = index.value();
|
||||||
|
if (field_bit_size != 1)
|
||||||
|
field_bit_offset *= 8;
|
||||||
|
|
||||||
|
auto field_name = AML::NameString::parse(context.aml_data);
|
||||||
|
if (!field_name.has_value())
|
||||||
|
return ParseResult::Failure;
|
||||||
|
if (field_name->path.empty())
|
||||||
|
{
|
||||||
|
AML_ERROR("Empty field name for BufferField");
|
||||||
|
return ParseResult::Failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto field = MUST(BAN::RefPtr<BufferField>::create(field_name->path.back(), buffer, field_bit_offset, field_bit_size));
|
||||||
|
if (!Namespace::root_namespace()->add_named_object(context, field_name.value(), field))
|
||||||
|
return ParseResult::Failure;
|
||||||
|
|
||||||
|
#if AML_DEBUG_LEVEL >= 2
|
||||||
|
field->debug_print(0);
|
||||||
|
AML_DEBUG_PRINTLN("");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ParseResult::Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void debug_print(int indent) const override
|
||||||
|
{
|
||||||
|
AML_DEBUG_PRINT_INDENT(indent);
|
||||||
|
AML_DEBUG_PRINT("BufferField {} at bit offset {} ({} bits) to { ", name, field_bit_offset, field_bit_size);
|
||||||
|
buffer->debug_print(0);
|
||||||
|
AML_DEBUG_PRINT(" }");
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,16 @@ namespace Kernel::ACPI::AML
|
||||||
WriteAsZeros = 2,
|
WriteAsZeros = 2,
|
||||||
};
|
};
|
||||||
UpdateRule update_rule;
|
UpdateRule update_rule;
|
||||||
|
|
||||||
|
enum class AccessAttrib
|
||||||
|
{
|
||||||
|
Normal = 0,
|
||||||
|
Bytes = 1,
|
||||||
|
RawBytes = 2,
|
||||||
|
RawProcessBytes = 3,
|
||||||
|
};
|
||||||
|
AccessAttrib access_attrib = AccessAttrib::Normal;
|
||||||
|
uint8_t access_length = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FieldElement : public NamedObject
|
struct FieldElement : public NamedObject
|
||||||
|
@ -98,4 +108,30 @@ namespace Kernel::ACPI::AML
|
||||||
static ParseResult parse(ParseContext& context);
|
static ParseResult parse(ParseContext& context);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct BankFieldElement : public NamedObject
|
||||||
|
{
|
||||||
|
uint64_t bit_offset;
|
||||||
|
uint64_t bit_count;
|
||||||
|
|
||||||
|
FieldRules access_rules;
|
||||||
|
|
||||||
|
BAN::RefPtr<OpRegion> op_region;
|
||||||
|
BAN::RefPtr<NamedObject> bank_selector;
|
||||||
|
uint64_t bank_value;
|
||||||
|
|
||||||
|
BankFieldElement(NameSeg name, uint64_t bit_offset, uint64_t bit_count, FieldRules access_rules)
|
||||||
|
: NamedObject(Node::Type::BankFieldElement, name)
|
||||||
|
, bit_offset(bit_offset)
|
||||||
|
, bit_count(bit_count)
|
||||||
|
, access_rules(access_rules)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void debug_print(int indent) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BankField
|
||||||
|
{
|
||||||
|
static ParseResult parse(ParseContext& context);
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <kernel/ACPI/AML/Buffer.h>
|
||||||
|
#include <kernel/ACPI/AML/Node.h>
|
||||||
|
#include <kernel/ACPI/AML/ParseContext.h>
|
||||||
|
#include <kernel/ACPI/AML/Reference.h>
|
||||||
|
|
||||||
|
namespace Kernel::ACPI::AML
|
||||||
|
{
|
||||||
|
|
||||||
|
struct Index
|
||||||
|
{
|
||||||
|
static ParseResult parse(ParseContext& context)
|
||||||
|
{
|
||||||
|
ASSERT(context.aml_data.size() >= 1);
|
||||||
|
ASSERT(static_cast<Byte>(context.aml_data[0]) == Byte::IndexOp);
|
||||||
|
context.aml_data = context.aml_data.slice(1);
|
||||||
|
|
||||||
|
auto source_result = AML::parse_object(context);
|
||||||
|
if (!source_result.success())
|
||||||
|
return ParseResult::Failure;
|
||||||
|
auto source = source_result.node() ? source_result.node()->evaluate() : BAN::RefPtr<AML::Node>();
|
||||||
|
if (!source)
|
||||||
|
{
|
||||||
|
AML_ERROR("IndexOp source is null");
|
||||||
|
return ParseResult::Failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto index_result = AML::parse_object(context);
|
||||||
|
if (!index_result.success())
|
||||||
|
return ParseResult::Failure;
|
||||||
|
auto index = index_result.node() ? index_result.node()->as_integer() : BAN::Optional<uint64_t>();
|
||||||
|
if (!index.has_value())
|
||||||
|
{
|
||||||
|
AML_ERROR("IndexOp index is not an integer");
|
||||||
|
return ParseResult::Failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::RefPtr<AML::Reference> result;
|
||||||
|
switch (source->type)
|
||||||
|
{
|
||||||
|
case AML::Node::Type::Buffer:
|
||||||
|
{
|
||||||
|
auto buffer = static_cast<AML::Buffer*>(source.ptr());
|
||||||
|
if (index.value() >= buffer->buffer.size())
|
||||||
|
{
|
||||||
|
AML_ERROR("IndexOp index is out of buffer bounds");
|
||||||
|
return ParseResult::Failure;
|
||||||
|
}
|
||||||
|
auto buffer_field = MUST(BAN::RefPtr<BufferField>::create(NameSeg(""sv), buffer, index.value() * 8, 8));
|
||||||
|
result = MUST(BAN::RefPtr<AML::Reference>::create(buffer_field));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case AML::Node::Type::Package:
|
||||||
|
AML_TODO("IndexOp source Package");
|
||||||
|
return ParseResult::Failure;
|
||||||
|
case AML::Node::Type::String:
|
||||||
|
AML_TODO("IndexOp source String");
|
||||||
|
return ParseResult::Failure;
|
||||||
|
default:
|
||||||
|
AML_ERROR("IndexOp source is not a Buffer, Package, or String");
|
||||||
|
return ParseResult::Failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if AML_DEBUG_LEVEL >= 2
|
||||||
|
AML_DEBUG_PRINT("Index {}, ", index.value());
|
||||||
|
source->debug_print(0);
|
||||||
|
AML_DEBUG_PRINTLN("");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (context.aml_data.size() < 1)
|
||||||
|
return ParseResult::Failure;
|
||||||
|
|
||||||
|
if (context.aml_data[0] == 0x00)
|
||||||
|
context.aml_data = context.aml_data.slice(1);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto destination_result = AML::parse_object(context);
|
||||||
|
if (!destination_result.success())
|
||||||
|
return ParseResult::Failure;
|
||||||
|
auto destination = destination_result.node();
|
||||||
|
if (!destination)
|
||||||
|
{
|
||||||
|
AML_ERROR("IndexOp failed to resolve destination");
|
||||||
|
return ParseResult::Failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!destination->store(result))
|
||||||
|
return ParseResult::Failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ParseResult(result);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -14,13 +14,16 @@ namespace Kernel::ACPI::AML
|
||||||
struct Integer : public Node
|
struct Integer : public Node
|
||||||
{
|
{
|
||||||
static constexpr uint64_t Ones = -1;
|
static constexpr uint64_t Ones = -1;
|
||||||
uint64_t value;
|
const uint64_t value;
|
||||||
|
|
||||||
Integer(uint64_t value) : Node(Node::Type::Integer), value(value) {}
|
Integer(uint64_t value)
|
||||||
|
: Node(Node::Type::Integer)
|
||||||
|
, value(value)
|
||||||
|
{}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> evaluate() override
|
BAN::RefPtr<AML::Node> evaluate() override
|
||||||
{
|
{
|
||||||
return MUST(BAN::RefPtr<Integer>::create(value));
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ParseResult parse(BAN::ConstByteSpan& aml_data)
|
static ParseResult parse(BAN::ConstByteSpan& aml_data)
|
||||||
|
|
|
@ -106,6 +106,23 @@ namespace Kernel::ACPI::AML
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool can_parse(BAN::ConstByteSpan aml_data)
|
||||||
|
{
|
||||||
|
if (aml_data.size() == 0)
|
||||||
|
return false;
|
||||||
|
switch (static_cast<AML::Byte>(aml_data[0]))
|
||||||
|
{
|
||||||
|
case AML::Byte::RootChar:
|
||||||
|
case AML::Byte::ParentPrefixChar:
|
||||||
|
case AML::Byte::NullName:
|
||||||
|
case AML::Byte::DualNamePrefix:
|
||||||
|
case AML::Byte::MultiNamePrefix:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return is_lead_name_char(aml_data[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static BAN::Optional<NameString> parse(BAN::ConstByteSpan& aml_data)
|
static BAN::Optional<NameString> parse(BAN::ConstByteSpan& aml_data)
|
||||||
{
|
{
|
||||||
if (aml_data.size() == 0)
|
if (aml_data.size() == 0)
|
||||||
|
|
|
@ -13,7 +13,9 @@ namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
enum class Type
|
enum class Type
|
||||||
{
|
{
|
||||||
|
BankFieldElement,
|
||||||
Buffer,
|
Buffer,
|
||||||
|
BufferField,
|
||||||
Device,
|
Device,
|
||||||
FieldElement,
|
FieldElement,
|
||||||
IndexFieldElement,
|
IndexFieldElement,
|
||||||
|
@ -24,9 +26,12 @@ namespace Kernel::ACPI::AML
|
||||||
Namespace,
|
Namespace,
|
||||||
OpRegion,
|
OpRegion,
|
||||||
Package,
|
Package,
|
||||||
|
PowerResource,
|
||||||
Processor,
|
Processor,
|
||||||
|
Reference,
|
||||||
Register,
|
Register,
|
||||||
String,
|
String,
|
||||||
|
ThermalZone,
|
||||||
};
|
};
|
||||||
const Type type;
|
const Type type;
|
||||||
|
|
||||||
|
@ -35,9 +40,9 @@ namespace Kernel::ACPI::AML
|
||||||
|
|
||||||
virtual bool is_scope() const { return false; }
|
virtual bool is_scope() const { return false; }
|
||||||
|
|
||||||
BAN::Optional<uint64_t> as_integer();
|
[[nodiscard]] BAN::Optional<uint64_t> as_integer();
|
||||||
virtual BAN::RefPtr<AML::Node> evaluate() { AML_TODO("evaluate, type {}", static_cast<uint8_t>(type)); return nullptr; }
|
[[nodiscard]] virtual BAN::RefPtr<AML::Node> evaluate() { AML_TODO("evaluate, type {}", static_cast<uint8_t>(type)); return nullptr; }
|
||||||
virtual bool store(BAN::RefPtr<AML::Node> source) { AML_TODO("store, type {}", static_cast<uint8_t>(type)); return false; }
|
[[nodiscard]] virtual bool store(BAN::RefPtr<AML::Node> source) { AML_TODO("store, type {}", static_cast<uint8_t>(type)); return false; }
|
||||||
|
|
||||||
virtual void debug_print(int indent) const = 0;
|
virtual void debug_print(int indent) const = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,27 +10,40 @@ namespace Kernel::ACPI::AML
|
||||||
|
|
||||||
struct Package : public AML::Node
|
struct Package : public AML::Node
|
||||||
{
|
{
|
||||||
|
struct UnresolvedReference
|
||||||
|
{
|
||||||
|
AML::NameString name;
|
||||||
|
size_t index;
|
||||||
|
};
|
||||||
|
BAN::Vector<UnresolvedReference> unresolved_references;
|
||||||
|
AML::NameString scope; // Used for resolving references
|
||||||
|
|
||||||
BAN::Vector<BAN::RefPtr<AML::Node>> elements;
|
BAN::Vector<BAN::RefPtr<AML::Node>> elements;
|
||||||
|
|
||||||
Package() : Node(Node::Type::Package) {}
|
Package(BAN::Vector<BAN::RefPtr<AML::Node>>&& elements, BAN::Vector<UnresolvedReference>&& unresolved_references, AML::NameString scope)
|
||||||
|
: Node(Node::Type::Package)
|
||||||
|
, elements(BAN::move(elements))
|
||||||
|
, unresolved_references(BAN::move(unresolved_references))
|
||||||
|
, scope(scope)
|
||||||
|
{}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> evaluate() override
|
BAN::RefPtr<AML::Node> evaluate() override
|
||||||
{
|
{
|
||||||
BAN::Vector<BAN::RefPtr<AML::Node>> evaluated_elements;
|
// resolve references
|
||||||
for (auto& element : elements)
|
for (auto& reference : unresolved_references)
|
||||||
{
|
{
|
||||||
auto evaluated = element->evaluate();
|
auto object = Namespace::root_namespace()->find_object(scope, reference.name);
|
||||||
if (!evaluated)
|
if (!object)
|
||||||
{
|
{
|
||||||
AML_ERROR("Failed to evaluate element in package");
|
AML_ERROR("Failed to resolve reference {} in package", reference.name);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
evaluated_elements.push_back(evaluated);
|
ASSERT(!elements[reference.index]);
|
||||||
|
elements[reference.index] = object;
|
||||||
}
|
}
|
||||||
|
unresolved_references.clear();
|
||||||
|
|
||||||
auto package = MUST(BAN::RefPtr<Package>::create());
|
return this;
|
||||||
package->elements = BAN::move(evaluated_elements);
|
|
||||||
return package;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static ParseResult parse(AML::ParseContext& context)
|
static ParseResult parse(AML::ParseContext& context)
|
||||||
|
@ -52,18 +65,33 @@ namespace Kernel::ACPI::AML
|
||||||
package_context.aml_data = package_context.aml_data.slice(1);
|
package_context.aml_data = package_context.aml_data.slice(1);
|
||||||
|
|
||||||
BAN::Vector<BAN::RefPtr<AML::Node>> elements;
|
BAN::Vector<BAN::RefPtr<AML::Node>> elements;
|
||||||
|
BAN::Vector<UnresolvedReference> unresolved_references;
|
||||||
while (elements.size() < num_elements && package_context.aml_data.size() > 0)
|
while (elements.size() < num_elements && package_context.aml_data.size() > 0)
|
||||||
|
{
|
||||||
|
BAN::RefPtr<AML::Node> element;
|
||||||
|
|
||||||
|
// Store name strings as references
|
||||||
|
if (AML::NameString::can_parse(package_context.aml_data))
|
||||||
|
{
|
||||||
|
auto name = AML::NameString::parse(package_context.aml_data);
|
||||||
|
if (!name.has_value())
|
||||||
|
return ParseResult::Failure;
|
||||||
|
MUST(unresolved_references.push_back(UnresolvedReference { .name = name.value(), .index = elements.size() }));
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
auto element_result = AML::parse_object(package_context);
|
auto element_result = AML::parse_object(package_context);
|
||||||
if (!element_result.success())
|
if (!element_result.success())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
MUST(elements.push_back(element_result.node()));
|
element = element_result.node();
|
||||||
|
}
|
||||||
|
|
||||||
|
MUST(elements.push_back(element));
|
||||||
}
|
}
|
||||||
while (elements.size() < num_elements)
|
while (elements.size() < num_elements)
|
||||||
MUST(elements.push_back(BAN::RefPtr<AML::Node>()));
|
MUST(elements.push_back(BAN::RefPtr<AML::Node>()));
|
||||||
|
|
||||||
auto package = MUST(BAN::RefPtr<Package>::create());
|
auto package = MUST(BAN::RefPtr<Package>::create(BAN::move(elements), BAN::move(unresolved_references), context.scope));
|
||||||
package->elements = BAN::move(elements);
|
|
||||||
return ParseResult(package);
|
return ParseResult(package);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +102,11 @@ namespace Kernel::ACPI::AML
|
||||||
AML_DEBUG_PRINTLN("");
|
AML_DEBUG_PRINTLN("");
|
||||||
for (const auto& element : elements)
|
for (const auto& element : elements)
|
||||||
{
|
{
|
||||||
element->debug_print(indent + 1);
|
AML_DEBUG_PRINT_INDENT(indent + 1);
|
||||||
|
if (element)
|
||||||
|
element->debug_print(0);
|
||||||
|
else
|
||||||
|
AML_DEBUG_PRINT("Uninitialized");
|
||||||
AML_DEBUG_PRINTLN("");
|
AML_DEBUG_PRINTLN("");
|
||||||
}
|
}
|
||||||
AML_DEBUG_PRINT_INDENT(indent);
|
AML_DEBUG_PRINT_INDENT(indent);
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <BAN/Endianness.h>
|
||||||
|
#include <kernel/ACPI/AML/Bytes.h>
|
||||||
|
#include <kernel/ACPI/AML/ParseContext.h>
|
||||||
|
#include <kernel/ACPI/AML/Pkg.h>
|
||||||
|
#include <kernel/ACPI/AML/Scope.h>
|
||||||
|
|
||||||
|
namespace Kernel::ACPI::AML
|
||||||
|
{
|
||||||
|
|
||||||
|
struct PowerResource : public AML::Scope
|
||||||
|
{
|
||||||
|
uint8_t system_level;
|
||||||
|
uint16_t resource_order;
|
||||||
|
|
||||||
|
PowerResource(NameSeg name, uint8_t system_level, uint16_t resource_order)
|
||||||
|
: Scope(Node::Type::PowerResource, name)
|
||||||
|
, system_level(system_level)
|
||||||
|
, resource_order(resource_order)
|
||||||
|
{}
|
||||||
|
|
||||||
|
static ParseResult parse(ParseContext& context)
|
||||||
|
{
|
||||||
|
ASSERT(context.aml_data.size() >= 2);
|
||||||
|
ASSERT(static_cast<AML::Byte>(context.aml_data[0]) == AML::Byte::ExtOpPrefix);
|
||||||
|
ASSERT(static_cast<AML::ExtOp>(context.aml_data[1]) == AML::ExtOp::PowerResOp);
|
||||||
|
context.aml_data = context.aml_data.slice(2);
|
||||||
|
|
||||||
|
auto opt_power_res_pkg = AML::parse_pkg(context.aml_data);
|
||||||
|
if (!opt_power_res_pkg.has_value())
|
||||||
|
return ParseResult::Failure;
|
||||||
|
auto power_res_pkg = opt_power_res_pkg.value();
|
||||||
|
|
||||||
|
auto name = NameString::parse(power_res_pkg);
|
||||||
|
if (!name.has_value())
|
||||||
|
return ParseResult::Failure;
|
||||||
|
|
||||||
|
if (power_res_pkg.size() < 1)
|
||||||
|
return ParseResult::Failure;
|
||||||
|
uint8_t system_level = power_res_pkg[0];
|
||||||
|
power_res_pkg = power_res_pkg.slice(1);
|
||||||
|
|
||||||
|
if (power_res_pkg.size() < 2)
|
||||||
|
return ParseResult::Failure;
|
||||||
|
uint16_t resource_order = BAN::little_endian_to_host<uint16_t>(*reinterpret_cast<const uint16_t*>(power_res_pkg.data()));
|
||||||
|
power_res_pkg = power_res_pkg.slice(2);
|
||||||
|
|
||||||
|
auto power_res = MUST(BAN::RefPtr<PowerResource>::create(name->path.back(), system_level, resource_order));
|
||||||
|
if (!Namespace::root_namespace()->add_named_object(context, name.value(), power_res))
|
||||||
|
return ParseResult::Failure;
|
||||||
|
|
||||||
|
#if AML_DEBUG_LEVEL >= 2
|
||||||
|
power_res->debug_print(0);
|
||||||
|
AML_DEBUG_PRINTLN("");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return power_res->enter_context_and_parse_term_list(context, name.value(), power_res_pkg);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void debug_print(int indent) const override
|
||||||
|
{
|
||||||
|
AML_DEBUG_PRINT_INDENT(indent);
|
||||||
|
AML_DEBUG_PRINT("PowerResource {} (SystemLevel {}, ResourceOrder {})", name, system_level, resource_order);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -29,42 +29,46 @@ namespace Kernel::ACPI::AML
|
||||||
ASSERT(static_cast<AML::ExtOp>(context.aml_data[1]) == AML::ExtOp::ProcessorOp);
|
ASSERT(static_cast<AML::ExtOp>(context.aml_data[1]) == AML::ExtOp::ProcessorOp);
|
||||||
context.aml_data = context.aml_data.slice(2);
|
context.aml_data = context.aml_data.slice(2);
|
||||||
|
|
||||||
auto processor_pkg = AML::parse_pkg(context.aml_data);
|
auto opt_processor_pkg = AML::parse_pkg(context.aml_data);
|
||||||
if (!processor_pkg.has_value())
|
if (!opt_processor_pkg.has_value())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
|
auto processor_pkg = opt_processor_pkg.value();
|
||||||
|
|
||||||
auto name = NameString::parse(processor_pkg.value());
|
auto name = NameString::parse(processor_pkg);
|
||||||
if (!name.has_value())
|
if (!name.has_value())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
|
|
||||||
if (processor_pkg->size() < 1)
|
if (processor_pkg.size() < 1)
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
uint8_t id = processor_pkg.value()[0];
|
uint8_t id = processor_pkg[0];
|
||||||
processor_pkg = processor_pkg->slice(1);
|
processor_pkg = processor_pkg.slice(1);
|
||||||
|
|
||||||
if (processor_pkg->size() < 4)
|
if (processor_pkg.size() < 4)
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
uint32_t pblk_addr = BAN::little_endian_to_host<uint32_t>(*reinterpret_cast<const uint32_t*>(processor_pkg->data()));
|
uint32_t pblk_addr = BAN::little_endian_to_host<uint32_t>(*reinterpret_cast<const uint32_t*>(processor_pkg.data()));
|
||||||
processor_pkg = processor_pkg->slice(4);
|
processor_pkg = processor_pkg.slice(4);
|
||||||
|
|
||||||
if (processor_pkg->size() < 1)
|
if (processor_pkg.size() < 1)
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
uint8_t pblk_len = processor_pkg.value()[0];
|
uint8_t pblk_len = processor_pkg[0];
|
||||||
processor_pkg = processor_pkg->slice(1);
|
processor_pkg = processor_pkg.slice(1);
|
||||||
|
|
||||||
auto processor = MUST(BAN::RefPtr<Processor>::create(name->path.back(), id, pblk_addr, pblk_len));
|
auto processor = MUST(BAN::RefPtr<Processor>::create(name->path.back(), id, pblk_addr, pblk_len));
|
||||||
if (!Namespace::root_namespace()->add_named_object(context, name.value(), processor))
|
if (!Namespace::root_namespace()->add_named_object(context, name.value(), processor))
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
|
|
||||||
return processor->enter_context_and_parse_term_list(context, name.value(), processor_pkg.value());
|
#if AML_DEBUG_LEVEL >= 2
|
||||||
|
processor->debug_print(0);
|
||||||
|
AML_DEBUG_PRINTLN("");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return processor->enter_context_and_parse_term_list(context, name.value(), processor_pkg);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void debug_print(int indent) const override
|
virtual void debug_print(int indent) const override
|
||||||
{
|
{
|
||||||
AML_DEBUG_PRINT_INDENT(indent);
|
AML_DEBUG_PRINT_INDENT(indent);
|
||||||
AML_DEBUG_PRINT("Processor ");
|
AML_DEBUG_PRINT("Processor {} (ID: {}, PBlkAddr: 0x{H}, PBlkLen: {})", name, id, pblk_addr, pblk_len);
|
||||||
name.debug_print();
|
|
||||||
AML_DEBUG_PRINT(" (ID: {}, PBlkAddr: 0x{H}, PBlkLen: {})", id, pblk_addr, pblk_len);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,155 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <kernel/ACPI/AML/Bytes.h>
|
||||||
|
#include <kernel/ACPI/AML/Integer.h>
|
||||||
|
#include <kernel/ACPI/AML/Node.h>
|
||||||
|
#include <kernel/ACPI/AML/Names.h>
|
||||||
|
#include <kernel/ACPI/AML/String.h>
|
||||||
|
#include <kernel/ACPI/AML/ParseContext.h>
|
||||||
|
|
||||||
|
namespace Kernel::ACPI::AML
|
||||||
|
{
|
||||||
|
|
||||||
|
struct Reference : public AML::Node
|
||||||
|
{
|
||||||
|
BAN::RefPtr<AML::Node> node;
|
||||||
|
|
||||||
|
Reference(BAN::RefPtr<AML::Node> node)
|
||||||
|
: Node(AML::Node::Type::Reference)
|
||||||
|
, node(node)
|
||||||
|
{
|
||||||
|
ASSERT(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::RefPtr<AML::Node> evaluate() override
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ParseResult parse(ParseContext& context)
|
||||||
|
{
|
||||||
|
ASSERT(context.aml_data.size() >= 1);
|
||||||
|
|
||||||
|
bool conditional = false;
|
||||||
|
switch (static_cast<AML::Byte>(context.aml_data[0]))
|
||||||
|
{
|
||||||
|
case AML::Byte::DerefOfOp:
|
||||||
|
return parse_dereference(context);
|
||||||
|
case AML::Byte::RefOfOp:
|
||||||
|
context.aml_data = context.aml_data.slice(1);
|
||||||
|
conditional = false;
|
||||||
|
break;
|
||||||
|
case AML::Byte::ExtOpPrefix:
|
||||||
|
ASSERT(static_cast<AML::ExtOp>(context.aml_data[1]) == AML::ExtOp::CondRefOfOp);
|
||||||
|
context.aml_data = context.aml_data.slice(2);
|
||||||
|
conditional = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::RefPtr<AML::Node> object;
|
||||||
|
if (NameString::can_parse(context.aml_data))
|
||||||
|
{
|
||||||
|
auto name = NameString::parse(context.aml_data);
|
||||||
|
if (!name.has_value())
|
||||||
|
return ParseResult::Failure;
|
||||||
|
object = Namespace::root_namespace()->find_object(context.scope, name.value());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto parse_result = AML::parse_object(context);
|
||||||
|
if (!parse_result.success())
|
||||||
|
return ParseResult::Failure;
|
||||||
|
object = parse_result.node();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!conditional)
|
||||||
|
{
|
||||||
|
if (!object)
|
||||||
|
{
|
||||||
|
AML_ERROR("RefOf failed to resolve reference");
|
||||||
|
return ParseResult::Failure;
|
||||||
|
}
|
||||||
|
auto reference = MUST(BAN::RefPtr<Reference>::create(object));
|
||||||
|
#if AML_DEBUG_LEVEL >= 2
|
||||||
|
reference->debug_print(0);
|
||||||
|
AML_DEBUG_PRINTLN("");
|
||||||
|
#endif
|
||||||
|
return ParseResult(reference);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context.aml_data.size() >= 1 && context.aml_data[0] != 0x00)
|
||||||
|
{
|
||||||
|
auto target_result = AML::parse_object(context);
|
||||||
|
if (!target_result.success())
|
||||||
|
return ParseResult::Failure;
|
||||||
|
auto target_node = target_result.node();
|
||||||
|
if (!target_node)
|
||||||
|
{
|
||||||
|
AML_ERROR("CondRefOf failed to resolve target");
|
||||||
|
return ParseResult::Failure;
|
||||||
|
}
|
||||||
|
target_node->store(MUST(BAN::RefPtr<Reference>::create(object)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#if AML_DEBUG_LEVEL >= 2
|
||||||
|
AML_DEBUG_PRINT("CondRefOf ");
|
||||||
|
if (object)
|
||||||
|
object->debug_print(0);
|
||||||
|
else
|
||||||
|
AML_DEBUG_PRINT("null");
|
||||||
|
AML_DEBUG_PRINTLN("");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
auto return_value = MUST(BAN::RefPtr<Integer>::create(object ? Integer::Ones : 0));
|
||||||
|
return AML::ParseResult(return_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ParseResult parse_dereference(ParseContext& context)
|
||||||
|
{
|
||||||
|
ASSERT(context.aml_data.size() >= 1);
|
||||||
|
ASSERT(static_cast<Byte>(context.aml_data[0]) == Byte::DerefOfOp);
|
||||||
|
context.aml_data = context.aml_data.slice(1);
|
||||||
|
|
||||||
|
if (context.aml_data.size() >= 1 && static_cast<AML::Byte>(context.aml_data[0]) == AML::Byte::StringPrefix)
|
||||||
|
{
|
||||||
|
auto string_result = AML::String::parse(context);
|
||||||
|
if (!string_result.success())
|
||||||
|
return ParseResult::Failure;
|
||||||
|
ASSERT(string_result.node());
|
||||||
|
auto string = static_cast<AML::String*>(string_result.node().ptr());
|
||||||
|
AML_TODO("DerefOf String ({})", string->string);
|
||||||
|
return ParseResult::Failure;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto parse_result = AML::parse_object(context);
|
||||||
|
if (!parse_result.success())
|
||||||
|
return ParseResult::Failure;
|
||||||
|
auto object = parse_result.node();
|
||||||
|
if (!object || object->type != AML::Node::Type::Reference)
|
||||||
|
{
|
||||||
|
AML_TODO("DerefOf source is not a Reference, but a {}", object ? static_cast<uint8_t>(object->type) : 999);
|
||||||
|
return ParseResult::Failure;
|
||||||
|
}
|
||||||
|
#if AML_DEBUG_LEVEL >= 2
|
||||||
|
AML_DEBUG_PRINT("DerefOf ");
|
||||||
|
object->debug_print(0);
|
||||||
|
AML_DEBUG_PRINTLN("");
|
||||||
|
#endif
|
||||||
|
return ParseResult(static_cast<Reference*>(object.ptr())->node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void debug_print(int indent) const override
|
||||||
|
{
|
||||||
|
AML_DEBUG_PRINT_INDENT(indent);
|
||||||
|
AML_DEBUG_PRINTLN("Reference {");
|
||||||
|
node->debug_print(indent + 1);
|
||||||
|
AML_DEBUG_PRINT_INDENT(indent);
|
||||||
|
AML_DEBUG_PRINT("}");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <BAN/Endianness.h>
|
||||||
|
#include <kernel/ACPI/AML/Bytes.h>
|
||||||
|
#include <kernel/ACPI/AML/ParseContext.h>
|
||||||
|
#include <kernel/ACPI/AML/Pkg.h>
|
||||||
|
#include <kernel/ACPI/AML/Scope.h>
|
||||||
|
|
||||||
|
namespace Kernel::ACPI::AML
|
||||||
|
{
|
||||||
|
|
||||||
|
struct ThermalZone : public AML::Scope
|
||||||
|
{
|
||||||
|
ThermalZone(NameSeg name)
|
||||||
|
: Scope(Node::Type::ThermalZone, name)
|
||||||
|
{}
|
||||||
|
|
||||||
|
static ParseResult parse(ParseContext& context)
|
||||||
|
{
|
||||||
|
ASSERT(context.aml_data.size() >= 2);
|
||||||
|
ASSERT(static_cast<AML::Byte>(context.aml_data[0]) == AML::Byte::ExtOpPrefix);
|
||||||
|
ASSERT(static_cast<AML::ExtOp>(context.aml_data[1]) == AML::ExtOp::PowerResOp);
|
||||||
|
context.aml_data = context.aml_data.slice(2);
|
||||||
|
|
||||||
|
auto opt_thermal_zone_pkg = AML::parse_pkg(context.aml_data);
|
||||||
|
if (!opt_thermal_zone_pkg.has_value())
|
||||||
|
return ParseResult::Failure;
|
||||||
|
auto thermal_zone_pkg = opt_thermal_zone_pkg.value();
|
||||||
|
|
||||||
|
auto name = NameString::parse(thermal_zone_pkg);
|
||||||
|
if (!name.has_value())
|
||||||
|
return ParseResult::Failure;
|
||||||
|
|
||||||
|
auto thermal_zone = MUST(BAN::RefPtr<ThermalZone>::create(name->path.back()));
|
||||||
|
if (!Namespace::root_namespace()->add_named_object(context, name.value(), thermal_zone))
|
||||||
|
return ParseResult::Failure;
|
||||||
|
|
||||||
|
#if AML_DEBUG_LEVEL >= 2
|
||||||
|
thermal_zone->debug_print(0);
|
||||||
|
AML_DEBUG_PRINTLN("");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return thermal_zone->enter_context_and_parse_term_list(context, name.value(), thermal_zone_pkg);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void debug_print(int indent) const override
|
||||||
|
{
|
||||||
|
AML_DEBUG_PRINT_INDENT(indent);
|
||||||
|
AML_DEBUG_PRINT("ThermalZone {}", name);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -607,4 +607,100 @@ namespace Kernel::ACPI
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AML::ParseResult AML::BankField::parse(ParseContext& context)
|
||||||
|
{
|
||||||
|
// BankFieldOp PkgLength NameString NameString BankValue FieldFlags FieldList
|
||||||
|
|
||||||
|
ASSERT(context.aml_data.size() >= 2);
|
||||||
|
ASSERT(static_cast<AML::Byte>(context.aml_data[0]) == AML::Byte::ExtOpPrefix);
|
||||||
|
ASSERT(static_cast<AML::ExtOp>(context.aml_data[1]) == AML::ExtOp::BankFieldOp);
|
||||||
|
context.aml_data = context.aml_data.slice(2);
|
||||||
|
|
||||||
|
auto opt_field_pkg = AML::parse_pkg(context.aml_data);
|
||||||
|
if (!opt_field_pkg.has_value())
|
||||||
|
return ParseResult::Failure;
|
||||||
|
auto field_pkg = opt_field_pkg.release_value();
|
||||||
|
|
||||||
|
auto op_region_name = NameString::parse(field_pkg);
|
||||||
|
if (!op_region_name.has_value())
|
||||||
|
return ParseResult::Failure;
|
||||||
|
auto op_region = Namespace::root_namespace()->find_object(context.scope, op_region_name.value());
|
||||||
|
if (!op_region || op_region->type != AML::Node::Type::OpRegion)
|
||||||
|
{
|
||||||
|
AML_ERROR("BankField RegionName {} does not name a valid OpRegion", op_region_name.value());
|
||||||
|
return ParseResult::Failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto bank_selector_name = NameString::parse(field_pkg);
|
||||||
|
if (!bank_selector_name.has_value())
|
||||||
|
return ParseResult::Failure;
|
||||||
|
auto bank_selector = Namespace::root_namespace()->find_object(context.scope, bank_selector_name.value());
|
||||||
|
if (!bank_selector)
|
||||||
|
{
|
||||||
|
AML_ERROR("BankField BankSelector {} does not name a valid object", bank_selector_name.value());
|
||||||
|
return ParseResult::Failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto temp_aml_data = context.aml_data;
|
||||||
|
context.aml_data = field_pkg;
|
||||||
|
auto bank_value_result = AML::parse_object(context);
|
||||||
|
field_pkg = context.aml_data;
|
||||||
|
context.aml_data = temp_aml_data;
|
||||||
|
if (!bank_value_result.success())
|
||||||
|
return ParseResult::Failure;
|
||||||
|
auto bank_value = bank_value_result.node() ? bank_value_result.node()->as_integer() : BAN::Optional<uint64_t>();
|
||||||
|
if (!bank_value.has_value())
|
||||||
|
{
|
||||||
|
AML_ERROR("BankField BankValue is not an integer");
|
||||||
|
return ParseResult::Failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (field_pkg.size() < 1)
|
||||||
|
return ParseResult::Failure;
|
||||||
|
auto field_flags = field_pkg[0];
|
||||||
|
field_pkg = field_pkg.slice(1);
|
||||||
|
|
||||||
|
ParseFieldElementContext<BankFieldElement> field_context;
|
||||||
|
field_context.field_rules.access_type = static_cast<FieldRules::AccessType>(field_flags & 0x0F);
|
||||||
|
field_context.field_rules.lock_rule = static_cast<FieldRules::LockRule>((field_flags >> 4) & 0x01);
|
||||||
|
field_context.field_rules.update_rule = static_cast<FieldRules::UpdateRule>((field_flags >> 5) & 0x03);
|
||||||
|
field_context.field_bit_offset = 0;
|
||||||
|
field_context.field_pkg = field_pkg;
|
||||||
|
while (field_context.field_pkg.size() > 0)
|
||||||
|
if (!parse_field_element(field_context))
|
||||||
|
return ParseResult::Failure;
|
||||||
|
|
||||||
|
for (auto& [_, element] : field_context.elements)
|
||||||
|
{
|
||||||
|
element->op_region = static_cast<OpRegion*>(op_region.ptr());
|
||||||
|
element->bank_selector = bank_selector;
|
||||||
|
element->bank_value = bank_value.value();
|
||||||
|
|
||||||
|
NameString element_name;
|
||||||
|
MUST(element_name.path.push_back(element->name));
|
||||||
|
if (!Namespace::root_namespace()->add_named_object(context, element_name, element))
|
||||||
|
return ParseResult::Failure;
|
||||||
|
|
||||||
|
#if AML_DEBUG_LEVEL >= 2
|
||||||
|
element->debug_print(0);
|
||||||
|
AML_DEBUG_PRINTLN("");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return ParseResult::Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AML::BankFieldElement::debug_print(int indent) const
|
||||||
|
{
|
||||||
|
AML_DEBUG_PRINT_INDENT(indent);
|
||||||
|
AML_DEBUG_PRINT("BankFieldElement {} ({}, offset {}, OpRegion {}, BankSelector {}, BankValue {H})",
|
||||||
|
name,
|
||||||
|
bit_count,
|
||||||
|
bit_offset,
|
||||||
|
op_region->name,
|
||||||
|
bank_selector->name,
|
||||||
|
bank_value
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,12 +33,8 @@ namespace Kernel::ACPI
|
||||||
void AML::Name::debug_print(int indent) const
|
void AML::Name::debug_print(int indent) const
|
||||||
{
|
{
|
||||||
AML_DEBUG_PRINT_INDENT(indent);
|
AML_DEBUG_PRINT_INDENT(indent);
|
||||||
AML_DEBUG_PRINT("Name ");
|
AML_DEBUG_PRINT("Name {} { ", name);
|
||||||
name.debug_print();
|
object->debug_print(0);
|
||||||
AML_DEBUG_PRINTLN(" {");
|
|
||||||
object->debug_print(indent + 1);
|
|
||||||
AML_DEBUG_PRINTLN("");
|
|
||||||
AML_DEBUG_PRINT_INDENT(indent);
|
|
||||||
AML_DEBUG_PRINT("}");
|
AML_DEBUG_PRINT("}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <kernel/ACPI/AML/Expression.h>
|
#include <kernel/ACPI/AML/Expression.h>
|
||||||
#include <kernel/ACPI/AML/Field.h>
|
#include <kernel/ACPI/AML/Field.h>
|
||||||
#include <kernel/ACPI/AML/IfElse.h>
|
#include <kernel/ACPI/AML/IfElse.h>
|
||||||
|
#include <kernel/ACPI/AML/Index.h>
|
||||||
#include <kernel/ACPI/AML/Integer.h>
|
#include <kernel/ACPI/AML/Integer.h>
|
||||||
#include <kernel/ACPI/AML/Method.h>
|
#include <kernel/ACPI/AML/Method.h>
|
||||||
#include <kernel/ACPI/AML/Mutex.h>
|
#include <kernel/ACPI/AML/Mutex.h>
|
||||||
|
@ -11,10 +12,13 @@
|
||||||
#include <kernel/ACPI/AML/Node.h>
|
#include <kernel/ACPI/AML/Node.h>
|
||||||
#include <kernel/ACPI/AML/Package.h>
|
#include <kernel/ACPI/AML/Package.h>
|
||||||
#include <kernel/ACPI/AML/ParseContext.h>
|
#include <kernel/ACPI/AML/ParseContext.h>
|
||||||
|
#include <kernel/ACPI/AML/PowerResource.h>
|
||||||
#include <kernel/ACPI/AML/Processor.h>
|
#include <kernel/ACPI/AML/Processor.h>
|
||||||
|
#include <kernel/ACPI/AML/Reference.h>
|
||||||
#include <kernel/ACPI/AML/Region.h>
|
#include <kernel/ACPI/AML/Region.h>
|
||||||
#include <kernel/ACPI/AML/Store.h>
|
#include <kernel/ACPI/AML/Store.h>
|
||||||
#include <kernel/ACPI/AML/String.h>
|
#include <kernel/ACPI/AML/String.h>
|
||||||
|
#include <kernel/ACPI/AML/ThermalZone.h>
|
||||||
#include <kernel/ACPI/AML/Utils.h>
|
#include <kernel/ACPI/AML/Utils.h>
|
||||||
|
|
||||||
namespace Kernel::ACPI
|
namespace Kernel::ACPI
|
||||||
|
@ -31,7 +35,7 @@ namespace Kernel::ACPI
|
||||||
if (!evaluated)
|
if (!evaluated)
|
||||||
return {};
|
return {};
|
||||||
if (evaluated->type == Type::Integer)
|
if (evaluated->type == Type::Integer)
|
||||||
return static_cast<const Integer*>(this)->value;
|
return static_cast<const Integer*>(evaluated.ptr())->value;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,6 +55,8 @@ namespace Kernel::ACPI
|
||||||
return AML::Field::parse(context);
|
return AML::Field::parse(context);
|
||||||
case AML::ExtOp::IndexFieldOp:
|
case AML::ExtOp::IndexFieldOp:
|
||||||
return AML::IndexField::parse(context);
|
return AML::IndexField::parse(context);
|
||||||
|
case AML::ExtOp::BankFieldOp:
|
||||||
|
return AML::BankField::parse(context);
|
||||||
case AML::ExtOp::OpRegionOp:
|
case AML::ExtOp::OpRegionOp:
|
||||||
return AML::OpRegion::parse(context);
|
return AML::OpRegion::parse(context);
|
||||||
case AML::ExtOp::DeviceOp:
|
case AML::ExtOp::DeviceOp:
|
||||||
|
@ -61,6 +67,12 @@ namespace Kernel::ACPI
|
||||||
return AML::Mutex::parse(context);
|
return AML::Mutex::parse(context);
|
||||||
case AML::ExtOp::ProcessorOp:
|
case AML::ExtOp::ProcessorOp:
|
||||||
return AML::Processor::parse(context);
|
return AML::Processor::parse(context);
|
||||||
|
case AML::ExtOp::PowerResOp:
|
||||||
|
return AML::PowerResource::parse(context);
|
||||||
|
case AML::ExtOp::ThermalZoneOp:
|
||||||
|
return AML::ThermalZone::parse(context);
|
||||||
|
case AML::ExtOp::CondRefOfOp:
|
||||||
|
return AML::Reference::parse(context);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -128,6 +140,12 @@ namespace Kernel::ACPI
|
||||||
case AML::Byte::SubtractOp:
|
case AML::Byte::SubtractOp:
|
||||||
case AML::Byte::XorOp:
|
case AML::Byte::XorOp:
|
||||||
return AML::Expression::parse(context);
|
return AML::Expression::parse(context);
|
||||||
|
case AML::Byte::CreateBitFieldOp:
|
||||||
|
case AML::Byte::CreateByteFieldOp:
|
||||||
|
case AML::Byte::CreateWordFieldOp:
|
||||||
|
case AML::Byte::CreateDWordFieldOp:
|
||||||
|
case AML::Byte::CreateQWordFieldOp:
|
||||||
|
return AML::BufferField::parse(context);
|
||||||
case AML::Byte::NameOp:
|
case AML::Byte::NameOp:
|
||||||
return AML::Name::parse(context);
|
return AML::Name::parse(context);
|
||||||
case AML::Byte::PackageOp:
|
case AML::Byte::PackageOp:
|
||||||
|
@ -142,6 +160,11 @@ namespace Kernel::ACPI
|
||||||
return AML::IfElse::parse(context);
|
return AML::IfElse::parse(context);
|
||||||
case AML::Byte::StoreOp:
|
case AML::Byte::StoreOp:
|
||||||
return AML::Store::parse(context);
|
return AML::Store::parse(context);
|
||||||
|
case AML::Byte::DerefOfOp:
|
||||||
|
case AML::Byte::RefOfOp:
|
||||||
|
return AML::Reference::parse(context);
|
||||||
|
case AML::Byte::IndexOp:
|
||||||
|
return AML::Index::parse(context);
|
||||||
case AML::Byte::ReturnOp:
|
case AML::Byte::ReturnOp:
|
||||||
{
|
{
|
||||||
context.aml_data = context.aml_data.slice(1);
|
context.aml_data = context.aml_data.slice(1);
|
||||||
|
|
Loading…
Reference in New Issue