Compare commits

..

No commits in common. "37e6cd6500499aa26320624bc27a9c5334688793" and "25a47f0df3f5218d9677503463af3123e5acfbb6" have entirely different histories.

34 changed files with 248 additions and 607 deletions

View File

@ -118,13 +118,13 @@ I have also created shell completion script for zsh. You can either copy the fil
## Contributing
As the upstream is hosted on my server https://git.bananymous.com/Bananymous/banan-os, merging contributions is not as trivial as it would be on GitHub. You can still send PRs in GitHub in which case I should be able to download the diff and apply it manually. If you want, I can also provide you an account to my git server. In this case please contact me ([email](mailto:oskari.alaranta@bananymous.com), [discord](https://discord.gg/ehjGySwYdK)).
As the upstream is hosted on my server https://git.bananymous.com/Bananymous/banan-os, please contact me about account creation ([email](mailto:oskari.alaranta@bananymous.com), [discord](https://discord.gg/ehjGySwYdK)) and I will add a account for you. This is done to limit the people with access to the server.
As this is mostly a learning experience for me, I would appreciate if you first contacted me about adding new features (email, discord, issue, ...). If you send a PR about something I was planning on doing myself and you didn't ask me, I will probably just close it. Bug fixes are always welcome!
As this is mostly a learning experience for me, I would appreciate if you first contacted me about adding new features (email, discord, issue, ...). Bug fixes are always welcome!
Commit message should be formatted followingly
1. First line is of the form "_Subject: Description_", where _Subject_ tells the area touched (Kernel, Shell, BuildSystem, ...) and _Description_ is brief description of the change done. First line should fit fully in 72 characters.
1. First line is of the form "_Subject: Description_", where _Subject_ tells the area touched (Kernel, Shell, BuildSystem, ...) and _Description_ is brief description of the change done. First line should fit fully in 70 characters.
2. Body of the message should further describe the change and reasoning behind the change.
All commits should pass the pre-commit hook defined in _.pre-commit-config.yaml_. For instructions on how to setup pre-commit, please see https://pre-commit.com/#install.

View File

@ -7,9 +7,7 @@ set(KERNEL_SOURCES
kernel/ACPI/AML/Namespace.cpp
kernel/ACPI/AML/Node.cpp
kernel/ACPI/AML/Package.cpp
kernel/ACPI/AML/Register.cpp
kernel/ACPI/AML/Scope.cpp
kernel/ACPI/AML/String.cpp
kernel/APIC.cpp
kernel/BootInfo.cpp
kernel/CPUID.cpp

View File

@ -1,74 +0,0 @@
#pragma once
#include <kernel/ACPI/AML/NamedObject.h>
#include <kernel/ACPI/AML/Names.h>
#include <kernel/ACPI/AML/ParseContext.h>
namespace Kernel::ACPI::AML
{
struct Alias : public AML::NamedObject
{
BAN::RefPtr<AML::Node> target;
Alias(NameSeg name, BAN::RefPtr<AML::Node> target)
: NamedObject(Node::Type::Alias, name)
, target(target)
{}
bool is_scope() const override { return target->is_scope(); }
BAN::RefPtr<Node> copy() override { return target->copy(); }
BAN::RefPtr<AML::Buffer> as_buffer() override { return target->as_buffer(); }
BAN::RefPtr<AML::Integer> as_integer() override { return target->as_integer(); }
BAN::RefPtr<AML::String> as_string() override { return target->as_string(); }
BAN::RefPtr<AML::Node> evaluate() override { return target->evaluate(); }
bool store(BAN::RefPtr<AML::Node> node) override { return target->store(node); }
static ParseResult parse(ParseContext& context)
{
ASSERT(context.aml_data.size() >= 1);
ASSERT(static_cast<Byte>(context.aml_data[0]) == Byte::AliasOp);
context.aml_data = context.aml_data.slice(1);
auto source_string = AML::NameString::parse(context.aml_data);
if (!source_string.has_value())
return ParseResult::Failure;
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);
if (!alias_string.has_value())
return ParseResult::Failure;
auto alias = MUST(BAN::RefPtr<Alias>::create(alias_string.value().path.back(), source_object));
if (!Namespace::root_namespace()->add_named_object(context, alias_string.value(), alias))
return ParseResult::Success;
#if AML_DEBUG_LEVEL >= 2
alias->debug_print(0);
AML_DEBUG_PRINTLN("");
#endif
return ParseResult::Success;
}
void debug_print(int indent) const override
{
AML_DEBUG_PRINT_INDENT(indent);
AML_DEBUG_PRINTLN("Alias {} { ", name);
target->debug_print(indent + 1);
AML_DEBUG_PRINTLN("");
AML_DEBUG_PRINT_INDENT(indent);
AML_DEBUG_PRINT("}");
}
};
}

View File

@ -18,30 +18,6 @@ namespace Kernel::ACPI::AML
: AML::Node(Node::Type::Buffer)
{}
BAN::Optional<bool> logical_compare(BAN::RefPtr<AML::Node> node, AML::Byte binaryop)
{
auto rhs = node ? node->as_buffer() : BAN::RefPtr<AML::Buffer>();
if (!rhs)
{
AML_ERROR("Buffer logical compare RHS is not buffer");
return {};
}
(void)binaryop;
AML_TODO("Logical compare buffer");
return {};
}
BAN::RefPtr<AML::Buffer> as_buffer() override { return this; }
BAN::RefPtr<AML::Integer> as_integer() override
{
uint64_t value = 0;
for (size_t i = 0; i < BAN::Math::min<size_t>(buffer.size(), 8); i++)
value |= static_cast<uint64_t>(buffer[i]) << (8 * i);
return MUST(BAN::RefPtr<Integer>::create(value));
}
BAN::RefPtr<AML::Node> evaluate() override
{
return this;
@ -65,10 +41,10 @@ namespace Kernel::ACPI::AML
return ParseResult::Failure;
auto buffer_size = buffer_size_object.node()->as_integer();
if (!buffer_size)
if (!buffer_size.has_value())
return ParseResult::Failure;
uint32_t actual_buffer_size = BAN::Math::max<uint32_t>(buffer_size->value, buffer_context.aml_data.size());
uint32_t actual_buffer_size = BAN::Math::max<uint32_t>(buffer_size.value(), buffer_context.aml_data.size());
auto buffer = MUST(BAN::RefPtr<Buffer>::create());
MUST(buffer->buffer.resize(actual_buffer_size, 0));
@ -104,27 +80,6 @@ namespace Kernel::ACPI::AML
, field_bit_size(field_bit_size)
{}
BAN::RefPtr<AML::Integer> as_integer() override
{
ASSERT(buffer);
ASSERT(buffer->type == AML::Node::Type::Buffer || buffer->type == AML::Node::Type::String);
const auto& buffer = (this->buffer->type == AML::Node::Type::Buffer)
? static_cast<AML::Buffer*>(this->buffer.ptr())->buffer
: static_cast<AML::String*>(this->buffer.ptr())->string;
uint64_t value = 0;
// TODO: optimize for whole byte accesses
for (size_t i = 0; i < BAN::Math::min<size_t>(field_bit_size, 64); i++)
{
const size_t bit = field_bit_offset + i;
value |= static_cast<uint64_t>((buffer[bit / 8] >> (bit % 8)) & 1) << i;
}
return MUST(BAN::RefPtr<Integer>::create(value));
}
BAN::RefPtr<AML::Node> evaluate() override
{
ASSERT(buffer);
@ -136,11 +91,17 @@ namespace Kernel::ACPI::AML
uint64_t value = 0;
// TODO: optimize for whole byte accesses
for (size_t i = 0; i < field_bit_size; i++)
const size_t byte_offset = field_bit_offset / 8;
const size_t bit_offset = field_bit_offset % 8;
if (field_bit_size == 1)
{
const size_t bit = field_bit_offset + i;
value |= static_cast<uint64_t>((buffer[bit / 8] >> (bit % 8)) & 1) << i;
value = (buffer[byte_offset] >> bit_offset) & 1;
}
else
{
ASSERT(bit_offset == 0);
for (size_t byte = 0; byte < field_bit_size / 8; byte++)
value |= buffer[byte_offset + byte] << byte;
}
return MUST(BAN::RefPtr<AML::Integer>::create(value));
@ -156,15 +117,21 @@ namespace Kernel::ACPI::AML
ASSERT(field_bit_offset + field_bit_size <= buffer.size() * 8);
auto value = node->as_integer();
if (!value)
if (!value.has_value())
return false;
// TODO: optimize for whole byte accesses
for (size_t i = 0; i < field_bit_size; i++)
const size_t byte_offset = field_bit_offset / 8;
const size_t bit_offset = field_bit_offset % 8;
if (field_bit_size == 1)
{
const size_t bit = field_bit_offset + 1;
buffer[bit / 8] &= ~(1 << (bit % 8));
buffer[bit / 8] |= ((value->value >> i) & 1) << (bit % 8);
buffer[byte_offset] &= ~(1 << bit_offset);
buffer[byte_offset] |= (value.value() & 1) << bit_offset;
}
else
{
ASSERT(bit_offset == 0);
for (size_t byte = 0; byte < field_bit_size / 8; byte++)
buffer[byte_offset + byte] = (value.value() >> (byte * 8)) & 0xFF;
}
return true;
@ -175,7 +142,7 @@ namespace Kernel::ACPI::AML
ASSERT(context.aml_data.size() >= 1);
size_t field_bit_size = 0;
switch (static_cast<AML::Byte>(context.aml_data[0]))
switch (static_cast<Byte>(context.aml_data[0]))
{
case AML::Byte::CreateBitFieldOp:
field_bit_size = 1;
@ -192,19 +159,15 @@ namespace Kernel::ACPI::AML
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));
context.aml_data = context.aml_data.slice(1);
auto buffer_result = AML::parse_object(context);
if (!buffer_result.success())
return ParseResult::Failure;
auto buffer_node = buffer_result.node() ? buffer_result.node()->as_buffer() : BAN::RefPtr<AML::Buffer>();
auto buffer_node = buffer_result.node() ? buffer_result.node()->evaluate() : nullptr;
if (!buffer_node || buffer_node->type != Node::Type::Buffer)
{
AML_ERROR("Buffer source does not evaluate to a Buffer");
@ -215,30 +178,16 @@ namespace Kernel::ACPI::AML
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)
auto index = index_result.node() ? index_result.node()->as_integer() : BAN::Optional<uint64_t>();
if (!index.has_value())
{
AML_ERROR("Failed to parse index for BufferField");
return ParseResult::Failure;
}
size_t field_bit_offset = index->value;
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;

View File

@ -25,21 +25,22 @@ namespace Kernel::ACPI::AML
auto source_result = AML::parse_object(context);
if (!source_result.success())
return ParseResult::Failure;
auto source_node = source_result.node() ? source_result.node()->as_integer(): BAN::RefPtr<AML::Integer>();
if (!source_node)
auto source_node = source_result.node() ? source_result.node()->evaluate() : BAN::RefPtr<AML::Node>();
if (!source_node || source_node->type != AML::Node::Type::Integer)
{
AML_ERROR("UnaryOp source not integer");
return ParseResult::Failure;
}
if (source_node->constant)
auto source_integer = static_cast<AML::Integer*>(source_node.ptr());
if (source_integer->constant)
{
AML_ERROR("UnaryOp source is constant");
return ParseResult::Failure;
}
source_node->value += (opcode == AML::Byte::AddOp) ? 1 : -1;
return ParseResult(source_node);
source_integer->value += (opcode == AML::Byte::AddOp) ? 1 : -1;
return ParseResult(source_integer);
}
case AML::Byte::NotOp:
AML_TODO("NotOp", context.aml_data[0]);
@ -52,14 +53,14 @@ namespace Kernel::ACPI::AML
if (!node_result.success())
return ParseResult::Failure;
auto value = node_result.node() ? node_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
if (!value)
auto value = node_result.node() ? node_result.node()->as_integer() : BAN::Optional<uint64_t>();
if (!value.has_value())
{
AML_ERROR("Logical NotOp source is not integer");
return ParseResult::Failure;
}
auto result = value->value ? Integer::Constants::Zero : Integer::Constants::Ones;
auto result = value.value() ? Integer::Constants::Zero : Integer::Constants::Ones;
return ParseResult(result);
}
case AML::Byte::AddOp:
@ -97,8 +98,8 @@ namespace Kernel::ACPI::AML
auto lhs_result = AML::parse_object(context);
if (!lhs_result.success())
return ParseResult::Failure;
auto lhs_value = lhs_result.node() ? lhs_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
if (!lhs_value)
auto lhs_value = lhs_result.node() ? lhs_result.node()->as_integer() : BAN::Optional<uint64_t>();
if (!lhs_value.has_value())
{
AML_ERROR("BinaryOP {2H} LHS not an integer", static_cast<uint8_t>(opcode));
if (lhs_result.node())
@ -110,8 +111,8 @@ namespace Kernel::ACPI::AML
auto rhs_result = AML::parse_object(context);
if (!rhs_result.success())
return ParseResult::Failure;
auto rhs_value = rhs_result.node() ? rhs_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
if (!rhs_value)
auto rhs_value = lhs_result.node() ? rhs_result.node()->as_integer() : BAN::Optional<uint64_t>();
if (!rhs_value.has_value())
{
AML_ERROR("BinaryOP {2H} RHS not an integer", static_cast<uint8_t>(opcode));
if (rhs_result.node())
@ -159,7 +160,7 @@ namespace Kernel::ACPI::AML
ASSERT_NOT_REACHED();
}
uint64_t result = func(lhs_value->value, rhs_value->value);
uint64_t result = func(lhs_value.value(), rhs_value.value());
auto result_node = MUST(BAN::RefPtr<AML::Integer>::create(result));
if (target_node && !target_node->store(result_node))
@ -179,37 +180,36 @@ namespace Kernel::ACPI::AML
auto lhs_result = AML::parse_object(context);
if (!lhs_result.success())
return ParseResult::Failure;
auto lhs_node = lhs_result.node() ? lhs_result.node()->evaluate() : BAN::RefPtr<AML::Node>();
if (!lhs_node)
auto lhs_value = lhs_result.node() ? lhs_result.node()->as_integer() : BAN::Optional<uint64_t>();
if (!lhs_value.has_value())
{
AML_TODO("Logical BinaryOP {2H} LHS evaluated to nothing", static_cast<uint8_t>(opcode));
AML_TODO("Logical BinaryOP {2H} LHS not integer", static_cast<uint8_t>(opcode));
return ParseResult::Failure;
}
auto rhs_result = AML::parse_object(context);
if (!rhs_result.success())
return ParseResult::Failure;
BAN::Optional<bool> result = false;
switch (lhs_node->type)
auto rhs_value = rhs_result.node() ? rhs_result.node()->as_integer() : BAN::Optional<uint64_t>();
if (!rhs_value.has_value())
{
case AML::Node::Type::Integer:
result = static_cast<AML::Integer*>(lhs_node.ptr())->logical_compare(rhs_result.node(), opcode);
break;
case AML::Node::Type::Buffer:
result = static_cast<AML::Buffer*>(lhs_node.ptr())->logical_compare(rhs_result.node(), opcode);
break;
case AML::Node::Type::String:
result = static_cast<AML::String*>(lhs_node.ptr())->logical_compare(rhs_result.node(), opcode);
break;
AML_TODO("Logical BinaryOP {2H} RHS not integer", static_cast<uint8_t>(opcode));
return ParseResult::Failure;
}
BAN::RefPtr<AML::Integer> (*func)(uint64_t, uint64_t) = nullptr;
switch (opcode)
{
case AML::Byte::LAndOp: func = [](uint64_t a, uint64_t b) { return a && b ? Integer::Constants::Ones : Integer::Constants::Zero; }; break;
case AML::Byte::LEqualOp: func = [](uint64_t a, uint64_t b) { return a == b ? Integer::Constants::Ones : Integer::Constants::Zero; }; break;
case AML::Byte::LGreaterOp: func = [](uint64_t a, uint64_t b) { return a > b ? Integer::Constants::Ones : Integer::Constants::Zero; }; break;
case AML::Byte::LLessOp: func = [](uint64_t a, uint64_t b) { return a < b ? Integer::Constants::Ones : Integer::Constants::Zero; }; break;
case AML::Byte::LOrOp: func = [](uint64_t a, uint64_t b) { return a || b ? Integer::Constants::Ones : Integer::Constants::Zero; }; break;
default:
ASSERT_NOT_REACHED();
}
if (!result.has_value())
return ParseResult::Failure;
return ParseResult(result.value() ? AML::Integer::Constants::Ones : AML::Integer::Constants::Zero);
return ParseResult(func(lhs_value.value(), rhs_value.value()));
}
};

View File

@ -63,9 +63,7 @@ namespace Kernel::ACPI::AML
, access_rules(access_rules)
{}
BAN::RefPtr<AML::Integer> as_integer() override;
BAN::RefPtr<Node> evaluate() override { return as_integer(); }
BAN::RefPtr<Node> evaluate() override;
bool store(BAN::RefPtr<Node> source) override;
void debug_print(int indent) const override;
@ -100,9 +98,7 @@ namespace Kernel::ACPI::AML
, access_rules(access_rules)
{}
BAN::RefPtr<AML::Integer> as_integer() override;
BAN::RefPtr<AML::Node> evaluate() override { return as_integer(); }
BAN::RefPtr<Node> evaluate() override;
bool store(BAN::RefPtr<Node> source) override;
void debug_print(int indent) const override;

View File

@ -26,8 +26,8 @@ namespace Kernel::ACPI::AML
auto predicate_result = AML::parse_object(context);
if (!predicate_result.success())
return ParseResult::Failure;
auto predicate = predicate_result.node() ? predicate_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
if (!predicate)
auto predicate = predicate_result.node() ? predicate_result.node()->as_integer() : BAN::Optional<uint64_t>();
if (!predicate.has_value())
{
AML_ERROR("If predicate is not an integer");
return ParseResult::Failure;
@ -43,7 +43,7 @@ namespace Kernel::ACPI::AML
return ParseResult::Failure;
else_pkg = else_pkg_result.value();
}
if (predicate->value == 0)
if (!predicate.value())
context.aml_data = else_pkg;
while (context.aml_data.size() > 0)

View File

@ -30,8 +30,8 @@ namespace Kernel::ACPI::AML
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)
auto index = index_result.node() ? index_result.node()->as_integer() : BAN::Optional<uint64_t>();
if (!index.has_value())
{
AML_ERROR("IndexOp index is not an integer");
return ParseResult::Failure;
@ -43,36 +43,36 @@ namespace Kernel::ACPI::AML
case AML::Node::Type::Buffer:
{
auto buffer = BAN::RefPtr<AML::Buffer>(static_cast<AML::Buffer*>(source.ptr()));
if (index->value >= buffer->buffer.size())
if (index.value() >= buffer->buffer.size())
{
AML_ERROR("IndexOp index is out of buffer bounds");
return ParseResult::Failure;
}
auto buffer_field = MUST(BAN::RefPtr<BufferField>::create(NameSeg(""_sv), buffer, index->value * 8, 8));
auto buffer_field = MUST(BAN::RefPtr<BufferField>::create(NameSeg(""_sv), buffer, index.value() * 8, 8));
result = MUST(BAN::RefPtr<AML::Reference>::create(buffer_field));
break;
}
case AML::Node::Type::Package:
{
auto package = static_cast<AML::Package*>(source.ptr());
if (index->value >= package->elements.size())
if (index.value() >= package->elements.size())
{
AML_ERROR("IndexOp index is out of package bounds");
return ParseResult::Failure;
}
auto package_element = package->elements[index->value];
auto package_element = package->elements[index.value()];
result = MUST(BAN::RefPtr<AML::Reference>::create(package_element));
break;
}
case AML::Node::Type::String:
{
auto string = BAN::RefPtr<AML::String>(static_cast<AML::String*>(source.ptr()));
if (index->value >= string->string.size())
if (index.value() >= string->string.size())
{
AML_ERROR("IndexOp index is out of string bounds");
return ParseResult::Failure;
}
auto buffer_field = MUST(BAN::RefPtr<BufferField>::create(NameSeg(""_sv), string, index->value * 8, 8));
auto buffer_field = MUST(BAN::RefPtr<BufferField>::create(NameSeg(""_sv), string, index.value() * 8, 8));
result = MUST(BAN::RefPtr<AML::Reference>::create(buffer_field));
break;
}
@ -82,7 +82,7 @@ namespace Kernel::ACPI::AML
}
#if AML_DEBUG_LEVEL >= 2
AML_DEBUG_PRINT("Index {}, ", index->value);
AML_DEBUG_PRINT("Index {}, ", index.value());
source->debug_print(0);
AML_DEBUG_PRINTLN("");
#endif

View File

@ -1,5 +1,6 @@
#pragma once
#include <BAN/Endianness.h>
#include <BAN/Optional.h>
#include <BAN/String.h>
#include <BAN/Vector.h>
@ -29,29 +30,6 @@ namespace Kernel::ACPI::AML
, constant(constant)
{}
BAN::Optional<bool> logical_compare(BAN::RefPtr<AML::Node> node, AML::Byte binaryop)
{
auto rhs = node ? node->as_integer() : BAN::RefPtr<AML::Integer>();
if (!rhs)
{
AML_ERROR("Integer logical compare RHS is not integer");
return {};
}
switch (binaryop)
{
case AML::Byte::LAndOp: return value && rhs->value;
case AML::Byte::LEqualOp: return value == rhs->value;
case AML::Byte::LGreaterOp: return value > rhs->value;
case AML::Byte::LLessOp: return value < rhs->value;
case AML::Byte::LOrOp: return value || rhs->value;
default:
ASSERT_NOT_REACHED();
}
}
BAN::RefPtr<AML::Integer> as_integer() override { return this; }
BAN::RefPtr<Node> copy() override { return MUST(BAN::RefPtr<Integer>::create(value)); }
BAN::RefPtr<AML::Node> evaluate() override
@ -67,12 +45,12 @@ namespace Kernel::ACPI::AML
return false;
}
auto store_value = store_node->as_integer();
if (!store_value)
if (!store_value.has_value())
{
AML_ERROR("Cannot store non-integer to integer");
return false;
}
value = store_value->value;
value = store_value.value();
return true;
}
@ -93,7 +71,7 @@ namespace Kernel::ACPI::AML
{
if (aml_data.size() < 2)
return ParseResult::Failure;
const uint8_t value = aml_data[1];
uint8_t value = aml_data[1];
aml_data = aml_data.slice(2);
return ParseResult(MUST(BAN::RefPtr<Integer>::create(value)));
}
@ -101,9 +79,9 @@ namespace Kernel::ACPI::AML
{
if (aml_data.size() < 3)
return ParseResult::Failure;
uint16_t value = 0;
value |= aml_data[1] << 0;
value |= aml_data[2] << 8;
uint16_t value = BAN::little_endian_to_host<uint16_t>(
*reinterpret_cast<const uint16_t*>(&aml_data[1])
);
aml_data = aml_data.slice(3);
return ParseResult(MUST(BAN::RefPtr<Integer>::create(value)));
}
@ -111,11 +89,9 @@ namespace Kernel::ACPI::AML
{
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;
uint32_t value = BAN::little_endian_to_host<uint32_t>(
*reinterpret_cast<const uint32_t*>(&aml_data[1])
);
aml_data = aml_data.slice(5);
return ParseResult(MUST(BAN::RefPtr<Integer>::create(value)));
}
@ -123,15 +99,9 @@ namespace Kernel::ACPI::AML
{
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;
uint64_t value = BAN::little_endian_to_host<uint64_t>(
*reinterpret_cast<const uint64_t*>(&aml_data[1])
);
aml_data = aml_data.slice(9);
return ParseResult(MUST(BAN::RefPtr<Integer>::create(value)));
}

View File

@ -53,7 +53,7 @@ namespace Kernel::ACPI::AML
method_flags >> 4
));
if (!Namespace::root_namespace()->add_named_object(context, name_string.value(), method))
return ParseResult::Success;
return ParseResult::Failure;
method->term_list = method_pkg.value();
#if AML_DEBUG_LEVEL >= 2
@ -142,9 +142,6 @@ namespace Kernel::ACPI::AML
}
}
if (return_value.has_value() && return_value.value())
return_value = return_value.value()->evaluate();
while (!context.created_objects.empty())
{
Namespace::root_namespace()->remove_named_object(context.created_objects.back());

View File

@ -22,10 +22,6 @@ namespace Kernel::ACPI::AML
: NamedObject(Node::Type::Name, name), object(BAN::move(object))
{}
BAN::RefPtr<AML::Buffer> as_buffer() override;
BAN::RefPtr<AML::Integer> as_integer() override;
BAN::RefPtr<AML::String> as_string() override;
BAN::RefPtr<AML::Node> evaluate() override
{
ASSERT(object);

View File

@ -11,7 +11,6 @@ namespace Kernel::ACPI::AML
struct Namespace : public AML::Scope
{
static BAN::RefPtr<AML::Namespace> root_namespace();
static BAN::RefPtr<AML::Node> debug_node;
template<typename F>
static void for_each_child(const AML::NameString& scope, const F& callback)

View File

@ -9,21 +9,15 @@
namespace Kernel::ACPI::AML
{
struct Buffer;
struct Integer;
struct String;
struct Node : public BAN::RefCounted<Node>
{
static uint64_t total_node_count;
enum class Type
{
Alias,
BankFieldElement,
Buffer,
BufferField,
Debug,
Device,
FieldElement,
IndexFieldElement,
@ -51,10 +45,7 @@ namespace Kernel::ACPI::AML
virtual BAN::RefPtr<Node> copy() { return this; }
[[nodiscard]] virtual BAN::RefPtr<AML::Buffer> as_buffer();
[[nodiscard]] virtual BAN::RefPtr<AML::Integer> as_integer();
[[nodiscard]] virtual BAN::RefPtr<AML::String> as_string();
[[nodiscard]] BAN::Optional<uint64_t> as_integer();
[[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; }
@ -93,6 +84,7 @@ namespace Kernel::ACPI::AML
BAN::RefPtr<Node> node()
{
ASSERT(m_node);
return m_node;
}

View File

@ -29,8 +29,8 @@ namespace Kernel::ACPI::AML
auto value_result = AML::parse_object(context);
if (!value_result.success())
return ParseResult::Failure;
auto value = value_result.node() ? value_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
if (!value)
auto value = value_result.node() ? value_result.node()->as_integer() : BAN::Optional<uint64_t>();
if (!value.has_value())
{
AML_ERROR("Notify value is not an integer");
return ParseResult::Failure;
@ -58,7 +58,7 @@ namespace Kernel::ACPI::AML
break;
}
AML_TODO("Notify: {} {}: {2H}", object_type_sv, object_name_sv, value->value);
AML_TODO("Notify: {} {}: {2H}", object_type_sv, object_name_sv, value.value());
return ParseResult::Success;
}
};

View File

@ -1,7 +1,6 @@
#pragma once
#include <kernel/ACPI/AML/Bytes.h>
#include <kernel/ACPI/AML/Integer.h>
#include <kernel/ACPI/AML/Node.h>
#include <kernel/ACPI/AML/ParseContext.h>
#include <kernel/ACPI/AML/Pkg.h>
@ -66,49 +65,6 @@ namespace Kernel::ACPI::AML
initialized = false;
}
bool resolve()
{
ASSERT(!resolved);
auto object = Namespace::root_namespace()->find_object(parent->scope, unresolved_name, Namespace::FindMode::Normal);
if (!object)
{
AML_ERROR("Failed to resolve reference {} in package {}", unresolved_name, parent->scope);
return false;
}
element = object;
resolved = true;
return true;
}
bool store(BAN::RefPtr<AML::Node> node) override
{
if (!initialized)
{
AML_ERROR("Trying to store into uninitialized PackageElement");
return {};
}
if (!resolved && !resolve())
return {};
if (element->type == AML::Node::Type::Reference)
return element->store(node);
element = node->copy();
return true;
}
BAN::RefPtr<AML::Integer> as_integer() override
{
if (!initialized)
{
AML_ERROR("Trying to evaluate uninitialized PackageElement");
return {};
}
if (!resolved && !resolve())
return {};
return element->as_integer();
}
BAN::RefPtr<AML::Node> evaluate() override
{
if (!initialized)
@ -116,8 +72,17 @@ namespace Kernel::ACPI::AML
AML_ERROR("Trying to evaluate uninitialized PackageElement");
return {};
}
if (!resolved && !resolve())
return {};
if (!resolved)
{
auto object = Namespace::root_namespace()->find_object(parent->scope, unresolved_name, Namespace::FindMode::Normal);
if (!object)
{
AML_ERROR("Failed to resolve reference {} in package {}", unresolved_name, parent->scope);
return {};
}
element = object;
resolved = true;
}
return element->evaluate();
}

View File

@ -21,28 +21,11 @@ namespace Kernel::ACPI::AML
ASSERT(node);
}
BAN::RefPtr<AML::Integer> as_integer() override
{
if (node)
return node->as_integer();
return {};
}
BAN::RefPtr<AML::Node> evaluate() override
{
return this;
}
bool store(BAN::RefPtr<AML::Node> value) override
{
if (!node)
{
AML_ERROR("Storing to null reference");
return false;
}
return node->store(value);
}
static ParseResult parse(ParseContext& context)
{
ASSERT(context.aml_data.size() >= 1);
@ -144,7 +127,7 @@ namespace Kernel::ACPI::AML
auto parse_result = AML::parse_object(context);
if (!parse_result.success())
return ParseResult::Failure;
auto object = parse_result.node() ? parse_result.node()->evaluate() : BAN::RefPtr<AML::Node>();
auto object = parse_result.node();
if (!object || object->type != AML::Node::Type::Reference)
{
AML_TODO("DerefOf source is not a Reference, but a {}", object ? static_cast<uint8_t>(object->type) : 999);

View File

@ -1,6 +1,5 @@
#pragma once
#include <kernel/ACPI/AML/Integer.h>
#include <kernel/ACPI/AML/NamedObject.h>
#include <kernel/ACPI/AML/Namespace.h>
#include <kernel/ACPI/AML/ParseContext.h>
@ -44,7 +43,7 @@ namespace Kernel::ACPI::AML
if (!offset_result.success())
return ParseResult::Failure;
auto offset = offset_result.node()->as_integer();
if (!offset)
if (!offset.has_value())
{
AML_ERROR("OpRegion offset must be an integer");
return ParseResult::Failure;
@ -54,7 +53,7 @@ namespace Kernel::ACPI::AML
if (!length_result.success())
return ParseResult::Failure;
auto length = length_result.node()->as_integer();
if (!length)
if (!length.has_value())
{
AML_ERROR("OpRegion length must be an integer");
return ParseResult::Failure;
@ -63,8 +62,8 @@ namespace Kernel::ACPI::AML
auto op_region = MUST(BAN::RefPtr<OpRegion>::create(
name->path.back(),
region_space,
offset->value,
length->value
offset.value(),
length.value()
));
if (!Namespace::root_namespace()->add_named_object(context, name.value(), op_region))

View File

@ -17,10 +17,6 @@ namespace Kernel::ACPI::AML
, value(value)
{}
BAN::RefPtr<AML::Buffer> as_buffer() override;
BAN::RefPtr<AML::Integer> as_integer() override;
BAN::RefPtr<AML::String> as_string() override;
BAN::RefPtr<AML::Node> evaluate() override
{
if (value)
@ -30,9 +26,6 @@ namespace Kernel::ACPI::AML
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)
{

View File

@ -19,18 +19,18 @@ namespace Kernel::ACPI::AML
auto sleep_time_result = AML::parse_object(context);
if (!sleep_time_result.success())
return ParseResult::Failure;
auto sleep_time = sleep_time_result.node() ? sleep_time_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
if (!sleep_time)
auto sleep_time = sleep_time_result.node() ? sleep_time_result.node()->as_integer() : BAN::Optional<uint64_t>();
if (!sleep_time.has_value())
{
AML_ERROR("Sleep time cannot be evaluated to an integer");
return ParseResult::Failure;
}
#if AML_DEBUG_LEVEL >= 2
AML_DEBUG_PRINTLN("Sleeping for {} ms", sleep_time->value);
AML_DEBUG_PRINTLN("Sleeping for {} ms", sleep_time.value());
#endif
SystemTimer::get().sleep_ms(sleep_time->value);
SystemTimer::get().sleep_ms(sleep_time.value());
return ParseResult::Success;
}
};

View File

@ -46,7 +46,7 @@ namespace Kernel::ACPI::AML
if (!destination->store(source))
return ParseResult::Failure;
return ParseResult(destination);
return ParseResult::Success;
}
};

View File

@ -20,10 +20,6 @@ namespace Kernel::ACPI::AML
this->string[i] = string[i];
}
BAN::Optional<bool> logical_compare(BAN::RefPtr<AML::Node> node, AML::Byte binaryop);
BAN::RefPtr<AML::Buffer> as_buffer() override;
BAN::RefPtr<AML::Node> evaluate() override
{
return this;
@ -34,7 +30,33 @@ namespace Kernel::ACPI::AML
return BAN::StringView(reinterpret_cast<const char*>(string.data()), string.size());
}
static ParseResult parse(ParseContext& context);
static ParseResult parse(ParseContext& context)
{
ASSERT(context.aml_data.size() >= 1);
ASSERT(static_cast<AML::Byte>(context.aml_data[0]) == AML::Byte::StringPrefix);
context.aml_data = context.aml_data.slice(1);
BAN::Vector<uint8_t> string;
while (context.aml_data.size() > 0)
{
if (context.aml_data[0] == 0x00)
break;
MUST(string.push_back(context.aml_data[0]));
context.aml_data = context.aml_data.slice(1);
}
if (context.aml_data.size() == 0)
return ParseResult::Failure;
if (context.aml_data[0] != 0x00)
return ParseResult::Failure;
context.aml_data = context.aml_data.slice(1);
auto string_node = MUST(BAN::RefPtr<String>::create());
string_node->string = BAN::move(string);
return ParseResult(string_node);
}
virtual void debug_print(int indent) const override
{

View File

@ -19,7 +19,7 @@ namespace Kernel::ACPI::AML
{
ASSERT(context.aml_data.size() >= 2);
ASSERT(static_cast<AML::Byte>(context.aml_data[0]) == AML::Byte::ExtOpPrefix);
ASSERT(static_cast<AML::ExtOp>(context.aml_data[1]) == AML::ExtOp::ThermalZoneOp);
ASSERT(static_cast<AML::ExtOp>(context.aml_data[1]) == AML::ExtOp::PowerResOp);
context.aml_data = context.aml_data.slice(2);
auto opt_thermal_zone_pkg = AML::parse_pkg(context.aml_data);

View File

@ -29,14 +29,14 @@ namespace Kernel::ACPI::AML
auto predicate_result = AML::parse_object(context);
if (!predicate_result.success())
return ParseResult::Failure;
auto predicate = predicate_result.node() ? predicate_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
if (!predicate)
auto predicate = predicate_result.node() ? predicate_result.node()->as_integer() : BAN::Optional<uint64_t>();
if (!predicate.has_value())
{
AML_ERROR("While predicate is not an integer");
return ParseResult::Failure;
}
if (!predicate->value)
if (!predicate.value())
break;
while (context.aml_data.size() > 0)

View File

@ -46,21 +46,21 @@ namespace Kernel
namespace TerminalColor
{
static constexpr TerminalDriver::Color BLACK = 0x000000;
static constexpr TerminalDriver::Color RED = 0xFF0000;
static constexpr TerminalDriver::Color GREEN = 0x00FF00;
static constexpr TerminalDriver::Color YELLOW = 0xFFFF00;
static constexpr TerminalDriver::Color BLUE = 0x0000FF;
static constexpr TerminalDriver::Color MAGENTA = 0xFF00FF;
static constexpr TerminalDriver::Color CYAN = 0x00FFFF;
static constexpr TerminalDriver::Color WHITE = 0xBFBFBF;
static constexpr TerminalDriver::Color BLUE = 0x0000AA;
static constexpr TerminalDriver::Color GREEN = 0x00AA00;
static constexpr TerminalDriver::Color CYAN = 0x00AAAA;
static constexpr TerminalDriver::Color RED = 0xAA0000;
static constexpr TerminalDriver::Color MAGENTA = 0xAA00AA;
static constexpr TerminalDriver::Color YELLOW = 0xAA5500;
static constexpr TerminalDriver::Color WHITE = 0xAAAAAA;
static constexpr TerminalDriver::Color BRIGHT_BLACK = 0x3F3F3F;
static constexpr TerminalDriver::Color BRIGHT_RED = 0xFF7F7F;
static constexpr TerminalDriver::Color BRIGHT_GREEN = 0x7FFF7F;
static constexpr TerminalDriver::Color BRIGHT_YELLOW = 0xFFFF7F;
static constexpr TerminalDriver::Color BRIGHT_BLUE = 0x7F7FFF;
static constexpr TerminalDriver::Color BRIGHT_MAGENTA = 0xFF7FFF;
static constexpr TerminalDriver::Color BRIGHT_CYAN = 0x7FFFFF;
static constexpr TerminalDriver::Color BRIGHT_BLACK = 0x555555;
static constexpr TerminalDriver::Color BRIGHT_BLUE = 0x5555FF;
static constexpr TerminalDriver::Color BRIGHT_GREEN = 0x55FF55;
static constexpr TerminalDriver::Color BRIGHT_CYAN = 0x55FFFF;
static constexpr TerminalDriver::Color BRIGHT_RED = 0xFF5555;
static constexpr TerminalDriver::Color BRIGHT_MAGENTA = 0xFF55FF;
static constexpr TerminalDriver::Color BRIGHT_YELLOW = 0xFFFF55;
static constexpr TerminalDriver::Color BRIGHT_WHITE = 0xFFFFFF;
}

View File

@ -145,9 +145,9 @@ acpi_release_global_lock:
field_element->op_region = op_region;
auto result = field_element->as_integer();
if (!result)
if (!result.has_value())
return {};
return result->value;
return result.value();
}
bool GAS::write(uint64_t value)
@ -514,7 +514,7 @@ acpi_release_global_lock:
auto slp_typa = s5_package->elements[0]->as_integer();
auto slp_typb = s5_package->elements[1]->as_integer();
if (!slp_typa || !slp_typb)
if (!slp_typa.has_value() || !slp_typb.has_value())
{
dwarnln("Failed to get SLP_TYPx values");
return;
@ -527,7 +527,7 @@ acpi_release_global_lock:
uint16_t pm1a_data = IO::inw(fadt().pm1a_cnt_blk);
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;
IO::outw(fadt().pm1a_cnt_blk, pm1a_data);
@ -535,7 +535,7 @@ acpi_release_global_lock:
{
uint16_t pm1b_data = IO::inw(fadt().pm1b_cnt_blk);
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;
IO::outw(fadt().pm1b_cnt_blk, pm1b_data);
}

View File

@ -479,7 +479,7 @@ namespace Kernel::ACPI
return perform_write_general(op_region->region_offset, bit_count, bit_offset, access_size.value(), value, access_rules.update_rule, read_func, write_func);
}
BAN::RefPtr<AML::Integer> AML::FieldElement::as_integer()
BAN::RefPtr<AML::Node> AML::FieldElement::evaluate()
{
op_region->mutex.lock();
BAN::ScopeGuard unlock_guard([&] {
@ -495,7 +495,7 @@ namespace Kernel::ACPI
bool AML::FieldElement::store(BAN::RefPtr<AML::Node> source)
{
auto source_integer = source->as_integer();
if (!source_integer)
if (!source_integer.has_value())
{
AML_TODO("FieldElement store with non-integer source, type {}", static_cast<uint8_t>(source->type));
return false;
@ -510,7 +510,7 @@ namespace Kernel::ACPI
ACPI::release_global_lock();
});
return store_internal(source_integer->value);
return store_internal(source_integer.value());
}
void AML::FieldElement::debug_print(int indent) const
@ -590,7 +590,7 @@ namespace Kernel::ACPI
return AML::ParseResult::Success;
}
BAN::RefPtr<AML::Integer> AML::IndexFieldElement::as_integer()
BAN::RefPtr<AML::Node> AML::IndexFieldElement::evaluate()
{
if (access_rules.access_attrib != FieldRules::AccessAttrib::Normal)
{
@ -634,7 +634,7 @@ namespace Kernel::ACPI
return {};
}
auto source_integer = source->as_integer();
if (!source_integer)
if (!source_integer.has_value())
{
AML_TODO("IndexFieldElement store with non-integer source, type {}", static_cast<uint8_t>(source->type));
return false;
@ -670,7 +670,7 @@ namespace Kernel::ACPI
ACPI::release_global_lock();
});
if (!perform_write_general(0, bit_count, bit_offset, access_size.value(), source_integer->value, access_rules.update_rule, read_func, write_func))
if (!perform_write_general(0, bit_count, bit_offset, access_size.value(), source_integer.value(), access_rules.update_rule, read_func, write_func))
return false;
return true;
@ -734,8 +734,8 @@ namespace Kernel::ACPI
context.aml_data = temp_aml_data;
if (!bank_value_result.success())
return ParseResult::Failure;
auto bank_value = bank_value_result.node() ? bank_value_result.node()->as_integer() : BAN::RefPtr<AML::Integer>();
if (!bank_value)
auto bank_value = bank_value_result.node() ? bank_value_result.node()->as_integer() : BAN::Optional<uint64_t>();
if (!bank_value.has_value())
{
AML_ERROR("BankField BankValue is not an integer");
return ParseResult::Failure;
@ -760,7 +760,7 @@ namespace Kernel::ACPI
{
element->op_region = static_cast<OpRegion*>(op_region.ptr());
element->bank_selector = static_cast<FieldElement*>(bank_selector.ptr());
element->bank_value = bank_value->value;
element->bank_value = bank_value.value();
NameString element_name;
MUST(element_name.path.push_back(element->name));
@ -821,7 +821,7 @@ namespace Kernel::ACPI
}
auto source_integer = source->as_integer();
if (!source_integer)
if (!source_integer.has_value())
{
AML_TODO("BankFieldElement store with non-integer source, type {}", static_cast<uint8_t>(source->type));
return false;
@ -852,7 +852,7 @@ namespace Kernel::ACPI
return {};
}
return perform_write_general(op_region->region_offset, bit_count, bit_offset, access_size.value(), source_integer->value, access_rules.update_rule, read_func, write_func);
return perform_write_general(op_region->region_offset, bit_count, bit_offset, access_size.value(), source_integer.value(), access_rules.update_rule, read_func, write_func);
}
void AML::BankFieldElement::debug_print(int indent) const

View File

@ -1,30 +1,9 @@
#include <kernel/ACPI/AML/Buffer.h>
#include <kernel/ACPI/AML/Integer.h>
#include <kernel/ACPI/AML/NamedObject.h>
#include <kernel/ACPI/AML/ParseContext.h>
#include <kernel/ACPI/AML/String.h>
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)
{
ASSERT(context.aml_data.size() >= 1);
@ -41,7 +20,7 @@ namespace Kernel::ACPI
auto name = MUST(BAN::RefPtr<Name>::create(name_string.value().path.back(), object.node()));
if (!Namespace::root_namespace()->add_named_object(context, name_string.value(), name))
return ParseResult::Success;
return ParseResult::Failure;
#if AML_DEBUG_LEVEL >= 2
name->debug_print(0);

View File

@ -17,24 +17,6 @@ namespace Kernel::ACPI
BAN::RefPtr<AML::Integer> AML::Integer::Constants::One;
BAN::RefPtr<AML::Integer> AML::Integer::Constants::Ones;
struct DebugNode : AML::Node
{
DebugNode() : AML::Node(AML::Node::Type::Debug) {}
bool store(BAN::RefPtr<AML::Node> node)
{
node->debug_print(0);
AML_DEBUG_PRINTLN("");
return true;
}
void debug_print(int indent) const override
{
AML_DEBUG_PRINT_INDENT(indent);
AML_DEBUG_PRINT("DEBUG");
}
};
BAN::RefPtr<AML::Node> AML::Namespace::debug_node;
BAN::RefPtr<AML::Namespace> AML::Namespace::root_namespace()
{
ASSERT(s_root_namespace);
@ -165,7 +147,7 @@ namespace Kernel::ACPI
if (m_objects.contains(canonical_path.value()))
{
AML_PRINT("Object '{}' already exists", canonical_path.value());
AML_ERROR("Object '{}' already exists", canonical_path.value());
return false;
}
@ -212,9 +194,6 @@ namespace Kernel::ACPI
s_root_namespace = MUST(BAN::RefPtr<Namespace>::create(NameSeg("\\"_sv)));
s_root_namespace->scope = AML::NameString("\\"_sv);
ASSERT(!Namespace::debug_node);
Namespace::debug_node = MUST(BAN::RefPtr<DebugNode>::create());
Integer::Constants::Zero = MUST(BAN::RefPtr<Integer>::create(0, true));
Integer::Constants::One = MUST(BAN::RefPtr<Integer>::create(1, true));
Integer::Constants::Ones = MUST(BAN::RefPtr<Integer>::create(0xFFFFFFFFFFFFFFFF, true));

View File

@ -1,4 +1,3 @@
#include <kernel/ACPI/AML/Alias.h>
#include <kernel/ACPI/AML/Buffer.h>
#include <kernel/ACPI/AML/Bytes.h>
#include <kernel/ACPI/AML/Device.h>
@ -34,21 +33,15 @@ namespace Kernel::ACPI
uint64_t AML::Node::total_node_count = 0;
BAN::RefPtr<AML::Buffer> AML::Node::as_buffer()
BAN::Optional<uint64_t> AML::Node::as_integer()
{
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));
if (type == Type::Integer)
return static_cast<const Integer*>(this)->value;
auto evaluated = evaluate();
if (!evaluated)
return {};
if (evaluated->type == Type::Integer)
return static_cast<const Integer*>(evaluated.ptr())->value;
return {};
}
@ -70,8 +63,6 @@ namespace Kernel::ACPI
return AML::IndexField::parse(context);
case AML::ExtOp::BankFieldOp:
return AML::BankField::parse(context);
case AML::ExtOp::CreateFieldOp:
return AML::BufferField::parse(context);
case AML::ExtOp::OpRegionOp:
return AML::OpRegion::parse(context);
case AML::ExtOp::DeviceOp:
@ -90,9 +81,6 @@ namespace Kernel::ACPI
return AML::Reference::parse(context);
case AML::ExtOp::SleepOp:
return AML::Sleep::parse(context);
case AML::ExtOp::DebugOp:
context.aml_data = context.aml_data.slice(2);
return ParseResult(AML::Namespace::debug_node);
default:
break;
}
@ -166,8 +154,6 @@ namespace Kernel::ACPI
case AML::Byte::CreateDWordFieldOp:
case AML::Byte::CreateQWordFieldOp:
return AML::BufferField::parse(context);
case AML::Byte::AliasOp:
return AML::Alias::parse(context);
case AML::Byte::NameOp:
return AML::Name::parse(context);
case AML::Byte::PackageOp:

View File

@ -1,30 +0,0 @@
#include <kernel/ACPI/AML/Buffer.h>
#include <kernel/ACPI/AML/Integer.h>
#include <kernel/ACPI/AML/Register.h>
#include <kernel/ACPI/AML/String.h>
namespace Kernel::ACPI::AML
{
BAN::RefPtr<AML::Buffer> Register::as_buffer()
{
if (value)
return value->as_buffer();
return {};
}
BAN::RefPtr<AML::Integer> Register::as_integer()
{
if (value)
return value->as_integer();
return {};
}
BAN::RefPtr<AML::String> Register::as_string()
{
if (value)
return value->as_string();
return {};
}
}

View File

@ -25,8 +25,8 @@ namespace Kernel::ACPI
auto named_object = Namespace::root_namespace()->find_object(context.scope, name_string.value(), Namespace::FindMode::Normal);
if (!named_object)
{
AML_DEBUG_PRINT("Scope '{}' not found in namespace", name_string.value());
return ParseResult::Success;
AML_ERROR("Scope '{}' not found in namespace", name_string.value());
return ParseResult::Failure;
}
if (!named_object->is_scope())
{
@ -66,7 +66,7 @@ namespace Kernel::ACPI
return ParseResult::Success;
}
static BAN::RefPtr<AML::Integer> evaluate_or_invoke(BAN::RefPtr<AML::Node> object)
static BAN::Optional<uint64_t> evaluate_or_invoke(BAN::RefPtr<AML::Node> object)
{
if (object->type != AML::Node::Type::Method)
return object->as_integer();
@ -85,7 +85,7 @@ namespace Kernel::ACPI
return {};
}
return result.value() ? result.value()->as_integer() : BAN::RefPtr<AML::Integer>();
return result.value() ? result.value()->as_integer() : BAN::Optional<uint64_t>();
}
bool AML::initialize_scope(BAN::RefPtr<AML::Scope> scope)
@ -138,14 +138,14 @@ namespace Kernel::ACPI
if (auto sta = Namespace::root_namespace()->find_object(scope->scope, AML::NameString("_STA"_sv), Namespace::FindMode::ForceAbsolute))
{
auto result = evaluate_or_invoke(sta);
if (!result)
if (!result.has_value())
{
AML_ERROR("Failed to evaluate {}._STA, return value could not be resolved to integer", scope->scope);
return false;
}
run_ini = (result->value & 0x01);
init_children = run_ini || (result->value & 0x02);
run_ini = (result.value() & 0x01);
init_children = run_ini || (result.value() & 0x02);
}
if (run_ini)

View File

@ -1,58 +0,0 @@
#include <kernel/ACPI/AML/Buffer.h>
#include <kernel/ACPI/AML/String.h>
namespace Kernel::ACPI::AML
{
BAN::Optional<bool> String::logical_compare(BAN::RefPtr<AML::Node> node, AML::Byte binaryop)
{
auto rhs = node ? node->as_string() : BAN::RefPtr<AML::String>();
if (!rhs)
{
AML_ERROR("String logical compare RHS is not string");
return {};
}
(void)binaryop;
AML_TODO("Logical compare string");
return {};
}
BAN::RefPtr<AML::Buffer> String::as_buffer()
{
auto buffer = MUST(BAN::RefPtr<AML::Buffer>::create());
MUST(buffer->buffer.resize(string.size()));
for (size_t i = 0; i < string.size(); i++)
buffer->buffer[i] = string[i];
return buffer;
}
ParseResult String::parse(ParseContext& context)
{
ASSERT(context.aml_data.size() >= 1);
ASSERT(static_cast<AML::Byte>(context.aml_data[0]) == AML::Byte::StringPrefix);
context.aml_data = context.aml_data.slice(1);
BAN::Vector<uint8_t> string;
while (context.aml_data.size() > 0)
{
if (context.aml_data[0] == 0x00)
break;
MUST(string.push_back(context.aml_data[0]));
context.aml_data = context.aml_data.slice(1);
}
if (context.aml_data.size() == 0)
return ParseResult::Failure;
if (context.aml_data[0] != 0x00)
return ParseResult::Failure;
context.aml_data = context.aml_data.slice(1);
auto string_node = MUST(BAN::RefPtr<String>::create());
string_node->string = BAN::move(string);
return ParseResult(string_node);
}
}

View File

@ -115,41 +115,41 @@ namespace Kernel
m_background = TerminalColor::BLACK;
break;
case 30: m_foreground = TerminalColor::BLACK; break;
case 31: m_foreground = TerminalColor::RED; break;
case 32: m_foreground = TerminalColor::GREEN; break;
case 33: m_foreground = TerminalColor::YELLOW; break;
case 34: m_foreground = TerminalColor::BLUE; break;
case 35: m_foreground = TerminalColor::MAGENTA; break;
case 36: m_foreground = TerminalColor::CYAN; break;
case 37: m_foreground = TerminalColor::WHITE; break;
case 30: m_foreground = TerminalColor::BRIGHT_BLACK; break;
case 31: m_foreground = TerminalColor::BRIGHT_RED; break;
case 32: m_foreground = TerminalColor::BRIGHT_GREEN; break;
case 33: m_foreground = TerminalColor::BRIGHT_YELLOW; break;
case 34: m_foreground = TerminalColor::BRIGHT_BLUE; break;
case 35: m_foreground = TerminalColor::BRIGHT_MAGENTA; break;
case 36: m_foreground = TerminalColor::BRIGHT_CYAN; break;
case 37: m_foreground = TerminalColor::BRIGHT_WHITE; break;
case 40: m_background = TerminalColor::BLACK; break;
case 41: m_background = TerminalColor::RED; break;
case 42: m_background = TerminalColor::GREEN; break;
case 43: m_background = TerminalColor::YELLOW; break;
case 44: m_background = TerminalColor::BLUE; break;
case 45: m_background = TerminalColor::MAGENTA; break;
case 46: m_background = TerminalColor::CYAN; break;
case 47: m_background = TerminalColor::WHITE; break;
case 40: m_background = TerminalColor::BRIGHT_BLACK; break;
case 41: m_background = TerminalColor::BRIGHT_RED; break;
case 42: m_background = TerminalColor::BRIGHT_GREEN; break;
case 43: m_background = TerminalColor::BRIGHT_YELLOW; break;
case 44: m_background = TerminalColor::BRIGHT_BLUE; break;
case 45: m_background = TerminalColor::BRIGHT_MAGENTA; break;
case 46: m_background = TerminalColor::BRIGHT_CYAN; break;
case 47: m_background = TerminalColor::BRIGHT_WHITE; break;
case 90: m_foreground = TerminalColor::BRIGHT_BLACK; break;
case 91: m_foreground = TerminalColor::BRIGHT_RED; break;
case 92: m_foreground = TerminalColor::BRIGHT_GREEN; break;
case 93: m_foreground = TerminalColor::BRIGHT_YELLOW; break;
case 94: m_foreground = TerminalColor::BRIGHT_BLUE; break;
case 95: m_foreground = TerminalColor::BRIGHT_MAGENTA; break;
case 96: m_foreground = TerminalColor::BRIGHT_CYAN; break;
case 97: m_foreground = TerminalColor::BRIGHT_WHITE; break;
case 90: m_foreground = TerminalColor::BLACK; break;
case 91: m_foreground = TerminalColor::RED; break;
case 92: m_foreground = TerminalColor::GREEN; break;
case 93: m_foreground = TerminalColor::YELLOW; break;
case 94: m_foreground = TerminalColor::BLUE; break;
case 95: m_foreground = TerminalColor::MAGENTA; break;
case 96: m_foreground = TerminalColor::CYAN; break;
case 97: m_foreground = TerminalColor::WHITE; break;
case 100: m_background = TerminalColor::BRIGHT_BLACK; break;
case 101: m_background = TerminalColor::BRIGHT_RED; break;
case 102: m_background = TerminalColor::BRIGHT_GREEN; break;
case 103: m_background = TerminalColor::BRIGHT_YELLOW; break;
case 104: m_background = TerminalColor::BRIGHT_BLUE; break;
case 105: m_background = TerminalColor::BRIGHT_MAGENTA; break;
case 106: m_background = TerminalColor::BRIGHT_CYAN; break;
case 107: m_background = TerminalColor::BRIGHT_WHITE; break;
case 100: m_background = TerminalColor::BLACK; break;
case 101: m_background = TerminalColor::RED; break;
case 102: m_background = TerminalColor::GREEN; break;
case 103: m_background = TerminalColor::YELLOW; break;
case 104: m_background = TerminalColor::BLUE; break;
case 105: m_background = TerminalColor::MAGENTA; break;
case 106: m_background = TerminalColor::CYAN; break;
case 107: m_background = TerminalColor::WHITE; break;
}
}

View File

@ -184,26 +184,26 @@ bool Terminal::read_shell()
void Terminal::handle_sgr()
{
constexpr uint32_t colors_dark[] {
0xFF'000000,
0xFF'FF0000,
0xFF'00FF00,
0xFF'FFFF00,
0xFF'0000FF,
0xFF'FF00FF,
0xFF'00FFFF,
0xFF'BFBFBF,
constexpr uint32_t colors_default[] {
0x555555,
0xFF5555,
0x55FF55,
0xFFFF55,
0x5555FF,
0xFF55FF,
0x55FFFF,
0xFFFFFF,
};
constexpr uint32_t colors_bright[] {
0xFF'3F3F3F,
0xFF'FF7F7F,
0xFF'7FFF7F,
0xFF'FFFF7F,
0xFF'7F7FFF,
0xFF'FF7FFF,
0xFF'7FFFFF,
0xFF'FFFFFF,
0xAAAAAA,
0xFFAAAA,
0xAAFFAA,
0xFFFFAA,
0xAAAAFF,
0xFFAAFF,
0xAAFFFF,
0xFFFFFF,
};
switch (m_csi_info.fields[0])
@ -213,10 +213,10 @@ void Terminal::handle_sgr()
m_bg_color = 0x000000;
break;
case 30: case 31: case 32: case 33: case 34: case 35: case 36: case 37:
m_fg_color = colors_dark[m_csi_info.fields[0] - 30];
m_fg_color = colors_default[m_csi_info.fields[0] - 30];
break;
case 40: case 41: case 42: case 43: case 44: case 45: case 46: case 47:
m_bg_color = colors_dark[m_csi_info.fields[0] - 40];
m_bg_color = colors_default[m_csi_info.fields[0] - 40];
break;
case 90: case 91: case 92: case 93: case 94: case 95: case 96: case 97:
m_fg_color = colors_bright[m_csi_info.fields[0] - 90];