Kernel: My AML parser can now enable ACPI mode on QEMU!
This commit is contained in:
@@ -16,6 +16,12 @@ namespace Kernel::ACPI
|
||||
|
||||
const SDTHeader* get_header(BAN::StringView signature, uint32_t index);
|
||||
|
||||
// mode
|
||||
// 0: PIC
|
||||
// 1: APIC
|
||||
// 2: SAPIC
|
||||
BAN::ErrorOr<void> enter_acpi_mode(uint8_t mode);
|
||||
|
||||
private:
|
||||
ACPI() = default;
|
||||
BAN::ErrorOr<void> initialize_impl();
|
||||
|
||||
@@ -54,8 +54,21 @@ namespace Kernel::ACPI::AML
|
||||
{}
|
||||
|
||||
BAN::RefPtr<Node> evaluate() override;
|
||||
bool store(BAN::RefPtr<Node> source) override;
|
||||
|
||||
void debug_print(int indent) const override;
|
||||
|
||||
private:
|
||||
struct AccessType
|
||||
{
|
||||
uint64_t offset;
|
||||
uint64_t mask;
|
||||
uint32_t access_size;
|
||||
uint32_t shift;
|
||||
};
|
||||
BAN::Optional<AccessType> determine_access_type() const;
|
||||
BAN::Optional<uint64_t> read_field(uint64_t offset, uint32_t access_size) const;
|
||||
bool write_field(uint64_t offset, uint32_t access_size, uint64_t value) const;
|
||||
};
|
||||
|
||||
struct Field
|
||||
|
||||
@@ -13,6 +13,7 @@ namespace Kernel::ACPI::AML
|
||||
{
|
||||
using Arguments = BAN::Array<BAN::RefPtr<AML::Register>, 7>;
|
||||
|
||||
Mutex mutex;
|
||||
uint8_t arg_count;
|
||||
bool serialized;
|
||||
uint8_t sync_level;
|
||||
@@ -68,17 +69,23 @@ namespace Kernel::ACPI::AML
|
||||
return ParseResult::Success;
|
||||
}
|
||||
|
||||
BAN::Optional<BAN::RefPtr<AML::Node>> evaluate(Arguments args)
|
||||
BAN::Optional<BAN::RefPtr<AML::Node>> evaluate(Arguments args, uint8_t old_sync_level = 0)
|
||||
{
|
||||
ParseContext context;
|
||||
context.aml_data = term_list;
|
||||
context.scope = scope;
|
||||
context.method_args = args;
|
||||
context.sync_level = old_sync_level;
|
||||
for (auto& local : context.method_locals)
|
||||
local = MUST(BAN::RefPtr<AML::Register>::create());
|
||||
|
||||
BAN::Optional<BAN::RefPtr<AML::Node>> return_value;
|
||||
if (serialized)
|
||||
{
|
||||
mutex.lock();
|
||||
context.sync_level = BAN::Math::max(sync_level, old_sync_level);
|
||||
}
|
||||
|
||||
BAN::Optional<BAN::RefPtr<AML::Node>> return_value;
|
||||
while (context.aml_data.size() > 0)
|
||||
{
|
||||
auto parse_result = AML::parse_object(context);
|
||||
@@ -88,7 +95,10 @@ namespace Kernel::ACPI::AML
|
||||
break;
|
||||
}
|
||||
if (!parse_result.success())
|
||||
{
|
||||
AML_ERROR("Method {} evaluate failed", scope);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (!context.created_objects.empty())
|
||||
@@ -97,6 +107,9 @@ namespace Kernel::ACPI::AML
|
||||
context.created_objects.pop_back();
|
||||
}
|
||||
|
||||
if (serialized)
|
||||
mutex.unlock();
|
||||
|
||||
return return_value;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <kernel/ACPI/AML/Scope.h>
|
||||
#include <kernel/Lock/Mutex.h>
|
||||
|
||||
namespace Kernel::ACPI::AML
|
||||
{
|
||||
|
||||
struct Namespace : public AML::Scope
|
||||
{
|
||||
Mutex global_lock;
|
||||
|
||||
static BAN::RefPtr<AML::Namespace> root_namespace();
|
||||
|
||||
Namespace(NameSeg name) : AML::Scope(Node::Type::Namespace, name) {}
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace Kernel::ACPI::AML
|
||||
// we don't really need large contiguous memory
|
||||
BAN::LinkedList<AML::NameString> created_objects;
|
||||
|
||||
uint8_t sync_level { 0 };
|
||||
BAN::Array<BAN::RefPtr<Register>, 7> method_args;
|
||||
BAN::Array<BAN::RefPtr<Register>, 8> method_locals;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user