Kernel: Fix and cleanup a lot of AML code
Node now have APIs to convert them to buffer, integer and string. This allows possibility to handle methods that need explicitly use one of the overloads instead of integer. This patch also adds handling of DebugOp. This is used quite heavily in uACPIs test suite.
This commit is contained in:
parent
dd79db6383
commit
ec4cfdee23
|
@ -7,7 +7,9 @@ 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/APIC.cpp
|
kernel/APIC.cpp
|
||||||
kernel/BootInfo.cpp
|
kernel/BootInfo.cpp
|
||||||
kernel/CPUID.cpp
|
kernel/CPUID.cpp
|
||||||
|
|
|
@ -18,6 +18,30 @@ namespace Kernel::ACPI::AML
|
||||||
: AML::Node(Node::Type::Buffer)
|
: AML::Node(Node::Type::Buffer)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
BAN::Optional<bool> logical_compare(BAN::RefPtr<AML::Node> node, AML::Byte binaryop)
|
||||||
|
{
|
||||||
|
auto rhs = node ? node->as_buffer() : BAN::RefPtr<AML::Buffer>();
|
||||||
|
if (!rhs)
|
||||||
|
{
|
||||||
|
AML_ERROR("Buffer logical compare RHS is not buffer");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)binaryop;
|
||||||
|
AML_TODO("Logical compare buffer");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::RefPtr<AML::Buffer> as_buffer() override { return this; }
|
||||||
|
|
||||||
|
BAN::RefPtr<AML::Integer> as_integer() override
|
||||||
|
{
|
||||||
|
uint64_t value = 0;
|
||||||
|
for (size_t i = 0; i < BAN::Math::min<size_t>(buffer.size(), 8); i++)
|
||||||
|
value |= buffer[i] << (8 * i);
|
||||||
|
return MUST(BAN::RefPtr<Integer>::create(value));
|
||||||
|
}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> evaluate() override
|
BAN::RefPtr<AML::Node> evaluate() override
|
||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
|
@ -41,10 +65,10 @@ namespace Kernel::ACPI::AML
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
|
|
||||||
auto buffer_size = buffer_size_object.node()->as_integer();
|
auto buffer_size = buffer_size_object.node()->as_integer();
|
||||||
if (!buffer_size.has_value())
|
if (!buffer_size)
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
|
|
||||||
uint32_t actual_buffer_size = BAN::Math::max<uint32_t>(buffer_size.value(), buffer_context.aml_data.size());
|
uint32_t actual_buffer_size = BAN::Math::max<uint32_t>(buffer_size->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));
|
||||||
|
@ -80,6 +104,27 @@ namespace Kernel::ACPI::AML
|
||||||
, field_bit_size(field_bit_size)
|
, field_bit_size(field_bit_size)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
BAN::RefPtr<AML::Integer> as_integer() 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;
|
||||||
|
|
||||||
|
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 |= ((buffer[bit / 8] >> (bit % 8)) & 1) << i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MUST(BAN::RefPtr<Integer>::create(value));
|
||||||
|
}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> evaluate() override
|
BAN::RefPtr<AML::Node> evaluate() override
|
||||||
{
|
{
|
||||||
ASSERT(buffer);
|
ASSERT(buffer);
|
||||||
|
@ -111,7 +156,7 @@ namespace Kernel::ACPI::AML
|
||||||
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->as_integer();
|
||||||
if (!value.has_value())
|
if (!value)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// TODO: optimize for whole byte accesses
|
// TODO: optimize for whole byte accesses
|
||||||
|
@ -119,7 +164,7 @@ namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
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->value >> i) & 1) << (bit % 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -159,7 +204,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()->evaluate() : nullptr;
|
auto buffer_node = buffer_result.node() ? buffer_result.node()->as_buffer() : BAN::RefPtr<AML::Buffer>();
|
||||||
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");
|
||||||
|
@ -170,13 +215,13 @@ 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::Optional<uint64_t>();
|
auto index = index_result.node() ? index_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
|
||||||
if (!index.has_value())
|
if (!index)
|
||||||
{
|
{
|
||||||
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();
|
size_t field_bit_offset = index->value;
|
||||||
if (field_bit_size != 1)
|
if (field_bit_size != 1)
|
||||||
field_bit_offset *= 8;
|
field_bit_offset *= 8;
|
||||||
|
|
||||||
|
@ -185,13 +230,13 @@ namespace Kernel::ACPI::AML
|
||||||
auto bit_count_result = AML::parse_object(context);
|
auto bit_count_result = AML::parse_object(context);
|
||||||
if (!index_result.success())
|
if (!index_result.success())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
auto bit_count = bit_count_result.node() ? bit_count_result.node()->as_integer() : BAN::Optional<uint64_t>();
|
auto bit_count = bit_count_result.node() ? bit_count_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
|
||||||
if (!bit_count.has_value())
|
if (!bit_count)
|
||||||
{
|
{
|
||||||
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 = bit_count->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto field_name = AML::NameString::parse(context.aml_data);
|
auto field_name = AML::NameString::parse(context.aml_data);
|
||||||
|
|
|
@ -25,22 +25,21 @@ 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()->evaluate() : BAN::RefPtr<AML::Node>();
|
auto source_node = source_result.node() ? source_result.node()->as_integer(): BAN::RefPtr<AML::Integer>();
|
||||||
if (!source_node || source_node->type != AML::Node::Type::Integer)
|
if (!source_node)
|
||||||
{
|
{
|
||||||
AML_ERROR("UnaryOp source not integer");
|
AML_ERROR("UnaryOp source not integer");
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto source_integer = static_cast<AML::Integer*>(source_node.ptr());
|
if (source_node->constant)
|
||||||
if (source_integer->constant)
|
|
||||||
{
|
{
|
||||||
AML_ERROR("UnaryOp source is constant");
|
AML_ERROR("UnaryOp source is constant");
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
source_integer->value += (opcode == AML::Byte::AddOp) ? 1 : -1;
|
source_node->value += (opcode == AML::Byte::AddOp) ? 1 : -1;
|
||||||
return ParseResult(source_integer);
|
return ParseResult(source_node);
|
||||||
}
|
}
|
||||||
case AML::Byte::NotOp:
|
case AML::Byte::NotOp:
|
||||||
AML_TODO("NotOp", context.aml_data[0]);
|
AML_TODO("NotOp", context.aml_data[0]);
|
||||||
|
@ -53,14 +52,14 @@ namespace Kernel::ACPI::AML
|
||||||
if (!node_result.success())
|
if (!node_result.success())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
|
|
||||||
auto value = node_result.node() ? node_result.node()->as_integer() : BAN::Optional<uint64_t>();
|
auto value = node_result.node() ? node_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
|
||||||
if (!value.has_value())
|
if (!value)
|
||||||
{
|
{
|
||||||
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 = value->value ? Integer::Constants::Zero : Integer::Constants::Ones;
|
||||||
return ParseResult(result);
|
return ParseResult(result);
|
||||||
}
|
}
|
||||||
case AML::Byte::AddOp:
|
case AML::Byte::AddOp:
|
||||||
|
@ -98,8 +97,8 @@ 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::Optional<uint64_t>();
|
auto lhs_value = lhs_result.node() ? lhs_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
|
||||||
if (!lhs_value.has_value())
|
if (!lhs_value)
|
||||||
{
|
{
|
||||||
AML_ERROR("BinaryOP {2H} LHS not an integer", static_cast<uint8_t>(opcode));
|
AML_ERROR("BinaryOP {2H} LHS not an integer", static_cast<uint8_t>(opcode));
|
||||||
if (lhs_result.node())
|
if (lhs_result.node())
|
||||||
|
@ -111,8 +110,8 @@ namespace Kernel::ACPI::AML
|
||||||
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 = lhs_result.node() ? rhs_result.node()->as_integer() : BAN::Optional<uint64_t>();
|
auto rhs_value = rhs_result.node() ? rhs_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
|
||||||
if (!rhs_value.has_value())
|
if (!rhs_value)
|
||||||
{
|
{
|
||||||
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())
|
||||||
|
@ -160,7 +159,7 @@ namespace Kernel::ACPI::AML
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t result = func(lhs_value.value(), rhs_value.value());
|
uint64_t result = func(lhs_value->value, rhs_value->value);
|
||||||
auto result_node = MUST(BAN::RefPtr<AML::Integer>::create(result));
|
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))
|
||||||
|
@ -180,36 +179,37 @@ 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::Optional<uint64_t>();
|
auto lhs_node = lhs_result.node() ? lhs_result.node()->evaluate() : BAN::RefPtr<AML::Node>();
|
||||||
if (!lhs_value.has_value())
|
if (!lhs_node)
|
||||||
{
|
{
|
||||||
AML_TODO("Logical BinaryOP {2H} LHS not integer", static_cast<uint8_t>(opcode));
|
AML_TODO("Logical BinaryOP {2H} LHS evaluated to nothing", static_cast<uint8_t>(opcode));
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
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::Optional<uint64_t>();
|
|
||||||
if (!rhs_value.has_value())
|
|
||||||
{
|
|
||||||
AML_TODO("Logical BinaryOP {2H} RHS not integer", static_cast<uint8_t>(opcode));
|
|
||||||
return ParseResult::Failure;
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::RefPtr<AML::Integer> (*func)(uint64_t, uint64_t) = nullptr;
|
BAN::Optional<bool> result = false;
|
||||||
switch (opcode)
|
switch (lhs_node->type)
|
||||||
{
|
{
|
||||||
case AML::Byte::LAndOp: func = [](uint64_t a, uint64_t b) { return a && b ? Integer::Constants::Ones : Integer::Constants::Zero; }; break;
|
case AML::Node::Type::Integer:
|
||||||
case AML::Byte::LEqualOp: func = [](uint64_t a, uint64_t b) { return a == b ? Integer::Constants::Ones : Integer::Constants::Zero; }; break;
|
result = static_cast<AML::Integer*>(lhs_node.ptr())->logical_compare(rhs_result.node(), opcode);
|
||||||
case AML::Byte::LGreaterOp: func = [](uint64_t a, uint64_t b) { return a > b ? Integer::Constants::Ones : Integer::Constants::Zero; }; break;
|
break;
|
||||||
case AML::Byte::LLessOp: func = [](uint64_t a, uint64_t b) { return a < b ? Integer::Constants::Ones : Integer::Constants::Zero; }; break;
|
case AML::Node::Type::Buffer:
|
||||||
case AML::Byte::LOrOp: func = [](uint64_t a, uint64_t b) { return a || b ? Integer::Constants::Ones : Integer::Constants::Zero; }; break;
|
result = static_cast<AML::Buffer*>(lhs_node.ptr())->logical_compare(rhs_result.node(), opcode);
|
||||||
|
break;
|
||||||
|
case AML::Node::Type::String:
|
||||||
|
result = static_cast<AML::String*>(lhs_node.ptr())->logical_compare(rhs_result.node(), opcode);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ParseResult(func(lhs_value.value(), rhs_value.value()));
|
if (!result.has_value())
|
||||||
|
return ParseResult::Failure;
|
||||||
|
|
||||||
|
return ParseResult(result.value() ? AML::Integer::Constants::Ones : AML::Integer::Constants::Zero);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,9 @@ namespace Kernel::ACPI::AML
|
||||||
, access_rules(access_rules)
|
, access_rules(access_rules)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
BAN::RefPtr<Node> evaluate() override;
|
BAN::RefPtr<AML::Integer> as_integer() override;
|
||||||
|
|
||||||
|
BAN::RefPtr<Node> evaluate() override { return as_integer(); }
|
||||||
bool 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;
|
||||||
|
@ -98,7 +100,9 @@ namespace Kernel::ACPI::AML
|
||||||
, access_rules(access_rules)
|
, access_rules(access_rules)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
BAN::RefPtr<Node> evaluate() override;
|
BAN::RefPtr<AML::Integer> as_integer() override;
|
||||||
|
|
||||||
|
BAN::RefPtr<AML::Node> evaluate() override { return as_integer(); }
|
||||||
bool 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;
|
||||||
|
|
|
@ -26,8 +26,8 @@ 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::Optional<uint64_t>();
|
auto predicate = predicate_result.node() ? predicate_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
|
||||||
if (!predicate.has_value())
|
if (!predicate)
|
||||||
{
|
{
|
||||||
AML_ERROR("If predicate is not an integer");
|
AML_ERROR("If predicate is not an integer");
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
|
@ -43,7 +43,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())
|
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)
|
||||||
|
|
|
@ -30,8 +30,8 @@ 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::Optional<uint64_t>();
|
auto index = index_result.node() ? index_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
|
||||||
if (!index.has_value())
|
if (!index)
|
||||||
{
|
{
|
||||||
AML_ERROR("IndexOp index is not an integer");
|
AML_ERROR("IndexOp index is not an integer");
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
|
@ -43,36 +43,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->value >= 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->value * 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->value >= 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->value];
|
||||||
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->value >= 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->value * 8, 8));
|
||||||
result = MUST(BAN::RefPtr<AML::Reference>::create(buffer_field));
|
result = MUST(BAN::RefPtr<AML::Reference>::create(buffer_field));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,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->value);
|
||||||
source->debug_print(0);
|
source->debug_print(0);
|
||||||
AML_DEBUG_PRINTLN("");
|
AML_DEBUG_PRINTLN("");
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -30,6 +30,29 @@ namespace Kernel::ACPI::AML
|
||||||
, constant(constant)
|
, constant(constant)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
BAN::Optional<bool> logical_compare(BAN::RefPtr<AML::Node> node, AML::Byte binaryop)
|
||||||
|
{
|
||||||
|
auto rhs = node ? node->as_integer() : BAN::RefPtr<AML::Integer>();
|
||||||
|
if (!rhs)
|
||||||
|
{
|
||||||
|
AML_ERROR("Integer logical compare RHS is not integer");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (binaryop)
|
||||||
|
{
|
||||||
|
case AML::Byte::LAndOp: return value && rhs->value;
|
||||||
|
case AML::Byte::LEqualOp: return value == rhs->value;
|
||||||
|
case AML::Byte::LGreaterOp: return value > rhs->value;
|
||||||
|
case AML::Byte::LLessOp: return value < rhs->value;
|
||||||
|
case AML::Byte::LOrOp: return value || rhs->value;
|
||||||
|
default:
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::RefPtr<AML::Integer> as_integer() override { return this; }
|
||||||
|
|
||||||
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> evaluate() override
|
||||||
|
@ -45,12 +68,12 @@ namespace Kernel::ACPI::AML
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto store_value = store_node->as_integer();
|
auto store_value = store_node->as_integer();
|
||||||
if (!store_value.has_value())
|
if (!store_value)
|
||||||
{
|
{
|
||||||
AML_ERROR("Cannot store non-integer to integer");
|
AML_ERROR("Cannot store non-integer to integer");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
value = store_value.value();
|
value = store_value->value;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ namespace Kernel::ACPI::AML
|
||||||
method_flags >> 4
|
method_flags >> 4
|
||||||
));
|
));
|
||||||
if (!Namespace::root_namespace()->add_named_object(context, name_string.value(), method))
|
if (!Namespace::root_namespace()->add_named_object(context, name_string.value(), method))
|
||||||
return ParseResult::Failure;
|
return ParseResult::Success;
|
||||||
method->term_list = method_pkg.value();
|
method->term_list = method_pkg.value();
|
||||||
|
|
||||||
#if AML_DEBUG_LEVEL >= 2
|
#if AML_DEBUG_LEVEL >= 2
|
||||||
|
@ -142,6 +142,9 @@ namespace Kernel::ACPI::AML
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (return_value.has_value() && return_value.value())
|
||||||
|
return_value = return_value.value()->evaluate();
|
||||||
|
|
||||||
while (!context.created_objects.empty())
|
while (!context.created_objects.empty())
|
||||||
{
|
{
|
||||||
Namespace::root_namespace()->remove_named_object(context.created_objects.back());
|
Namespace::root_namespace()->remove_named_object(context.created_objects.back());
|
||||||
|
|
|
@ -22,6 +22,10 @@ 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::Integer> as_integer() override;
|
||||||
|
BAN::RefPtr<AML::String> as_string() override;
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> evaluate() override
|
BAN::RefPtr<AML::Node> evaluate() override
|
||||||
{
|
{
|
||||||
ASSERT(object);
|
ASSERT(object);
|
||||||
|
|
|
@ -11,6 +11,7 @@ namespace Kernel::ACPI::AML
|
||||||
struct Namespace : public AML::Scope
|
struct Namespace : public AML::Scope
|
||||||
{
|
{
|
||||||
static BAN::RefPtr<AML::Namespace> root_namespace();
|
static BAN::RefPtr<AML::Namespace> root_namespace();
|
||||||
|
static BAN::RefPtr<AML::Node> debug_node;
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
static void for_each_child(const AML::NameString& scope, const F& callback)
|
static void for_each_child(const AML::NameString& scope, const F& callback)
|
||||||
|
|
|
@ -9,12 +9,17 @@
|
||||||
namespace Kernel::ACPI::AML
|
namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
|
|
||||||
|
struct Buffer;
|
||||||
|
struct Integer;
|
||||||
|
struct String;
|
||||||
|
|
||||||
struct Node : public BAN::RefCounted<Node>
|
struct Node : public BAN::RefCounted<Node>
|
||||||
{
|
{
|
||||||
static uint64_t total_node_count;
|
static uint64_t total_node_count;
|
||||||
|
|
||||||
enum class Type
|
enum class Type
|
||||||
{
|
{
|
||||||
|
Debug,
|
||||||
BankFieldElement,
|
BankFieldElement,
|
||||||
Buffer,
|
Buffer,
|
||||||
BufferField,
|
BufferField,
|
||||||
|
@ -45,7 +50,10 @@ namespace Kernel::ACPI::AML
|
||||||
|
|
||||||
virtual BAN::RefPtr<Node> copy() { return this; }
|
virtual BAN::RefPtr<Node> copy() { return this; }
|
||||||
|
|
||||||
[[nodiscard]] BAN::Optional<uint64_t> as_integer();
|
[[nodiscard]] virtual BAN::RefPtr<AML::Buffer> as_buffer();
|
||||||
|
[[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 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; }
|
[[nodiscard]] virtual bool store(BAN::RefPtr<AML::Node>) { AML_TODO("store, type {}", static_cast<uint8_t>(type)); return false; }
|
||||||
|
|
||||||
|
@ -84,7 +92,6 @@ namespace Kernel::ACPI::AML
|
||||||
|
|
||||||
BAN::RefPtr<Node> node()
|
BAN::RefPtr<Node> node()
|
||||||
{
|
{
|
||||||
ASSERT(m_node);
|
|
||||||
return m_node;
|
return m_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,8 +29,8 @@ 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::Optional<uint64_t>();
|
auto value = value_result.node() ? value_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
|
||||||
if (!value.has_value())
|
if (!value)
|
||||||
{
|
{
|
||||||
AML_ERROR("Notify value is not an integer");
|
AML_ERROR("Notify value is not an integer");
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
|
@ -58,7 +58,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->value);
|
||||||
return ParseResult::Success;
|
return ParseResult::Success;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <kernel/ACPI/AML/Bytes.h>
|
#include <kernel/ACPI/AML/Bytes.h>
|
||||||
|
#include <kernel/ACPI/AML/Integer.h>
|
||||||
#include <kernel/ACPI/AML/Node.h>
|
#include <kernel/ACPI/AML/Node.h>
|
||||||
#include <kernel/ACPI/AML/ParseContext.h>
|
#include <kernel/ACPI/AML/ParseContext.h>
|
||||||
#include <kernel/ACPI/AML/Pkg.h>
|
#include <kernel/ACPI/AML/Pkg.h>
|
||||||
|
@ -65,6 +66,49 @@ namespace Kernel::ACPI::AML
|
||||||
initialized = false;
|
initialized = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool resolve()
|
||||||
|
{
|
||||||
|
ASSERT(!resolved);
|
||||||
|
|
||||||
|
auto object = Namespace::root_namespace()->find_object(parent->scope, unresolved_name, Namespace::FindMode::Normal);
|
||||||
|
if (!object)
|
||||||
|
{
|
||||||
|
AML_ERROR("Failed to resolve reference {} in package {}", unresolved_name, parent->scope);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
element = object;
|
||||||
|
resolved = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool store(BAN::RefPtr<AML::Node> node) override
|
||||||
|
{
|
||||||
|
if (!initialized)
|
||||||
|
{
|
||||||
|
AML_ERROR("Trying to store into uninitialized PackageElement");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
if (!resolved && !resolve())
|
||||||
|
return {};
|
||||||
|
if (element->type == AML::Node::Type::Reference)
|
||||||
|
return element->store(node);
|
||||||
|
element = node->copy();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
BAN::RefPtr<AML::Node> evaluate() override
|
||||||
{
|
{
|
||||||
if (!initialized)
|
if (!initialized)
|
||||||
|
@ -72,17 +116,8 @@ namespace Kernel::ACPI::AML
|
||||||
AML_ERROR("Trying to evaluate uninitialized PackageElement");
|
AML_ERROR("Trying to evaluate uninitialized PackageElement");
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
if (!resolved)
|
if (!resolved && !resolve())
|
||||||
{
|
return {};
|
||||||
auto object = Namespace::root_namespace()->find_object(parent->scope, unresolved_name, Namespace::FindMode::Normal);
|
|
||||||
if (!object)
|
|
||||||
{
|
|
||||||
AML_ERROR("Failed to resolve reference {} in package {}", unresolved_name, parent->scope);
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
element = object;
|
|
||||||
resolved = true;
|
|
||||||
}
|
|
||||||
return element->evaluate();
|
return element->evaluate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,11 +21,28 @@ namespace Kernel::ACPI::AML
|
||||||
ASSERT(node);
|
ASSERT(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BAN::RefPtr<AML::Integer> as_integer() override
|
||||||
|
{
|
||||||
|
if (node)
|
||||||
|
return node->as_integer();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> evaluate() override
|
BAN::RefPtr<AML::Node> evaluate() override
|
||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool store(BAN::RefPtr<AML::Node> value) override
|
||||||
|
{
|
||||||
|
if (!node)
|
||||||
|
{
|
||||||
|
AML_ERROR("Storing to null reference");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return node->store(value);
|
||||||
|
}
|
||||||
|
|
||||||
static ParseResult parse(ParseContext& context)
|
static ParseResult parse(ParseContext& context)
|
||||||
{
|
{
|
||||||
ASSERT(context.aml_data.size() >= 1);
|
ASSERT(context.aml_data.size() >= 1);
|
||||||
|
@ -127,7 +144,7 @@ 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();
|
auto object = parse_result.node() ? parse_result.node()->evaluate() : BAN::RefPtr<AML::Node>();
|
||||||
if (!object || object->type != AML::Node::Type::Reference)
|
if (!object || object->type != AML::Node::Type::Reference)
|
||||||
{
|
{
|
||||||
AML_TODO("DerefOf source is not a Reference, but a {}", object ? static_cast<uint8_t>(object->type) : 999);
|
AML_TODO("DerefOf source is not a Reference, but a {}", object ? static_cast<uint8_t>(object->type) : 999);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <kernel/ACPI/AML/Integer.h>
|
||||||
#include <kernel/ACPI/AML/NamedObject.h>
|
#include <kernel/ACPI/AML/NamedObject.h>
|
||||||
#include <kernel/ACPI/AML/Namespace.h>
|
#include <kernel/ACPI/AML/Namespace.h>
|
||||||
#include <kernel/ACPI/AML/ParseContext.h>
|
#include <kernel/ACPI/AML/ParseContext.h>
|
||||||
|
@ -43,7 +44,7 @@ namespace Kernel::ACPI::AML
|
||||||
if (!offset_result.success())
|
if (!offset_result.success())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
auto offset = offset_result.node()->as_integer();
|
auto offset = offset_result.node()->as_integer();
|
||||||
if (!offset.has_value())
|
if (!offset)
|
||||||
{
|
{
|
||||||
AML_ERROR("OpRegion offset must be an integer");
|
AML_ERROR("OpRegion offset must be an integer");
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
|
@ -53,7 +54,7 @@ namespace Kernel::ACPI::AML
|
||||||
if (!length_result.success())
|
if (!length_result.success())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
auto length = length_result.node()->as_integer();
|
auto length = length_result.node()->as_integer();
|
||||||
if (!length.has_value())
|
if (!length)
|
||||||
{
|
{
|
||||||
AML_ERROR("OpRegion length must be an integer");
|
AML_ERROR("OpRegion length must be an integer");
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
|
@ -62,8 +63,8 @@ namespace Kernel::ACPI::AML
|
||||||
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->value,
|
||||||
length.value()
|
length->value
|
||||||
));
|
));
|
||||||
|
|
||||||
if (!Namespace::root_namespace()->add_named_object(context, name.value(), op_region))
|
if (!Namespace::root_namespace()->add_named_object(context, name.value(), op_region))
|
||||||
|
|
|
@ -17,6 +17,10 @@ namespace Kernel::ACPI::AML
|
||||||
, value(value)
|
, value(value)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
BAN::RefPtr<AML::Buffer> as_buffer() override;
|
||||||
|
BAN::RefPtr<AML::Integer> as_integer() override;
|
||||||
|
BAN::RefPtr<AML::String> as_string() override;
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> evaluate() override
|
BAN::RefPtr<AML::Node> evaluate() override
|
||||||
{
|
{
|
||||||
if (value)
|
if (value)
|
||||||
|
@ -26,6 +30,9 @@ namespace Kernel::ACPI::AML
|
||||||
|
|
||||||
bool store(BAN::RefPtr<AML::Node> source) override
|
bool store(BAN::RefPtr<AML::Node> source) override
|
||||||
{
|
{
|
||||||
|
if (value && value->type == AML::Node::Type::Reference)
|
||||||
|
return value->store(source);
|
||||||
|
|
||||||
auto evaluated = source->evaluate();
|
auto evaluated = source->evaluate();
|
||||||
if (!evaluated)
|
if (!evaluated)
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,18 +19,18 @@ 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::Optional<uint64_t>();
|
auto sleep_time = sleep_time_result.node() ? sleep_time_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
|
||||||
if (!sleep_time.has_value())
|
if (!sleep_time)
|
||||||
{
|
{
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
#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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -46,7 +46,7 @@ namespace Kernel::ACPI::AML
|
||||||
|
|
||||||
if (!destination->store(source))
|
if (!destination->store(source))
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
return ParseResult::Success;
|
return ParseResult(destination);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,10 @@ namespace Kernel::ACPI::AML
|
||||||
this->string[i] = string[i];
|
this->string[i] = string[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BAN::Optional<bool> logical_compare(BAN::RefPtr<AML::Node> node, AML::Byte binaryop);
|
||||||
|
|
||||||
|
BAN::RefPtr<AML::Buffer> as_buffer() override;
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> evaluate() override
|
BAN::RefPtr<AML::Node> evaluate() override
|
||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
|
@ -30,33 +34,7 @@ namespace Kernel::ACPI::AML
|
||||||
return BAN::StringView(reinterpret_cast<const char*>(string.data()), string.size());
|
return BAN::StringView(reinterpret_cast<const char*>(string.data()), string.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
static ParseResult parse(ParseContext& context)
|
static ParseResult parse(ParseContext& context);
|
||||||
{
|
|
||||||
ASSERT(context.aml_data.size() >= 1);
|
|
||||||
ASSERT(static_cast<AML::Byte>(context.aml_data[0]) == AML::Byte::StringPrefix);
|
|
||||||
context.aml_data = context.aml_data.slice(1);
|
|
||||||
|
|
||||||
BAN::Vector<uint8_t> string;
|
|
||||||
|
|
||||||
while (context.aml_data.size() > 0)
|
|
||||||
{
|
|
||||||
if (context.aml_data[0] == 0x00)
|
|
||||||
break;
|
|
||||||
MUST(string.push_back(context.aml_data[0]));
|
|
||||||
context.aml_data = context.aml_data.slice(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (context.aml_data.size() == 0)
|
|
||||||
return ParseResult::Failure;
|
|
||||||
if (context.aml_data[0] != 0x00)
|
|
||||||
return ParseResult::Failure;
|
|
||||||
context.aml_data = context.aml_data.slice(1);
|
|
||||||
|
|
||||||
auto string_node = MUST(BAN::RefPtr<String>::create());
|
|
||||||
string_node->string = BAN::move(string);
|
|
||||||
|
|
||||||
return ParseResult(string_node);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void debug_print(int indent) const override
|
virtual void debug_print(int indent) const override
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,7 +19,7 @@ namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
ASSERT(context.aml_data.size() >= 2);
|
ASSERT(context.aml_data.size() >= 2);
|
||||||
ASSERT(static_cast<AML::Byte>(context.aml_data[0]) == AML::Byte::ExtOpPrefix);
|
ASSERT(static_cast<AML::Byte>(context.aml_data[0]) == AML::Byte::ExtOpPrefix);
|
||||||
ASSERT(static_cast<AML::ExtOp>(context.aml_data[1]) == AML::ExtOp::PowerResOp);
|
ASSERT(static_cast<AML::ExtOp>(context.aml_data[1]) == AML::ExtOp::ThermalZoneOp);
|
||||||
context.aml_data = context.aml_data.slice(2);
|
context.aml_data = context.aml_data.slice(2);
|
||||||
|
|
||||||
auto opt_thermal_zone_pkg = AML::parse_pkg(context.aml_data);
|
auto opt_thermal_zone_pkg = AML::parse_pkg(context.aml_data);
|
||||||
|
|
|
@ -29,14 +29,14 @@ 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::Optional<uint64_t>();
|
auto predicate = predicate_result.node() ? predicate_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
|
||||||
if (!predicate.has_value())
|
if (!predicate)
|
||||||
{
|
{
|
||||||
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 (!predicate->value)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
while (context.aml_data.size() > 0)
|
while (context.aml_data.size() > 0)
|
||||||
|
|
|
@ -145,9 +145,9 @@ acpi_release_global_lock:
|
||||||
field_element->op_region = op_region;
|
field_element->op_region = op_region;
|
||||||
|
|
||||||
auto result = field_element->as_integer();
|
auto result = field_element->as_integer();
|
||||||
if (!result.has_value())
|
if (!result)
|
||||||
return {};
|
return {};
|
||||||
return result.value();
|
return result->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GAS::write(uint64_t value)
|
bool GAS::write(uint64_t value)
|
||||||
|
@ -514,7 +514,7 @@ acpi_release_global_lock:
|
||||||
|
|
||||||
auto slp_typa = s5_package->elements[0]->as_integer();
|
auto slp_typa = s5_package->elements[0]->as_integer();
|
||||||
auto slp_typb = s5_package->elements[1]->as_integer();
|
auto slp_typb = s5_package->elements[1]->as_integer();
|
||||||
if (!slp_typa.has_value() || !slp_typb.has_value())
|
if (!slp_typa || !slp_typb)
|
||||||
{
|
{
|
||||||
dwarnln("Failed to get SLP_TYPx values");
|
dwarnln("Failed to get SLP_TYPx values");
|
||||||
return;
|
return;
|
||||||
|
@ -527,7 +527,7 @@ acpi_release_global_lock:
|
||||||
|
|
||||||
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 +535,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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -479,7 +479,7 @@ namespace Kernel::ACPI
|
||||||
return perform_write_general(op_region->region_offset, bit_count, bit_offset, access_size.value(), value, access_rules.update_rule, read_func, write_func);
|
return perform_write_general(op_region->region_offset, bit_count, bit_offset, access_size.value(), value, access_rules.update_rule, read_func, write_func);
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> AML::FieldElement::evaluate()
|
BAN::RefPtr<AML::Integer> AML::FieldElement::as_integer()
|
||||||
{
|
{
|
||||||
op_region->mutex.lock();
|
op_region->mutex.lock();
|
||||||
BAN::ScopeGuard unlock_guard([&] {
|
BAN::ScopeGuard unlock_guard([&] {
|
||||||
|
@ -495,7 +495,7 @@ namespace Kernel::ACPI
|
||||||
bool AML::FieldElement::store(BAN::RefPtr<AML::Node> source)
|
bool AML::FieldElement::store(BAN::RefPtr<AML::Node> source)
|
||||||
{
|
{
|
||||||
auto source_integer = source->as_integer();
|
auto source_integer = source->as_integer();
|
||||||
if (!source_integer.has_value())
|
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 false;
|
||||||
|
@ -510,7 +510,7 @@ namespace Kernel::ACPI
|
||||||
ACPI::release_global_lock();
|
ACPI::release_global_lock();
|
||||||
});
|
});
|
||||||
|
|
||||||
return store_internal(source_integer.value());
|
return store_internal(source_integer->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AML::FieldElement::debug_print(int indent) const
|
void AML::FieldElement::debug_print(int indent) const
|
||||||
|
@ -590,7 +590,7 @@ namespace Kernel::ACPI
|
||||||
return AML::ParseResult::Success;
|
return AML::ParseResult::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> AML::IndexFieldElement::evaluate()
|
BAN::RefPtr<AML::Integer> AML::IndexFieldElement::as_integer()
|
||||||
{
|
{
|
||||||
if (access_rules.access_attrib != FieldRules::AccessAttrib::Normal)
|
if (access_rules.access_attrib != FieldRules::AccessAttrib::Normal)
|
||||||
{
|
{
|
||||||
|
@ -634,7 +634,7 @@ namespace Kernel::ACPI
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
auto source_integer = source->as_integer();
|
auto source_integer = source->as_integer();
|
||||||
if (!source_integer.has_value())
|
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 false;
|
||||||
|
@ -670,7 +670,7 @@ 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))
|
if (!perform_write_general(0, bit_count, bit_offset, access_size.value(), source_integer->value, access_rules.update_rule, read_func, write_func))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -734,8 +734,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::Optional<uint64_t>();
|
auto bank_value = bank_value_result.node() ? bank_value_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
|
||||||
if (!bank_value.has_value())
|
if (!bank_value)
|
||||||
{
|
{
|
||||||
AML_ERROR("BankField BankValue is not an integer");
|
AML_ERROR("BankField BankValue is not an integer");
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
|
@ -760,7 +760,7 @@ namespace Kernel::ACPI
|
||||||
{
|
{
|
||||||
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->value;
|
||||||
|
|
||||||
NameString element_name;
|
NameString element_name;
|
||||||
MUST(element_name.path.push_back(element->name));
|
MUST(element_name.path.push_back(element->name));
|
||||||
|
@ -821,7 +821,7 @@ namespace Kernel::ACPI
|
||||||
}
|
}
|
||||||
|
|
||||||
auto source_integer = source->as_integer();
|
auto source_integer = source->as_integer();
|
||||||
if (!source_integer.has_value())
|
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 false;
|
||||||
|
@ -852,7 +852,7 @@ 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);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AML::BankFieldElement::debug_print(int indent) const
|
void AML::BankFieldElement::debug_print(int indent) const
|
||||||
|
|
|
@ -1,9 +1,30 @@
|
||||||
|
#include <kernel/ACPI/AML/Buffer.h>
|
||||||
|
#include <kernel/ACPI/AML/Integer.h>
|
||||||
#include <kernel/ACPI/AML/NamedObject.h>
|
#include <kernel/ACPI/AML/NamedObject.h>
|
||||||
#include <kernel/ACPI/AML/ParseContext.h>
|
#include <kernel/ACPI/AML/ParseContext.h>
|
||||||
|
#include <kernel/ACPI/AML/String.h>
|
||||||
|
|
||||||
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,7 +41,7 @@ namespace Kernel::ACPI
|
||||||
|
|
||||||
auto name = MUST(BAN::RefPtr<Name>::create(name_string.value().path.back(), object.node()));
|
auto name = MUST(BAN::RefPtr<Name>::create(name_string.value().path.back(), object.node()));
|
||||||
if (!Namespace::root_namespace()->add_named_object(context, name_string.value(), name))
|
if (!Namespace::root_namespace()->add_named_object(context, name_string.value(), name))
|
||||||
return ParseResult::Failure;
|
return ParseResult::Success;
|
||||||
|
|
||||||
#if AML_DEBUG_LEVEL >= 2
|
#if AML_DEBUG_LEVEL >= 2
|
||||||
name->debug_print(0);
|
name->debug_print(0);
|
||||||
|
|
|
@ -17,6 +17,24 @@ namespace Kernel::ACPI
|
||||||
BAN::RefPtr<AML::Integer> AML::Integer::Constants::One;
|
BAN::RefPtr<AML::Integer> AML::Integer::Constants::One;
|
||||||
BAN::RefPtr<AML::Integer> AML::Integer::Constants::Ones;
|
BAN::RefPtr<AML::Integer> AML::Integer::Constants::Ones;
|
||||||
|
|
||||||
|
struct DebugNode : AML::Node
|
||||||
|
{
|
||||||
|
DebugNode() : AML::Node(AML::Node::Type::Debug) {}
|
||||||
|
bool store(BAN::RefPtr<AML::Node> node)
|
||||||
|
{
|
||||||
|
node->debug_print(0);
|
||||||
|
AML_DEBUG_PRINTLN("");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void debug_print(int indent) const override
|
||||||
|
{
|
||||||
|
AML_DEBUG_PRINT_INDENT(indent);
|
||||||
|
AML_DEBUG_PRINT("DEBUG");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BAN::RefPtr<AML::Node> AML::Namespace::debug_node;
|
||||||
|
|
||||||
BAN::RefPtr<AML::Namespace> AML::Namespace::root_namespace()
|
BAN::RefPtr<AML::Namespace> AML::Namespace::root_namespace()
|
||||||
{
|
{
|
||||||
ASSERT(s_root_namespace);
|
ASSERT(s_root_namespace);
|
||||||
|
@ -147,7 +165,7 @@ namespace Kernel::ACPI
|
||||||
|
|
||||||
if (m_objects.contains(canonical_path.value()))
|
if (m_objects.contains(canonical_path.value()))
|
||||||
{
|
{
|
||||||
AML_ERROR("Object '{}' already exists", canonical_path.value());
|
AML_PRINT("Object '{}' already exists", canonical_path.value());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,6 +212,9 @@ namespace Kernel::ACPI
|
||||||
s_root_namespace = MUST(BAN::RefPtr<Namespace>::create(NameSeg("\\"_sv)));
|
s_root_namespace = MUST(BAN::RefPtr<Namespace>::create(NameSeg("\\"_sv)));
|
||||||
s_root_namespace->scope = AML::NameString("\\"_sv);
|
s_root_namespace->scope = AML::NameString("\\"_sv);
|
||||||
|
|
||||||
|
ASSERT(!Namespace::debug_node);
|
||||||
|
Namespace::debug_node = MUST(BAN::RefPtr<DebugNode>::create());
|
||||||
|
|
||||||
Integer::Constants::Zero = MUST(BAN::RefPtr<Integer>::create(0, true));
|
Integer::Constants::Zero = MUST(BAN::RefPtr<Integer>::create(0, true));
|
||||||
Integer::Constants::One = MUST(BAN::RefPtr<Integer>::create(1, true));
|
Integer::Constants::One = MUST(BAN::RefPtr<Integer>::create(1, true));
|
||||||
Integer::Constants::Ones = MUST(BAN::RefPtr<Integer>::create(0xFFFFFFFFFFFFFFFF, true));
|
Integer::Constants::Ones = MUST(BAN::RefPtr<Integer>::create(0xFFFFFFFFFFFFFFFF, true));
|
||||||
|
|
|
@ -33,15 +33,21 @@ namespace Kernel::ACPI
|
||||||
|
|
||||||
uint64_t AML::Node::total_node_count = 0;
|
uint64_t AML::Node::total_node_count = 0;
|
||||||
|
|
||||||
BAN::Optional<uint64_t> AML::Node::as_integer()
|
BAN::RefPtr<AML::Buffer> AML::Node::as_buffer()
|
||||||
{
|
{
|
||||||
if (type == Type::Integer)
|
AML_TODO("Node type {} to buffer", static_cast<uint32_t>(type));
|
||||||
return static_cast<const Integer*>(this)->value;
|
return {};
|
||||||
auto evaluated = evaluate();
|
}
|
||||||
if (!evaluated)
|
|
||||||
return {};
|
BAN::RefPtr<AML::Integer> AML::Node::as_integer()
|
||||||
if (evaluated->type == Type::Integer)
|
{
|
||||||
return static_cast<const Integer*>(evaluated.ptr())->value;
|
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 {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,6 +89,9 @@ namespace Kernel::ACPI
|
||||||
return AML::Reference::parse(context);
|
return AML::Reference::parse(context);
|
||||||
case AML::ExtOp::SleepOp:
|
case AML::ExtOp::SleepOp:
|
||||||
return AML::Sleep::parse(context);
|
return AML::Sleep::parse(context);
|
||||||
|
case AML::ExtOp::DebugOp:
|
||||||
|
context.aml_data = context.aml_data.slice(2);
|
||||||
|
return ParseResult(AML::Namespace::debug_node);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
#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,8 +25,8 @@ 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_ERROR("Scope '{}' not found in namespace", name_string.value());
|
AML_DEBUG_PRINT("Scope '{}' not found in namespace", name_string.value());
|
||||||
return ParseResult::Failure;
|
return ParseResult::Success;
|
||||||
}
|
}
|
||||||
if (!named_object->is_scope())
|
if (!named_object->is_scope())
|
||||||
{
|
{
|
||||||
|
@ -66,7 +66,7 @@ namespace Kernel::ACPI
|
||||||
return ParseResult::Success;
|
return ParseResult::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BAN::Optional<uint64_t> 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();
|
return object->as_integer();
|
||||||
|
@ -85,7 +85,7 @@ namespace Kernel::ACPI
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.value() ? result.value()->as_integer() : BAN::Optional<uint64_t>();
|
return result.value() ? result.value()->as_integer() : BAN::RefPtr<AML::Integer>();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AML::initialize_scope(BAN::RefPtr<AML::Scope> scope)
|
bool AML::initialize_scope(BAN::RefPtr<AML::Scope> scope)
|
||||||
|
@ -138,14 +138,14 @@ namespace Kernel::ACPI
|
||||||
if (auto sta = Namespace::root_namespace()->find_object(scope->scope, AML::NameString("_STA"_sv), Namespace::FindMode::ForceAbsolute))
|
if (auto sta = Namespace::root_namespace()->find_object(scope->scope, AML::NameString("_STA"_sv), Namespace::FindMode::ForceAbsolute))
|
||||||
{
|
{
|
||||||
auto result = evaluate_or_invoke(sta);
|
auto result = evaluate_or_invoke(sta);
|
||||||
if (!result.has_value())
|
if (!result)
|
||||||
{
|
{
|
||||||
AML_ERROR("Failed to evaluate {}._STA, return value could not be resolved to integer", scope->scope);
|
AML_ERROR("Failed to evaluate {}._STA, return value could not be resolved to integer", scope->scope);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
run_ini = (result.value() & 0x01);
|
run_ini = (result->value & 0x01);
|
||||||
init_children = run_ini || (result.value() & 0x02);
|
init_children = run_ini || (result->value & 0x02);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (run_ini)
|
if (run_ini)
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
#include <kernel/ACPI/AML/Buffer.h>
|
||||||
|
#include <kernel/ACPI/AML/String.h>
|
||||||
|
|
||||||
|
namespace Kernel::ACPI::AML
|
||||||
|
{
|
||||||
|
|
||||||
|
BAN::Optional<bool> String::logical_compare(BAN::RefPtr<AML::Node> node, AML::Byte binaryop)
|
||||||
|
{
|
||||||
|
auto rhs = node ? node->as_string() : BAN::RefPtr<AML::String>();
|
||||||
|
if (!rhs)
|
||||||
|
{
|
||||||
|
AML_ERROR("String logical compare RHS is not string");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)binaryop;
|
||||||
|
AML_TODO("Logical compare string");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::RefPtr<AML::Buffer> String::as_buffer()
|
||||||
|
{
|
||||||
|
auto buffer = MUST(BAN::RefPtr<AML::Buffer>::create());
|
||||||
|
MUST(buffer->buffer.resize(string.size()));
|
||||||
|
for (size_t i = 0; i < string.size(); i++)
|
||||||
|
buffer->buffer[i] = string[i];
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParseResult String::parse(ParseContext& context)
|
||||||
|
{
|
||||||
|
ASSERT(context.aml_data.size() >= 1);
|
||||||
|
ASSERT(static_cast<AML::Byte>(context.aml_data[0]) == AML::Byte::StringPrefix);
|
||||||
|
context.aml_data = context.aml_data.slice(1);
|
||||||
|
|
||||||
|
BAN::Vector<uint8_t> string;
|
||||||
|
|
||||||
|
while (context.aml_data.size() > 0)
|
||||||
|
{
|
||||||
|
if (context.aml_data[0] == 0x00)
|
||||||
|
break;
|
||||||
|
MUST(string.push_back(context.aml_data[0]));
|
||||||
|
context.aml_data = context.aml_data.slice(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context.aml_data.size() == 0)
|
||||||
|
return ParseResult::Failure;
|
||||||
|
if (context.aml_data[0] != 0x00)
|
||||||
|
return ParseResult::Failure;
|
||||||
|
context.aml_data = context.aml_data.slice(1);
|
||||||
|
|
||||||
|
auto string_node = MUST(BAN::RefPtr<String>::create());
|
||||||
|
string_node->string = BAN::move(string);
|
||||||
|
|
||||||
|
return ParseResult(string_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue