Kernel: Rewrite the AML conversion API
This doesn't currently make the interpreter any better, but it will make further implementation easier to be spec (or hardware...) compliant
This commit is contained in:
parent
44d5c8c4b4
commit
3f5ee6f414
|
@ -7,7 +7,6 @@ set(KERNEL_SOURCES
|
||||||
kernel/ACPI/AML/Namespace.cpp
|
kernel/ACPI/AML/Namespace.cpp
|
||||||
kernel/ACPI/AML/Node.cpp
|
kernel/ACPI/AML/Node.cpp
|
||||||
kernel/ACPI/AML/Package.cpp
|
kernel/ACPI/AML/Package.cpp
|
||||||
kernel/ACPI/AML/Register.cpp
|
|
||||||
kernel/ACPI/AML/Scope.cpp
|
kernel/ACPI/AML/Scope.cpp
|
||||||
kernel/ACPI/AML/String.cpp
|
kernel/ACPI/AML/String.cpp
|
||||||
kernel/APIC.cpp
|
kernel/APIC.cpp
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
namespace Kernel::ACPI::AML
|
namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
|
|
||||||
struct Alias : public AML::NamedObject
|
struct Alias final : public AML::NamedObject
|
||||||
{
|
{
|
||||||
BAN::RefPtr<AML::Node> target;
|
BAN::RefPtr<AML::Node> target;
|
||||||
|
|
||||||
|
@ -18,14 +18,11 @@ namespace Kernel::ACPI::AML
|
||||||
|
|
||||||
bool is_scope() const override { return target->is_scope(); }
|
bool is_scope() const override { return target->is_scope(); }
|
||||||
|
|
||||||
|
BAN::RefPtr<AML::Node> convert(uint8_t) override { return {}; }
|
||||||
|
|
||||||
BAN::RefPtr<Node> copy() override { return target->copy(); }
|
BAN::RefPtr<Node> copy() override { return target->copy(); }
|
||||||
|
|
||||||
BAN::RefPtr<AML::Buffer> as_buffer() override { return target->as_buffer(); }
|
BAN::RefPtr<AML::Node> store(BAN::RefPtr<AML::Node> node) override { ASSERT(target); return target->store(node); }
|
||||||
BAN::RefPtr<AML::Integer> as_integer() override { return target->as_integer(); }
|
|
||||||
BAN::RefPtr<AML::String> as_string() override { return target->as_string(); }
|
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> evaluate() override { return target->evaluate(); }
|
|
||||||
bool store(BAN::RefPtr<AML::Node> node) override { return target->store(node); }
|
|
||||||
|
|
||||||
static ParseResult parse(ParseContext& context)
|
static ParseResult parse(ParseContext& context)
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
namespace Kernel::ACPI::AML
|
namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
|
|
||||||
struct Buffer : public AML::Node
|
struct Buffer final : public AML::Node
|
||||||
{
|
{
|
||||||
BAN::Vector<uint8_t> buffer;
|
BAN::Vector<uint8_t> buffer;
|
||||||
|
|
||||||
|
@ -20,10 +20,10 @@ namespace Kernel::ACPI::AML
|
||||||
|
|
||||||
BAN::Optional<bool> logical_compare(BAN::RefPtr<AML::Node> node, AML::Byte binaryop)
|
BAN::Optional<bool> logical_compare(BAN::RefPtr<AML::Node> node, AML::Byte binaryop)
|
||||||
{
|
{
|
||||||
auto rhs = node ? node->as_buffer() : BAN::RefPtr<AML::Buffer>();
|
auto rhs_node = node ? node->convert(AML::Node::ConvBuffer) : BAN::RefPtr<AML::Node>();
|
||||||
if (!rhs)
|
if (!rhs_node)
|
||||||
{
|
{
|
||||||
AML_ERROR("Buffer logical compare RHS is not buffer");
|
AML_ERROR("Buffer logical compare RHS cannot be converted to buffer");
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,19 +32,18 @@ namespace Kernel::ACPI::AML
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Buffer> as_buffer() override { return this; }
|
BAN::RefPtr<AML::Node> convert(uint8_t mask) override
|
||||||
|
|
||||||
BAN::RefPtr<AML::Integer> as_integer() override
|
|
||||||
{
|
{
|
||||||
uint64_t value = 0;
|
if (mask & AML::Node::ConvBuffer)
|
||||||
for (size_t i = 0; i < BAN::Math::min<size_t>(buffer.size(), 8); i++)
|
return this;
|
||||||
value |= static_cast<uint64_t>(buffer[i]) << (8 * i);
|
if (mask & AML::Node::ConvInteger)
|
||||||
return MUST(BAN::RefPtr<Integer>::create(value));
|
return as_integer();
|
||||||
}
|
if (mask & AML::Node::ConvString)
|
||||||
|
{
|
||||||
BAN::RefPtr<AML::Node> evaluate() override
|
AML_TODO("Convert BufferField to String");
|
||||||
{
|
return {};
|
||||||
return this;
|
}
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
static ParseResult parse(AML::ParseContext& context)
|
static ParseResult parse(AML::ParseContext& context)
|
||||||
|
@ -60,15 +59,21 @@ namespace Kernel::ACPI::AML
|
||||||
auto buffer_context = context;
|
auto buffer_context = context;
|
||||||
buffer_context.aml_data = buffer_pkg.value();
|
buffer_context.aml_data = buffer_pkg.value();
|
||||||
|
|
||||||
auto buffer_size_object = AML::parse_object(buffer_context);
|
auto buffer_size_result = AML::parse_object(buffer_context);
|
||||||
if (!buffer_size_object.success())
|
if (!buffer_size_result.success())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
|
|
||||||
auto buffer_size = buffer_size_object.node()->as_integer();
|
auto buffer_size_node = buffer_size_result.node() ? buffer_size_result.node()->convert(AML::Node::ConvInteger) : BAN::RefPtr<AML::Node>();
|
||||||
if (!buffer_size)
|
if (!buffer_size_node)
|
||||||
|
{
|
||||||
|
AML_ERROR("Buffer size is not an integer");
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t actual_buffer_size = BAN::Math::max<uint32_t>(buffer_size->value, buffer_context.aml_data.size());
|
const uint32_t actual_buffer_size = BAN::Math::max<uint32_t>(
|
||||||
|
static_cast<AML::Integer*>(buffer_size_node.ptr())->value,
|
||||||
|
buffer_context.aml_data.size()
|
||||||
|
);
|
||||||
|
|
||||||
auto buffer = MUST(BAN::RefPtr<Buffer>::create());
|
auto buffer = MUST(BAN::RefPtr<Buffer>::create());
|
||||||
MUST(buffer->buffer.resize(actual_buffer_size, 0));
|
MUST(buffer->buffer.resize(actual_buffer_size, 0));
|
||||||
|
@ -88,9 +93,18 @@ namespace Kernel::ACPI::AML
|
||||||
AML_DEBUG_PRINT_INDENT(indent);
|
AML_DEBUG_PRINT_INDENT(indent);
|
||||||
AML_DEBUG_PRINT("Buffer ({} bytes)", buffer.size());
|
AML_DEBUG_PRINT("Buffer ({} bytes)", buffer.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
BAN::RefPtr<AML::Integer> as_integer()
|
||||||
|
{
|
||||||
|
uint64_t value = 0;
|
||||||
|
for (size_t i = 0; i < BAN::Math::min<size_t>(buffer.size(), 8); i++)
|
||||||
|
value |= static_cast<uint64_t>(buffer[i]) << (8 * i);
|
||||||
|
return MUST(BAN::RefPtr<Integer>::create(value));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BufferField : AML::NamedObject
|
struct BufferField final : AML::NamedObject
|
||||||
{
|
{
|
||||||
BAN::RefPtr<AML::Node> buffer;
|
BAN::RefPtr<AML::Node> buffer;
|
||||||
size_t field_bit_offset;
|
size_t field_bit_offset;
|
||||||
|
@ -104,49 +118,26 @@ namespace Kernel::ACPI::AML
|
||||||
, field_bit_size(field_bit_size)
|
, field_bit_size(field_bit_size)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Integer> as_integer() override
|
BAN::RefPtr<AML::Node> convert(uint8_t mask) override
|
||||||
{
|
{
|
||||||
ASSERT(buffer);
|
if (mask & AML::Node::ConvBufferField)
|
||||||
ASSERT(buffer->type == AML::Node::Type::Buffer || buffer->type == AML::Node::Type::String);
|
return this;
|
||||||
|
if (mask & AML::Node::ConvInteger)
|
||||||
const auto& buffer = (this->buffer->type == AML::Node::Type::Buffer)
|
return as_integer();
|
||||||
? static_cast<AML::Buffer*>(this->buffer.ptr())->buffer
|
if (mask & AML::Node::ConvBuffer)
|
||||||
: static_cast<AML::String*>(this->buffer.ptr())->string;
|
|
||||||
|
|
||||||
uint64_t value = 0;
|
|
||||||
|
|
||||||
// TODO: optimize for whole byte accesses
|
|
||||||
for (size_t i = 0; i < BAN::Math::min<size_t>(field_bit_size, 64); i++)
|
|
||||||
{
|
{
|
||||||
const size_t bit = field_bit_offset + i;
|
AML_TODO("Convert BufferField to Buffer");
|
||||||
value |= static_cast<uint64_t>((buffer[bit / 8] >> (bit % 8)) & 1) << i;
|
return {};
|
||||||
}
|
}
|
||||||
|
if (mask & AML::Node::ConvString)
|
||||||
return MUST(BAN::RefPtr<Integer>::create(value));
|
{
|
||||||
|
AML_TODO("Convert BufferField to String");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> evaluate() override
|
BAN::RefPtr<AML::Node> store(BAN::RefPtr<AML::Node> node) override
|
||||||
{
|
|
||||||
ASSERT(buffer);
|
|
||||||
ASSERT(buffer->type == AML::Node::Type::Buffer || buffer->type == AML::Node::Type::String);
|
|
||||||
const auto& buffer = (this->buffer->type == AML::Node::Type::Buffer)
|
|
||||||
? static_cast<AML::Buffer*>(this->buffer.ptr())->buffer
|
|
||||||
: static_cast<AML::String*>(this->buffer.ptr())->string;
|
|
||||||
ASSERT(field_bit_offset + field_bit_size <= buffer.size() * 8);
|
|
||||||
|
|
||||||
uint64_t value = 0;
|
|
||||||
|
|
||||||
// TODO: optimize for whole byte accesses
|
|
||||||
for (size_t i = 0; i < field_bit_size; i++)
|
|
||||||
{
|
|
||||||
const size_t bit = field_bit_offset + i;
|
|
||||||
value |= static_cast<uint64_t>((buffer[bit / 8] >> (bit % 8)) & 1) << i;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MUST(BAN::RefPtr<AML::Integer>::create(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool store(BAN::RefPtr<AML::Node> node) override
|
|
||||||
{
|
{
|
||||||
ASSERT(buffer);
|
ASSERT(buffer);
|
||||||
ASSERT(buffer->type == AML::Node::Type::Buffer || buffer->type == AML::Node::Type::String);
|
ASSERT(buffer->type == AML::Node::Type::Buffer || buffer->type == AML::Node::Type::String);
|
||||||
|
@ -155,19 +146,20 @@ namespace Kernel::ACPI::AML
|
||||||
: static_cast<AML::String*>(this->buffer.ptr())->string;
|
: static_cast<AML::String*>(this->buffer.ptr())->string;
|
||||||
ASSERT(field_bit_offset + field_bit_size <= buffer.size() * 8);
|
ASSERT(field_bit_offset + field_bit_size <= buffer.size() * 8);
|
||||||
|
|
||||||
auto value = node->as_integer();
|
auto value_node = node ? node->convert(AML::Node::ConvInteger) : BAN::RefPtr<AML::Node>();
|
||||||
if (!value)
|
if (!value_node)
|
||||||
return false;
|
return {};
|
||||||
|
const auto value = static_cast<AML::Integer*>(value_node.ptr())->value;
|
||||||
|
|
||||||
// TODO: optimize for whole byte accesses
|
// TODO: optimize for whole byte accesses
|
||||||
for (size_t i = 0; i < field_bit_size; i++)
|
for (size_t i = 0; i < field_bit_size; i++)
|
||||||
{
|
{
|
||||||
const size_t bit = field_bit_offset + 1;
|
const size_t bit = field_bit_offset + 1;
|
||||||
buffer[bit / 8] &= ~(1 << (bit % 8));
|
buffer[bit / 8] &= ~(1 << (bit % 8));
|
||||||
buffer[bit / 8] |= ((value->value >> i) & 1) << (bit % 8);
|
buffer[bit / 8] |= ((value >> i) & 1) << (bit % 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return value_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ParseResult parse(AML::ParseContext& context)
|
static ParseResult parse(AML::ParseContext& context)
|
||||||
|
@ -204,7 +196,7 @@ namespace Kernel::ACPI::AML
|
||||||
auto buffer_result = AML::parse_object(context);
|
auto buffer_result = AML::parse_object(context);
|
||||||
if (!buffer_result.success())
|
if (!buffer_result.success())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
auto buffer_node = buffer_result.node() ? buffer_result.node()->as_buffer() : BAN::RefPtr<AML::Buffer>();
|
auto buffer_node = buffer_result.node() ? buffer_result.node()->convert(AML::Node::ConvBuffer) : BAN::RefPtr<AML::Node>();
|
||||||
if (!buffer_node || buffer_node->type != Node::Type::Buffer)
|
if (!buffer_node || buffer_node->type != Node::Type::Buffer)
|
||||||
{
|
{
|
||||||
AML_ERROR("Buffer source does not evaluate to a Buffer");
|
AML_ERROR("Buffer source does not evaluate to a Buffer");
|
||||||
|
@ -215,28 +207,25 @@ namespace Kernel::ACPI::AML
|
||||||
auto index_result = AML::parse_object(context);
|
auto index_result = AML::parse_object(context);
|
||||||
if (!index_result.success())
|
if (!index_result.success())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
auto index = index_result.node() ? index_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
|
auto index_node = index_result.node() ? index_result.node()->convert(AML::Node::ConvInteger) : BAN::RefPtr<AML::Node>();
|
||||||
if (!index)
|
if (!index_node)
|
||||||
{
|
{
|
||||||
AML_ERROR("Failed to parse index for BufferField");
|
AML_ERROR("Failed to parse index for BufferField");
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
size_t field_bit_offset = index->value;
|
|
||||||
if (field_bit_size != 1)
|
|
||||||
field_bit_offset *= 8;
|
|
||||||
|
|
||||||
if (field_bit_size == 0)
|
if (field_bit_size == 0)
|
||||||
{
|
{
|
||||||
auto bit_count_result = AML::parse_object(context);
|
auto bit_count_result = AML::parse_object(context);
|
||||||
if (!index_result.success())
|
if (!bit_count_result.success())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
auto bit_count = bit_count_result.node() ? bit_count_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
|
auto bit_count_node = bit_count_result.node() ? bit_count_result.node()->convert(AML::Node::ConvInteger) : BAN::RefPtr<AML::Node>();
|
||||||
if (!bit_count)
|
if (!bit_count_node)
|
||||||
{
|
{
|
||||||
AML_ERROR("Failed to parse bit count for BufferField");
|
AML_ERROR("Failed to parse bit count for BufferField");
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
field_bit_size = bit_count->value;
|
field_bit_size = static_cast<AML::Integer*>(bit_count_node.ptr())->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto field_name = AML::NameString::parse(context.aml_data);
|
auto field_name = AML::NameString::parse(context.aml_data);
|
||||||
|
@ -248,6 +237,10 @@ namespace Kernel::ACPI::AML
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t field_bit_offset = static_cast<AML::Integer*>(index_node.ptr())->value;
|
||||||
|
if (field_bit_size != 1)
|
||||||
|
field_bit_offset *= 8;
|
||||||
|
|
||||||
auto field = MUST(BAN::RefPtr<BufferField>::create(field_name->path.back(), buffer, field_bit_offset, field_bit_size));
|
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))
|
if (!Namespace::root_namespace()->add_named_object(context, field_name.value(), field))
|
||||||
return ParseResult::Success;
|
return ParseResult::Success;
|
||||||
|
@ -268,6 +261,27 @@ namespace Kernel::ACPI::AML
|
||||||
AML_DEBUG_PRINT(" }");
|
AML_DEBUG_PRINT(" }");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
BAN::RefPtr<AML::Integer> as_integer()
|
||||||
|
{
|
||||||
|
ASSERT(buffer);
|
||||||
|
ASSERT(buffer->type == AML::Node::Type::Buffer || buffer->type == AML::Node::Type::String);
|
||||||
|
|
||||||
|
const auto& buffer = (this->buffer->type == AML::Node::Type::Buffer)
|
||||||
|
? static_cast<AML::Buffer*>(this->buffer.ptr())->buffer
|
||||||
|
: static_cast<AML::String*>(this->buffer.ptr())->string;
|
||||||
|
|
||||||
|
uint64_t value = 0;
|
||||||
|
|
||||||
|
// TODO: optimize for whole byte accesses
|
||||||
|
for (size_t i = 0; i < BAN::Math::min<size_t>(field_bit_size, 64); i++)
|
||||||
|
{
|
||||||
|
const size_t bit = field_bit_offset + i;
|
||||||
|
value |= static_cast<uint64_t>((buffer[bit / 8] >> (bit % 8)) & 1) << i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MUST(BAN::RefPtr<Integer>::create(value));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,13 +61,13 @@ namespace Kernel::ACPI::AML
|
||||||
switch (opcode)
|
switch (opcode)
|
||||||
{
|
{
|
||||||
case AML::Byte::ToBufferOp:
|
case AML::Byte::ToBufferOp:
|
||||||
converted = data_node->as_buffer();
|
converted = data_node->convert(AML::Node::ConvBuffer);
|
||||||
break;
|
break;
|
||||||
case AML::Byte::ToIntegerOp:
|
case AML::Byte::ToIntegerOp:
|
||||||
converted = data_node->as_integer();
|
converted = data_node->convert(AML::Node::ConvInteger);
|
||||||
break;
|
break;
|
||||||
case AML::Byte::ToStringOp:
|
case AML::Byte::ToStringOp:
|
||||||
converted = data_node->as_string();
|
converted = data_node->convert(AML::Node::ConvString);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
|
|
|
@ -8,12 +8,14 @@
|
||||||
namespace Kernel::ACPI::AML
|
namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
|
|
||||||
struct Device : public AML::Scope
|
struct Device final : public AML::Scope
|
||||||
{
|
{
|
||||||
Device(NameSeg name)
|
Device(NameSeg name)
|
||||||
: Scope(Node::Type::Device, name)
|
: Scope(Node::Type::Device, name)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
BAN::RefPtr<AML::Node> convert(uint8_t) override { return {}; }
|
||||||
|
|
||||||
static ParseResult parse(ParseContext& context)
|
static ParseResult parse(ParseContext& context)
|
||||||
{
|
{
|
||||||
ASSERT(context.aml_data.size() >= 2);
|
ASSERT(context.aml_data.size() >= 2);
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
namespace Kernel::ACPI::AML
|
namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
|
|
||||||
struct Event : public AML::NamedObject
|
struct Event final : public AML::NamedObject
|
||||||
{
|
{
|
||||||
BAN::Atomic<uint32_t> signal_count { 0 };
|
BAN::Atomic<uint32_t> signal_count { 0 };
|
||||||
ThreadBlocker thread_blocker;
|
ThreadBlocker thread_blocker;
|
||||||
|
@ -19,6 +19,8 @@ namespace Kernel::ACPI::AML
|
||||||
: NamedObject(Node::Type::Event, name)
|
: NamedObject(Node::Type::Event, name)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
BAN::RefPtr<AML::Node> convert(uint8_t) override { return {}; }
|
||||||
|
|
||||||
static ParseResult parse(ParseContext& context)
|
static ParseResult parse(ParseContext& context)
|
||||||
{
|
{
|
||||||
ASSERT(context.aml_data.size() >= 2);
|
ASSERT(context.aml_data.size() >= 2);
|
||||||
|
@ -43,7 +45,7 @@ namespace Kernel::ACPI::AML
|
||||||
if (!event_result.success())
|
if (!event_result.success())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
|
|
||||||
auto general_node = event_result.node() ? event_result.node()->evaluate() : BAN::RefPtr<AML::Node>();
|
auto general_node = event_result.node();
|
||||||
if (!general_node || general_node->type != Node::Type::Event)
|
if (!general_node || general_node->type != Node::Type::Event)
|
||||||
{
|
{
|
||||||
AML_ERROR("Release, Wait or Signal does not name an event");
|
AML_ERROR("Release, Wait or Signal does not name an event");
|
||||||
|
@ -58,12 +60,15 @@ namespace Kernel::ACPI::AML
|
||||||
if (!timeout_result.success())
|
if (!timeout_result.success())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
|
|
||||||
auto timeout = timeout_result.node() ? timeout_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
|
auto timeout_node = timeout_result.node()
|
||||||
if (!timeout)
|
? timeout_result.node()->convert(AML::Node::ConvInteger)
|
||||||
|
: BAN::RefPtr<AML::Node>();
|
||||||
|
if (!timeout_node)
|
||||||
{
|
{
|
||||||
AML_ERROR("Wait timeout does not evaluate to integer");
|
AML_ERROR("Wait timeout does not evaluate to integer");
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
|
const auto timeout_value = static_cast<AML::Integer*>(timeout_node.ptr())->value;
|
||||||
|
|
||||||
const uint64_t start_ms = SystemTimer::get().ms_since_boot();
|
const uint64_t start_ms = SystemTimer::get().ms_since_boot();
|
||||||
while (true)
|
while (true)
|
||||||
|
@ -77,14 +82,14 @@ namespace Kernel::ACPI::AML
|
||||||
return ParseResult(Integer::Constants::Zero);
|
return ParseResult(Integer::Constants::Zero);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timeout->value >= 0xFFFF)
|
if (timeout_value >= 0xFFFF)
|
||||||
event_node->thread_blocker.block_indefinite();
|
event_node->thread_blocker.block_indefinite();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const uint64_t current_ms = SystemTimer::get().ms_since_boot();
|
const uint64_t current_ms = SystemTimer::get().ms_since_boot();
|
||||||
if (current_ms >= start_ms + timeout->value)
|
if (current_ms >= start_ms + timeout_value)
|
||||||
return ParseResult(Integer::Constants::Ones);
|
return ParseResult(Integer::Constants::Ones);
|
||||||
event_node->thread_blocker.block_with_timeout_ms(start_ms + timeout->value - current_ms);
|
event_node->thread_blocker.block_with_timeout_ms(start_ms + timeout_value - current_ms);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <kernel/ACPI/AML/Buffer.h>
|
||||||
#include <kernel/ACPI/AML/Bytes.h>
|
#include <kernel/ACPI/AML/Bytes.h>
|
||||||
#include <kernel/ACPI/AML/Integer.h>
|
#include <kernel/ACPI/AML/Integer.h>
|
||||||
#include <kernel/ACPI/AML/Node.h>
|
|
||||||
#include <kernel/ACPI/AML/ParseContext.h>
|
#include <kernel/ACPI/AML/ParseContext.h>
|
||||||
|
#include <kernel/ACPI/AML/String.h>
|
||||||
|
|
||||||
namespace Kernel::ACPI::AML
|
namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
|
@ -25,13 +26,14 @@ namespace Kernel::ACPI::AML
|
||||||
auto source_result = AML::parse_object(context);
|
auto source_result = AML::parse_object(context);
|
||||||
if (!source_result.success())
|
if (!source_result.success())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
auto source_node = source_result.node() ? source_result.node()->as_integer(): BAN::RefPtr<AML::Integer>();
|
auto conv_node = source_result.node() ? source_result.node()->convert(AML::Node::ConvInteger) : BAN::RefPtr<AML::Node>();
|
||||||
if (!source_node)
|
if (!conv_node)
|
||||||
{
|
{
|
||||||
AML_ERROR("UnaryOp source not integer");
|
AML_ERROR("UnaryOp source not integer, type {}", static_cast<uint8_t>(source_result.node()->type));
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto source_node = static_cast<AML::Integer*>(conv_node.ptr());
|
||||||
if (source_node->constant)
|
if (source_node->constant)
|
||||||
{
|
{
|
||||||
AML_ERROR("UnaryOp source is constant");
|
AML_ERROR("UnaryOp source is constant");
|
||||||
|
@ -48,18 +50,23 @@ namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
context.aml_data = context.aml_data.slice(1);
|
context.aml_data = context.aml_data.slice(1);
|
||||||
|
|
||||||
auto node_result = AML::parse_object(context);
|
auto source_result = AML::parse_object(context);
|
||||||
if (!node_result.success())
|
if (!source_result.success())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
|
auto conv_node = source_result.node() ? source_result.node()->convert(AML::Node::ConvInteger) : BAN::RefPtr<AML::Node>();
|
||||||
auto value = node_result.node() ? node_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
|
if (!conv_node)
|
||||||
if (!value)
|
{
|
||||||
|
AML_ERROR("UnaryOp source not integer, type {}", static_cast<uint8_t>(source_result.node()->type));
|
||||||
|
return ParseResult::Failure;
|
||||||
|
}
|
||||||
|
auto source_node = static_cast<AML::Integer*>(conv_node.ptr());
|
||||||
|
if (!source_node)
|
||||||
{
|
{
|
||||||
AML_ERROR("Logical NotOp source is not integer");
|
AML_ERROR("Logical NotOp source is not integer");
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto result = value->value ? Integer::Constants::Zero : Integer::Constants::Ones;
|
auto result = source_node->value ? Integer::Constants::Zero : Integer::Constants::Ones;
|
||||||
return ParseResult(result);
|
return ParseResult(result);
|
||||||
}
|
}
|
||||||
case AML::Byte::AddOp:
|
case AML::Byte::AddOp:
|
||||||
|
@ -97,21 +104,25 @@ namespace Kernel::ACPI::AML
|
||||||
auto lhs_result = AML::parse_object(context);
|
auto lhs_result = AML::parse_object(context);
|
||||||
if (!lhs_result.success())
|
if (!lhs_result.success())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
auto lhs_value = lhs_result.node() ? lhs_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
|
auto lhs_conv = lhs_result.node() ? lhs_result.node()->convert(AML::Node::ConvInteger) : BAN::RefPtr<AML::Node>();
|
||||||
if (!lhs_value)
|
if (!lhs_conv)
|
||||||
{
|
{
|
||||||
AML_ERROR("BinaryOP {2H} LHS not an integer", static_cast<uint8_t>(opcode));
|
AML_ERROR("BinaryOP {2H} LHS not an integer, type {}",
|
||||||
|
static_cast<uint8_t>(opcode),
|
||||||
|
static_cast<uint8_t>(lhs_result.node()->type)
|
||||||
|
);
|
||||||
if (lhs_result.node())
|
if (lhs_result.node())
|
||||||
lhs_result.node()->debug_print(1);
|
lhs_result.node()->debug_print(1);
|
||||||
AML_DEBUG_PRINTLN("");
|
AML_DEBUG_PRINTLN("");
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
|
const auto lhs_value = static_cast<AML::Integer*>(lhs_conv.ptr())->value;
|
||||||
|
|
||||||
auto rhs_result = AML::parse_object(context);
|
auto rhs_result = AML::parse_object(context);
|
||||||
if (!rhs_result.success())
|
if (!rhs_result.success())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
auto rhs_value = rhs_result.node() ? rhs_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
|
auto rhs_conv = rhs_result.node() ? rhs_result.node()->convert(AML::Node::ConvInteger) : BAN::RefPtr<AML::Node>();
|
||||||
if (!rhs_value)
|
if (!rhs_conv)
|
||||||
{
|
{
|
||||||
AML_ERROR("BinaryOP {2H} RHS not an integer", static_cast<uint8_t>(opcode));
|
AML_ERROR("BinaryOP {2H} RHS not an integer", static_cast<uint8_t>(opcode));
|
||||||
if (rhs_result.node())
|
if (rhs_result.node())
|
||||||
|
@ -119,12 +130,14 @@ namespace Kernel::ACPI::AML
|
||||||
AML_DEBUG_PRINTLN("");
|
AML_DEBUG_PRINTLN("");
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
|
const auto rhs_value = static_cast<AML::Integer*>(rhs_conv.ptr())->value;
|
||||||
|
|
||||||
if (context.aml_data.size() < 1)
|
if (context.aml_data.size() < 1)
|
||||||
{
|
{
|
||||||
AML_ERROR("BinaryOP {2H} missing target", static_cast<uint8_t>(opcode));
|
AML_ERROR("BinaryOP {2H} missing target", static_cast<uint8_t>(opcode));
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> target_node;
|
BAN::RefPtr<AML::Node> target_node;
|
||||||
if (context.aml_data[0] == 0x00)
|
if (context.aml_data[0] == 0x00)
|
||||||
context.aml_data = context.aml_data.slice(1);
|
context.aml_data = context.aml_data.slice(1);
|
||||||
|
@ -159,9 +172,7 @@ namespace Kernel::ACPI::AML
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t result = func(lhs_value->value, rhs_value->value);
|
auto result_node = MUST(BAN::RefPtr<AML::Integer>::create(func(lhs_value, rhs_value)));
|
||||||
auto result_node = MUST(BAN::RefPtr<AML::Integer>::create(result));
|
|
||||||
|
|
||||||
if (target_node && !target_node->store(result_node))
|
if (target_node && !target_node->store(result_node))
|
||||||
{
|
{
|
||||||
AML_ERROR("BinaryOp {2H} failed to store result", static_cast<uint8_t>(opcode));
|
AML_ERROR("BinaryOp {2H} failed to store result", static_cast<uint8_t>(opcode));
|
||||||
|
@ -176,10 +187,26 @@ namespace Kernel::ACPI::AML
|
||||||
auto opcode = static_cast<AML::Byte>(context.aml_data[0]);
|
auto opcode = static_cast<AML::Byte>(context.aml_data[0]);
|
||||||
context.aml_data = context.aml_data.slice(1);
|
context.aml_data = context.aml_data.slice(1);
|
||||||
|
|
||||||
|
uint8_t mask;
|
||||||
|
switch (opcode)
|
||||||
|
{
|
||||||
|
case AML::Byte::LAndOp:
|
||||||
|
case AML::Byte::LOrOp:
|
||||||
|
mask = AML::Node::ConvInteger;
|
||||||
|
break;
|
||||||
|
case AML::Byte::LEqualOp:
|
||||||
|
case AML::Byte::LGreaterOp:
|
||||||
|
case AML::Byte::LLessOp:
|
||||||
|
mask = AML::Node::ConvInteger | AML::Node::ConvString | AML::Node::ConvBuffer;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
auto lhs_result = AML::parse_object(context);
|
auto lhs_result = AML::parse_object(context);
|
||||||
if (!lhs_result.success())
|
if (!lhs_result.success())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
auto lhs_node = lhs_result.node() ? lhs_result.node()->evaluate() : BAN::RefPtr<AML::Node>();
|
auto lhs_node = lhs_result.node() ? lhs_result.node()->convert(mask) : BAN::RefPtr<AML::Node>();
|
||||||
if (!lhs_node)
|
if (!lhs_node)
|
||||||
{
|
{
|
||||||
AML_TODO("Logical BinaryOP {2H} LHS evaluated to nothing", static_cast<uint8_t>(opcode));
|
AML_TODO("Logical BinaryOP {2H} LHS evaluated to nothing", static_cast<uint8_t>(opcode));
|
||||||
|
|
|
@ -47,7 +47,7 @@ namespace Kernel::ACPI::AML
|
||||||
uint8_t access_length = 0;
|
uint8_t access_length = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FieldElement : public NamedObject
|
struct FieldElement final : public AML::NamedObject
|
||||||
{
|
{
|
||||||
uint64_t bit_offset;
|
uint64_t bit_offset;
|
||||||
uint64_t bit_count;
|
uint64_t bit_count;
|
||||||
|
@ -63,14 +63,30 @@ namespace Kernel::ACPI::AML
|
||||||
, access_rules(access_rules)
|
, access_rules(access_rules)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Integer> as_integer() override;
|
BAN::RefPtr<AML::Node> convert(uint8_t mask) override
|
||||||
|
{
|
||||||
|
if (mask & AML::Node::ConvInteger)
|
||||||
|
return as_integer();
|
||||||
|
if (mask & AML::Node::ConvBuffer)
|
||||||
|
{
|
||||||
|
AML_TODO("Convert BankFieldElement to Buffer");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
if (mask & AML::Node::ConvString)
|
||||||
|
{
|
||||||
|
AML_TODO("Convert BankFieldElement to String");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
BAN::RefPtr<Node> evaluate() override { return as_integer(); }
|
BAN::RefPtr<AML::Node> store(BAN::RefPtr<Node> source) override;
|
||||||
bool store(BAN::RefPtr<Node> source) override;
|
|
||||||
|
|
||||||
void debug_print(int indent) const override;
|
void debug_print(int indent) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
BAN::RefPtr<AML::Integer> as_integer();
|
||||||
|
|
||||||
BAN::Optional<uint64_t> evaluate_internal();
|
BAN::Optional<uint64_t> evaluate_internal();
|
||||||
bool store_internal(uint64_t value);
|
bool store_internal(uint64_t value);
|
||||||
|
|
||||||
|
@ -83,7 +99,7 @@ namespace Kernel::ACPI::AML
|
||||||
static ParseResult parse(ParseContext& context);
|
static ParseResult parse(ParseContext& context);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IndexFieldElement : public NamedObject
|
struct IndexFieldElement final : public AML::NamedObject
|
||||||
{
|
{
|
||||||
uint64_t bit_offset;
|
uint64_t bit_offset;
|
||||||
uint64_t bit_count;
|
uint64_t bit_count;
|
||||||
|
@ -100,12 +116,30 @@ namespace Kernel::ACPI::AML
|
||||||
, access_rules(access_rules)
|
, access_rules(access_rules)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Integer> as_integer() override;
|
BAN::RefPtr<AML::Node> convert(uint8_t mask) override
|
||||||
|
{
|
||||||
|
if (mask & AML::Node::ConvInteger)
|
||||||
|
if (auto node = as_integer())
|
||||||
|
return node;
|
||||||
|
if (mask & AML::Node::ConvBuffer)
|
||||||
|
{
|
||||||
|
AML_TODO("convert BankFieldElement to Buffer");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
if (mask & AML::Node::ConvString)
|
||||||
|
{
|
||||||
|
AML_TODO("convert BankFieldElement to String");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> evaluate() override { return as_integer(); }
|
BAN::RefPtr<AML::Node> store(BAN::RefPtr<Node> source) override;
|
||||||
bool store(BAN::RefPtr<Node> source) override;
|
|
||||||
|
|
||||||
void debug_print(int indent) const override;
|
void debug_print(int indent) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
BAN::RefPtr<AML::Integer> as_integer();
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IndexField
|
struct IndexField
|
||||||
|
@ -113,7 +147,7 @@ namespace Kernel::ACPI::AML
|
||||||
static ParseResult parse(ParseContext& context);
|
static ParseResult parse(ParseContext& context);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BankFieldElement : public NamedObject
|
struct BankFieldElement final : public AML::NamedObject
|
||||||
{
|
{
|
||||||
uint64_t bit_offset;
|
uint64_t bit_offset;
|
||||||
uint64_t bit_count;
|
uint64_t bit_count;
|
||||||
|
@ -131,10 +165,30 @@ namespace Kernel::ACPI::AML
|
||||||
, access_rules(access_rules)
|
, access_rules(access_rules)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
BAN::RefPtr<Node> evaluate() override;
|
BAN::RefPtr<AML::Node> convert(uint8_t mask) override
|
||||||
bool store(BAN::RefPtr<Node> source) override;
|
{
|
||||||
|
if (mask & AML::Node::ConvInteger)
|
||||||
|
if (auto node = as_integer())
|
||||||
|
return node;
|
||||||
|
if (mask & AML::Node::ConvBuffer)
|
||||||
|
{
|
||||||
|
AML_TODO("convert BankFieldElement to Buffer");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
if (mask & AML::Node::ConvString)
|
||||||
|
{
|
||||||
|
AML_TODO("convert BankFieldElement to String");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::RefPtr<AML::Node> store(BAN::RefPtr<Node> source) override;
|
||||||
|
|
||||||
void debug_print(int indent) const override;
|
void debug_print(int indent) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
BAN::RefPtr<AML::Integer> as_integer();
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BankField
|
struct BankField
|
||||||
|
|
|
@ -26,12 +26,13 @@ namespace Kernel::ACPI::AML
|
||||||
auto predicate_result = AML::parse_object(context);
|
auto predicate_result = AML::parse_object(context);
|
||||||
if (!predicate_result.success())
|
if (!predicate_result.success())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
auto predicate = predicate_result.node() ? predicate_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
|
auto predicate_node = predicate_result.node() ? predicate_result.node()->convert(AML::Node::ConvInteger) : BAN::RefPtr<AML::Node>();
|
||||||
if (!predicate)
|
if (!predicate_node)
|
||||||
{
|
{
|
||||||
AML_ERROR("If predicate is not an integer");
|
AML_ERROR("If predicate is not an integer");
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
|
const auto predicate_value = static_cast<AML::Integer*>(predicate_node.ptr())->value;
|
||||||
|
|
||||||
// Else
|
// Else
|
||||||
BAN::ConstByteSpan else_pkg;
|
BAN::ConstByteSpan else_pkg;
|
||||||
|
@ -43,7 +44,7 @@ namespace Kernel::ACPI::AML
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
else_pkg = else_pkg_result.value();
|
else_pkg = else_pkg_result.value();
|
||||||
}
|
}
|
||||||
if (predicate->value == 0)
|
if (predicate_value == 0)
|
||||||
context.aml_data = else_pkg;
|
context.aml_data = else_pkg;
|
||||||
|
|
||||||
while (context.aml_data.size() > 0)
|
while (context.aml_data.size() > 0)
|
||||||
|
|
|
@ -20,22 +20,32 @@ namespace Kernel::ACPI::AML
|
||||||
auto source_result = AML::parse_object(context);
|
auto source_result = AML::parse_object(context);
|
||||||
if (!source_result.success())
|
if (!source_result.success())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
auto source = source_result.node() ? source_result.node()->evaluate() : BAN::RefPtr<AML::Node>();
|
auto source = source_result.node()
|
||||||
|
? source_result.node()->convert(AML::Node::ConvBuffer | AML::Node::ConvInteger | AML::Node::ConvString)
|
||||||
|
: BAN::RefPtr<AML::Node>();
|
||||||
if (!source)
|
if (!source)
|
||||||
{
|
{
|
||||||
AML_ERROR("IndexOp source is null");
|
AML_ERROR("IndexOp source could not be converted");
|
||||||
|
if (source)
|
||||||
|
{
|
||||||
|
source->debug_print(0);
|
||||||
|
AML_DEBUG_PRINTLN("");
|
||||||
|
}
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto index_result = AML::parse_object(context);
|
auto index_result = AML::parse_object(context);
|
||||||
if (!index_result.success())
|
if (!index_result.success())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
auto index = index_result.node() ? index_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
|
auto index_node = source_result.node()
|
||||||
if (!index)
|
? source_result.node()->convert(AML::Node::ConvInteger)
|
||||||
|
: BAN::RefPtr<AML::Node>();
|
||||||
|
if (!index_node)
|
||||||
{
|
{
|
||||||
AML_ERROR("IndexOp index is not an integer");
|
AML_ERROR("IndexOp index is not an integer");
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
|
const auto index = static_cast<AML::Integer*>(index_node.ptr())->value;
|
||||||
|
|
||||||
BAN::RefPtr<AML::Reference> result;
|
BAN::RefPtr<AML::Reference> result;
|
||||||
switch (source->type)
|
switch (source->type)
|
||||||
|
@ -43,36 +53,36 @@ namespace Kernel::ACPI::AML
|
||||||
case AML::Node::Type::Buffer:
|
case AML::Node::Type::Buffer:
|
||||||
{
|
{
|
||||||
auto buffer = BAN::RefPtr<AML::Buffer>(static_cast<AML::Buffer*>(source.ptr()));
|
auto buffer = BAN::RefPtr<AML::Buffer>(static_cast<AML::Buffer*>(source.ptr()));
|
||||||
if (index->value >= buffer->buffer.size())
|
if (index >= buffer->buffer.size())
|
||||||
{
|
{
|
||||||
AML_ERROR("IndexOp index is out of buffer bounds");
|
AML_ERROR("IndexOp index is out of buffer bounds");
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
auto buffer_field = MUST(BAN::RefPtr<BufferField>::create(NameSeg(""_sv), buffer, index->value * 8, 8));
|
auto buffer_field = MUST(BAN::RefPtr<BufferField>::create(NameSeg(""_sv), buffer, index * 8, 8));
|
||||||
result = MUST(BAN::RefPtr<AML::Reference>::create(buffer_field));
|
result = MUST(BAN::RefPtr<AML::Reference>::create(buffer_field));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AML::Node::Type::Package:
|
case AML::Node::Type::Package:
|
||||||
{
|
{
|
||||||
auto package = static_cast<AML::Package*>(source.ptr());
|
auto package = static_cast<AML::Package*>(source.ptr());
|
||||||
if (index->value >= package->elements.size())
|
if (index >= package->elements.size())
|
||||||
{
|
{
|
||||||
AML_ERROR("IndexOp index is out of package bounds");
|
AML_ERROR("IndexOp index is out of package bounds");
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
auto package_element = package->elements[index->value];
|
auto package_element = package->elements[index];
|
||||||
result = MUST(BAN::RefPtr<AML::Reference>::create(package_element));
|
result = MUST(BAN::RefPtr<AML::Reference>::create(package_element));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AML::Node::Type::String:
|
case AML::Node::Type::String:
|
||||||
{
|
{
|
||||||
auto string = BAN::RefPtr<AML::String>(static_cast<AML::String*>(source.ptr()));
|
auto string = BAN::RefPtr<AML::String>(static_cast<AML::String*>(source.ptr()));
|
||||||
if (index->value >= string->string.size())
|
if (index >= string->string.size())
|
||||||
{
|
{
|
||||||
AML_ERROR("IndexOp index is out of string bounds");
|
AML_ERROR("IndexOp index is out of string bounds");
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
auto buffer_field = MUST(BAN::RefPtr<BufferField>::create(NameSeg(""_sv), string, index->value * 8, 8));
|
auto buffer_field = MUST(BAN::RefPtr<BufferField>::create(NameSeg(""_sv), string, index * 8, 8));
|
||||||
result = MUST(BAN::RefPtr<AML::Reference>::create(buffer_field));
|
result = MUST(BAN::RefPtr<AML::Reference>::create(buffer_field));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -82,7 +92,7 @@ namespace Kernel::ACPI::AML
|
||||||
}
|
}
|
||||||
|
|
||||||
#if AML_DEBUG_LEVEL >= 2
|
#if AML_DEBUG_LEVEL >= 2
|
||||||
AML_DEBUG_PRINT("Index {}, ", index->value);
|
AML_DEBUG_PRINT("Index {}, ", index);
|
||||||
source->debug_print(0);
|
source->debug_print(0);
|
||||||
AML_DEBUG_PRINTLN("");
|
AML_DEBUG_PRINTLN("");
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
namespace Kernel::ACPI::AML
|
namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
|
|
||||||
struct Integer : public Node
|
struct Integer final : public AML::Node
|
||||||
{
|
{
|
||||||
struct Constants
|
struct Constants
|
||||||
{
|
{
|
||||||
|
@ -31,49 +31,70 @@ namespace Kernel::ACPI::AML
|
||||||
|
|
||||||
BAN::Optional<bool> logical_compare(BAN::RefPtr<AML::Node> node, AML::Byte binaryop)
|
BAN::Optional<bool> logical_compare(BAN::RefPtr<AML::Node> node, AML::Byte binaryop)
|
||||||
{
|
{
|
||||||
auto rhs = node ? node->as_integer() : BAN::RefPtr<AML::Integer>();
|
auto rhs_node = node ? node->convert(AML::Node::ConvInteger) : BAN::RefPtr<AML::Node>();
|
||||||
if (!rhs)
|
if (!rhs_node)
|
||||||
{
|
{
|
||||||
AML_ERROR("Integer logical compare RHS is not integer");
|
AML_ERROR("Integer logical compare RHS cannot be converted to");
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
const auto rhs_value = static_cast<AML::Integer*>(rhs_node.ptr())->value;
|
||||||
|
|
||||||
switch (binaryop)
|
switch (binaryop)
|
||||||
{
|
{
|
||||||
case AML::Byte::LAndOp: return value && rhs->value;
|
case AML::Byte::LAndOp: return value && rhs_value;
|
||||||
case AML::Byte::LEqualOp: return value == rhs->value;
|
case AML::Byte::LEqualOp: return value == rhs_value;
|
||||||
case AML::Byte::LGreaterOp: return value > rhs->value;
|
case AML::Byte::LGreaterOp: return value > rhs_value;
|
||||||
case AML::Byte::LLessOp: return value < rhs->value;
|
case AML::Byte::LLessOp: return value < rhs_value;
|
||||||
case AML::Byte::LOrOp: return value || rhs->value;
|
case AML::Byte::LOrOp: return value || rhs_value;
|
||||||
default:
|
default:
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Integer> as_integer() override { return this; }
|
BAN::RefPtr<AML::Node> convert(uint8_t mask) override
|
||||||
|
{
|
||||||
|
if (mask & AML::Node::ConvInteger)
|
||||||
|
return this;
|
||||||
|
if (mask & AML::Node::ConvBuffer)
|
||||||
|
{
|
||||||
|
AML_TODO("Convert Integer to Buffer");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
if (mask & AML::Node::ConvBufferField)
|
||||||
|
{
|
||||||
|
AML_TODO("Convert Integer to BufferField");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
if (mask & AML::Node::ConvFieldUnit)
|
||||||
|
{
|
||||||
|
AML_TODO("Convert Integer to FieldUnit");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
if (mask & AML::Node::ConvString)
|
||||||
|
{
|
||||||
|
AML_TODO("Convert Integer to String");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
BAN::RefPtr<Node> copy() override { return MUST(BAN::RefPtr<Integer>::create(value)); }
|
BAN::RefPtr<Node> copy() override { return MUST(BAN::RefPtr<Integer>::create(value)); }
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> evaluate() override
|
BAN::RefPtr<AML::Node> store(BAN::RefPtr<AML::Node> store_node) override
|
||||||
{
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool store(BAN::RefPtr<AML::Node> store_node) override
|
|
||||||
{
|
{
|
||||||
if (constant)
|
if (constant)
|
||||||
{
|
{
|
||||||
AML_ERROR("Cannot store to constant integer");
|
AML_ERROR("Cannot store to constant integer");
|
||||||
return false;
|
return {};
|
||||||
}
|
}
|
||||||
auto store_value = store_node->as_integer();
|
auto conv_node = store_node ? store_node->convert(AML::Node::ConvInteger) : BAN::RefPtr<AML::Node>();
|
||||||
if (!store_value)
|
if (!conv_node)
|
||||||
{
|
{
|
||||||
AML_ERROR("Cannot store non-integer to integer");
|
AML_ERROR("Cannot store non-integer to integer");
|
||||||
return false;
|
return {};
|
||||||
}
|
}
|
||||||
value = store_value->value;
|
value = static_cast<AML::Integer*>(conv_node.ptr())->value;
|
||||||
return true;
|
return MUST(BAN::RefPtr<AML::Integer>::create(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ParseResult parse(BAN::ConstByteSpan& aml_data)
|
static ParseResult parse(BAN::ConstByteSpan& aml_data)
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
namespace Kernel::ACPI::AML
|
namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
|
|
||||||
struct Method : public AML::Scope
|
struct Method final : public AML::Scope
|
||||||
{
|
{
|
||||||
Kernel::Mutex mutex;
|
Kernel::Mutex mutex;
|
||||||
uint8_t arg_count;
|
uint8_t arg_count;
|
||||||
|
@ -27,6 +27,8 @@ namespace Kernel::ACPI::AML
|
||||||
, sync_level(sync_level)
|
, sync_level(sync_level)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
BAN::RefPtr<AML::Node> convert(uint8_t) override { return {}; }
|
||||||
|
|
||||||
static ParseResult parse(AML::ParseContext& context)
|
static ParseResult parse(AML::ParseContext& context)
|
||||||
{
|
{
|
||||||
ASSERT(context.aml_data.size() >= 1);
|
ASSERT(context.aml_data.size() >= 1);
|
||||||
|
@ -98,13 +100,13 @@ namespace Kernel::ACPI::AML
|
||||||
ParseContext context;
|
ParseContext context;
|
||||||
context.aml_data = term_list;
|
context.aml_data = term_list;
|
||||||
context.scope = scope;
|
context.scope = scope;
|
||||||
context.method_args[0] = MUST(BAN::RefPtr<AML::Register>::create(arg0));
|
context.method_args[0] = MUST(BAN::RefPtr<AML::Register>::create(arg0 && arg0->type == AML::Node::Type::Register ? static_cast<AML::Register*>(arg0.ptr())->value : arg0));
|
||||||
context.method_args[1] = MUST(BAN::RefPtr<AML::Register>::create(arg1));
|
context.method_args[1] = MUST(BAN::RefPtr<AML::Register>::create(arg1 && arg1->type == AML::Node::Type::Register ? static_cast<AML::Register*>(arg1.ptr())->value : arg1));
|
||||||
context.method_args[2] = MUST(BAN::RefPtr<AML::Register>::create(arg2));
|
context.method_args[2] = MUST(BAN::RefPtr<AML::Register>::create(arg2 && arg2->type == AML::Node::Type::Register ? static_cast<AML::Register*>(arg2.ptr())->value : arg2));
|
||||||
context.method_args[3] = MUST(BAN::RefPtr<AML::Register>::create(arg3));
|
context.method_args[3] = MUST(BAN::RefPtr<AML::Register>::create(arg3 && arg3->type == AML::Node::Type::Register ? static_cast<AML::Register*>(arg3.ptr())->value : arg3));
|
||||||
context.method_args[4] = MUST(BAN::RefPtr<AML::Register>::create(arg4));
|
context.method_args[4] = MUST(BAN::RefPtr<AML::Register>::create(arg4 && arg4->type == AML::Node::Type::Register ? static_cast<AML::Register*>(arg4.ptr())->value : arg4));
|
||||||
context.method_args[5] = MUST(BAN::RefPtr<AML::Register>::create(arg5));
|
context.method_args[5] = MUST(BAN::RefPtr<AML::Register>::create(arg5 && arg5->type == AML::Node::Type::Register ? static_cast<AML::Register*>(arg5.ptr())->value : arg5));
|
||||||
context.method_args[6] = MUST(BAN::RefPtr<AML::Register>::create(arg6));
|
context.method_args[6] = MUST(BAN::RefPtr<AML::Register>::create(arg6 && arg6->type == AML::Node::Type::Register ? static_cast<AML::Register*>(arg6.ptr())->value : arg6));
|
||||||
context.sync_stack = BAN::move(current_sync_stack);
|
context.sync_stack = BAN::move(current_sync_stack);
|
||||||
for (auto& local : context.method_locals)
|
for (auto& local : context.method_locals)
|
||||||
local = MUST(BAN::RefPtr<AML::Register>::create());
|
local = MUST(BAN::RefPtr<AML::Register>::create());
|
||||||
|
@ -142,8 +144,8 @@ namespace Kernel::ACPI::AML
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (return_value.has_value() && return_value.value())
|
if (return_value.has_value() && return_value.value() && return_value.value()->type == AML::Node::Type::Register)
|
||||||
return_value = return_value.value()->evaluate();
|
return_value.value() = static_cast<AML::Register*>(return_value.value().ptr())->value;
|
||||||
|
|
||||||
while (!context.created_objects.empty())
|
while (!context.created_objects.empty())
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
namespace Kernel::ACPI::AML
|
namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
|
|
||||||
struct Mutex : public AML::NamedObject
|
struct Mutex final : public AML::NamedObject
|
||||||
{
|
{
|
||||||
Kernel::Mutex mutex;
|
Kernel::Mutex mutex;
|
||||||
uint8_t sync_level;
|
uint8_t sync_level;
|
||||||
|
@ -20,6 +20,8 @@ namespace Kernel::ACPI::AML
|
||||||
, sync_level(sync_level)
|
, sync_level(sync_level)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
BAN::RefPtr<AML::Node> convert(uint8_t) override { return {}; }
|
||||||
|
|
||||||
static ParseResult parse(ParseContext& context)
|
static ParseResult parse(ParseContext& context)
|
||||||
{
|
{
|
||||||
ASSERT(context.aml_data.size() >= 2);
|
ASSERT(context.aml_data.size() >= 2);
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
namespace Kernel::ACPI::AML
|
namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
|
|
||||||
struct NamedObject : public Node
|
struct NamedObject : public AML::Node
|
||||||
{
|
{
|
||||||
BAN::RefPtr<NamedObject> parent;
|
BAN::RefPtr<NamedObject> parent;
|
||||||
NameSeg name;
|
NameSeg name;
|
||||||
|
@ -14,7 +14,7 @@ namespace Kernel::ACPI::AML
|
||||||
NamedObject(Node::Type type, NameSeg name) : Node(type), name(name) {}
|
NamedObject(Node::Type type, NameSeg name) : Node(type), name(name) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Name : public NamedObject
|
struct Name final : public AML::NamedObject
|
||||||
{
|
{
|
||||||
BAN::RefPtr<AML::Node> object;
|
BAN::RefPtr<AML::Node> object;
|
||||||
|
|
||||||
|
@ -22,21 +22,15 @@ namespace Kernel::ACPI::AML
|
||||||
: NamedObject(Node::Type::Name, name), object(BAN::move(object))
|
: NamedObject(Node::Type::Name, name), object(BAN::move(object))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Buffer> as_buffer() override;
|
BAN::RefPtr<AML::Node> convert(uint8_t) override { return {}; }
|
||||||
BAN::RefPtr<AML::Integer> as_integer() override;
|
|
||||||
BAN::RefPtr<AML::String> as_string() override;
|
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> evaluate() override
|
BAN::RefPtr<AML::Node> store(BAN::RefPtr<AML::Node> node) override
|
||||||
{
|
|
||||||
ASSERT(object);
|
|
||||||
return object->evaluate();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool store(BAN::RefPtr<AML::Node> node) override
|
|
||||||
{
|
{
|
||||||
ASSERT(object);
|
ASSERT(object);
|
||||||
|
if (object->type == AML::Node::Type::Reference)
|
||||||
|
return object->store(node);
|
||||||
object = node;
|
object = node;
|
||||||
return true;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ParseResult parse(ParseContext& context);
|
static ParseResult parse(ParseContext& context);
|
||||||
|
|
|
@ -8,8 +8,9 @@
|
||||||
namespace Kernel::ACPI::AML
|
namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
|
|
||||||
struct Namespace : public AML::Scope
|
struct Namespace final : public AML::Scope
|
||||||
{
|
{
|
||||||
|
static BAN::RefPtr<AML::Namespace> create_root_namespace();
|
||||||
static BAN::RefPtr<AML::Namespace> root_namespace();
|
static BAN::RefPtr<AML::Namespace> root_namespace();
|
||||||
static BAN::RefPtr<AML::Node> debug_node;
|
static BAN::RefPtr<AML::Node> debug_node;
|
||||||
|
|
||||||
|
@ -35,7 +36,8 @@ namespace Kernel::ACPI::AML
|
||||||
|
|
||||||
Namespace(NameSeg name) : AML::Scope(Node::Type::Namespace, name) {}
|
Namespace(NameSeg name) : AML::Scope(Node::Type::Namespace, name) {}
|
||||||
|
|
||||||
static BAN::RefPtr<AML::Namespace> create_root_namespace();
|
BAN::RefPtr<AML::Node> convert(uint8_t) override { return {}; }
|
||||||
|
|
||||||
bool parse(const SDTHeader& header);
|
bool parse(const SDTHeader& header);
|
||||||
|
|
||||||
void debug_print(int indent) const override;
|
void debug_print(int indent) const override;
|
||||||
|
|
|
@ -17,8 +17,18 @@ namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
static uint64_t total_node_count;
|
static uint64_t total_node_count;
|
||||||
|
|
||||||
enum class Type
|
enum Conversion : uint8_t
|
||||||
{
|
{
|
||||||
|
ConvBuffer = 1 << 0,
|
||||||
|
ConvBufferField = 1 << 1,
|
||||||
|
ConvFieldUnit = 1 << 2,
|
||||||
|
ConvInteger = 1 << 3,
|
||||||
|
ConvString = 1 << 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class Type : uint8_t
|
||||||
|
{
|
||||||
|
None,
|
||||||
Alias,
|
Alias,
|
||||||
BankFieldElement,
|
BankFieldElement,
|
||||||
Buffer,
|
Buffer,
|
||||||
|
@ -50,14 +60,9 @@ namespace Kernel::ACPI::AML
|
||||||
|
|
||||||
virtual bool is_scope() const { return false; }
|
virtual bool is_scope() const { return false; }
|
||||||
|
|
||||||
virtual BAN::RefPtr<Node> copy() { return this; }
|
[[nodiscard]] virtual BAN::RefPtr<AML::Node> convert(uint8_t mask) = 0;
|
||||||
|
[[nodiscard]] virtual BAN::RefPtr<Node> copy() { return this; }
|
||||||
[[nodiscard]] virtual BAN::RefPtr<AML::Buffer> as_buffer();
|
[[nodiscard]] virtual BAN::RefPtr<AML::Node> store(BAN::RefPtr<AML::Node>) { AML_TODO("store, type {}", static_cast<uint8_t>(type)); return {}; }
|
||||||
[[nodiscard]] virtual BAN::RefPtr<AML::Integer> as_integer();
|
|
||||||
[[nodiscard]] virtual BAN::RefPtr<AML::String> as_string();
|
|
||||||
|
|
||||||
[[nodiscard]] virtual BAN::RefPtr<AML::Node> evaluate() { AML_TODO("evaluate, type {}", static_cast<uint8_t>(type)); return nullptr; }
|
|
||||||
[[nodiscard]] virtual bool store(BAN::RefPtr<AML::Node>) { 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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -29,12 +29,13 @@ namespace Kernel::ACPI::AML
|
||||||
auto value_result = AML::parse_object(context);
|
auto value_result = AML::parse_object(context);
|
||||||
if (!value_result.success())
|
if (!value_result.success())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
auto value = value_result.node() ? value_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
|
auto value_node = value_result.node() ? value_result.node()->convert(AML::Node::ConvInteger) : BAN::RefPtr<AML::Node>();
|
||||||
if (!value)
|
if (!value_node)
|
||||||
{
|
{
|
||||||
AML_ERROR("Notify value is not an integer");
|
AML_ERROR("Notify value is not an integer");
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
|
const auto value = static_cast<AML::Integer*>(value_node.ptr())->value;
|
||||||
|
|
||||||
BAN::StringView object_type_sv;
|
BAN::StringView object_type_sv;
|
||||||
BAN::StringView object_name_sv;
|
BAN::StringView object_name_sv;
|
||||||
|
@ -58,7 +59,7 @@ namespace Kernel::ACPI::AML
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
AML_TODO("Notify: {} {}: {2H}", object_type_sv, object_name_sv, value->value);
|
AML_TODO("Notify: {} {}: {2H}", object_type_sv, object_name_sv, value);
|
||||||
return ParseResult::Success;
|
return ParseResult::Success;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace Kernel::ACPI::AML
|
||||||
|
|
||||||
struct PackageElement;
|
struct PackageElement;
|
||||||
|
|
||||||
struct Package : public AML::Node
|
struct Package final : public AML::Node
|
||||||
{
|
{
|
||||||
BAN::Vector<BAN::RefPtr<PackageElement>> elements;
|
BAN::Vector<BAN::RefPtr<PackageElement>> elements;
|
||||||
AML::NameString scope;
|
AML::NameString scope;
|
||||||
|
@ -22,16 +22,13 @@ namespace Kernel::ACPI::AML
|
||||||
, scope(scope)
|
, scope(scope)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> evaluate() override
|
BAN::RefPtr<AML::Node> convert(uint8_t) override { return {}; }
|
||||||
{
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ParseResult parse(AML::ParseContext& context);
|
static ParseResult parse(AML::ParseContext& context);
|
||||||
virtual void debug_print(int indent) const override;
|
virtual void debug_print(int indent) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PackageElement : public AML::Node
|
struct PackageElement final : public AML::Node
|
||||||
{
|
{
|
||||||
BAN::RefPtr<AML::Package> parent;
|
BAN::RefPtr<AML::Package> parent;
|
||||||
BAN::RefPtr<AML::Node> element;
|
BAN::RefPtr<AML::Node> element;
|
||||||
|
@ -82,7 +79,19 @@ namespace Kernel::ACPI::AML
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool store(BAN::RefPtr<AML::Node> node) override
|
BAN::RefPtr<AML::Node> convert(uint8_t mask) override
|
||||||
|
{
|
||||||
|
if (!initialized)
|
||||||
|
{
|
||||||
|
AML_ERROR("Trying to store into uninitialized PackageElement");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
if (!resolved && !resolve())
|
||||||
|
return {};
|
||||||
|
return element->convert(mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::RefPtr<AML::Node> store(BAN::RefPtr<AML::Node> node) override
|
||||||
{
|
{
|
||||||
if (!initialized)
|
if (!initialized)
|
||||||
{
|
{
|
||||||
|
@ -94,31 +103,7 @@ namespace Kernel::ACPI::AML
|
||||||
if (element->type == AML::Node::Type::Reference)
|
if (element->type == AML::Node::Type::Reference)
|
||||||
return element->store(node);
|
return element->store(node);
|
||||||
element = node->copy();
|
element = node->copy();
|
||||||
return true;
|
return element;
|
||||||
}
|
|
||||||
|
|
||||||
BAN::RefPtr<AML::Integer> as_integer() override
|
|
||||||
{
|
|
||||||
if (!initialized)
|
|
||||||
{
|
|
||||||
AML_ERROR("Trying to evaluate uninitialized PackageElement");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
if (!resolved && !resolve())
|
|
||||||
return {};
|
|
||||||
return element->as_integer();
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> evaluate() override
|
|
||||||
{
|
|
||||||
if (!initialized)
|
|
||||||
{
|
|
||||||
AML_ERROR("Trying to evaluate uninitialized PackageElement");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
if (!resolved && !resolve())
|
|
||||||
return {};
|
|
||||||
return element->evaluate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static ParseResult parse(AML::ParseContext& context, BAN::RefPtr<AML::Package> package)
|
static ParseResult parse(AML::ParseContext& context, BAN::RefPtr<AML::Package> package)
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
namespace Kernel::ACPI::AML
|
namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
|
|
||||||
struct PowerResource : public AML::Scope
|
struct PowerResource final : public AML::Scope
|
||||||
{
|
{
|
||||||
uint8_t system_level;
|
uint8_t system_level;
|
||||||
uint16_t resource_order;
|
uint16_t resource_order;
|
||||||
|
@ -20,6 +20,8 @@ namespace Kernel::ACPI::AML
|
||||||
, resource_order(resource_order)
|
, resource_order(resource_order)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
BAN::RefPtr<AML::Node> convert(uint8_t) override { return {}; }
|
||||||
|
|
||||||
static ParseResult parse(ParseContext& context)
|
static ParseResult parse(ParseContext& context)
|
||||||
{
|
{
|
||||||
ASSERT(context.aml_data.size() >= 2);
|
ASSERT(context.aml_data.size() >= 2);
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
namespace Kernel::ACPI::AML
|
namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
|
|
||||||
struct Processor : public AML::Scope
|
struct Processor final : public AML::Scope
|
||||||
{
|
{
|
||||||
uint8_t id;
|
uint8_t id;
|
||||||
uint32_t pblk_addr;
|
uint32_t pblk_addr;
|
||||||
|
@ -22,6 +22,8 @@ namespace Kernel::ACPI::AML
|
||||||
, pblk_len(pblk_len)
|
, pblk_len(pblk_len)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
BAN::RefPtr<AML::Node> convert(uint8_t) override { return {}; }
|
||||||
|
|
||||||
static ParseResult parse(ParseContext& context)
|
static ParseResult parse(ParseContext& context)
|
||||||
{
|
{
|
||||||
ASSERT(context.aml_data.size() >= 2);
|
ASSERT(context.aml_data.size() >= 2);
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
namespace Kernel::ACPI::AML
|
namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
|
|
||||||
struct Reference : public AML::Node
|
struct Reference final : public AML::Node
|
||||||
{
|
{
|
||||||
BAN::RefPtr<AML::Node> node;
|
BAN::RefPtr<AML::Node> node;
|
||||||
|
|
||||||
|
@ -21,24 +21,22 @@ namespace Kernel::ACPI::AML
|
||||||
ASSERT(node);
|
ASSERT(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Integer> as_integer() override
|
BAN::RefPtr<AML::Node> convert(uint8_t mask) override
|
||||||
{
|
|
||||||
if (node)
|
|
||||||
return node->as_integer();
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> evaluate() override
|
|
||||||
{
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool store(BAN::RefPtr<AML::Node> value) override
|
|
||||||
{
|
{
|
||||||
if (!node)
|
if (!node)
|
||||||
{
|
{
|
||||||
AML_ERROR("Storing to null reference");
|
AML_ERROR("Trying to convert null Reference");
|
||||||
return false;
|
return {};
|
||||||
|
}
|
||||||
|
return node->convert(mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::RefPtr<AML::Node> store(BAN::RefPtr<AML::Node> value) override
|
||||||
|
{
|
||||||
|
if (!node)
|
||||||
|
{
|
||||||
|
AML_ERROR("Storing to null Reference");
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
return node->store(value);
|
return node->store(value);
|
||||||
}
|
}
|
||||||
|
@ -79,6 +77,8 @@ namespace Kernel::ACPI::AML
|
||||||
if (!parse_result.success())
|
if (!parse_result.success())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
object = parse_result.node();
|
object = parse_result.node();
|
||||||
|
if (object && object->type == AML::Node::Type::Register)
|
||||||
|
object = static_cast<AML::Register*>(object.ptr())->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!conditional)
|
if (!conditional)
|
||||||
|
@ -96,18 +96,26 @@ namespace Kernel::ACPI::AML
|
||||||
return ParseResult(reference);
|
return ParseResult(reference);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.aml_data.size() >= 1 && context.aml_data[0] != 0x00)
|
if (context.aml_data.size() < 1)
|
||||||
|
{
|
||||||
|
AML_ERROR("CondRefOf missing target");
|
||||||
|
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);
|
auto target_result = AML::parse_object(context);
|
||||||
if (!target_result.success())
|
if (!target_result.success())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
auto target_node = target_result.node();
|
target_node = target_result.node();
|
||||||
if (!target_node)
|
if (!target_node)
|
||||||
{
|
{
|
||||||
AML_ERROR("CondRefOf failed to resolve target");
|
AML_ERROR("CondRefOf failed to resolve target");
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
target_node->store(MUST(BAN::RefPtr<Reference>::create(object)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if AML_DEBUG_LEVEL >= 2
|
#if AML_DEBUG_LEVEL >= 2
|
||||||
|
@ -119,8 +127,16 @@ namespace Kernel::ACPI::AML
|
||||||
AML_DEBUG_PRINTLN("");
|
AML_DEBUG_PRINTLN("");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
auto return_value = object ? Integer::Constants::Ones : Integer::Constants::Zero;
|
if (!object)
|
||||||
return AML::ParseResult(return_value);
|
return AML::ParseResult(Integer::Constants::Zero);
|
||||||
|
|
||||||
|
if (target_node && !target_node->store(object))
|
||||||
|
{
|
||||||
|
AML_ERROR("CondRefOf failed to store into target");
|
||||||
|
return ParseResult::Failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
return AML::ParseResult(Integer::Constants::Ones);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ParseResult parse_dereference(ParseContext& context)
|
static ParseResult parse_dereference(ParseContext& context)
|
||||||
|
@ -144,18 +160,20 @@ namespace Kernel::ACPI::AML
|
||||||
auto parse_result = AML::parse_object(context);
|
auto parse_result = AML::parse_object(context);
|
||||||
if (!parse_result.success())
|
if (!parse_result.success())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
auto object = parse_result.node() ? parse_result.node()->evaluate() : BAN::RefPtr<AML::Node>();
|
auto node = parse_result.node();
|
||||||
if (!object || object->type != AML::Node::Type::Reference)
|
if (node && node->type == AML::Node::Type::Register)
|
||||||
|
node = static_cast<AML::Register*>(node.ptr())->value;
|
||||||
|
if (!node || node->type != AML::Node::Type::Reference)
|
||||||
{
|
{
|
||||||
AML_TODO("DerefOf source is not a Reference, but a {}", object ? static_cast<uint8_t>(object->type) : 999);
|
AML_TODO("DerefOf source is not a Reference, but a {}", node ? static_cast<uint8_t>(node->type) : 999);
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
#if AML_DEBUG_LEVEL >= 2
|
#if AML_DEBUG_LEVEL >= 2
|
||||||
AML_DEBUG_PRINT("DerefOf ");
|
AML_DEBUG_PRINT("DerefOf ");
|
||||||
object->debug_print(0);
|
node->debug_print(0);
|
||||||
AML_DEBUG_PRINTLN("");
|
AML_DEBUG_PRINTLN("");
|
||||||
#endif
|
#endif
|
||||||
return ParseResult(static_cast<Reference*>(object.ptr())->node);
|
return ParseResult(static_cast<Reference*>(node.ptr())->node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,6 +182,7 @@ namespace Kernel::ACPI::AML
|
||||||
AML_DEBUG_PRINT_INDENT(indent);
|
AML_DEBUG_PRINT_INDENT(indent);
|
||||||
AML_DEBUG_PRINTLN("Reference {");
|
AML_DEBUG_PRINTLN("Reference {");
|
||||||
node->debug_print(indent + 1);
|
node->debug_print(indent + 1);
|
||||||
|
AML_DEBUG_PRINTLN("");
|
||||||
AML_DEBUG_PRINT_INDENT(indent);
|
AML_DEBUG_PRINT_INDENT(indent);
|
||||||
AML_DEBUG_PRINT("}");
|
AML_DEBUG_PRINT("}");
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
namespace Kernel::ACPI::AML
|
namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
|
|
||||||
struct OpRegion : public NamedObject
|
struct OpRegion final : public AML::NamedObject
|
||||||
{
|
{
|
||||||
using RegionSpace = GAS::AddressSpaceID;
|
using RegionSpace = GAS::AddressSpaceID;
|
||||||
RegionSpace region_space;
|
RegionSpace region_space;
|
||||||
|
@ -24,6 +24,8 @@ namespace Kernel::ACPI::AML
|
||||||
, region_length(region_length)
|
, region_length(region_length)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
BAN::RefPtr<AML::Node> convert(uint8_t) override { return {}; }
|
||||||
|
|
||||||
static ParseResult parse(AML::ParseContext& context)
|
static ParseResult parse(AML::ParseContext& context)
|
||||||
{
|
{
|
||||||
ASSERT(context.aml_data.size() > 2);
|
ASSERT(context.aml_data.size() > 2);
|
||||||
|
@ -43,8 +45,10 @@ namespace Kernel::ACPI::AML
|
||||||
auto offset_result = AML::parse_object(context);
|
auto offset_result = AML::parse_object(context);
|
||||||
if (!offset_result.success())
|
if (!offset_result.success())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
auto offset = offset_result.node()->as_integer();
|
auto offset_node = offset_result.node()
|
||||||
if (!offset)
|
? offset_result.node()->convert(AML::Node::ConvInteger)
|
||||||
|
: BAN::RefPtr<AML::Node>();
|
||||||
|
if (!offset_node)
|
||||||
{
|
{
|
||||||
AML_ERROR("OpRegion offset must be an integer");
|
AML_ERROR("OpRegion offset must be an integer");
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
|
@ -53,18 +57,23 @@ namespace Kernel::ACPI::AML
|
||||||
auto length_result = AML::parse_object(context);
|
auto length_result = AML::parse_object(context);
|
||||||
if (!length_result.success())
|
if (!length_result.success())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
auto length = length_result.node()->as_integer();
|
auto length_node = length_result.node()
|
||||||
if (!length)
|
? length_result.node()->convert(AML::Node::ConvInteger)
|
||||||
|
: BAN::RefPtr<AML::Node>();
|
||||||
|
if (!length_node)
|
||||||
{
|
{
|
||||||
AML_ERROR("OpRegion length must be an integer");
|
AML_ERROR("OpRegion length must be an integer");
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto offset = static_cast<AML::Integer*>(offset_node.ptr())->value;
|
||||||
|
const auto length = static_cast<AML::Integer*>(length_node.ptr())->value;
|
||||||
|
|
||||||
auto op_region = MUST(BAN::RefPtr<OpRegion>::create(
|
auto op_region = MUST(BAN::RefPtr<OpRegion>::create(
|
||||||
name->path.back(),
|
name->path.back(),
|
||||||
region_space,
|
region_space,
|
||||||
offset->value,
|
offset,
|
||||||
length->value
|
length
|
||||||
));
|
));
|
||||||
|
|
||||||
if (!Namespace::root_namespace()->add_named_object(context, name.value(), op_region))
|
if (!Namespace::root_namespace()->add_named_object(context, name.value(), op_region))
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
namespace Kernel::ACPI::AML
|
namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
|
|
||||||
struct Register : public AML::Node
|
struct Register final : public AML::Node
|
||||||
{
|
{
|
||||||
BAN::RefPtr<AML::Node> value;
|
BAN::RefPtr<AML::Node> value;
|
||||||
|
|
||||||
|
@ -17,30 +17,22 @@ namespace Kernel::ACPI::AML
|
||||||
, value(value)
|
, value(value)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Buffer> as_buffer() override;
|
BAN::RefPtr<AML::Node> convert(uint8_t mask) override
|
||||||
BAN::RefPtr<AML::Integer> as_integer() override;
|
|
||||||
BAN::RefPtr<AML::String> as_string() override;
|
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> evaluate() override
|
|
||||||
{
|
{
|
||||||
if (value)
|
if (!value)
|
||||||
return value->evaluate();
|
{
|
||||||
return {};
|
AML_ERROR("Trying to convert null Register");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return value->convert(mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool store(BAN::RefPtr<AML::Node> source) override
|
BAN::RefPtr<AML::Node> store(BAN::RefPtr<AML::Node> source) override
|
||||||
{
|
{
|
||||||
if (value && value->type == AML::Node::Type::Reference)
|
if (value && value->type == AML::Node::Type::Reference)
|
||||||
return value->store(source);
|
return value->store(source);
|
||||||
|
value = source->copy();
|
||||||
auto evaluated = source->evaluate();
|
return value;
|
||||||
if (!evaluated)
|
|
||||||
{
|
|
||||||
AML_ERROR("Failed to evaluate source for store");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
value = evaluated->copy();
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void debug_print(int indent) const override
|
void debug_print(int indent) const override
|
||||||
|
|
|
@ -21,30 +21,34 @@ namespace Kernel::ACPI::AML
|
||||||
auto object_result = AML::parse_object(context);
|
auto object_result = AML::parse_object(context);
|
||||||
if (!object_result.success())
|
if (!object_result.success())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
auto object = object_result.node()->evaluate();
|
auto object_node = object_result.node();
|
||||||
if (object && object->type == AML::Node::Type::Reference)
|
if (!object_node)
|
||||||
object = static_cast<AML::Reference*>(object.ptr())->node->evaluate();
|
|
||||||
if (!object)
|
|
||||||
{
|
{
|
||||||
AML_ERROR("SizeOf object is null");
|
AML_ERROR("SizeOf object is null");
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
|
if (object_node->type != AML::Node::Type::Package)
|
||||||
|
object_node = object_node->convert(AML::Node::ConvBuffer | AML::Node::ConvString);
|
||||||
|
if (!object_node)
|
||||||
|
{
|
||||||
|
AML_ERROR("SizeOf object is not Buffer, String or Package");
|
||||||
|
return ParseResult::Failure;
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t size = 0;
|
uint64_t size = 0;
|
||||||
switch (object->type)
|
switch (object_node->type)
|
||||||
{
|
{
|
||||||
case AML::Node::Type::Buffer:
|
case AML::Node::Type::Buffer:
|
||||||
size = static_cast<AML::Buffer*>(object.ptr())->buffer.size();
|
size = static_cast<AML::Buffer*>(object_node.ptr())->buffer.size();
|
||||||
break;
|
break;
|
||||||
case AML::Node::Type::String:
|
case AML::Node::Type::String:
|
||||||
size = static_cast<AML::String*>(object.ptr())->string.size();
|
size = static_cast<AML::String*>(object_node.ptr())->string.size();
|
||||||
break;
|
break;
|
||||||
case AML::Node::Type::Package:
|
case AML::Node::Type::Package:
|
||||||
size = static_cast<AML::Package*>(object.ptr())->elements.size();
|
size = static_cast<AML::Package*>(object_node.ptr())->elements.size();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
AML_ERROR("SizeOf object is not a buffer, string or package ({})", static_cast<uint8_t>(object->type));
|
ASSERT_NOT_REACHED();
|
||||||
return ParseResult::Failure;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ParseResult(MUST(BAN::RefPtr<Integer>::create(size)));
|
return ParseResult(MUST(BAN::RefPtr<Integer>::create(size)));
|
||||||
|
|
|
@ -19,18 +19,22 @@ namespace Kernel::ACPI::AML
|
||||||
auto sleep_time_result = AML::parse_object(context);
|
auto sleep_time_result = AML::parse_object(context);
|
||||||
if (!sleep_time_result.success())
|
if (!sleep_time_result.success())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
auto sleep_time = sleep_time_result.node() ? sleep_time_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
|
auto sleep_time_node = sleep_time_result.node()
|
||||||
if (!sleep_time)
|
? sleep_time_result.node()->convert(AML::Node::ConvInteger)
|
||||||
|
: BAN::RefPtr<AML::Node>();
|
||||||
|
if (!sleep_time_node)
|
||||||
{
|
{
|
||||||
AML_ERROR("Sleep time cannot be evaluated to an integer");
|
AML_ERROR("Sleep time cannot be evaluated to an integer");
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto sleep_time_value = static_cast<AML::Integer*>(sleep_time_node.ptr())->value;
|
||||||
|
|
||||||
#if AML_DEBUG_LEVEL >= 2
|
#if AML_DEBUG_LEVEL >= 2
|
||||||
AML_DEBUG_PRINTLN("Sleeping for {} ms", sleep_time->value);
|
AML_DEBUG_PRINTLN("Sleeping for {} ms", sleep_time_value);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SystemTimer::get().sleep_ms(sleep_time->value);
|
SystemTimer::get().sleep_ms(sleep_time_value);
|
||||||
return ParseResult::Success;
|
return ParseResult::Success;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,10 +17,10 @@ namespace Kernel::ACPI::AML
|
||||||
auto source_result = AML::parse_object(context);
|
auto source_result = AML::parse_object(context);
|
||||||
if (!source_result.success())
|
if (!source_result.success())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
auto source = source_result.node() ? source_result.node()->evaluate() : BAN::RefPtr<AML::Node>();
|
auto source = source_result.node();
|
||||||
if (!source)
|
if (!source)
|
||||||
{
|
{
|
||||||
AML_ERROR("Store source cannot be evaluated");
|
AML_ERROR("Store source is null");
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
namespace Kernel::ACPI::AML
|
namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
|
|
||||||
struct String : public AML::Node
|
struct String final : public AML::Node
|
||||||
{
|
{
|
||||||
BAN::Vector<uint8_t> string;
|
BAN::Vector<uint8_t> string;
|
||||||
|
|
||||||
|
@ -22,12 +22,7 @@ namespace Kernel::ACPI::AML
|
||||||
|
|
||||||
BAN::Optional<bool> logical_compare(BAN::RefPtr<AML::Node> node, AML::Byte binaryop);
|
BAN::Optional<bool> logical_compare(BAN::RefPtr<AML::Node> node, AML::Byte binaryop);
|
||||||
|
|
||||||
BAN::RefPtr<AML::Buffer> as_buffer() override;
|
BAN::RefPtr<AML::Node> convert(uint8_t mask) override;
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> evaluate() override
|
|
||||||
{
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::StringView string_view() const
|
BAN::StringView string_view() const
|
||||||
{
|
{
|
||||||
|
@ -41,6 +36,9 @@ namespace Kernel::ACPI::AML
|
||||||
AML_DEBUG_PRINT_INDENT(indent);
|
AML_DEBUG_PRINT_INDENT(indent);
|
||||||
AML_DEBUG_PRINT("String \"{}\"", string_view());
|
AML_DEBUG_PRINT("String \"{}\"", string_view());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
BAN::RefPtr<AML::Buffer> as_buffer();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,12 +9,14 @@
|
||||||
namespace Kernel::ACPI::AML
|
namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
|
|
||||||
struct ThermalZone : public AML::Scope
|
struct ThermalZone final : public AML::Scope
|
||||||
{
|
{
|
||||||
ThermalZone(NameSeg name)
|
ThermalZone(NameSeg name)
|
||||||
: Scope(Node::Type::ThermalZone, name)
|
: Scope(Node::Type::ThermalZone, name)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
BAN::RefPtr<AML::Node> convert(uint8_t) override { return {}; }
|
||||||
|
|
||||||
static ParseResult parse(ParseContext& context)
|
static ParseResult parse(ParseContext& context)
|
||||||
{
|
{
|
||||||
ASSERT(context.aml_data.size() >= 2);
|
ASSERT(context.aml_data.size() >= 2);
|
||||||
|
|
|
@ -29,14 +29,16 @@ namespace Kernel::ACPI::AML
|
||||||
auto predicate_result = AML::parse_object(context);
|
auto predicate_result = AML::parse_object(context);
|
||||||
if (!predicate_result.success())
|
if (!predicate_result.success())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
auto predicate = predicate_result.node() ? predicate_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
|
auto predicate_node = predicate_result.node()
|
||||||
if (!predicate)
|
? predicate_result.node()->convert(AML::Node::ConvInteger)
|
||||||
|
: BAN::RefPtr<AML::Node>();
|
||||||
|
if (!predicate_node)
|
||||||
{
|
{
|
||||||
AML_ERROR("While predicate is not an integer");
|
AML_ERROR("While predicate is not an integer");
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!predicate->value)
|
if (!static_cast<AML::Integer*>(predicate_node.ptr())->value)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
while (context.aml_data.size() > 0)
|
while (context.aml_data.size() > 0)
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include <BAN/StringView.h>
|
#include <BAN/StringView.h>
|
||||||
#include <kernel/ACPI/ACPI.h>
|
#include <kernel/ACPI/ACPI.h>
|
||||||
#include <kernel/ACPI/AML.h>
|
#include <kernel/ACPI/AML.h>
|
||||||
|
#include <kernel/ACPI/AML/Alias.h>
|
||||||
#include <kernel/ACPI/AML/Device.h>
|
#include <kernel/ACPI/AML/Device.h>
|
||||||
#include <kernel/ACPI/AML/Field.h>
|
#include <kernel/ACPI/AML/Field.h>
|
||||||
#include <kernel/ACPI/AML/Integer.h>
|
#include <kernel/ACPI/AML/Integer.h>
|
||||||
|
@ -144,10 +145,10 @@ acpi_release_global_lock:
|
||||||
auto field_element = MUST(BAN::RefPtr<AML::FieldElement>::create(""_sv, register_bit_offset, register_bit_width, field_rules));
|
auto field_element = MUST(BAN::RefPtr<AML::FieldElement>::create(""_sv, register_bit_offset, register_bit_width, field_rules));
|
||||||
field_element->op_region = op_region;
|
field_element->op_region = op_region;
|
||||||
|
|
||||||
auto result = field_element->as_integer();
|
auto result = field_element->convert(AML::Node::ConvInteger);
|
||||||
if (!result)
|
if (!result)
|
||||||
return {};
|
return {};
|
||||||
return result->value;
|
return static_cast<AML::Integer*>(result.ptr())->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GAS::write(uint64_t value)
|
bool GAS::write(uint64_t value)
|
||||||
|
@ -168,7 +169,7 @@ acpi_release_global_lock:
|
||||||
auto field_element = MUST(BAN::RefPtr<AML::FieldElement>::create(""_sv, register_bit_offset, register_bit_width, field_rules));
|
auto field_element = MUST(BAN::RefPtr<AML::FieldElement>::create(""_sv, register_bit_offset, register_bit_width, field_rules));
|
||||||
field_element->op_region = op_region;
|
field_element->op_region = op_region;
|
||||||
|
|
||||||
return field_element->store(MUST(BAN::RefPtr<AML::Integer>::create(value)));
|
return !!field_element->store(MUST(BAN::RefPtr<AML::Integer>::create(value)));
|
||||||
}
|
}
|
||||||
|
|
||||||
enum PM1Event : uint16_t
|
enum PM1Event : uint16_t
|
||||||
|
@ -494,7 +495,25 @@ acpi_release_global_lock:
|
||||||
dwarnln("\\_S5 not found");
|
dwarnln("\\_S5 not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto s5_evaluated = s5_object->evaluate();
|
BAN::RefPtr<AML::Node> s5_evaluated = s5_object;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
bool done = false;
|
||||||
|
switch (s5_evaluated->type)
|
||||||
|
{
|
||||||
|
case AML::Node::Type::Alias:
|
||||||
|
s5_evaluated = static_cast<AML::Alias*>(s5_evaluated.ptr())->target;
|
||||||
|
break;
|
||||||
|
case AML::Node::Type::Name:
|
||||||
|
s5_evaluated = static_cast<AML::Name*>(s5_evaluated.ptr())->object;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
done = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (done)
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (!s5_evaluated)
|
if (!s5_evaluated)
|
||||||
{
|
{
|
||||||
dwarnln("Failed to evaluate \\_S5");
|
dwarnln("Failed to evaluate \\_S5");
|
||||||
|
@ -512,9 +531,9 @@ acpi_release_global_lock:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto slp_typa = s5_package->elements[0]->as_integer();
|
auto slp_typa_node = s5_package->elements[0]->convert(AML::Node::ConvInteger);
|
||||||
auto slp_typb = s5_package->elements[1]->as_integer();
|
auto slp_typb_node = s5_package->elements[1]->convert(AML::Node::ConvInteger);
|
||||||
if (!slp_typa || !slp_typb)
|
if (!slp_typa_node || !slp_typb_node)
|
||||||
{
|
{
|
||||||
dwarnln("Failed to get SLP_TYPx values");
|
dwarnln("Failed to get SLP_TYPx values");
|
||||||
return;
|
return;
|
||||||
|
@ -525,9 +544,12 @@ acpi_release_global_lock:
|
||||||
|
|
||||||
dprintln("Entering sleep state S5");
|
dprintln("Entering sleep state S5");
|
||||||
|
|
||||||
|
const auto slp_typa_value = static_cast<AML::Integer*>(slp_typa_node.ptr())->value;
|
||||||
|
const auto slp_typb_value = static_cast<AML::Integer*>(slp_typb_node.ptr())->value;
|
||||||
|
|
||||||
uint16_t pm1a_data = IO::inw(fadt().pm1a_cnt_blk);
|
uint16_t pm1a_data = IO::inw(fadt().pm1a_cnt_blk);
|
||||||
pm1a_data &= ~(PM1_CNT_SLP_TYP_MASK << PM1_CNT_SLP_TYP_SHIFT);
|
pm1a_data &= ~(PM1_CNT_SLP_TYP_MASK << PM1_CNT_SLP_TYP_SHIFT);
|
||||||
pm1a_data |= (slp_typa->value & PM1_CNT_SLP_TYP_MASK) << PM1_CNT_SLP_TYP_SHIFT;
|
pm1a_data |= (slp_typa_value & PM1_CNT_SLP_TYP_MASK) << PM1_CNT_SLP_TYP_SHIFT;
|
||||||
pm1a_data |= PM1_CNT_SLP_EN;
|
pm1a_data |= PM1_CNT_SLP_EN;
|
||||||
IO::outw(fadt().pm1a_cnt_blk, pm1a_data);
|
IO::outw(fadt().pm1a_cnt_blk, pm1a_data);
|
||||||
|
|
||||||
|
@ -535,7 +557,7 @@ acpi_release_global_lock:
|
||||||
{
|
{
|
||||||
uint16_t pm1b_data = IO::inw(fadt().pm1b_cnt_blk);
|
uint16_t pm1b_data = IO::inw(fadt().pm1b_cnt_blk);
|
||||||
pm1b_data &= ~(PM1_CNT_SLP_TYP_MASK << PM1_CNT_SLP_TYP_SHIFT);
|
pm1b_data &= ~(PM1_CNT_SLP_TYP_MASK << PM1_CNT_SLP_TYP_SHIFT);
|
||||||
pm1b_data |= (slp_typb->value & PM1_CNT_SLP_TYP_MASK) << PM1_CNT_SLP_TYP_SHIFT;
|
pm1b_data |= (slp_typb_value & PM1_CNT_SLP_TYP_MASK) << PM1_CNT_SLP_TYP_SHIFT;
|
||||||
pm1b_data |= PM1_CNT_SLP_EN;
|
pm1b_data |= PM1_CNT_SLP_EN;
|
||||||
IO::outw(fadt().pm1b_cnt_blk, pm1b_data);
|
IO::outw(fadt().pm1b_cnt_blk, pm1b_data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -492,13 +492,14 @@ namespace Kernel::ACPI
|
||||||
return MUST(BAN::RefPtr<Integer>::create(result.value()));
|
return MUST(BAN::RefPtr<Integer>::create(result.value()));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AML::FieldElement::store(BAN::RefPtr<AML::Node> source)
|
BAN::RefPtr<AML::Node> AML::FieldElement::store(BAN::RefPtr<AML::Node> source)
|
||||||
{
|
{
|
||||||
auto source_integer = source->as_integer();
|
ASSERT(source);
|
||||||
|
auto source_integer = source->convert(AML::Node::ConvInteger);
|
||||||
if (!source_integer)
|
if (!source_integer)
|
||||||
{
|
{
|
||||||
AML_TODO("FieldElement store with non-integer source, type {}", static_cast<uint8_t>(source->type));
|
AML_TODO("FieldElement store with non-integer source, type {}", static_cast<uint8_t>(source->type));
|
||||||
return false;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
op_region->mutex.lock();
|
op_region->mutex.lock();
|
||||||
|
@ -510,7 +511,9 @@ namespace Kernel::ACPI
|
||||||
ACPI::release_global_lock();
|
ACPI::release_global_lock();
|
||||||
});
|
});
|
||||||
|
|
||||||
return store_internal(source_integer->value);
|
if (!store_internal(static_cast<AML::Integer*>(source_integer.ptr())->value))
|
||||||
|
return {};
|
||||||
|
return source_integer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AML::FieldElement::debug_print(int indent) const
|
void AML::FieldElement::debug_print(int indent) const
|
||||||
|
@ -626,28 +629,30 @@ namespace Kernel::ACPI
|
||||||
return MUST(BAN::RefPtr<Integer>::create(result.value()));
|
return MUST(BAN::RefPtr<Integer>::create(result.value()));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AML::IndexFieldElement::store(BAN::RefPtr<Node> source)
|
BAN::RefPtr<AML::Node> AML::IndexFieldElement::store(BAN::RefPtr<Node> source)
|
||||||
{
|
{
|
||||||
if (access_rules.access_attrib != FieldRules::AccessAttrib::Normal)
|
if (access_rules.access_attrib != FieldRules::AccessAttrib::Normal)
|
||||||
{
|
{
|
||||||
AML_TODO("FieldElement with access attribute {}", static_cast<uint8_t>(access_rules.access_attrib));
|
AML_TODO("FieldElement with access attribute {}", static_cast<uint8_t>(access_rules.access_attrib));
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
auto source_integer = source->as_integer();
|
|
||||||
|
ASSERT(source);
|
||||||
|
auto source_integer = source->convert(AML::Node::ConvInteger);
|
||||||
if (!source_integer)
|
if (!source_integer)
|
||||||
{
|
{
|
||||||
AML_TODO("IndexFieldElement store with non-integer source, type {}", static_cast<uint8_t>(source->type));
|
AML_TODO("IndexFieldElement store with non-integer source, type {}", static_cast<uint8_t>(source->type));
|
||||||
return false;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto access_size = determine_access_size(access_rules.access_type);
|
auto access_size = determine_access_size(access_rules.access_type);
|
||||||
if (!access_size.has_value())
|
if (!access_size.has_value())
|
||||||
return false;
|
return {};
|
||||||
|
|
||||||
if (access_size.value() > data_element->bit_count)
|
if (access_size.value() > data_element->bit_count)
|
||||||
{
|
{
|
||||||
AML_ERROR("IndexFieldElement write_field with access size {} > data element bit count {}", access_size.value(), data_element->bit_count);
|
AML_ERROR("IndexFieldElement write_field with access size {} > data element bit count {}", access_size.value(), data_element->bit_count);
|
||||||
return false;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto read_func = [&](uint64_t byte_offset) -> BAN::Optional<uint64_t> {
|
auto read_func = [&](uint64_t byte_offset) -> BAN::Optional<uint64_t> {
|
||||||
|
@ -657,7 +662,7 @@ namespace Kernel::ACPI
|
||||||
};
|
};
|
||||||
auto write_func = [&](uint64_t byte_offset, uint64_t value) -> bool {
|
auto write_func = [&](uint64_t byte_offset, uint64_t value) -> bool {
|
||||||
if (!index_element->store_internal(byte_offset))
|
if (!index_element->store_internal(byte_offset))
|
||||||
return false;
|
return {};
|
||||||
return data_element->store_internal(value);
|
return data_element->store_internal(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -670,10 +675,10 @@ namespace Kernel::ACPI
|
||||||
ACPI::release_global_lock();
|
ACPI::release_global_lock();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!perform_write_general(0, bit_count, bit_offset, access_size.value(), source_integer->value, access_rules.update_rule, read_func, write_func))
|
const auto source_value = static_cast<AML::Integer*>(source_integer.ptr())->value;
|
||||||
return false;
|
if (!perform_write_general(0, bit_count, bit_offset, access_size.value(), source_value, access_rules.update_rule, read_func, write_func))
|
||||||
|
return {};
|
||||||
return true;
|
return source_integer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AML::IndexFieldElement::debug_print(int indent) const
|
void AML::IndexFieldElement::debug_print(int indent) const
|
||||||
|
@ -734,8 +739,8 @@ namespace Kernel::ACPI
|
||||||
context.aml_data = temp_aml_data;
|
context.aml_data = temp_aml_data;
|
||||||
if (!bank_value_result.success())
|
if (!bank_value_result.success())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
auto bank_value = bank_value_result.node() ? bank_value_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
|
auto bank_value_node = bank_value_result.node() ? bank_value_result.node()->convert(AML::Node::ConvInteger) : BAN::RefPtr<AML::Node>();
|
||||||
if (!bank_value)
|
if (!bank_value_node)
|
||||||
{
|
{
|
||||||
AML_ERROR("BankField BankValue is not an integer");
|
AML_ERROR("BankField BankValue is not an integer");
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
|
@ -756,11 +761,12 @@ namespace Kernel::ACPI
|
||||||
if (!parse_field_element(field_context))
|
if (!parse_field_element(field_context))
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
|
|
||||||
|
const auto bank_value = static_cast<AML::Integer*>(bank_value_node.ptr())->value;
|
||||||
for (auto& [_, element] : field_context.elements)
|
for (auto& [_, element] : field_context.elements)
|
||||||
{
|
{
|
||||||
element->op_region = static_cast<OpRegion*>(op_region.ptr());
|
element->op_region = static_cast<OpRegion*>(op_region.ptr());
|
||||||
element->bank_selector = static_cast<FieldElement*>(bank_selector.ptr());
|
element->bank_selector = static_cast<FieldElement*>(bank_selector.ptr());
|
||||||
element->bank_value = bank_value->value;
|
element->bank_value = bank_value;
|
||||||
|
|
||||||
NameString element_name;
|
NameString element_name;
|
||||||
MUST(element_name.path.push_back(element->name));
|
MUST(element_name.path.push_back(element->name));
|
||||||
|
@ -776,7 +782,7 @@ namespace Kernel::ACPI
|
||||||
return ParseResult::Success;
|
return ParseResult::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> AML::BankFieldElement::evaluate()
|
BAN::RefPtr<AML::Integer> AML::BankFieldElement::as_integer()
|
||||||
{
|
{
|
||||||
if (access_rules.access_attrib != FieldRules::AccessAttrib::Normal)
|
if (access_rules.access_attrib != FieldRules::AccessAttrib::Normal)
|
||||||
{
|
{
|
||||||
|
@ -812,7 +818,7 @@ namespace Kernel::ACPI
|
||||||
return MUST(BAN::RefPtr<Integer>::create(result.value()));
|
return MUST(BAN::RefPtr<Integer>::create(result.value()));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AML::BankFieldElement::store(BAN::RefPtr<AML::Node> source)
|
BAN::RefPtr<AML::Node> AML::BankFieldElement::store(BAN::RefPtr<AML::Node> source)
|
||||||
{
|
{
|
||||||
if (access_rules.access_attrib != FieldRules::AccessAttrib::Normal)
|
if (access_rules.access_attrib != FieldRules::AccessAttrib::Normal)
|
||||||
{
|
{
|
||||||
|
@ -820,16 +826,17 @@ namespace Kernel::ACPI
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto source_integer = source->as_integer();
|
ASSERT(source);
|
||||||
|
auto source_integer = source->convert(AML::Node::ConvInteger);
|
||||||
if (!source_integer)
|
if (!source_integer)
|
||||||
{
|
{
|
||||||
AML_TODO("BankFieldElement store with non-integer source, type {}", static_cast<uint8_t>(source->type));
|
AML_TODO("BankFieldElement store with non-integer source, type {}", static_cast<uint8_t>(source->type));
|
||||||
return false;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto access_size = determine_access_size(access_rules.access_type);
|
auto access_size = determine_access_size(access_rules.access_type);
|
||||||
if (!access_size.has_value())
|
if (!access_size.has_value())
|
||||||
return false;
|
return {};
|
||||||
auto read_func = [&](uint64_t byte_offset) -> BAN::Optional<uint64_t> {
|
auto read_func = [&](uint64_t byte_offset) -> BAN::Optional<uint64_t> {
|
||||||
return perform_read(op_region->region_space, byte_offset, access_size.value());
|
return perform_read(op_region->region_space, byte_offset, access_size.value());
|
||||||
};
|
};
|
||||||
|
@ -852,7 +859,10 @@ namespace Kernel::ACPI
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
return perform_write_general(op_region->region_offset, bit_count, bit_offset, access_size.value(), source_integer->value, access_rules.update_rule, read_func, write_func);
|
const auto source_value = static_cast<AML::Integer*>(source_integer.ptr())->value;
|
||||||
|
if (!perform_write_general(op_region->region_offset, bit_count, bit_offset, access_size.value(), source_value, access_rules.update_rule, read_func, write_func))
|
||||||
|
return {};
|
||||||
|
return source_integer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AML::BankFieldElement::debug_print(int indent) const
|
void AML::BankFieldElement::debug_print(int indent) const
|
||||||
|
|
|
@ -7,24 +7,6 @@
|
||||||
namespace Kernel::ACPI
|
namespace Kernel::ACPI
|
||||||
{
|
{
|
||||||
|
|
||||||
BAN::RefPtr<AML::Buffer> AML::Name::as_buffer()
|
|
||||||
{
|
|
||||||
ASSERT(object);
|
|
||||||
return object->as_buffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::RefPtr<AML::Integer> AML::Name::as_integer()
|
|
||||||
{
|
|
||||||
ASSERT(object);
|
|
||||||
return object->as_integer();
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::RefPtr<AML::String> AML::Name::as_string()
|
|
||||||
{
|
|
||||||
ASSERT(object);
|
|
||||||
return object->as_string();
|
|
||||||
}
|
|
||||||
|
|
||||||
AML::ParseResult AML::Name::parse(ParseContext& context)
|
AML::ParseResult AML::Name::parse(ParseContext& context)
|
||||||
{
|
{
|
||||||
ASSERT(context.aml_data.size() >= 1);
|
ASSERT(context.aml_data.size() >= 1);
|
||||||
|
|
|
@ -20,11 +20,12 @@ namespace Kernel::ACPI
|
||||||
struct DebugNode : AML::Node
|
struct DebugNode : AML::Node
|
||||||
{
|
{
|
||||||
DebugNode() : AML::Node(AML::Node::Type::Debug) {}
|
DebugNode() : AML::Node(AML::Node::Type::Debug) {}
|
||||||
bool store(BAN::RefPtr<AML::Node> node)
|
BAN::RefPtr<AML::Node> convert(uint8_t) override { return {}; }
|
||||||
|
BAN::RefPtr<AML::Node> store(BAN::RefPtr<AML::Node> node)
|
||||||
{
|
{
|
||||||
node->debug_print(0);
|
node->debug_print(0);
|
||||||
AML_DEBUG_PRINTLN("");
|
AML_DEBUG_PRINTLN("");
|
||||||
return true;
|
return node;
|
||||||
}
|
}
|
||||||
void debug_print(int indent) const override
|
void debug_print(int indent) const override
|
||||||
{
|
{
|
||||||
|
@ -236,7 +237,7 @@ namespace Kernel::ACPI
|
||||||
auto osi = MUST(BAN::RefPtr<AML::Method>::create(NameSeg("_OSI"_sv), 1, false, 0));
|
auto osi = MUST(BAN::RefPtr<AML::Method>::create(NameSeg("_OSI"_sv), 1, false, 0));
|
||||||
osi->override_function = [](AML::ParseContext& context) -> BAN::RefPtr<AML::Node> {
|
osi->override_function = [](AML::ParseContext& context) -> BAN::RefPtr<AML::Node> {
|
||||||
ASSERT(context.method_args[0]);
|
ASSERT(context.method_args[0]);
|
||||||
auto arg = context.method_args[0]->evaluate();
|
auto arg = context.method_args[0]->convert(AML::Node::ConvString);
|
||||||
if (!arg || arg->type != AML::Node::Type::String)
|
if (!arg || arg->type != AML::Node::Type::String)
|
||||||
{
|
{
|
||||||
AML_ERROR("Invalid _OSI argument");
|
AML_ERROR("Invalid _OSI argument");
|
||||||
|
|
|
@ -36,24 +36,6 @@ namespace Kernel::ACPI
|
||||||
|
|
||||||
uint64_t AML::Node::total_node_count = 0;
|
uint64_t AML::Node::total_node_count = 0;
|
||||||
|
|
||||||
BAN::RefPtr<AML::Buffer> AML::Node::as_buffer()
|
|
||||||
{
|
|
||||||
AML_TODO("Node type {} to buffer", static_cast<uint32_t>(type));
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::RefPtr<AML::Integer> AML::Node::as_integer()
|
|
||||||
{
|
|
||||||
AML_TODO("Node type {} to integer", static_cast<uint32_t>(type));
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::RefPtr<AML::String> AML::Node::as_string()
|
|
||||||
{
|
|
||||||
AML_TODO("Node type {} to string", static_cast<uint32_t>(type));
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
AML::ParseResult AML::parse_object(AML::ParseContext& context)
|
AML::ParseResult AML::parse_object(AML::ParseContext& context)
|
||||||
{
|
{
|
||||||
if (context.aml_data.size() < 1)
|
if (context.aml_data.size() < 1)
|
||||||
|
@ -204,6 +186,7 @@ namespace Kernel::ACPI
|
||||||
return AML::Notify::parse(context);
|
return AML::Notify::parse(context);
|
||||||
case AML::Byte::SizeOfOp:
|
case AML::Byte::SizeOfOp:
|
||||||
return AML::SizeOf::parse(context);
|
return AML::SizeOf::parse(context);
|
||||||
|
case AML::Byte::BreakPointOp: // TODO: support breakpoints?
|
||||||
case AML::Byte::NoopOp:
|
case AML::Byte::NoopOp:
|
||||||
context.aml_data = context.aml_data.slice(1);
|
context.aml_data = context.aml_data.slice(1);
|
||||||
return ParseResult::Success;
|
return ParseResult::Success;
|
||||||
|
@ -269,6 +252,9 @@ namespace Kernel::ACPI
|
||||||
return ParseResult::Success;
|
return ParseResult::Success;
|
||||||
return ParseResult(result.value());
|
return ParseResult(result.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (aml_object->type == AML::Node::Type::Name)
|
||||||
|
return ParseResult(static_cast<AML::Name*>(aml_object.ptr())->object);
|
||||||
return ParseResult(aml_object);
|
return ParseResult(aml_object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
#include <kernel/ACPI/AML/Buffer.h>
|
|
||||||
#include <kernel/ACPI/AML/Integer.h>
|
|
||||||
#include <kernel/ACPI/AML/Register.h>
|
|
||||||
#include <kernel/ACPI/AML/String.h>
|
|
||||||
|
|
||||||
namespace Kernel::ACPI::AML
|
|
||||||
{
|
|
||||||
|
|
||||||
BAN::RefPtr<AML::Buffer> Register::as_buffer()
|
|
||||||
{
|
|
||||||
if (value)
|
|
||||||
return value->as_buffer();
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::RefPtr<AML::Integer> Register::as_integer()
|
|
||||||
{
|
|
||||||
if (value)
|
|
||||||
return value->as_integer();
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::RefPtr<AML::String> Register::as_string()
|
|
||||||
{
|
|
||||||
if (value)
|
|
||||||
return value->as_string();
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -25,7 +25,7 @@ namespace Kernel::ACPI
|
||||||
auto named_object = Namespace::root_namespace()->find_object(context.scope, name_string.value(), Namespace::FindMode::Normal);
|
auto named_object = Namespace::root_namespace()->find_object(context.scope, name_string.value(), Namespace::FindMode::Normal);
|
||||||
if (!named_object)
|
if (!named_object)
|
||||||
{
|
{
|
||||||
AML_DEBUG_PRINT("Scope '{}' not found in namespace", name_string.value());
|
AML_PRINT("Scope '{}' not found in namespace", name_string.value());
|
||||||
return ParseResult::Success;
|
return ParseResult::Success;
|
||||||
}
|
}
|
||||||
if (!named_object->is_scope())
|
if (!named_object->is_scope())
|
||||||
|
@ -69,7 +69,12 @@ namespace Kernel::ACPI
|
||||||
static BAN::RefPtr<AML::Integer> evaluate_or_invoke(BAN::RefPtr<AML::Node> object)
|
static BAN::RefPtr<AML::Integer> evaluate_or_invoke(BAN::RefPtr<AML::Node> object)
|
||||||
{
|
{
|
||||||
if (object->type != AML::Node::Type::Method)
|
if (object->type != AML::Node::Type::Method)
|
||||||
return object->as_integer();
|
{
|
||||||
|
auto converted = object->convert(AML::Node::ConvInteger);
|
||||||
|
if (!converted)
|
||||||
|
return {};
|
||||||
|
return static_cast<AML::Integer*>(converted.ptr());
|
||||||
|
}
|
||||||
|
|
||||||
auto* method = static_cast<AML::Method*>(object.ptr());
|
auto* method = static_cast<AML::Method*>(object.ptr());
|
||||||
if (method->arg_count != 0)
|
if (method->arg_count != 0)
|
||||||
|
@ -85,7 +90,10 @@ namespace Kernel::ACPI
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.value() ? result.value()->as_integer() : BAN::RefPtr<AML::Integer>();
|
auto result_integer = result.value()
|
||||||
|
? result.value()->convert(AML::Node::ConvInteger)
|
||||||
|
: BAN::RefPtr<AML::Node>();
|
||||||
|
return static_cast<AML::Integer*>(result_integer.ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AML::initialize_scope(BAN::RefPtr<AML::Scope> scope)
|
bool AML::initialize_scope(BAN::RefPtr<AML::Scope> scope)
|
||||||
|
|
|
@ -6,7 +6,7 @@ namespace Kernel::ACPI::AML
|
||||||
|
|
||||||
BAN::Optional<bool> String::logical_compare(BAN::RefPtr<AML::Node> node, AML::Byte binaryop)
|
BAN::Optional<bool> String::logical_compare(BAN::RefPtr<AML::Node> node, AML::Byte binaryop)
|
||||||
{
|
{
|
||||||
auto rhs = node ? node->as_string() : BAN::RefPtr<AML::String>();
|
auto rhs = node ? node->convert(AML::Node::ConvString) : BAN::RefPtr<AML::Node>();
|
||||||
if (!rhs)
|
if (!rhs)
|
||||||
{
|
{
|
||||||
AML_ERROR("String logical compare RHS is not string");
|
AML_ERROR("String logical compare RHS is not string");
|
||||||
|
@ -27,6 +27,20 @@ namespace Kernel::ACPI::AML
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BAN::RefPtr<AML::Node> String::convert(uint8_t mask)
|
||||||
|
{
|
||||||
|
if (mask & AML::Node::ConvString)
|
||||||
|
return this;
|
||||||
|
if (mask & AML::Node::ConvInteger)
|
||||||
|
{
|
||||||
|
AML_TODO("Convert String to Integer");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
if (mask & AML::Node::ConvBuffer)
|
||||||
|
return as_buffer();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
ParseResult String::parse(ParseContext& context)
|
ParseResult String::parse(ParseContext& context)
|
||||||
{
|
{
|
||||||
ASSERT(context.aml_data.size() >= 1);
|
ASSERT(context.aml_data.size() >= 1);
|
||||||
|
|
Loading…
Reference in New Issue