Compare commits
No commits in common. "490a28ee7a9a95ef68c624acd15574d1fe9de3ea" and "957df0893271fd2eac5a353d8480850fed3b6e25" have entirely different histories.
490a28ee7a
...
957df08932
|
@ -11,21 +11,21 @@ namespace BAN::Formatter
|
||||||
struct ValueFormat;
|
struct ValueFormat;
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
inline void print(F putc, const char* format);
|
static void print(F putc, const char* format);
|
||||||
|
|
||||||
template<typename F, typename Arg, typename... Args>
|
template<typename F, typename Arg, typename... Args>
|
||||||
inline void print(F putc, const char* format, Arg&& arg, Args&&... args);
|
static void print(F putc, const char* format, Arg&& arg, Args&&... args);
|
||||||
|
|
||||||
template<typename F, typename... Args>
|
template<typename F, typename... Args>
|
||||||
inline void println(F putc, const char* format, Args&&... args);
|
static void println(F putc, const char* format, Args&&... args);
|
||||||
|
|
||||||
template<typename F, typename T>
|
template<typename F, typename T>
|
||||||
inline void print_argument(F putc, T value, const ValueFormat& format);
|
static void print_argument(F putc, T value, const ValueFormat& format);
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
template<typename F, typename T>
|
template<typename F, typename T>
|
||||||
inline size_t parse_format_and_print_argument(F putc, const char* format, T&& arg);
|
static size_t parse_format_and_print_argument(F putc, const char* format, T&& arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -44,7 +44,7 @@ namespace BAN::Formatter
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
inline void print(F putc, const char* format)
|
void print(F putc, const char* format)
|
||||||
{
|
{
|
||||||
while (*format)
|
while (*format)
|
||||||
{
|
{
|
||||||
|
@ -54,7 +54,7 @@ namespace BAN::Formatter
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename F, typename Arg, typename... Args>
|
template<typename F, typename Arg, typename... Args>
|
||||||
inline void print(F putc, const char* format, Arg&& arg, Args&&... args)
|
void print(F putc, const char* format, Arg&& arg, Args&&... args)
|
||||||
{
|
{
|
||||||
while (*format && *format != '{')
|
while (*format && *format != '{')
|
||||||
{
|
{
|
||||||
|
@ -72,7 +72,7 @@ namespace BAN::Formatter
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename F, typename... Args>
|
template<typename F, typename... Args>
|
||||||
inline void println(F putc, const char* format, Args&&... args)
|
void println(F putc, const char* format, Args&&... args)
|
||||||
{
|
{
|
||||||
print(putc, format, args...);
|
print(putc, format, args...);
|
||||||
putc('\n');
|
putc('\n');
|
||||||
|
@ -82,7 +82,7 @@ namespace BAN::Formatter
|
||||||
{
|
{
|
||||||
|
|
||||||
template<typename F, typename Arg>
|
template<typename F, typename Arg>
|
||||||
inline size_t parse_format_and_print_argument(F putc, const char* format, Arg&& argument)
|
size_t parse_format_and_print_argument(F putc, const char* format, Arg&& argument)
|
||||||
{
|
{
|
||||||
ValueFormat value_format;
|
ValueFormat value_format;
|
||||||
|
|
||||||
|
@ -150,7 +150,7 @@ namespace BAN::Formatter
|
||||||
return i + 1;
|
return i + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline char value_to_base_char(uint8_t value, int base, bool upper)
|
static char value_to_base_char(uint8_t value, int base, bool upper)
|
||||||
{
|
{
|
||||||
if (base <= 10)
|
if (base <= 10)
|
||||||
return value + '0';
|
return value + '0';
|
||||||
|
@ -164,7 +164,7 @@ namespace BAN::Formatter
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename F, typename T>
|
template<typename F, typename T>
|
||||||
inline void print_integer(F putc, T value, const ValueFormat& format)
|
void print_integer(F putc, T value, const ValueFormat& format)
|
||||||
{
|
{
|
||||||
if (value == 0)
|
if (value == 0)
|
||||||
{
|
{
|
||||||
|
@ -205,7 +205,7 @@ namespace BAN::Formatter
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename F, typename T>
|
template<typename F, typename T>
|
||||||
inline void print_floating(F putc, T value, const ValueFormat& format)
|
void print_floating(F putc, T value, const ValueFormat& format)
|
||||||
{
|
{
|
||||||
int64_t int_part = (int64_t)value;
|
int64_t int_part = (int64_t)value;
|
||||||
T frac_part = value - (T)int_part;
|
T frac_part = value - (T)int_part;
|
||||||
|
@ -228,7 +228,7 @@ namespace BAN::Formatter
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
inline void print_pointer(F putc, void* ptr, const ValueFormat& format)
|
void print_pointer(F putc, void* ptr, const ValueFormat& format)
|
||||||
{
|
{
|
||||||
uintptr_t value = (uintptr_t)ptr;
|
uintptr_t value = (uintptr_t)ptr;
|
||||||
print(putc, "0x");
|
print(putc, "0x");
|
||||||
|
@ -244,13 +244,13 @@ namespace BAN::Formatter
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template<typename F, integral T> inline void print_argument(F putc, T value, const ValueFormat& format) { detail::print_integer(putc, value, format); }
|
template<typename F, integral T> void print_argument(F putc, T value, const ValueFormat& format) { detail::print_integer(putc, value, format); }
|
||||||
template<typename F, floating_point T> inline void print_argument(F putc, T value, const ValueFormat& format) { detail::print_floating(putc, value, format); }
|
template<typename F, floating_point T> void print_argument(F putc, T value, const ValueFormat& format) { detail::print_floating(putc, value, format); }
|
||||||
template<typename F, pointer T> inline void print_argument(F putc, T value, const ValueFormat& format) { detail::print_pointer(putc, (void*)value, format); }
|
template<typename F, pointer T> void print_argument(F putc, T value, const ValueFormat& format) { detail::print_pointer(putc, (void*)value, format); }
|
||||||
|
|
||||||
template<typename F> inline void print_argument(F putc, char value, const ValueFormat&) { putc(value); }
|
template<typename F> void print_argument(F putc, char value, const ValueFormat&) { putc(value); }
|
||||||
template<typename F> inline void print_argument(F putc, bool value, const ValueFormat&) { print(putc, value ? "true" : "false"); }
|
template<typename F> void print_argument(F putc, bool value, const ValueFormat&) { print(putc, value ? "true" : "false"); }
|
||||||
template<typename F> inline void print_argument(F putc, const char* value, const ValueFormat&) { print(putc, value); }
|
template<typename F> void print_argument(F putc, const char* value, const ValueFormat&) { print(putc, value); }
|
||||||
template<typename F> inline void print_argument(F putc, char* value, const ValueFormat&) { print(putc, value); }
|
template<typename F> void print_argument(F putc, char* value, const ValueFormat&) { print(putc, value); }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ set(KERNEL_SOURCES
|
||||||
kernel/ACPI/ACPI.cpp
|
kernel/ACPI/ACPI.cpp
|
||||||
kernel/ACPI/AML.cpp
|
kernel/ACPI/AML.cpp
|
||||||
kernel/ACPI/AML/Field.cpp
|
kernel/ACPI/AML/Field.cpp
|
||||||
kernel/ACPI/AML/Integer.cpp
|
|
||||||
kernel/ACPI/AML/NamedObject.cpp
|
kernel/ACPI/AML/NamedObject.cpp
|
||||||
kernel/ACPI/AML/Namespace.cpp
|
kernel/ACPI/AML/Namespace.cpp
|
||||||
kernel/ACPI/AML/Node.cpp
|
kernel/ACPI/AML/Node.cpp
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
namespace Kernel::ACPI::AML
|
namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
|
|
||||||
struct Alias final : public AML::NamedObject
|
struct Alias : public AML::NamedObject
|
||||||
{
|
{
|
||||||
BAN::RefPtr<AML::Node> target;
|
BAN::RefPtr<AML::Node> target;
|
||||||
|
|
||||||
|
@ -16,27 +16,16 @@ namespace Kernel::ACPI::AML
|
||||||
, target(target)
|
, target(target)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> to_underlying() override { return target; }
|
|
||||||
|
|
||||||
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 mask) override
|
BAN::RefPtr<Node> copy() override { return target->copy(); }
|
||||||
{
|
|
||||||
ASSERT(target);
|
|
||||||
return target->convert(mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::RefPtr<Node> copy() override
|
BAN::RefPtr<AML::Buffer> as_buffer() override { return target->as_buffer(); }
|
||||||
{
|
BAN::RefPtr<AML::Integer> as_integer() override { return target->as_integer(); }
|
||||||
ASSERT(target);
|
BAN::RefPtr<AML::String> as_string() override { return target->as_string(); }
|
||||||
return target->copy();
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> store(BAN::RefPtr<AML::Node> node) override
|
BAN::RefPtr<AML::Node> evaluate() override { return target->evaluate(); }
|
||||||
{
|
bool store(BAN::RefPtr<AML::Node> node) override { return target->store(node); }
|
||||||
ASSERT(target);
|
|
||||||
return target->store(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ParseResult parse(ParseContext& context)
|
static ParseResult parse(ParseContext& context)
|
||||||
{
|
{
|
||||||
|
@ -49,17 +38,17 @@ namespace Kernel::ACPI::AML
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
|
|
||||||
auto source_object = AML::Namespace::root_namespace()->find_object(context.scope, source_string.value(), AML::Namespace::FindMode::Normal);
|
auto source_object = AML::Namespace::root_namespace()->find_object(context.scope, source_string.value(), AML::Namespace::FindMode::Normal);
|
||||||
|
if (!source_object)
|
||||||
|
{
|
||||||
|
AML_ERROR("Alias target could not be found");
|
||||||
|
return ParseResult::Failure;
|
||||||
|
}
|
||||||
|
|
||||||
auto alias_string = AML::NameString::parse(context.aml_data);
|
auto alias_string = AML::NameString::parse(context.aml_data);
|
||||||
if (!alias_string.has_value())
|
if (!alias_string.has_value())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
|
|
||||||
if (!source_object)
|
auto alias = MUST(BAN::RefPtr<Alias>::create(alias_string.value().path.back(), source_object));
|
||||||
{
|
|
||||||
AML_PRINT("Alias target could not be found");
|
|
||||||
return ParseResult::Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto alias = MUST(BAN::RefPtr<Alias>::create(alias_string.value().path.back(), source_object->to_underlying()));
|
|
||||||
if (!Namespace::root_namespace()->add_named_object(context, alias_string.value(), alias))
|
if (!Namespace::root_namespace()->add_named_object(context, alias_string.value(), alias))
|
||||||
return ParseResult::Success;
|
return ParseResult::Success;
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
namespace Kernel::ACPI::AML
|
namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
|
|
||||||
struct Buffer final : public AML::Node
|
struct Buffer : 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 ? node->convert(AML::Node::ConvBuffer) : BAN::RefPtr<AML::Node>();
|
auto rhs = node ? node->as_buffer() : BAN::RefPtr<AML::Buffer>();
|
||||||
if (!rhs_node)
|
if (!rhs)
|
||||||
{
|
{
|
||||||
AML_ERROR("Buffer logical compare RHS cannot be converted to buffer");
|
AML_ERROR("Buffer logical compare RHS is not buffer");
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,34 +32,18 @@ namespace Kernel::ACPI::AML
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> convert(uint8_t mask) override
|
BAN::RefPtr<AML::Buffer> as_buffer() override { return this; }
|
||||||
|
|
||||||
|
BAN::RefPtr<AML::Integer> as_integer() override
|
||||||
{
|
{
|
||||||
if (mask & AML::Node::ConvBuffer)
|
uint64_t value = 0;
|
||||||
return this;
|
for (size_t i = 0; i < BAN::Math::min<size_t>(buffer.size(), 8); i++)
|
||||||
if (mask & AML::Node::ConvInteger)
|
value |= static_cast<uint64_t>(buffer[i]) << (8 * i);
|
||||||
return as_integer();
|
return MUST(BAN::RefPtr<Integer>::create(value));
|
||||||
if (mask & AML::Node::ConvString)
|
|
||||||
{
|
|
||||||
AML_TODO("Convert BufferField to String");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> store(BAN::RefPtr<AML::Node> node) override
|
BAN::RefPtr<AML::Node> evaluate() override
|
||||||
{
|
{
|
||||||
ASSERT(node);
|
|
||||||
auto conv_node = node->convert(AML::Node::ConvBuffer);
|
|
||||||
if (!conv_node)
|
|
||||||
{
|
|
||||||
AML_ERROR("Buffer store could not convert to buffer");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& conv_buffer = static_cast<AML::Buffer*>(conv_node.ptr())->buffer;
|
|
||||||
MUST(buffer.resize(conv_buffer.size()));
|
|
||||||
for (size_t i = 0; i < buffer.size(); i++)
|
|
||||||
buffer[i] = conv_buffer[i];
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,21 +60,15 @@ 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_result = AML::parse_object(buffer_context);
|
auto buffer_size_object = AML::parse_object(buffer_context);
|
||||||
if (!buffer_size_result.success())
|
if (!buffer_size_object.success())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
|
|
||||||
auto buffer_size_node = buffer_size_result.node() ? buffer_size_result.node()->convert(AML::Node::ConvInteger) : BAN::RefPtr<AML::Node>();
|
auto buffer_size = buffer_size_object.node()->as_integer();
|
||||||
if (!buffer_size_node)
|
if (!buffer_size)
|
||||||
{
|
|
||||||
AML_ERROR("Buffer size is not an integer");
|
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
|
||||||
|
|
||||||
const uint32_t actual_buffer_size = BAN::Math::max<uint32_t>(
|
uint32_t actual_buffer_size = BAN::Math::max<uint32_t>(buffer_size->value, buffer_context.aml_data.size());
|
||||||
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));
|
||||||
|
@ -110,18 +88,9 @@ 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 final : AML::NamedObject
|
struct BufferField : AML::NamedObject
|
||||||
{
|
{
|
||||||
BAN::RefPtr<AML::Node> buffer;
|
BAN::RefPtr<AML::Node> buffer;
|
||||||
size_t field_bit_offset;
|
size_t field_bit_offset;
|
||||||
|
@ -135,159 +104,7 @@ namespace Kernel::ACPI::AML
|
||||||
, field_bit_size(field_bit_size)
|
, field_bit_size(field_bit_size)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> convert(uint8_t mask) override
|
BAN::RefPtr<AML::Integer> as_integer() override
|
||||||
{
|
|
||||||
if (mask & AML::Node::ConvBufferField)
|
|
||||||
return this;
|
|
||||||
if (mask & AML::Node::ConvInteger)
|
|
||||||
return as_integer();
|
|
||||||
if (mask & AML::Node::ConvBuffer)
|
|
||||||
{
|
|
||||||
AML_TODO("Convert BufferField to Buffer");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
if (mask & AML::Node::ConvString)
|
|
||||||
{
|
|
||||||
AML_TODO("Convert BufferField to String");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
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);
|
|
||||||
|
|
||||||
auto value_node = node ? node->convert(AML::Node::ConvInteger) : BAN::RefPtr<AML::Node>();
|
|
||||||
if (!value_node)
|
|
||||||
return {};
|
|
||||||
const auto value = static_cast<AML::Integer*>(value_node.ptr())->value;
|
|
||||||
|
|
||||||
// TODO: optimize for whole byte accesses
|
|
||||||
for (size_t i = 0; i < field_bit_size; i++)
|
|
||||||
{
|
|
||||||
const size_t bit = field_bit_offset + i;
|
|
||||||
buffer[bit / 8] &= ~(1 << (bit % 8));
|
|
||||||
buffer[bit / 8] |= ((value >> i) & 1) << (bit % 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
return value_node;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ParseResult parse(AML::ParseContext& context)
|
|
||||||
{
|
|
||||||
ASSERT(context.aml_data.size() >= 1);
|
|
||||||
|
|
||||||
bool offset_in_bytes;
|
|
||||||
size_t field_bit_size;
|
|
||||||
switch (static_cast<AML::Byte>(context.aml_data[0]))
|
|
||||||
{
|
|
||||||
case AML::Byte::CreateBitFieldOp:
|
|
||||||
field_bit_size = 1;
|
|
||||||
offset_in_bytes = false;
|
|
||||||
break;
|
|
||||||
case AML::Byte::CreateByteFieldOp:
|
|
||||||
field_bit_size = 8;
|
|
||||||
offset_in_bytes = true;
|
|
||||||
break;
|
|
||||||
case AML::Byte::CreateWordFieldOp:
|
|
||||||
field_bit_size = 16;
|
|
||||||
offset_in_bytes = true;
|
|
||||||
break;
|
|
||||||
case AML::Byte::CreateDWordFieldOp:
|
|
||||||
field_bit_size = 32;
|
|
||||||
offset_in_bytes = true;
|
|
||||||
break;
|
|
||||||
case AML::Byte::CreateQWordFieldOp:
|
|
||||||
field_bit_size = 64;
|
|
||||||
offset_in_bytes = true;
|
|
||||||
break;
|
|
||||||
case AML::Byte::ExtOpPrefix:
|
|
||||||
ASSERT(context.aml_data.size() >= 2);
|
|
||||||
ASSERT(static_cast<AML::ExtOp>(context.aml_data[1]) == AML::ExtOp::CreateFieldOp);
|
|
||||||
field_bit_size = 0;
|
|
||||||
offset_in_bytes = false;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ASSERT_NOT_REACHED();
|
|
||||||
}
|
|
||||||
context.aml_data = context.aml_data.slice(1 + (static_cast<AML::Byte>(context.aml_data[0]) == AML::Byte::ExtOpPrefix));
|
|
||||||
|
|
||||||
auto buffer_result = AML::parse_object(context);
|
|
||||||
if (!buffer_result.success())
|
|
||||||
return ParseResult::Failure;
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
AML_ERROR("Buffer source does not evaluate to a Buffer");
|
|
||||||
return ParseResult::Failure;
|
|
||||||
}
|
|
||||||
auto buffer = BAN::RefPtr<AML::Buffer>(static_cast<AML::Buffer*>(buffer_node.ptr()));
|
|
||||||
|
|
||||||
auto index_result = AML::parse_object(context);
|
|
||||||
if (!index_result.success())
|
|
||||||
return ParseResult::Failure;
|
|
||||||
auto index_node = index_result.node() ? index_result.node()->convert(AML::Node::ConvInteger) : BAN::RefPtr<AML::Node>();
|
|
||||||
if (!index_node)
|
|
||||||
{
|
|
||||||
AML_ERROR("Failed to parse index for BufferField");
|
|
||||||
return ParseResult::Failure;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (field_bit_size == 0)
|
|
||||||
{
|
|
||||||
auto bit_count_result = AML::parse_object(context);
|
|
||||||
if (!bit_count_result.success())
|
|
||||||
return ParseResult::Failure;
|
|
||||||
auto bit_count_node = bit_count_result.node() ? bit_count_result.node()->convert(AML::Node::ConvInteger) : BAN::RefPtr<AML::Node>();
|
|
||||||
if (!bit_count_node)
|
|
||||||
{
|
|
||||||
AML_ERROR("Failed to parse bit count for BufferField");
|
|
||||||
return ParseResult::Failure;
|
|
||||||
}
|
|
||||||
field_bit_size = static_cast<AML::Integer*>(bit_count_node.ptr())->value;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto field_name = AML::NameString::parse(context.aml_data);
|
|
||||||
if (!field_name.has_value())
|
|
||||||
return ParseResult::Failure;
|
|
||||||
if (field_name->path.empty())
|
|
||||||
{
|
|
||||||
AML_ERROR("Empty field name for BufferField");
|
|
||||||
return ParseResult::Failure;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t field_bit_offset = static_cast<AML::Integer*>(index_node.ptr())->value;
|
|
||||||
if (offset_in_bytes)
|
|
||||||
field_bit_offset *= 8;
|
|
||||||
|
|
||||||
auto field = MUST(BAN::RefPtr<BufferField>::create(field_name->path.back(), buffer, field_bit_offset, field_bit_size));
|
|
||||||
if (!Namespace::root_namespace()->add_named_object(context, field_name.value(), field))
|
|
||||||
return ParseResult::Success;
|
|
||||||
|
|
||||||
#if AML_DEBUG_LEVEL >= 2
|
|
||||||
field->debug_print(0);
|
|
||||||
AML_DEBUG_PRINTLN("");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return ParseResult::Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void debug_print(int indent) const override
|
|
||||||
{
|
|
||||||
AML_DEBUG_PRINT_INDENT(indent);
|
|
||||||
AML_DEBUG_PRINT("BufferField {} at bit offset {} ({} bits) to { ", name, field_bit_offset, field_bit_size);
|
|
||||||
buffer->debug_print(0);
|
|
||||||
AML_DEBUG_PRINT(" }");
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
BAN::RefPtr<AML::Integer> as_integer()
|
|
||||||
{
|
{
|
||||||
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);
|
||||||
|
@ -307,6 +124,150 @@ namespace Kernel::ACPI::AML
|
||||||
|
|
||||||
return MUST(BAN::RefPtr<Integer>::create(value));
|
return MUST(BAN::RefPtr<Integer>::create(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BAN::RefPtr<AML::Node> evaluate() 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->type == AML::Node::Type::Buffer || buffer->type == AML::Node::Type::String);
|
||||||
|
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);
|
||||||
|
|
||||||
|
auto value = node->as_integer();
|
||||||
|
if (!value)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// TODO: optimize for whole byte accesses
|
||||||
|
for (size_t i = 0; i < field_bit_size; i++)
|
||||||
|
{
|
||||||
|
const size_t bit = field_bit_offset + 1;
|
||||||
|
buffer[bit / 8] &= ~(1 << (bit % 8));
|
||||||
|
buffer[bit / 8] |= ((value->value >> i) & 1) << (bit % 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ParseResult parse(AML::ParseContext& context)
|
||||||
|
{
|
||||||
|
ASSERT(context.aml_data.size() >= 1);
|
||||||
|
|
||||||
|
size_t field_bit_size = 0;
|
||||||
|
switch (static_cast<AML::Byte>(context.aml_data[0]))
|
||||||
|
{
|
||||||
|
case AML::Byte::CreateBitFieldOp:
|
||||||
|
field_bit_size = 1;
|
||||||
|
break;
|
||||||
|
case AML::Byte::CreateByteFieldOp:
|
||||||
|
field_bit_size = 8;
|
||||||
|
break;
|
||||||
|
case AML::Byte::CreateWordFieldOp:
|
||||||
|
field_bit_size = 16;
|
||||||
|
break;
|
||||||
|
case AML::Byte::CreateDWordFieldOp:
|
||||||
|
field_bit_size = 32;
|
||||||
|
break;
|
||||||
|
case AML::Byte::CreateQWordFieldOp:
|
||||||
|
field_bit_size = 64;
|
||||||
|
break;
|
||||||
|
case AML::Byte::ExtOpPrefix:
|
||||||
|
ASSERT(context.aml_data.size() >= 2);
|
||||||
|
ASSERT(static_cast<AML::ExtOp>(context.aml_data[1]) == AML::ExtOp::CreateFieldOp);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
}
|
||||||
|
context.aml_data = context.aml_data.slice(1 + (static_cast<AML::Byte>(context.aml_data[0]) == AML::Byte::ExtOpPrefix));
|
||||||
|
|
||||||
|
auto buffer_result = AML::parse_object(context);
|
||||||
|
if (!buffer_result.success())
|
||||||
|
return ParseResult::Failure;
|
||||||
|
auto buffer_node = buffer_result.node() ? buffer_result.node()->as_buffer() : BAN::RefPtr<AML::Buffer>();
|
||||||
|
if (!buffer_node || buffer_node->type != Node::Type::Buffer)
|
||||||
|
{
|
||||||
|
AML_ERROR("Buffer source does not evaluate to a Buffer");
|
||||||
|
return ParseResult::Failure;
|
||||||
|
}
|
||||||
|
auto buffer = BAN::RefPtr<AML::Buffer>(static_cast<AML::Buffer*>(buffer_node.ptr()));
|
||||||
|
|
||||||
|
auto index_result = AML::parse_object(context);
|
||||||
|
if (!index_result.success())
|
||||||
|
return ParseResult::Failure;
|
||||||
|
auto index = index_result.node() ? index_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
|
||||||
|
if (!index)
|
||||||
|
{
|
||||||
|
AML_ERROR("Failed to parse index for BufferField");
|
||||||
|
return ParseResult::Failure;
|
||||||
|
}
|
||||||
|
size_t field_bit_offset = index->value;
|
||||||
|
if (field_bit_size != 1)
|
||||||
|
field_bit_offset *= 8;
|
||||||
|
|
||||||
|
if (field_bit_size == 0)
|
||||||
|
{
|
||||||
|
auto bit_count_result = AML::parse_object(context);
|
||||||
|
if (!index_result.success())
|
||||||
|
return ParseResult::Failure;
|
||||||
|
auto bit_count = bit_count_result.node() ? bit_count_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
|
||||||
|
if (!bit_count)
|
||||||
|
{
|
||||||
|
AML_ERROR("Failed to parse bit count for BufferField");
|
||||||
|
return ParseResult::Failure;
|
||||||
|
}
|
||||||
|
field_bit_size = bit_count->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto field_name = AML::NameString::parse(context.aml_data);
|
||||||
|
if (!field_name.has_value())
|
||||||
|
return ParseResult::Failure;
|
||||||
|
if (field_name->path.empty())
|
||||||
|
{
|
||||||
|
AML_ERROR("Empty field name for BufferField");
|
||||||
|
return ParseResult::Failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto field = MUST(BAN::RefPtr<BufferField>::create(field_name->path.back(), buffer, field_bit_offset, field_bit_size));
|
||||||
|
if (!Namespace::root_namespace()->add_named_object(context, field_name.value(), field))
|
||||||
|
return ParseResult::Failure;
|
||||||
|
|
||||||
|
#if AML_DEBUG_LEVEL >= 2
|
||||||
|
field->debug_print(0);
|
||||||
|
AML_DEBUG_PRINTLN("");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ParseResult::Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void debug_print(int indent) const override
|
||||||
|
{
|
||||||
|
AML_DEBUG_PRINT_INDENT(indent);
|
||||||
|
AML_DEBUG_PRINT("BufferField {} at bit offset {} ({} bits) to { ", name, field_bit_offset, field_bit_size);
|
||||||
|
buffer->debug_print(0);
|
||||||
|
AML_DEBUG_PRINT(" }");
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,92 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <kernel/ACPI/AML/Buffer.h>
|
|
||||||
#include <kernel/ACPI/AML/Integer.h>
|
|
||||||
#include <kernel/ACPI/AML/ParseContext.h>
|
|
||||||
#include <kernel/ACPI/AML/String.h>
|
|
||||||
|
|
||||||
namespace Kernel::ACPI::AML
|
|
||||||
{
|
|
||||||
|
|
||||||
struct Conversion
|
|
||||||
{
|
|
||||||
static ParseResult parse(AML::ParseContext& context)
|
|
||||||
{
|
|
||||||
const auto opcode = static_cast<AML::Byte>(context.aml_data[0]);
|
|
||||||
context.aml_data = context.aml_data.slice(1);
|
|
||||||
|
|
||||||
switch (opcode)
|
|
||||||
{
|
|
||||||
case AML::Byte::ToIntegerOp:
|
|
||||||
case AML::Byte::ToBufferOp:
|
|
||||||
case AML::Byte::ToStringOp:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ASSERT_NOT_REACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto data_result = AML::parse_object(context);
|
|
||||||
if (!data_result.success())
|
|
||||||
return ParseResult::Failure;
|
|
||||||
auto data_node = data_result.node();
|
|
||||||
if (!data_node)
|
|
||||||
{
|
|
||||||
AML_ERROR("Conversion {2H} data could not be evaluated", static_cast<uint8_t>(opcode));
|
|
||||||
return ParseResult::Failure;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (context.aml_data.size() < 1)
|
|
||||||
{
|
|
||||||
AML_ERROR("Conversion {2H} missing target", static_cast<uint8_t>(opcode));
|
|
||||||
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);
|
|
||||||
if (!target_result.success())
|
|
||||||
return ParseResult::Failure;
|
|
||||||
target_node = target_result.node();
|
|
||||||
if (!target_node)
|
|
||||||
{
|
|
||||||
AML_ERROR("Conversion {2H} target invalid", static_cast<uint8_t>(opcode));
|
|
||||||
return ParseResult::Failure;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> converted;
|
|
||||||
switch (opcode)
|
|
||||||
{
|
|
||||||
case AML::Byte::ToBufferOp:
|
|
||||||
converted = data_node->convert(AML::Node::ConvBuffer);
|
|
||||||
break;
|
|
||||||
case AML::Byte::ToIntegerOp:
|
|
||||||
converted = data_node->convert(AML::Node::ConvInteger);
|
|
||||||
break;
|
|
||||||
case AML::Byte::ToStringOp:
|
|
||||||
converted = data_node->convert(AML::Node::ConvString);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ASSERT_NOT_REACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!converted)
|
|
||||||
{
|
|
||||||
AML_ERROR("Conversion {2H} could not convert from node type {}", static_cast<uint8_t>(opcode), static_cast<uint8_t>(data_node->type));
|
|
||||||
return ParseResult::Failure;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target_node && !target_node->store(converted))
|
|
||||||
{
|
|
||||||
AML_ERROR("Conversion {2H} failed to store converted value", static_cast<uint8_t>(opcode));
|
|
||||||
return ParseResult::Failure;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ParseResult(converted);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,68 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <kernel/ACPI/AML/Alias.h>
|
|
||||||
#include <kernel/ACPI/AML/NamedObject.h>
|
|
||||||
#include <kernel/ACPI/AML/ParseContext.h>
|
|
||||||
#include <kernel/ACPI/AML/Register.h>
|
|
||||||
|
|
||||||
namespace Kernel::ACPI::AML
|
|
||||||
{
|
|
||||||
|
|
||||||
struct CopyObject
|
|
||||||
{
|
|
||||||
static ParseResult parse(ParseContext& context)
|
|
||||||
{
|
|
||||||
ASSERT(context.aml_data.size() >= 1);
|
|
||||||
ASSERT(static_cast<Byte>(context.aml_data[0]) == Byte::CopyObjectOp);
|
|
||||||
context.aml_data = context.aml_data.slice(1);
|
|
||||||
|
|
||||||
auto source_result = AML::parse_object(context);
|
|
||||||
if (!source_result.success())
|
|
||||||
return ParseResult::Failure;
|
|
||||||
auto source = source_result.node()
|
|
||||||
? source_result.node()->to_underlying()
|
|
||||||
: BAN::RefPtr<AML::Node>();
|
|
||||||
if (!source)
|
|
||||||
{
|
|
||||||
AML_ERROR("CopyObject source is null");
|
|
||||||
return ParseResult::Failure;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto destination_result = AML::parse_object(context);
|
|
||||||
if (!destination_result.success())
|
|
||||||
return ParseResult::Failure;
|
|
||||||
auto destination = destination_result.node();
|
|
||||||
if (!destination)
|
|
||||||
{
|
|
||||||
AML_ERROR("CopyObject destination is null");
|
|
||||||
return ParseResult::Failure;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if AML_DEBUG_LEVEL >= 2
|
|
||||||
AML_DEBUG_PRINTLN("CopyObject {");
|
|
||||||
source->debug_print(1);
|
|
||||||
AML_DEBUG_PRINTLN("");
|
|
||||||
AML_DEBUG_PRINTLN("} to {");
|
|
||||||
destination->debug_print(1);
|
|
||||||
AML_DEBUG_PRINTLN("");
|
|
||||||
AML_DEBUG_PRINTLN("}");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch (destination->type)
|
|
||||||
{
|
|
||||||
case AML::Node::Type::Alias:
|
|
||||||
static_cast<AML::Alias*>(destination.ptr())->target = source->copy();
|
|
||||||
return source;
|
|
||||||
case AML::Node::Type::Name:
|
|
||||||
static_cast<AML::Name*>(destination.ptr())->object = source->copy();
|
|
||||||
return source;
|
|
||||||
case AML::Node::Type::Register:
|
|
||||||
static_cast<AML::Register*>(destination.ptr())->value = source->copy();
|
|
||||||
return source;
|
|
||||||
default:
|
|
||||||
ASSERT_NOT_REACHED();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
|
@ -8,14 +8,12 @@
|
||||||
namespace Kernel::ACPI::AML
|
namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
|
|
||||||
struct Device final : public AML::Scope
|
struct Device : 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);
|
||||||
|
@ -33,7 +31,7 @@ namespace Kernel::ACPI::AML
|
||||||
|
|
||||||
auto device = MUST(BAN::RefPtr<Device>::create(name_string->path.back()));
|
auto device = MUST(BAN::RefPtr<Device>::create(name_string->path.back()));
|
||||||
if (!Namespace::root_namespace()->add_named_object(context, name_string.value(), device))
|
if (!Namespace::root_namespace()->add_named_object(context, name_string.value(), device))
|
||||||
return ParseResult::Success;
|
return ParseResult::Failure;
|
||||||
|
|
||||||
return device->enter_context_and_parse_term_list(context, name_string.value(), device_pkg.value());
|
return device->enter_context_and_parse_term_list(context, name_string.value(), device_pkg.value());
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
namespace Kernel::ACPI::AML
|
namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
|
|
||||||
struct Event final : public AML::NamedObject
|
struct Event : public AML::NamedObject
|
||||||
{
|
{
|
||||||
BAN::Atomic<uint32_t> signal_count { 0 };
|
BAN::Atomic<uint32_t> signal_count { 0 };
|
||||||
ThreadBlocker thread_blocker;
|
ThreadBlocker thread_blocker;
|
||||||
|
@ -19,8 +19,6 @@ 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);
|
||||||
|
@ -45,7 +43,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();
|
auto general_node = event_result.node() ? event_result.node()->evaluate() : BAN::RefPtr<AML::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");
|
||||||
|
@ -60,15 +58,12 @@ namespace Kernel::ACPI::AML
|
||||||
if (!timeout_result.success())
|
if (!timeout_result.success())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
|
|
||||||
auto timeout_node = timeout_result.node()
|
auto timeout = timeout_result.node() ? timeout_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
|
||||||
? timeout_result.node()->convert(AML::Node::ConvInteger)
|
if (!timeout)
|
||||||
: 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)
|
||||||
|
@ -82,14 +77,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,10 +1,9 @@
|
||||||
#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
|
||||||
{
|
{
|
||||||
|
@ -26,14 +25,13 @@ 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 conv_node = source_result.node() ? source_result.node()->convert(AML::Node::ConvInteger) : BAN::RefPtr<AML::Node>();
|
auto source_node = source_result.node() ? source_result.node()->as_integer(): BAN::RefPtr<AML::Integer>();
|
||||||
if (!conv_node)
|
if (!source_node)
|
||||||
{
|
{
|
||||||
AML_ERROR("UnaryOp source not integer, type {}", static_cast<uint8_t>(source_result.node()->type));
|
AML_ERROR("UnaryOp source not integer");
|
||||||
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");
|
||||||
|
@ -50,23 +48,18 @@ namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
context.aml_data = context.aml_data.slice(1);
|
context.aml_data = context.aml_data.slice(1);
|
||||||
|
|
||||||
auto source_result = AML::parse_object(context);
|
auto node_result = AML::parse_object(context);
|
||||||
if (!source_result.success())
|
if (!node_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>();
|
|
||||||
if (!conv_node)
|
auto value = node_result.node() ? node_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
|
||||||
{
|
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 = source_node->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:
|
||||||
|
@ -104,25 +97,21 @@ 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_conv = lhs_result.node() ? lhs_result.node()->convert(AML::Node::ConvInteger) : BAN::RefPtr<AML::Node>();
|
auto lhs_value = lhs_result.node() ? lhs_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
|
||||||
if (!lhs_conv)
|
if (!lhs_value)
|
||||||
{
|
{
|
||||||
AML_ERROR("BinaryOP {2H} LHS not an integer, type {}",
|
AML_ERROR("BinaryOP {2H} LHS not an integer", static_cast<uint8_t>(opcode));
|
||||||
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_conv = rhs_result.node() ? rhs_result.node()->convert(AML::Node::ConvInteger) : BAN::RefPtr<AML::Node>();
|
auto rhs_value = rhs_result.node() ? rhs_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
|
||||||
if (!rhs_conv)
|
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())
|
||||||
|
@ -130,14 +119,12 @@ 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);
|
||||||
|
@ -172,7 +159,9 @@ namespace Kernel::ACPI::AML
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto result_node = MUST(BAN::RefPtr<AML::Integer>::create(func(lhs_value, rhs_value)));
|
uint64_t result = func(lhs_value->value, rhs_value->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));
|
||||||
|
@ -187,26 +176,10 @@ 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()->convert(mask) : BAN::RefPtr<AML::Node>();
|
auto lhs_node = lhs_result.node() ? lhs_result.node()->evaluate() : 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 final : public AML::NamedObject
|
struct FieldElement : public NamedObject
|
||||||
{
|
{
|
||||||
uint64_t bit_offset;
|
uint64_t bit_offset;
|
||||||
uint64_t bit_count;
|
uint64_t bit_count;
|
||||||
|
@ -63,30 +63,14 @@ namespace Kernel::ACPI::AML
|
||||||
, access_rules(access_rules)
|
, access_rules(access_rules)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> convert(uint8_t mask) override
|
BAN::RefPtr<AML::Integer> as_integer() 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<AML::Node> store(BAN::RefPtr<Node> source) override;
|
BAN::RefPtr<Node> evaluate() override { return as_integer(); }
|
||||||
|
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);
|
||||||
|
|
||||||
|
@ -99,7 +83,7 @@ namespace Kernel::ACPI::AML
|
||||||
static ParseResult parse(ParseContext& context);
|
static ParseResult parse(ParseContext& context);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IndexFieldElement final : public AML::NamedObject
|
struct IndexFieldElement : public NamedObject
|
||||||
{
|
{
|
||||||
uint64_t bit_offset;
|
uint64_t bit_offset;
|
||||||
uint64_t bit_count;
|
uint64_t bit_count;
|
||||||
|
@ -116,30 +100,12 @@ namespace Kernel::ACPI::AML
|
||||||
, access_rules(access_rules)
|
, access_rules(access_rules)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> convert(uint8_t mask) override
|
BAN::RefPtr<AML::Integer> as_integer() 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;
|
BAN::RefPtr<AML::Node> evaluate() override { return as_integer(); }
|
||||||
|
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
|
||||||
|
@ -147,7 +113,7 @@ namespace Kernel::ACPI::AML
|
||||||
static ParseResult parse(ParseContext& context);
|
static ParseResult parse(ParseContext& context);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BankFieldElement final : public AML::NamedObject
|
struct BankFieldElement : public NamedObject
|
||||||
{
|
{
|
||||||
uint64_t bit_offset;
|
uint64_t bit_offset;
|
||||||
uint64_t bit_count;
|
uint64_t bit_count;
|
||||||
|
@ -165,30 +131,10 @@ namespace Kernel::ACPI::AML
|
||||||
, access_rules(access_rules)
|
, access_rules(access_rules)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> convert(uint8_t mask) override
|
BAN::RefPtr<Node> evaluate() 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,13 +26,12 @@ 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_node = predicate_result.node() ? predicate_result.node()->convert(AML::Node::ConvInteger) : BAN::RefPtr<AML::Node>();
|
auto predicate = predicate_result.node() ? predicate_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
|
||||||
if (!predicate_node)
|
if (!predicate)
|
||||||
{
|
{
|
||||||
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;
|
||||||
|
@ -44,14 +43,14 @@ 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)
|
||||||
{
|
{
|
||||||
auto object_result = AML::parse_object(context);
|
auto object_result = AML::parse_object(context);
|
||||||
if (object_result.returned() || object_result.breaked() || object_result.continued())
|
if (object_result.returned())
|
||||||
return object_result;
|
return ParseResult(ParseResult::Result::Returned, object_result.node());
|
||||||
if (!object_result.success())
|
if (!object_result.success())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#include <kernel/ACPI/AML/Package.h>
|
#include <kernel/ACPI/AML/Package.h>
|
||||||
#include <kernel/ACPI/AML/ParseContext.h>
|
#include <kernel/ACPI/AML/ParseContext.h>
|
||||||
#include <kernel/ACPI/AML/Reference.h>
|
#include <kernel/ACPI/AML/Reference.h>
|
||||||
#include <kernel/ACPI/AML/Register.h>
|
|
||||||
|
|
||||||
namespace Kernel::ACPI::AML
|
namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
|
@ -21,27 +20,22 @@ 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()->to_underlying() : BAN::RefPtr<AML::Node>();
|
auto source = source_result.node() ? source_result.node()->evaluate() : BAN::RefPtr<AML::Node>();
|
||||||
if (source && source->type != AML::Node::Type::Package)
|
|
||||||
source = source->convert(AML::Node::ConvBuffer | AML::Node::ConvInteger | AML::Node::ConvString);
|
|
||||||
if (!source)
|
if (!source)
|
||||||
{
|
{
|
||||||
AML_ERROR("IndexOp source could not be converted");
|
AML_ERROR("IndexOp source is null");
|
||||||
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_node = index_result.node()
|
auto index = index_result.node() ? index_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
|
||||||
? index_result.node()->convert(AML::Node::ConvInteger)
|
if (!index)
|
||||||
: 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)
|
||||||
|
@ -49,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 >= 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 * 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 >= 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];
|
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 >= 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 * 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;
|
||||||
}
|
}
|
||||||
|
@ -88,7 +82,7 @@ namespace Kernel::ACPI::AML
|
||||||
}
|
}
|
||||||
|
|
||||||
#if AML_DEBUG_LEVEL >= 2
|
#if AML_DEBUG_LEVEL >= 2
|
||||||
AML_DEBUG_PRINT("Index {}, ", index);
|
AML_DEBUG_PRINT("Index {}, ", index->value);
|
||||||
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 final : public AML::Node
|
struct Integer : public Node
|
||||||
{
|
{
|
||||||
struct Constants
|
struct Constants
|
||||||
{
|
{
|
||||||
|
@ -23,17 +23,141 @@ namespace Kernel::ACPI::AML
|
||||||
uint64_t value;
|
uint64_t value;
|
||||||
const bool constant;
|
const bool constant;
|
||||||
|
|
||||||
Integer(uint64_t value, bool constant = false);
|
Integer(uint64_t value, bool constant = false)
|
||||||
|
: Node(Node::Type::Integer)
|
||||||
|
, value(value)
|
||||||
|
, constant(constant)
|
||||||
|
{}
|
||||||
|
|
||||||
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>();
|
||||||
|
if (!rhs)
|
||||||
|
{
|
||||||
|
AML_ERROR("Integer logical compare RHS is not integer");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> convert(uint8_t mask) override;
|
switch (binaryop)
|
||||||
BAN::RefPtr<Node> copy() override;
|
{
|
||||||
BAN::RefPtr<AML::Node> store(BAN::RefPtr<AML::Node> store_node) override;
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static ParseResult parse(BAN::ConstByteSpan& aml_data);
|
BAN::RefPtr<AML::Integer> as_integer() override { return this; }
|
||||||
|
|
||||||
void debug_print(int indent) const override;
|
BAN::RefPtr<Node> copy() override { return MUST(BAN::RefPtr<Integer>::create(value)); }
|
||||||
|
|
||||||
|
BAN::RefPtr<AML::Node> evaluate() override
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool store(BAN::RefPtr<AML::Node> store_node) override
|
||||||
|
{
|
||||||
|
if (constant)
|
||||||
|
{
|
||||||
|
AML_ERROR("Cannot store to constant integer");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto store_value = store_node->as_integer();
|
||||||
|
if (!store_value)
|
||||||
|
{
|
||||||
|
AML_ERROR("Cannot store non-integer to integer");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
value = store_value->value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ParseResult parse(BAN::ConstByteSpan& aml_data)
|
||||||
|
{
|
||||||
|
switch (static_cast<AML::Byte>(aml_data[0]))
|
||||||
|
{
|
||||||
|
case AML::Byte::ZeroOp:
|
||||||
|
aml_data = aml_data.slice(1);
|
||||||
|
return ParseResult(Constants::Zero);
|
||||||
|
case AML::Byte::OneOp:
|
||||||
|
aml_data = aml_data.slice(1);
|
||||||
|
return ParseResult(Constants::One);
|
||||||
|
case AML::Byte::OnesOp:
|
||||||
|
aml_data = aml_data.slice(1);
|
||||||
|
return ParseResult(Constants::Ones);
|
||||||
|
case AML::Byte::BytePrefix:
|
||||||
|
{
|
||||||
|
if (aml_data.size() < 2)
|
||||||
|
return ParseResult::Failure;
|
||||||
|
const uint8_t value = aml_data[1];
|
||||||
|
aml_data = aml_data.slice(2);
|
||||||
|
return ParseResult(MUST(BAN::RefPtr<Integer>::create(value)));
|
||||||
|
}
|
||||||
|
case AML::Byte::WordPrefix:
|
||||||
|
{
|
||||||
|
if (aml_data.size() < 3)
|
||||||
|
return ParseResult::Failure;
|
||||||
|
uint16_t value = 0;
|
||||||
|
value |= aml_data[1] << 0;
|
||||||
|
value |= aml_data[2] << 8;
|
||||||
|
aml_data = aml_data.slice(3);
|
||||||
|
return ParseResult(MUST(BAN::RefPtr<Integer>::create(value)));
|
||||||
|
}
|
||||||
|
case AML::Byte::DWordPrefix:
|
||||||
|
{
|
||||||
|
if (aml_data.size() < 5)
|
||||||
|
return ParseResult::Failure;
|
||||||
|
uint32_t value = 0;
|
||||||
|
value |= static_cast<uint32_t>(aml_data[1]) << 0;
|
||||||
|
value |= static_cast<uint32_t>(aml_data[2]) << 8;
|
||||||
|
value |= static_cast<uint32_t>(aml_data[3]) << 16;
|
||||||
|
value |= static_cast<uint32_t>(aml_data[4]) << 24;
|
||||||
|
aml_data = aml_data.slice(5);
|
||||||
|
return ParseResult(MUST(BAN::RefPtr<Integer>::create(value)));
|
||||||
|
}
|
||||||
|
case AML::Byte::QWordPrefix:
|
||||||
|
{
|
||||||
|
if (aml_data.size() < 9)
|
||||||
|
return ParseResult::Failure;
|
||||||
|
uint64_t value = 0;
|
||||||
|
value |= static_cast<uint64_t>(aml_data[1]) << 0;
|
||||||
|
value |= static_cast<uint64_t>(aml_data[2]) << 8;
|
||||||
|
value |= static_cast<uint64_t>(aml_data[3]) << 16;
|
||||||
|
value |= static_cast<uint64_t>(aml_data[4]) << 24;
|
||||||
|
value |= static_cast<uint64_t>(aml_data[5]) << 32;
|
||||||
|
value |= static_cast<uint64_t>(aml_data[6]) << 40;
|
||||||
|
value |= static_cast<uint64_t>(aml_data[7]) << 48;
|
||||||
|
value |= static_cast<uint64_t>(aml_data[8]) << 56;
|
||||||
|
aml_data = aml_data.slice(9);
|
||||||
|
return ParseResult(MUST(BAN::RefPtr<Integer>::create(value)));
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void debug_print(int indent) const override
|
||||||
|
{
|
||||||
|
AML_DEBUG_PRINT_INDENT(indent);
|
||||||
|
if (!constant)
|
||||||
|
AML_DEBUG_PRINT("0x{H}", value);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AML_DEBUG_PRINT("Const ");
|
||||||
|
if (value == Constants::Zero->value)
|
||||||
|
AML_DEBUG_PRINT("Zero");
|
||||||
|
else if (value == Constants::One->value)
|
||||||
|
AML_DEBUG_PRINT("One");
|
||||||
|
else if (value == Constants::Ones->value)
|
||||||
|
AML_DEBUG_PRINT("Ones");
|
||||||
|
else
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,16 +3,14 @@
|
||||||
#include <BAN/Function.h>
|
#include <BAN/Function.h>
|
||||||
#include <kernel/ACPI/AML/Bytes.h>
|
#include <kernel/ACPI/AML/Bytes.h>
|
||||||
#include <kernel/ACPI/AML/Namespace.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>
|
||||||
#include <kernel/ACPI/AML/Pkg.h>
|
#include <kernel/ACPI/AML/Pkg.h>
|
||||||
#include <kernel/ACPI/AML/Register.h>
|
|
||||||
#include <kernel/ACPI/AML/Scope.h>
|
#include <kernel/ACPI/AML/Scope.h>
|
||||||
|
|
||||||
namespace Kernel::ACPI::AML
|
namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
|
|
||||||
struct Method final : public AML::Scope
|
struct Method : public AML::Scope
|
||||||
{
|
{
|
||||||
Kernel::Mutex mutex;
|
Kernel::Mutex mutex;
|
||||||
uint8_t arg_count;
|
uint8_t arg_count;
|
||||||
|
@ -29,8 +27,6 @@ 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);
|
||||||
|
@ -146,8 +142,8 @@ namespace Kernel::ACPI::AML
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (return_value.has_value() && return_value.value() && return_value.value()->type == AML::Node::Type::Register)
|
if (return_value.has_value() && return_value.value())
|
||||||
return_value.value() = static_cast<AML::Register*>(return_value.value().ptr())->value;
|
return_value = return_value.value()->evaluate();
|
||||||
|
|
||||||
while (!context.created_objects.empty())
|
while (!context.created_objects.empty())
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,20 +10,16 @@
|
||||||
namespace Kernel::ACPI::AML
|
namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
|
|
||||||
struct Mutex final : public AML::NamedObject
|
struct Mutex : public AML::NamedObject
|
||||||
{
|
{
|
||||||
Kernel::Mutex mutex;
|
Kernel::Mutex mutex;
|
||||||
uint8_t sync_level;
|
uint8_t sync_level;
|
||||||
bool global;
|
|
||||||
|
|
||||||
Mutex(NameSeg name, uint8_t sync_level, bool global = false)
|
Mutex(NameSeg name, uint8_t sync_level)
|
||||||
: NamedObject(Node::Type::Mutex, name)
|
: NamedObject(Node::Type::Mutex, name)
|
||||||
, sync_level(sync_level)
|
, sync_level(sync_level)
|
||||||
, global(global)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
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);
|
||||||
|
@ -75,7 +71,7 @@ namespace Kernel::ACPI::AML
|
||||||
|
|
||||||
auto mutex = MUST(BAN::RefPtr<Mutex>::create(name->path.back(), sync_level));
|
auto mutex = MUST(BAN::RefPtr<Mutex>::create(name->path.back(), sync_level));
|
||||||
if (!Namespace::root_namespace()->add_named_object(context, name.value(), mutex))
|
if (!Namespace::root_namespace()->add_named_object(context, name.value(), mutex))
|
||||||
return ParseResult::Success;
|
return ParseResult::Failure;
|
||||||
|
|
||||||
#if AML_DEBUG_LEVEL >= 2
|
#if AML_DEBUG_LEVEL >= 2
|
||||||
mutex->debug_print(0);
|
mutex->debug_print(0);
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
namespace Kernel::ACPI::AML
|
namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
|
|
||||||
struct NamedObject : public AML::Node
|
struct NamedObject : public 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 final : public AML::NamedObject
|
struct Name : public NamedObject
|
||||||
{
|
{
|
||||||
BAN::RefPtr<AML::Node> object;
|
BAN::RefPtr<AML::Node> object;
|
||||||
|
|
||||||
|
@ -22,19 +22,21 @@ 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::Node> to_underlying() override { return 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> convert(uint8_t mask) override
|
BAN::RefPtr<AML::Node> evaluate() override
|
||||||
{
|
{
|
||||||
ASSERT(object);
|
ASSERT(object);
|
||||||
return object->convert(mask);
|
return object->evaluate();
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> store(BAN::RefPtr<AML::Node> node) override
|
bool store(BAN::RefPtr<AML::Node> node) override
|
||||||
{
|
{
|
||||||
ASSERT(object);
|
ASSERT(object);
|
||||||
ASSERT(object->type != AML::Node::Type::Reference);
|
object = node;
|
||||||
return object->store(node);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ParseResult parse(ParseContext& context);
|
static ParseResult parse(ParseContext& context);
|
||||||
|
|
|
@ -8,9 +8,8 @@
|
||||||
namespace Kernel::ACPI::AML
|
namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
|
|
||||||
struct Namespace final : public AML::Scope
|
struct Namespace : 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;
|
||||||
|
|
||||||
|
@ -36,8 +35,7 @@ namespace Kernel::ACPI::AML
|
||||||
|
|
||||||
Namespace(NameSeg name) : AML::Scope(Node::Type::Namespace, name) {}
|
Namespace(NameSeg name) : AML::Scope(Node::Type::Namespace, name) {}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> convert(uint8_t) override { return {}; }
|
static BAN::RefPtr<AML::Namespace> create_root_namespace();
|
||||||
|
|
||||||
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,18 +17,8 @@ namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
static uint64_t total_node_count;
|
static uint64_t total_node_count;
|
||||||
|
|
||||||
enum Conversion : uint8_t
|
enum class Type
|
||||||
{
|
{
|
||||||
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,
|
||||||
|
@ -60,10 +50,14 @@ namespace Kernel::ACPI::AML
|
||||||
|
|
||||||
virtual bool is_scope() const { return false; }
|
virtual bool is_scope() const { return false; }
|
||||||
|
|
||||||
[[nodiscard]] virtual BAN::RefPtr<AML::Node> to_underlying() { return this; }
|
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;
|
||||||
};
|
};
|
||||||
|
@ -79,8 +73,6 @@ namespace Kernel::ACPI::AML
|
||||||
Success,
|
Success,
|
||||||
Failure,
|
Failure,
|
||||||
Returned,
|
Returned,
|
||||||
Breaked,
|
|
||||||
Continued,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ParseResult(Result success)
|
ParseResult(Result success)
|
||||||
|
@ -99,8 +91,6 @@ namespace Kernel::ACPI::AML
|
||||||
|
|
||||||
bool success() const { return m_result == Result::Success; }
|
bool success() const { return m_result == Result::Success; }
|
||||||
bool returned() const { return m_result == Result::Returned; }
|
bool returned() const { return m_result == Result::Returned; }
|
||||||
bool breaked() const { return m_result == Result::Breaked; }
|
|
||||||
bool continued() const { return m_result == Result::Continued; }
|
|
||||||
|
|
||||||
BAN::RefPtr<Node> node()
|
BAN::RefPtr<Node> node()
|
||||||
{
|
{
|
||||||
|
|
|
@ -29,13 +29,12 @@ 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_node = value_result.node() ? value_result.node()->convert(AML::Node::ConvInteger) : BAN::RefPtr<AML::Node>();
|
auto value = value_result.node() ? value_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
|
||||||
if (!value_node)
|
if (!value)
|
||||||
{
|
{
|
||||||
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;
|
||||||
|
@ -59,7 +58,7 @@ namespace Kernel::ACPI::AML
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
AML_TODO("Notify: {} {}: {2H}", object_type_sv, object_name_sv, value);
|
AML_TODO("Notify: {} {}: {2H}", object_type_sv, object_name_sv, value->value);
|
||||||
return ParseResult::Success;
|
return ParseResult::Success;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,14 +5,13 @@
|
||||||
#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>
|
||||||
#include <kernel/ACPI/AML/Reference.h>
|
|
||||||
|
|
||||||
namespace Kernel::ACPI::AML
|
namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
|
|
||||||
struct PackageElement;
|
struct PackageElement;
|
||||||
|
|
||||||
struct Package final : public AML::Node
|
struct Package : public AML::Node
|
||||||
{
|
{
|
||||||
BAN::Vector<BAN::RefPtr<PackageElement>> elements;
|
BAN::Vector<BAN::RefPtr<PackageElement>> elements;
|
||||||
AML::NameString scope;
|
AML::NameString scope;
|
||||||
|
@ -23,13 +22,16 @@ namespace Kernel::ACPI::AML
|
||||||
, scope(scope)
|
, scope(scope)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> convert(uint8_t) override { return {}; }
|
BAN::RefPtr<AML::Node> evaluate() override
|
||||||
|
{
|
||||||
|
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 final : public AML::Node
|
struct PackageElement : public AML::Node
|
||||||
{
|
{
|
||||||
BAN::RefPtr<AML::Package> parent;
|
BAN::RefPtr<AML::Package> parent;
|
||||||
BAN::RefPtr<AML::Node> element;
|
BAN::RefPtr<AML::Node> element;
|
||||||
|
@ -80,7 +82,7 @@ namespace Kernel::ACPI::AML
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> convert(uint8_t mask) override
|
bool store(BAN::RefPtr<AML::Node> node) override
|
||||||
{
|
{
|
||||||
if (!initialized)
|
if (!initialized)
|
||||||
{
|
{
|
||||||
|
@ -89,24 +91,34 @@ namespace Kernel::ACPI::AML
|
||||||
}
|
}
|
||||||
if (!resolved && !resolve())
|
if (!resolved && !resolve())
|
||||||
return {};
|
return {};
|
||||||
return element->convert(mask);
|
if (element->type == AML::Node::Type::Reference)
|
||||||
|
return element->store(node);
|
||||||
|
element = node->copy();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> store(BAN::RefPtr<AML::Node> node) override
|
BAN::RefPtr<AML::Integer> as_integer() override
|
||||||
{
|
{
|
||||||
if (!initialized)
|
if (!initialized)
|
||||||
{
|
{
|
||||||
AML_ERROR("Trying to store into uninitialized PackageElement");
|
AML_ERROR("Trying to evaluate uninitialized PackageElement");
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
if (!resolved && !resolve())
|
if (!resolved && !resolve())
|
||||||
return {};
|
return {};
|
||||||
ASSERT(element->type != AML::Node::Type::Reference);
|
return element->as_integer();
|
||||||
if (node->type == AML::Node::Type::Reference)
|
}
|
||||||
element = static_cast<AML::Reference*>(element.ptr())->node;
|
|
||||||
else
|
BAN::RefPtr<AML::Node> evaluate() override
|
||||||
element = element->copy();
|
{
|
||||||
return element;
|
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 final : public AML::Scope
|
struct PowerResource : public AML::Scope
|
||||||
{
|
{
|
||||||
uint8_t system_level;
|
uint8_t system_level;
|
||||||
uint16_t resource_order;
|
uint16_t resource_order;
|
||||||
|
@ -20,8 +20,6 @@ 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 final : public AML::Scope
|
struct Processor : public AML::Scope
|
||||||
{
|
{
|
||||||
uint8_t id;
|
uint8_t id;
|
||||||
uint32_t pblk_addr;
|
uint32_t pblk_addr;
|
||||||
|
@ -22,8 +22,6 @@ 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);
|
||||||
|
@ -57,7 +55,7 @@ namespace Kernel::ACPI::AML
|
||||||
|
|
||||||
auto processor = MUST(BAN::RefPtr<Processor>::create(name->path.back(), id, pblk_addr, pblk_len));
|
auto processor = MUST(BAN::RefPtr<Processor>::create(name->path.back(), id, pblk_addr, pblk_len));
|
||||||
if (!Namespace::root_namespace()->add_named_object(context, name.value(), processor))
|
if (!Namespace::root_namespace()->add_named_object(context, name.value(), processor))
|
||||||
return ParseResult::Success;
|
return ParseResult::Failure;
|
||||||
|
|
||||||
#if AML_DEBUG_LEVEL >= 2
|
#if AML_DEBUG_LEVEL >= 2
|
||||||
processor->debug_print(0);
|
processor->debug_print(0);
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
namespace Kernel::ACPI::AML
|
namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
|
|
||||||
struct Reference final : public AML::Node
|
struct Reference : public AML::Node
|
||||||
{
|
{
|
||||||
BAN::RefPtr<AML::Node> node;
|
BAN::RefPtr<AML::Node> node;
|
||||||
|
|
||||||
|
@ -21,15 +21,25 @@ namespace Kernel::ACPI::AML
|
||||||
ASSERT(node);
|
ASSERT(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> convert(uint8_t mask) override
|
BAN::RefPtr<AML::Integer> as_integer() override
|
||||||
{
|
{
|
||||||
ASSERT(node);
|
if (node)
|
||||||
return node->convert(mask);
|
return node->as_integer();
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> store(BAN::RefPtr<AML::Node> value) override
|
BAN::RefPtr<AML::Node> evaluate() override
|
||||||
{
|
{
|
||||||
ASSERT(node);
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool store(BAN::RefPtr<AML::Node> value) override
|
||||||
|
{
|
||||||
|
if (!node)
|
||||||
|
{
|
||||||
|
AML_ERROR("Storing to null reference");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return node->store(value);
|
return node->store(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,11 +81,6 @@ namespace Kernel::ACPI::AML
|
||||||
object = parse_result.node();
|
object = parse_result.node();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (object && object->type == AML::Node::Type::Reference)
|
|
||||||
object = static_cast<AML::Reference*>(object.ptr())->node;
|
|
||||||
if (object && object->type == AML::Node::Type::Register)
|
|
||||||
object = static_cast<AML::Register*>(object.ptr())->value;
|
|
||||||
|
|
||||||
if (!conditional)
|
if (!conditional)
|
||||||
{
|
{
|
||||||
if (!object)
|
if (!object)
|
||||||
|
@ -91,26 +96,18 @@ namespace Kernel::ACPI::AML
|
||||||
return ParseResult(reference);
|
return ParseResult(reference);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.aml_data.size() < 1)
|
if (context.aml_data.size() >= 1 && context.aml_data[0] != 0x00)
|
||||||
{
|
|
||||||
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;
|
||||||
target_node = target_result.node();
|
auto 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
|
||||||
|
@ -122,16 +119,8 @@ namespace Kernel::ACPI::AML
|
||||||
AML_DEBUG_PRINTLN("");
|
AML_DEBUG_PRINTLN("");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!object)
|
auto return_value = object ? Integer::Constants::Ones : Integer::Constants::Zero;
|
||||||
return AML::ParseResult(Integer::Constants::Zero);
|
return AML::ParseResult(return_value);
|
||||||
|
|
||||||
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)
|
||||||
|
@ -155,20 +144,18 @@ 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 node = parse_result.node();
|
auto object = parse_result.node() ? parse_result.node()->evaluate() : BAN::RefPtr<AML::Node>();
|
||||||
if (node && node->type == AML::Node::Type::Register)
|
if (!object || object->type != AML::Node::Type::Reference)
|
||||||
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 {}", node ? static_cast<uint8_t>(node->type) : 999);
|
AML_TODO("DerefOf source is not a Reference, but a {}", object ? static_cast<uint8_t>(object->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 ");
|
||||||
node->debug_print(0);
|
object->debug_print(0);
|
||||||
AML_DEBUG_PRINTLN("");
|
AML_DEBUG_PRINTLN("");
|
||||||
#endif
|
#endif
|
||||||
return ParseResult(static_cast<Reference*>(node.ptr())->node);
|
return ParseResult(static_cast<Reference*>(object.ptr())->node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,7 +164,6 @@ 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 final : public AML::NamedObject
|
struct OpRegion : public NamedObject
|
||||||
{
|
{
|
||||||
using RegionSpace = GAS::AddressSpaceID;
|
using RegionSpace = GAS::AddressSpaceID;
|
||||||
RegionSpace region_space;
|
RegionSpace region_space;
|
||||||
|
@ -24,8 +24,6 @@ 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);
|
||||||
|
@ -45,10 +43,8 @@ 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_node = offset_result.node()
|
auto offset = offset_result.node()->as_integer();
|
||||||
? offset_result.node()->convert(AML::Node::ConvInteger)
|
if (!offset)
|
||||||
: 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;
|
||||||
|
@ -57,27 +53,22 @@ 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_node = length_result.node()
|
auto length = length_result.node()->as_integer();
|
||||||
? length_result.node()->convert(AML::Node::ConvInteger)
|
if (!length)
|
||||||
: 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,
|
offset->value,
|
||||||
length
|
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))
|
||||||
return ParseResult::Success;
|
return ParseResult::Failure;
|
||||||
|
|
||||||
#if AML_DEBUG_LEVEL >= 2
|
#if AML_DEBUG_LEVEL >= 2
|
||||||
op_region->debug_print(0);
|
op_region->debug_print(0);
|
||||||
|
|
|
@ -5,19 +5,58 @@
|
||||||
namespace Kernel::ACPI::AML
|
namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
|
|
||||||
struct Register final : public AML::Node
|
struct Register : public AML::Node
|
||||||
{
|
{
|
||||||
BAN::RefPtr<AML::Node> value;
|
BAN::RefPtr<AML::Node> value;
|
||||||
|
|
||||||
Register();
|
Register()
|
||||||
Register(BAN::RefPtr<AML::Node> node);
|
: Node(Node::Type::Register)
|
||||||
|
{}
|
||||||
|
Register(BAN::RefPtr<AML::Node> value)
|
||||||
|
: Node(Node::Type::Register)
|
||||||
|
, value(value)
|
||||||
|
{}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> to_underlying() override { return 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> convert(uint8_t mask) override;
|
BAN::RefPtr<AML::Node> evaluate() override
|
||||||
BAN::RefPtr<AML::Node> store(BAN::RefPtr<AML::Node> source) override;
|
{
|
||||||
|
if (value)
|
||||||
|
return value->evaluate();
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
void debug_print(int indent) const 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();
|
||||||
|
if (!evaluated)
|
||||||
|
{
|
||||||
|
AML_ERROR("Failed to evaluate source for store");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
value = evaluated->copy();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void debug_print(int indent) const override
|
||||||
|
{
|
||||||
|
AML_DEBUG_PRINT_INDENT(indent);
|
||||||
|
if (!value)
|
||||||
|
AML_DEBUG_PRINT("Register { No value }");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AML_DEBUG_PRINTLN("Register { ");
|
||||||
|
value->debug_print(indent + 1);
|
||||||
|
AML_DEBUG_PRINTLN("");
|
||||||
|
AML_DEBUG_PRINT_INDENT(indent);
|
||||||
|
AML_DEBUG_PRINT(" }");
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,36 +21,30 @@ 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_node = object_result.node();
|
auto object = object_result.node()->evaluate();
|
||||||
if (object_node && object_node->type == AML::Node::Type::Register)
|
if (object && object->type == AML::Node::Type::Reference)
|
||||||
object_node = static_cast<AML::Register*>(object_node.ptr())->value;
|
object = static_cast<AML::Reference*>(object.ptr())->node->evaluate();
|
||||||
if (!object_node)
|
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_node->type)
|
switch (object->type)
|
||||||
{
|
{
|
||||||
case AML::Node::Type::Buffer:
|
case AML::Node::Type::Buffer:
|
||||||
size = static_cast<AML::Buffer*>(object_node.ptr())->buffer.size();
|
size = static_cast<AML::Buffer*>(object.ptr())->buffer.size();
|
||||||
break;
|
break;
|
||||||
case AML::Node::Type::String:
|
case AML::Node::Type::String:
|
||||||
size = static_cast<AML::String*>(object_node.ptr())->string.size();
|
size = static_cast<AML::String*>(object.ptr())->string.size();
|
||||||
break;
|
break;
|
||||||
case AML::Node::Type::Package:
|
case AML::Node::Type::Package:
|
||||||
size = static_cast<AML::Package*>(object_node.ptr())->elements.size();
|
size = static_cast<AML::Package*>(object.ptr())->elements.size();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ASSERT_NOT_REACHED();
|
AML_ERROR("SizeOf object is not a buffer, string or package ({})", static_cast<uint8_t>(object->type));
|
||||||
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ParseResult(MUST(BAN::RefPtr<Integer>::create(size)));
|
return ParseResult(MUST(BAN::RefPtr<Integer>::create(size)));
|
||||||
|
|
|
@ -19,22 +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_node = sleep_time_result.node()
|
auto sleep_time = sleep_time_result.node() ? sleep_time_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
|
||||||
? sleep_time_result.node()->convert(AML::Node::ConvInteger)
|
if (!sleep_time)
|
||||||
: 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();
|
auto source = source_result.node() ? source_result.node()->evaluate() : BAN::RefPtr<AML::Node>();
|
||||||
if (!source)
|
if (!source)
|
||||||
{
|
{
|
||||||
AML_ERROR("Store source is null");
|
AML_ERROR("Store source cannot be evaluated");
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,9 +44,9 @@ namespace Kernel::ACPI::AML
|
||||||
AML_DEBUG_PRINTLN("}");
|
AML_DEBUG_PRINTLN("}");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (auto stored = destination->store(source))
|
if (!destination->store(source))
|
||||||
return ParseResult(stored);
|
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
|
return ParseResult(destination);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
namespace Kernel::ACPI::AML
|
namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
|
|
||||||
struct String final : public AML::Node
|
struct String : public AML::Node
|
||||||
{
|
{
|
||||||
BAN::Vector<uint8_t> string;
|
BAN::Vector<uint8_t> string;
|
||||||
|
|
||||||
|
@ -22,31 +22,11 @@ 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::Node> convert(uint8_t mask) override;
|
BAN::RefPtr<AML::Buffer> as_buffer() override;
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> copy() override
|
BAN::RefPtr<AML::Node> evaluate() override
|
||||||
{
|
{
|
||||||
auto new_string = MUST(BAN::RefPtr<AML::String>::create());
|
return this;
|
||||||
MUST(new_string->string.resize(this->string.size()));
|
|
||||||
for (size_t i = 0; i < this->string.size(); i++)
|
|
||||||
new_string->string[i] = this->string[i];
|
|
||||||
return new_string;
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> store(BAN::RefPtr<AML::Node> node) override
|
|
||||||
{
|
|
||||||
ASSERT(node);
|
|
||||||
auto conv_node = node->convert(AML::Node::ConvString);
|
|
||||||
if (!conv_node)
|
|
||||||
{
|
|
||||||
AML_ERROR("Could not convert to String");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
auto* string_node = static_cast<AML::String*>(conv_node.ptr());
|
|
||||||
MUST(string.resize(string_node->string.size()));
|
|
||||||
for (size_t i = 0; i < string.size(); i++)
|
|
||||||
string[i] = string_node->string[i];
|
|
||||||
return string_node->copy();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::StringView string_view() const
|
BAN::StringView string_view() const
|
||||||
|
@ -61,9 +41,6 @@ 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,14 +9,12 @@
|
||||||
namespace Kernel::ACPI::AML
|
namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
|
|
||||||
struct ThermalZone final : public AML::Scope
|
struct ThermalZone : 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);
|
||||||
|
@ -35,7 +33,7 @@ namespace Kernel::ACPI::AML
|
||||||
|
|
||||||
auto thermal_zone = MUST(BAN::RefPtr<ThermalZone>::create(name->path.back()));
|
auto thermal_zone = MUST(BAN::RefPtr<ThermalZone>::create(name->path.back()));
|
||||||
if (!Namespace::root_namespace()->add_named_object(context, name.value(), thermal_zone))
|
if (!Namespace::root_namespace()->add_named_object(context, name.value(), thermal_zone))
|
||||||
return ParseResult::Success;
|
return ParseResult::Failure;
|
||||||
|
|
||||||
#if AML_DEBUG_LEVEL >= 2
|
#if AML_DEBUG_LEVEL >= 2
|
||||||
thermal_zone->debug_print(0);
|
thermal_zone->debug_print(0);
|
||||||
|
|
|
@ -12,22 +12,9 @@ namespace Kernel::ACPI::AML
|
||||||
static ParseResult parse(ParseContext& context)
|
static ParseResult parse(ParseContext& context)
|
||||||
{
|
{
|
||||||
ASSERT(context.aml_data.size() >= 1);
|
ASSERT(context.aml_data.size() >= 1);
|
||||||
|
ASSERT(static_cast<Byte>(context.aml_data[0]) == Byte::WhileOp);
|
||||||
AML::Byte opcode = static_cast<Byte>(context.aml_data[0]);
|
|
||||||
context.aml_data = context.aml_data.slice(1);
|
context.aml_data = context.aml_data.slice(1);
|
||||||
|
|
||||||
switch (opcode)
|
|
||||||
{
|
|
||||||
case AML::Byte::BreakOp:
|
|
||||||
return ParseResult(ParseResult::Result::Breaked);
|
|
||||||
case AML::Byte::ContinueOp:
|
|
||||||
return ParseResult(ParseResult::Result::Continued);
|
|
||||||
case AML::Byte::WhileOp:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ASSERT_NOT_REACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto while_pkg = AML::parse_pkg(context.aml_data);
|
auto while_pkg = AML::parse_pkg(context.aml_data);
|
||||||
if (!while_pkg.has_value())
|
if (!while_pkg.has_value())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
|
@ -42,27 +29,28 @@ 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_node = predicate_result.node()
|
auto predicate = predicate_result.node() ? predicate_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
|
||||||
? predicate_result.node()->convert(AML::Node::ConvInteger)
|
if (!predicate)
|
||||||
: 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 (!static_cast<AML::Integer*>(predicate_node.ptr())->value)
|
if (!predicate->value)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
while (context.aml_data.size() > 0)
|
while (context.aml_data.size() > 0)
|
||||||
{
|
{
|
||||||
|
// NOTE: we can just parse BreakOp here, since this is the only legal place for BreakOp
|
||||||
|
if (static_cast<AML::Byte>(context.aml_data[0]) == AML::Byte::BreakOp)
|
||||||
|
{
|
||||||
|
context.aml_data = context.aml_data.slice(1);
|
||||||
|
breaked = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
auto object_result = AML::parse_object(context);
|
auto object_result = AML::parse_object(context);
|
||||||
if (object_result.returned())
|
if (object_result.returned())
|
||||||
return ParseResult(ParseResult::Result::Returned, object_result.node());
|
return ParseResult(ParseResult::Result::Returned, object_result.node());
|
||||||
if (object_result.breaked())
|
|
||||||
breaked = true;
|
|
||||||
if (object_result.breaked() || object_result.continued())
|
|
||||||
break;
|
|
||||||
if (!object_result.success())
|
if (!object_result.success())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
#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>
|
||||||
|
@ -145,10 +144,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->convert(AML::Node::ConvInteger);
|
auto result = field_element->as_integer();
|
||||||
if (!result)
|
if (!result)
|
||||||
return {};
|
return {};
|
||||||
return static_cast<AML::Integer*>(result.ptr())->value;
|
return result->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GAS::write(uint64_t value)
|
bool GAS::write(uint64_t value)
|
||||||
|
@ -169,7 +168,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
|
||||||
|
@ -495,25 +494,7 @@ acpi_release_global_lock:
|
||||||
dwarnln("\\_S5 not found");
|
dwarnln("\\_S5 not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
BAN::RefPtr<AML::Node> s5_evaluated = s5_object;
|
auto s5_evaluated = s5_object->evaluate();
|
||||||
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");
|
||||||
|
@ -531,9 +512,9 @@ acpi_release_global_lock:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto slp_typa_node = s5_package->elements[0]->convert(AML::Node::ConvInteger);
|
auto slp_typa = s5_package->elements[0]->as_integer();
|
||||||
auto slp_typb_node = s5_package->elements[1]->convert(AML::Node::ConvInteger);
|
auto slp_typb = s5_package->elements[1]->as_integer();
|
||||||
if (!slp_typa_node || !slp_typb_node)
|
if (!slp_typa || !slp_typb)
|
||||||
{
|
{
|
||||||
dwarnln("Failed to get SLP_TYPx values");
|
dwarnln("Failed to get SLP_TYPx values");
|
||||||
return;
|
return;
|
||||||
|
@ -544,12 +525,9 @@ 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);
|
||||||
|
|
||||||
|
@ -557,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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -492,14 +492,13 @@ namespace Kernel::ACPI
|
||||||
return MUST(BAN::RefPtr<Integer>::create(result.value()));
|
return MUST(BAN::RefPtr<Integer>::create(result.value()));
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> AML::FieldElement::store(BAN::RefPtr<AML::Node> source)
|
bool AML::FieldElement::store(BAN::RefPtr<AML::Node> source)
|
||||||
{
|
{
|
||||||
ASSERT(source);
|
auto source_integer = source->as_integer();
|
||||||
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 {};
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
op_region->mutex.lock();
|
op_region->mutex.lock();
|
||||||
|
@ -511,9 +510,7 @@ namespace Kernel::ACPI
|
||||||
ACPI::release_global_lock();
|
ACPI::release_global_lock();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!store_internal(static_cast<AML::Integer*>(source_integer.ptr())->value))
|
return store_internal(source_integer->value);
|
||||||
return {};
|
|
||||||
return source_integer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AML::FieldElement::debug_print(int indent) const
|
void AML::FieldElement::debug_print(int indent) const
|
||||||
|
@ -629,30 +626,28 @@ namespace Kernel::ACPI
|
||||||
return MUST(BAN::RefPtr<Integer>::create(result.value()));
|
return MUST(BAN::RefPtr<Integer>::create(result.value()));
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> AML::IndexFieldElement::store(BAN::RefPtr<Node> source)
|
bool 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 {};
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {};
|
return false;
|
||||||
|
|
||||||
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 {};
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto read_func = [&](uint64_t byte_offset) -> BAN::Optional<uint64_t> {
|
auto read_func = [&](uint64_t byte_offset) -> BAN::Optional<uint64_t> {
|
||||||
|
@ -662,7 +657,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 {};
|
return false;
|
||||||
return data_element->store_internal(value);
|
return data_element->store_internal(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -675,10 +670,10 @@ namespace Kernel::ACPI
|
||||||
ACPI::release_global_lock();
|
ACPI::release_global_lock();
|
||||||
});
|
});
|
||||||
|
|
||||||
const auto source_value = static_cast<AML::Integer*>(source_integer.ptr())->value;
|
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_value, access_rules.update_rule, read_func, write_func))
|
return false;
|
||||||
return {};
|
|
||||||
return source_integer;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AML::IndexFieldElement::debug_print(int indent) const
|
void AML::IndexFieldElement::debug_print(int indent) const
|
||||||
|
@ -739,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_node = bank_value_result.node() ? bank_value_result.node()->convert(AML::Node::ConvInteger) : BAN::RefPtr<AML::Node>();
|
auto bank_value = bank_value_result.node() ? bank_value_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
|
||||||
if (!bank_value_node)
|
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;
|
||||||
|
@ -761,12 +756,11 @@ 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;
|
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));
|
||||||
|
@ -782,7 +776,7 @@ namespace Kernel::ACPI
|
||||||
return ParseResult::Success;
|
return ParseResult::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Integer> AML::BankFieldElement::as_integer()
|
BAN::RefPtr<AML::Node> AML::BankFieldElement::evaluate()
|
||||||
{
|
{
|
||||||
if (access_rules.access_attrib != FieldRules::AccessAttrib::Normal)
|
if (access_rules.access_attrib != FieldRules::AccessAttrib::Normal)
|
||||||
{
|
{
|
||||||
|
@ -818,7 +812,7 @@ namespace Kernel::ACPI
|
||||||
return MUST(BAN::RefPtr<Integer>::create(result.value()));
|
return MUST(BAN::RefPtr<Integer>::create(result.value()));
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> AML::BankFieldElement::store(BAN::RefPtr<AML::Node> source)
|
bool AML::BankFieldElement::store(BAN::RefPtr<AML::Node> source)
|
||||||
{
|
{
|
||||||
if (access_rules.access_attrib != FieldRules::AccessAttrib::Normal)
|
if (access_rules.access_attrib != FieldRules::AccessAttrib::Normal)
|
||||||
{
|
{
|
||||||
|
@ -826,17 +820,16 @@ namespace Kernel::ACPI
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(source);
|
auto source_integer = source->as_integer();
|
||||||
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 {};
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {};
|
return false;
|
||||||
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());
|
||||||
};
|
};
|
||||||
|
@ -859,10 +852,7 @@ namespace Kernel::ACPI
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto source_value = static_cast<AML::Integer*>(source_integer.ptr())->value;
|
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);
|
||||||
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
|
||||||
|
|
|
@ -1,180 +0,0 @@
|
||||||
#include <kernel/ACPI/AML/Buffer.h>
|
|
||||||
#include <kernel/ACPI/AML/Integer.h>
|
|
||||||
#include <kernel/ACPI/AML/String.h>
|
|
||||||
|
|
||||||
namespace Kernel::ACPI
|
|
||||||
{
|
|
||||||
|
|
||||||
AML::Integer::Integer(uint64_t value, bool constant)
|
|
||||||
: Node(Node::Type::Integer)
|
|
||||||
, value(value)
|
|
||||||
, constant(constant)
|
|
||||||
{}
|
|
||||||
|
|
||||||
BAN::Optional<bool> AML::Integer::logical_compare(BAN::RefPtr<AML::Node> node, AML::Byte binaryop)
|
|
||||||
{
|
|
||||||
auto rhs_node = node ? node->convert(AML::Node::ConvInteger) : BAN::RefPtr<AML::Node>();
|
|
||||||
if (!rhs_node)
|
|
||||||
{
|
|
||||||
AML_ERROR("Integer logical compare RHS cannot be converted to");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
const auto rhs_value = static_cast<AML::Integer*>(rhs_node.ptr())->value;
|
|
||||||
|
|
||||||
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::Node> AML::Integer::convert(uint8_t mask)
|
|
||||||
{
|
|
||||||
if (mask & AML::Node::ConvInteger)
|
|
||||||
return this;
|
|
||||||
if (mask & AML::Node::ConvBuffer)
|
|
||||||
{
|
|
||||||
auto buffer = MUST(BAN::RefPtr<AML::Buffer>::create());
|
|
||||||
MUST(buffer->buffer.resize(8));
|
|
||||||
for (size_t i = 0; i < 8; i++)
|
|
||||||
buffer->buffer[i] = (value >> (56 - i * 8)) & 0xFF;
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
constexpr auto get_hex_char =
|
|
||||||
[](uint8_t nibble)
|
|
||||||
{
|
|
||||||
return (nibble < 10 ? '0' : 'A' - 10) + nibble;
|
|
||||||
};
|
|
||||||
|
|
||||||
auto string = MUST(BAN::RefPtr<AML::String>::create());
|
|
||||||
MUST(string->string.resize(16));
|
|
||||||
for (size_t i = 0; i < 16; i++)
|
|
||||||
string->string[i] = get_hex_char((value >> (60 - i * 4)) & 0xF);
|
|
||||||
return string;
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> AML::Integer::copy()
|
|
||||||
{
|
|
||||||
return MUST(BAN::RefPtr<Integer>::create(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> AML::Integer::store(BAN::RefPtr<AML::Node> store_node)
|
|
||||||
{
|
|
||||||
if (constant)
|
|
||||||
{
|
|
||||||
AML_ERROR("Cannot store to constant integer");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
auto conv_node = store_node ? store_node->convert(AML::Node::ConvInteger) : BAN::RefPtr<AML::Node>();
|
|
||||||
if (!conv_node)
|
|
||||||
{
|
|
||||||
AML_ERROR("Cannot store non-integer to integer");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
value = static_cast<AML::Integer*>(conv_node.ptr())->value;
|
|
||||||
return MUST(BAN::RefPtr<AML::Integer>::create(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
AML::ParseResult AML::Integer::parse(BAN::ConstByteSpan& aml_data)
|
|
||||||
{
|
|
||||||
switch (static_cast<AML::Byte>(aml_data[0]))
|
|
||||||
{
|
|
||||||
case AML::Byte::ZeroOp:
|
|
||||||
aml_data = aml_data.slice(1);
|
|
||||||
return ParseResult(Constants::Zero);
|
|
||||||
case AML::Byte::OneOp:
|
|
||||||
aml_data = aml_data.slice(1);
|
|
||||||
return ParseResult(Constants::One);
|
|
||||||
case AML::Byte::OnesOp:
|
|
||||||
aml_data = aml_data.slice(1);
|
|
||||||
return ParseResult(Constants::Ones);
|
|
||||||
case AML::Byte::BytePrefix:
|
|
||||||
{
|
|
||||||
if (aml_data.size() < 2)
|
|
||||||
return ParseResult::Failure;
|
|
||||||
const uint8_t value = aml_data[1];
|
|
||||||
aml_data = aml_data.slice(2);
|
|
||||||
return ParseResult(MUST(BAN::RefPtr<Integer>::create(value)));
|
|
||||||
}
|
|
||||||
case AML::Byte::WordPrefix:
|
|
||||||
{
|
|
||||||
if (aml_data.size() < 3)
|
|
||||||
return ParseResult::Failure;
|
|
||||||
uint16_t value = 0;
|
|
||||||
value |= aml_data[1] << 0;
|
|
||||||
value |= aml_data[2] << 8;
|
|
||||||
aml_data = aml_data.slice(3);
|
|
||||||
return ParseResult(MUST(BAN::RefPtr<Integer>::create(value)));
|
|
||||||
}
|
|
||||||
case AML::Byte::DWordPrefix:
|
|
||||||
{
|
|
||||||
if (aml_data.size() < 5)
|
|
||||||
return ParseResult::Failure;
|
|
||||||
uint32_t value = 0;
|
|
||||||
value |= static_cast<uint32_t>(aml_data[1]) << 0;
|
|
||||||
value |= static_cast<uint32_t>(aml_data[2]) << 8;
|
|
||||||
value |= static_cast<uint32_t>(aml_data[3]) << 16;
|
|
||||||
value |= static_cast<uint32_t>(aml_data[4]) << 24;
|
|
||||||
aml_data = aml_data.slice(5);
|
|
||||||
return ParseResult(MUST(BAN::RefPtr<Integer>::create(value)));
|
|
||||||
}
|
|
||||||
case AML::Byte::QWordPrefix:
|
|
||||||
{
|
|
||||||
if (aml_data.size() < 9)
|
|
||||||
return ParseResult::Failure;
|
|
||||||
uint64_t value = 0;
|
|
||||||
value |= static_cast<uint64_t>(aml_data[1]) << 0;
|
|
||||||
value |= static_cast<uint64_t>(aml_data[2]) << 8;
|
|
||||||
value |= static_cast<uint64_t>(aml_data[3]) << 16;
|
|
||||||
value |= static_cast<uint64_t>(aml_data[4]) << 24;
|
|
||||||
value |= static_cast<uint64_t>(aml_data[5]) << 32;
|
|
||||||
value |= static_cast<uint64_t>(aml_data[6]) << 40;
|
|
||||||
value |= static_cast<uint64_t>(aml_data[7]) << 48;
|
|
||||||
value |= static_cast<uint64_t>(aml_data[8]) << 56;
|
|
||||||
aml_data = aml_data.slice(9);
|
|
||||||
return ParseResult(MUST(BAN::RefPtr<Integer>::create(value)));
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
ASSERT_NOT_REACHED();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AML::Integer::debug_print(int indent) const
|
|
||||||
{
|
|
||||||
AML_DEBUG_PRINT_INDENT(indent);
|
|
||||||
if (!constant)
|
|
||||||
AML_DEBUG_PRINT("0x{H}", value);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AML_DEBUG_PRINT("Const ");
|
|
||||||
if (value == Constants::Zero->value)
|
|
||||||
AML_DEBUG_PRINT("Zero");
|
|
||||||
else if (value == Constants::One->value)
|
|
||||||
AML_DEBUG_PRINT("One");
|
|
||||||
else if (value == Constants::Ones->value)
|
|
||||||
AML_DEBUG_PRINT("Ones");
|
|
||||||
else
|
|
||||||
ASSERT_NOT_REACHED();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -7,6 +7,24 @@
|
||||||
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);
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#include <kernel/ACPI/AML/Device.h>
|
#include <kernel/ACPI/AML/Device.h>
|
||||||
#include <kernel/ACPI/AML/Integer.h>
|
#include <kernel/ACPI/AML/Integer.h>
|
||||||
#include <kernel/ACPI/AML/Method.h>
|
#include <kernel/ACPI/AML/Method.h>
|
||||||
#include <kernel/ACPI/AML/Mutex.h>
|
|
||||||
#include <kernel/ACPI/AML/Namespace.h>
|
#include <kernel/ACPI/AML/Namespace.h>
|
||||||
#include <kernel/ACPI/AML/ParseContext.h>
|
#include <kernel/ACPI/AML/ParseContext.h>
|
||||||
#include <kernel/ACPI/AML/Region.h>
|
#include <kernel/ACPI/AML/Region.h>
|
||||||
|
@ -21,12 +20,11 @@ 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) {}
|
||||||
BAN::RefPtr<AML::Node> convert(uint8_t) override { return {}; }
|
bool store(BAN::RefPtr<AML::Node> node)
|
||||||
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 node;
|
return true;
|
||||||
}
|
}
|
||||||
void debug_print(int indent) const override
|
void debug_print(int indent) const override
|
||||||
{
|
{
|
||||||
|
@ -234,14 +232,11 @@ namespace Kernel::ACPI
|
||||||
ADD_PREDEFIED_NAMESPACE("_TZ"_sv);
|
ADD_PREDEFIED_NAMESPACE("_TZ"_sv);
|
||||||
#undef ADD_PREDEFIED_NAMESPACE
|
#undef ADD_PREDEFIED_NAMESPACE
|
||||||
|
|
||||||
auto gl = MUST(BAN::RefPtr<AML::Mutex>::create(NameSeg("_GL"_sv), 0, true));
|
|
||||||
ASSERT(s_root_namespace->add_named_object(context, AML::NameString("\\_GL"), gl));
|
|
||||||
|
|
||||||
// Add \_OSI that returns true for Linux compatibility
|
// Add \_OSI that returns true for Linux compatibility
|
||||||
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]->convert(AML::Node::ConvString);
|
auto arg = context.method_args[0]->evaluate();
|
||||||
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");
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
#include <kernel/ACPI/AML/Alias.h>
|
#include <kernel/ACPI/AML/Alias.h>
|
||||||
#include <kernel/ACPI/AML/Buffer.h>
|
#include <kernel/ACPI/AML/Buffer.h>
|
||||||
#include <kernel/ACPI/AML/Bytes.h>
|
#include <kernel/ACPI/AML/Bytes.h>
|
||||||
#include <kernel/ACPI/AML/Conversion.h>
|
|
||||||
#include <kernel/ACPI/AML/CopyObject.h>
|
|
||||||
#include <kernel/ACPI/AML/Device.h>
|
#include <kernel/ACPI/AML/Device.h>
|
||||||
#include <kernel/ACPI/AML/Expression.h>
|
#include <kernel/ACPI/AML/Expression.h>
|
||||||
#include <kernel/ACPI/AML/Event.h>
|
#include <kernel/ACPI/AML/Event.h>
|
||||||
|
@ -37,6 +35,24 @@ 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)
|
||||||
|
@ -150,10 +166,6 @@ namespace Kernel::ACPI
|
||||||
case AML::Byte::SubtractOp:
|
case AML::Byte::SubtractOp:
|
||||||
case AML::Byte::XorOp:
|
case AML::Byte::XorOp:
|
||||||
return AML::Expression::parse(context);
|
return AML::Expression::parse(context);
|
||||||
case AML::Byte::ToBufferOp:
|
|
||||||
case AML::Byte::ToIntegerOp:
|
|
||||||
case AML::Byte::ToStringOp:
|
|
||||||
return AML::Conversion::parse(context);
|
|
||||||
case AML::Byte::CreateBitFieldOp:
|
case AML::Byte::CreateBitFieldOp:
|
||||||
case AML::Byte::CreateByteFieldOp:
|
case AML::Byte::CreateByteFieldOp:
|
||||||
case AML::Byte::CreateWordFieldOp:
|
case AML::Byte::CreateWordFieldOp:
|
||||||
|
@ -174,14 +186,10 @@ namespace Kernel::ACPI
|
||||||
return AML::Scope::parse(context);
|
return AML::Scope::parse(context);
|
||||||
case AML::Byte::IfOp:
|
case AML::Byte::IfOp:
|
||||||
return AML::IfElse::parse(context);
|
return AML::IfElse::parse(context);
|
||||||
case AML::Byte::BreakOp:
|
|
||||||
case AML::Byte::ContinueOp:
|
|
||||||
case AML::Byte::WhileOp:
|
case AML::Byte::WhileOp:
|
||||||
return AML::While::parse(context);
|
return AML::While::parse(context);
|
||||||
case AML::Byte::StoreOp:
|
case AML::Byte::StoreOp:
|
||||||
return AML::Store::parse(context);
|
return AML::Store::parse(context);
|
||||||
case AML::Byte::CopyObjectOp:
|
|
||||||
return AML::CopyObject::parse(context);
|
|
||||||
case AML::Byte::DerefOfOp:
|
case AML::Byte::DerefOfOp:
|
||||||
case AML::Byte::RefOfOp:
|
case AML::Byte::RefOfOp:
|
||||||
return AML::Reference::parse(context);
|
return AML::Reference::parse(context);
|
||||||
|
@ -191,7 +199,6 @@ 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;
|
||||||
|
@ -222,27 +229,20 @@ namespace Kernel::ACPI
|
||||||
AML_ERROR("NameString {} not found in namespace", name_string.value());
|
AML_ERROR("NameString {} not found in namespace", name_string.value());
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
|
if (aml_object->type == AML::Node::Type::Method)
|
||||||
auto underlying = aml_object->to_underlying();
|
{
|
||||||
if (aml_object->type != AML::Node::Type::Method && underlying->type != AML::Node::Type::Method)
|
auto* method = static_cast<AML::Method*>(aml_object.ptr());
|
||||||
return ParseResult(aml_object);
|
|
||||||
|
|
||||||
auto* method = static_cast<AML::Method*>(
|
|
||||||
aml_object->type == AML::Node::Type::Method
|
|
||||||
? aml_object.ptr()
|
|
||||||
: underlying.ptr()
|
|
||||||
);
|
|
||||||
|
|
||||||
BAN::Array<BAN::RefPtr<AML::Node>, 7> args;
|
BAN::Array<BAN::RefPtr<AML::Node>, 7> args;
|
||||||
for (uint8_t i = 0; i < method->arg_count; i++)
|
for (uint8_t i = 0; i < method->arg_count; i++)
|
||||||
{
|
{
|
||||||
auto arg_result = AML::parse_object(context);
|
auto arg = AML::parse_object(context);
|
||||||
if (!arg_result.success() || !arg_result.node())
|
if (!arg.success())
|
||||||
{
|
{
|
||||||
AML_ERROR("Failed to parse argument {} for method {}", i, name_string.value());
|
AML_ERROR("Failed to parse argument {} for method {}", i, name_string.value());
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
args[i] = arg_result.node();
|
args[i] = MUST(BAN::RefPtr<AML::Register>::create(arg.node()));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto result = method->invoke_with_sync_stack(
|
auto result = method->invoke_with_sync_stack(
|
||||||
|
@ -264,6 +264,8 @@ namespace Kernel::ACPI
|
||||||
return ParseResult::Success;
|
return ParseResult::Success;
|
||||||
return ParseResult(result.value());
|
return ParseResult(result.value());
|
||||||
}
|
}
|
||||||
|
return ParseResult(aml_object);
|
||||||
|
}
|
||||||
|
|
||||||
AML_TODO("{2H}", context.aml_data[0]);
|
AML_TODO("{2H}", context.aml_data[0]);
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
|
|
|
@ -1,71 +1,30 @@
|
||||||
#include <kernel/ACPI/AML/Reference.h>
|
#include <kernel/ACPI/AML/Buffer.h>
|
||||||
|
#include <kernel/ACPI/AML/Integer.h>
|
||||||
#include <kernel/ACPI/AML/Register.h>
|
#include <kernel/ACPI/AML/Register.h>
|
||||||
|
#include <kernel/ACPI/AML/String.h>
|
||||||
|
|
||||||
namespace Kernel::ACPI
|
namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
|
|
||||||
AML::Register::Register()
|
BAN::RefPtr<AML::Buffer> Register::as_buffer()
|
||||||
: Node(Node::Type::Register)
|
|
||||||
{}
|
|
||||||
AML::Register::Register(BAN::RefPtr<AML::Node> node)
|
|
||||||
: Node(Node::Type::Register)
|
|
||||||
{
|
{
|
||||||
if (!node)
|
if (value)
|
||||||
{
|
return value->as_buffer();
|
||||||
value = node;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (node)
|
|
||||||
{
|
|
||||||
if (node->type == AML::Node::Type::Reference)
|
|
||||||
node = static_cast<AML::Reference*>(node.ptr())->node;
|
|
||||||
else if (node->type != AML::Node::Type::Buffer && node->type != AML::Node::Type::Package)
|
|
||||||
node = node->copy();
|
|
||||||
if (node->type == AML::Node::Type::Register)
|
|
||||||
{
|
|
||||||
node = static_cast<AML::Register*>(node.ptr())->value;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ASSERT(node);
|
|
||||||
value = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> AML::Register::convert(uint8_t mask)
|
|
||||||
{
|
|
||||||
if (!value)
|
|
||||||
{
|
|
||||||
AML_ERROR("Trying to convert null Register");
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
return value->convert(mask);
|
|
||||||
|
BAN::RefPtr<AML::Integer> Register::as_integer()
|
||||||
|
{
|
||||||
|
if (value)
|
||||||
|
return value->as_integer();
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> AML::Register::store(BAN::RefPtr<AML::Node> source)
|
BAN::RefPtr<AML::String> Register::as_string()
|
||||||
{
|
{
|
||||||
if (source && source->type == AML::Node::Type::Register)
|
if (value)
|
||||||
source = static_cast<AML::Register*>(source.ptr())->value;
|
return value->as_string();
|
||||||
if (value && value->type == AML::Node::Type::Reference)
|
return {};
|
||||||
return value->store(source);
|
|
||||||
value = source->copy();
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AML::Register::debug_print(int indent) const
|
|
||||||
{
|
|
||||||
AML_DEBUG_PRINT_INDENT(indent);
|
|
||||||
if (!value)
|
|
||||||
AML_DEBUG_PRINT("Register { No value }");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AML_DEBUG_PRINTLN("Register { ");
|
|
||||||
value->debug_print(indent + 1);
|
|
||||||
AML_DEBUG_PRINTLN("");
|
|
||||||
AML_DEBUG_PRINT_INDENT(indent);
|
|
||||||
AML_DEBUG_PRINT(" }");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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_PRINT("Scope '{}' not found in namespace", name_string.value());
|
AML_DEBUG_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,12 +69,7 @@ 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)
|
||||||
|
@ -90,10 +85,7 @@ namespace Kernel::ACPI
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto result_integer = result.value()
|
return result.value() ? result.value()->as_integer() : BAN::RefPtr<AML::Integer>();
|
||||||
? 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->convert(AML::Node::ConvString) : BAN::RefPtr<AML::Node>();
|
auto rhs = node ? node->as_string() : BAN::RefPtr<AML::String>();
|
||||||
if (!rhs)
|
if (!rhs)
|
||||||
{
|
{
|
||||||
AML_ERROR("String logical compare RHS is not string");
|
AML_ERROR("String logical compare RHS is not string");
|
||||||
|
@ -27,23 +27,6 @@ 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)
|
|
||||||
{
|
|
||||||
// Apparently this is what NT does, but its definitely not spec compliant :D
|
|
||||||
uint64_t value = 0;
|
|
||||||
const size_t bytes = BAN::Math::min<size_t>(string.size(), sizeof(value));
|
|
||||||
memcpy(&value, string.data(), bytes);
|
|
||||||
return MUST(BAN::RefPtr<AML::Integer>::create(value));
|
|
||||||
}
|
|
||||||
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