Compare commits
No commits in common. "aefb33efffbd4eac65f3db91f9df1e44598a1f06" and "b6587b32b9abdf988f1281ccc37507d88b4eeef0" have entirely different histories.
aefb33efff
...
b6587b32b9
|
@ -84,18 +84,17 @@ namespace Kernel::ACPI::AML
|
||||||
ASSERT(field_bit_offset + field_bit_size <= buffer->buffer.size() * 8);
|
ASSERT(field_bit_offset + field_bit_size <= buffer->buffer.size() * 8);
|
||||||
|
|
||||||
uint64_t value = 0;
|
uint64_t value = 0;
|
||||||
|
|
||||||
const size_t byte_offset = field_bit_offset / 8;
|
|
||||||
const size_t bit_offset = field_bit_offset % 8;
|
|
||||||
if (field_bit_size == 1)
|
if (field_bit_size == 1)
|
||||||
{
|
{
|
||||||
|
size_t byte_offset = field_bit_offset / 8;
|
||||||
|
size_t bit_offset = field_bit_offset % 8;
|
||||||
value = (buffer->buffer[byte_offset] >> bit_offset) & 1;
|
value = (buffer->buffer[byte_offset] >> bit_offset) & 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ASSERT(bit_offset == 0);
|
ASSERT(field_bit_size % 8 == 0);
|
||||||
for (size_t byte = 0; byte < field_bit_size / 8; byte++)
|
for (size_t byte = 0; byte < field_bit_size / 8; byte++)
|
||||||
value |= buffer->buffer[byte_offset + byte] << byte;
|
value |= buffer->buffer[byte] << byte;
|
||||||
}
|
}
|
||||||
|
|
||||||
return MUST(BAN::RefPtr<AML::Integer>::create(value));
|
return MUST(BAN::RefPtr<AML::Integer>::create(value));
|
||||||
|
@ -110,18 +109,18 @@ namespace Kernel::ACPI::AML
|
||||||
if (!value.has_value())
|
if (!value.has_value())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const size_t byte_offset = field_bit_offset / 8;
|
|
||||||
const size_t bit_offset = field_bit_offset % 8;
|
|
||||||
if (field_bit_size == 1)
|
if (field_bit_size == 1)
|
||||||
{
|
{
|
||||||
|
size_t byte_offset = field_bit_offset / 8;
|
||||||
|
size_t bit_offset = field_bit_offset % 8;
|
||||||
buffer->buffer[byte_offset] &= ~(1 << bit_offset);
|
buffer->buffer[byte_offset] &= ~(1 << bit_offset);
|
||||||
buffer->buffer[byte_offset] |= (value.value() & 1) << bit_offset;
|
buffer->buffer[byte_offset] |= (value.value() & 1) << bit_offset;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ASSERT(bit_offset == 0);
|
ASSERT(field_bit_size % 8 == 0);
|
||||||
for (size_t byte = 0; byte < field_bit_size / 8; byte++)
|
for (size_t byte = 0; byte < field_bit_size / 8; byte++)
|
||||||
buffer->buffer[byte_offset + byte] = (value.value() >> (byte * 8)) & 0xFF;
|
buffer->buffer[byte] = (value.value() >> (byte * 8)) & 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -42,13 +42,11 @@ namespace Kernel::ACPI::AML
|
||||||
AML_DEBUG_PRINT("Device ");
|
AML_DEBUG_PRINT("Device ");
|
||||||
name.debug_print();
|
name.debug_print();
|
||||||
AML_DEBUG_PRINTLN(" {");
|
AML_DEBUG_PRINTLN(" {");
|
||||||
Namespace::root_namespace()->for_each_child(scope,
|
for (const auto& [name, object] : objects)
|
||||||
[&](const auto&, const auto& child)
|
|
||||||
{
|
{
|
||||||
child->debug_print(indent + 1);
|
object->debug_print(indent + 1);
|
||||||
AML_DEBUG_PRINTLN("");
|
AML_DEBUG_PRINTLN("");
|
||||||
}
|
}
|
||||||
);
|
|
||||||
AML_DEBUG_PRINT_INDENT(indent);
|
AML_DEBUG_PRINT_INDENT(indent);
|
||||||
AML_DEBUG_PRINT("}");
|
AML_DEBUG_PRINT("}");
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,7 +104,6 @@ namespace Kernel::ACPI::AML
|
||||||
AML_ERROR("BinaryOP {2H} LHS not an integer", static_cast<uint8_t>(opcode));
|
AML_ERROR("BinaryOP {2H} LHS not an integer", static_cast<uint8_t>(opcode));
|
||||||
if (lhs_result.node())
|
if (lhs_result.node())
|
||||||
lhs_result.node()->debug_print(1);
|
lhs_result.node()->debug_print(1);
|
||||||
AML_DEBUG_PRINTLN("");
|
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +116,6 @@ namespace Kernel::ACPI::AML
|
||||||
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())
|
||||||
rhs_result.node()->debug_print(1);
|
rhs_result.node()->debug_print(1);
|
||||||
AML_DEBUG_PRINTLN("");
|
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,6 @@ namespace Kernel::ACPI::AML
|
||||||
bool store_internal(uint64_t value);
|
bool store_internal(uint64_t value);
|
||||||
|
|
||||||
friend struct IndexFieldElement;
|
friend struct IndexFieldElement;
|
||||||
friend struct BankFieldElement;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Field
|
struct Field
|
||||||
|
@ -117,7 +116,7 @@ namespace Kernel::ACPI::AML
|
||||||
FieldRules access_rules;
|
FieldRules access_rules;
|
||||||
|
|
||||||
BAN::RefPtr<OpRegion> op_region;
|
BAN::RefPtr<OpRegion> op_region;
|
||||||
BAN::RefPtr<FieldElement> bank_selector;
|
BAN::RefPtr<NamedObject> bank_selector;
|
||||||
uint64_t bank_value;
|
uint64_t bank_value;
|
||||||
|
|
||||||
BankFieldElement(NameSeg name, uint64_t bit_offset, uint64_t bit_count, FieldRules access_rules)
|
BankFieldElement(NameSeg name, uint64_t bit_offset, uint64_t bit_count, FieldRules access_rules)
|
||||||
|
@ -127,9 +126,6 @@ namespace Kernel::ACPI::AML
|
||||||
, access_rules(access_rules)
|
, access_rules(access_rules)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
BAN::RefPtr<Node> evaluate() override;
|
|
||||||
bool store(BAN::RefPtr<Node> source) override;
|
|
||||||
|
|
||||||
void debug_print(int indent) const override;
|
void debug_print(int indent) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -23,28 +23,36 @@ namespace Kernel::ACPI::AML
|
||||||
auto outer_aml_data = context.aml_data;
|
auto outer_aml_data = context.aml_data;
|
||||||
context.aml_data = if_pkg.value();
|
context.aml_data = if_pkg.value();
|
||||||
|
|
||||||
auto predicate_result = AML::parse_object(context);
|
auto predicate = AML::parse_object(context);
|
||||||
if (!predicate_result.success())
|
if (!predicate.success())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
auto predicate = predicate_result.node() ? predicate_result.node()->as_integer() : BAN::Optional<uint64_t>();
|
auto predicate_node = predicate.node();
|
||||||
if (!predicate.has_value())
|
if (!predicate_node)
|
||||||
|
{
|
||||||
|
AML_ERROR("If predicate is not an integer");
|
||||||
|
return ParseResult::Failure;
|
||||||
|
}
|
||||||
|
auto predicate_integer = predicate_node->as_integer();
|
||||||
|
if (!predicate_integer.has_value())
|
||||||
{
|
{
|
||||||
AML_ERROR("If predicate is not an integer");
|
AML_ERROR("If predicate is not an integer");
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Else
|
// Else
|
||||||
BAN::ConstByteSpan else_pkg;
|
if (!predicate_integer.value())
|
||||||
if (outer_aml_data.size() >= 1 && static_cast<AML::Byte>(outer_aml_data[0]) == Byte::ElseOp)
|
{
|
||||||
|
if (outer_aml_data.size() < 1 || static_cast<Byte>(outer_aml_data[0]) != Byte::ElseOp)
|
||||||
|
context.aml_data = BAN::ConstByteSpan();
|
||||||
|
else
|
||||||
{
|
{
|
||||||
outer_aml_data = outer_aml_data.slice(1);
|
outer_aml_data = outer_aml_data.slice(1);
|
||||||
auto else_pkg_result = AML::parse_pkg(outer_aml_data);
|
auto else_pkg = AML::parse_pkg(outer_aml_data);
|
||||||
if (!else_pkg_result.has_value())
|
if (!else_pkg.has_value())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
else_pkg = else_pkg_result.value();
|
context.aml_data = else_pkg.value();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!predicate.value())
|
|
||||||
context.aml_data = else_pkg;
|
|
||||||
|
|
||||||
while (context.aml_data.size() > 0)
|
while (context.aml_data.size() > 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#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/ParseContext.h>
|
#include <kernel/ACPI/AML/ParseContext.h>
|
||||||
|
@ -12,12 +11,13 @@ namespace Kernel::ACPI::AML
|
||||||
|
|
||||||
struct Method : public AML::Scope
|
struct Method : public AML::Scope
|
||||||
{
|
{
|
||||||
Kernel::Mutex mutex;
|
using Arguments = BAN::Array<BAN::RefPtr<AML::Register>, 7>;
|
||||||
|
|
||||||
|
Mutex mutex;
|
||||||
uint8_t arg_count;
|
uint8_t arg_count;
|
||||||
bool serialized;
|
bool serialized;
|
||||||
uint8_t sync_level;
|
uint8_t sync_level;
|
||||||
|
|
||||||
BAN::Function<BAN::RefPtr<AML::Node>(ParseContext&)> override_function;
|
|
||||||
BAN::ConstByteSpan term_list;
|
BAN::ConstByteSpan term_list;
|
||||||
|
|
||||||
Method(AML::NameSeg name, uint8_t arg_count, bool serialized, uint8_t sync_level)
|
Method(AML::NameSeg name, uint8_t arg_count, bool serialized, uint8_t sync_level)
|
||||||
|
@ -54,7 +54,12 @@ namespace Kernel::ACPI::AML
|
||||||
));
|
));
|
||||||
if (!Namespace::root_namespace()->add_named_object(context, name_string.value(), method))
|
if (!Namespace::root_namespace()->add_named_object(context, name_string.value(), method))
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
|
|
||||||
|
auto method_scope = Namespace::root_namespace()->resolve_path(context.scope, name_string.value());
|
||||||
|
if (!method_scope.has_value())
|
||||||
|
return ParseResult::Failure;
|
||||||
method->term_list = method_pkg.value();
|
method->term_list = method_pkg.value();
|
||||||
|
method->scope = method_scope.release_value();
|
||||||
|
|
||||||
#if AML_DEBUG_LEVEL >= 2
|
#if AML_DEBUG_LEVEL >= 2
|
||||||
method->debug_print(0);
|
method->debug_print(0);
|
||||||
|
@ -64,30 +69,7 @@ namespace Kernel::ACPI::AML
|
||||||
return ParseResult::Success;
|
return ParseResult::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::Optional<BAN::RefPtr<AML::Node>> invoke(
|
BAN::Optional<BAN::RefPtr<AML::Node>> evaluate(Arguments args, BAN::Vector<uint8_t>& current_sync_stack)
|
||||||
BAN::RefPtr<AML::Node> arg0 = {},
|
|
||||||
BAN::RefPtr<AML::Node> arg1 = {},
|
|
||||||
BAN::RefPtr<AML::Node> arg2 = {},
|
|
||||||
BAN::RefPtr<AML::Node> arg3 = {},
|
|
||||||
BAN::RefPtr<AML::Node> arg4 = {},
|
|
||||||
BAN::RefPtr<AML::Node> arg5 = {},
|
|
||||||
BAN::RefPtr<AML::Node> arg6 = {}
|
|
||||||
)
|
|
||||||
{
|
|
||||||
BAN::Vector<uint8_t> sync_stack;
|
|
||||||
return invoke_with_sync_stack(sync_stack, arg0, arg1, arg2, arg3, arg4, arg5, arg6);
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::Optional<BAN::RefPtr<AML::Node>> invoke_with_sync_stack(
|
|
||||||
BAN::Vector<uint8_t>& current_sync_stack,
|
|
||||||
BAN::RefPtr<AML::Node> arg0 = {},
|
|
||||||
BAN::RefPtr<AML::Node> arg1 = {},
|
|
||||||
BAN::RefPtr<AML::Node> arg2 = {},
|
|
||||||
BAN::RefPtr<AML::Node> arg3 = {},
|
|
||||||
BAN::RefPtr<AML::Node> arg4 = {},
|
|
||||||
BAN::RefPtr<AML::Node> arg5 = {},
|
|
||||||
BAN::RefPtr<AML::Node> arg6 = {}
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
if (serialized && !current_sync_stack.empty() && sync_level < current_sync_stack.back())
|
if (serialized && !current_sync_stack.empty() && sync_level < current_sync_stack.back())
|
||||||
{
|
{
|
||||||
|
@ -98,13 +80,7 @@ namespace Kernel::ACPI::AML
|
||||||
ParseContext context;
|
ParseContext context;
|
||||||
context.aml_data = term_list;
|
context.aml_data = term_list;
|
||||||
context.scope = scope;
|
context.scope = scope;
|
||||||
context.method_args[0] = MUST(BAN::RefPtr<AML::Register>::create(arg0));
|
context.method_args = args;
|
||||||
context.method_args[1] = MUST(BAN::RefPtr<AML::Register>::create(arg1));
|
|
||||||
context.method_args[2] = MUST(BAN::RefPtr<AML::Register>::create(arg2));
|
|
||||||
context.method_args[3] = MUST(BAN::RefPtr<AML::Register>::create(arg3));
|
|
||||||
context.method_args[4] = MUST(BAN::RefPtr<AML::Register>::create(arg4));
|
|
||||||
context.method_args[5] = MUST(BAN::RefPtr<AML::Register>::create(arg5));
|
|
||||||
context.method_args[6] = MUST(BAN::RefPtr<AML::Register>::create(arg6));
|
|
||||||
context.sync_stack = BAN::move(current_sync_stack);
|
context.sync_stack = BAN::move(current_sync_stack);
|
||||||
for (auto& local : context.method_locals)
|
for (auto& local : context.method_locals)
|
||||||
local = MUST(BAN::RefPtr<AML::Register>::create());
|
local = MUST(BAN::RefPtr<AML::Register>::create());
|
||||||
|
@ -119,12 +95,8 @@ namespace Kernel::ACPI::AML
|
||||||
AML_DEBUG_PRINTLN("Evaluating {}", scope);
|
AML_DEBUG_PRINTLN("Evaluating {}", scope);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
BAN::Optional<BAN::RefPtr<AML::Node>> return_value = BAN::RefPtr<AML::Node>();
|
|
||||||
|
|
||||||
if (override_function)
|
BAN::Optional<BAN::RefPtr<AML::Node>> return_value = BAN::RefPtr<AML::Node>();
|
||||||
return_value = override_function(context);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
while (context.aml_data.size() > 0)
|
while (context.aml_data.size() > 0)
|
||||||
{
|
{
|
||||||
auto parse_result = AML::parse_object(context);
|
auto parse_result = AML::parse_object(context);
|
||||||
|
@ -140,7 +112,6 @@ namespace Kernel::ACPI::AML
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
while (!context.created_objects.empty())
|
while (!context.created_objects.empty())
|
||||||
{
|
{
|
||||||
|
|
|
@ -36,14 +36,6 @@ namespace Kernel::ACPI::AML
|
||||||
aml_data = aml_data.slice(4);
|
aml_data = aml_data.slice(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::StringView sv() const
|
|
||||||
{
|
|
||||||
size_t len = 4;
|
|
||||||
while (len > 0 && chars[len - 1] == '_')
|
|
||||||
len--;
|
|
||||||
return BAN::StringView(chars, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
static BAN::Optional<NameSeg> parse(BAN::ConstByteSpan& aml_data)
|
static BAN::Optional<NameSeg> parse(BAN::ConstByteSpan& aml_data)
|
||||||
{
|
{
|
||||||
if (aml_data.size() < 4)
|
if (aml_data.size() < 4)
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <BAN/HashMap.h>
|
|
||||||
#include <kernel/ACPI/AML/Scope.h>
|
#include <kernel/ACPI/AML/Scope.h>
|
||||||
#include <kernel/ACPI/Headers.h>
|
#include <kernel/ACPI/Headers.h>
|
||||||
#include <kernel/Lock/Mutex.h>
|
#include <kernel/Lock/Mutex.h>
|
||||||
|
@ -12,52 +11,21 @@ namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
static BAN::RefPtr<AML::Namespace> root_namespace();
|
static BAN::RefPtr<AML::Namespace> root_namespace();
|
||||||
|
|
||||||
template<typename F>
|
|
||||||
static void for_each_child(const AML::NameString& scope, const F& callback)
|
|
||||||
{
|
|
||||||
auto canonical_path = root_namespace()->resolve_path(scope, {}, FindMode::ForceAbsolute);
|
|
||||||
ASSERT(canonical_path.has_value());
|
|
||||||
|
|
||||||
for (auto& [path, child] : root_namespace()->m_objects)
|
|
||||||
{
|
|
||||||
if (path.size() < canonical_path->size() + 1)
|
|
||||||
continue;
|
|
||||||
if (canonical_path->size() != 1 && path[canonical_path->size()] != '.')
|
|
||||||
continue;
|
|
||||||
if (path.sv().substring(0, canonical_path->size()) != canonical_path->sv())
|
|
||||||
continue;
|
|
||||||
if (path.sv().substring(canonical_path->size() + 1).contains('.'))
|
|
||||||
continue;
|
|
||||||
callback(path, child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Namespace(NameSeg name) : AML::Scope(Node::Type::Namespace, name) {}
|
Namespace(NameSeg name) : AML::Scope(Node::Type::Namespace, name) {}
|
||||||
|
|
||||||
static BAN::RefPtr<AML::Namespace> create_root_namespace();
|
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;
|
BAN::Optional<AML::NameString> resolve_path(const AML::NameString& relative_base, const AML::NameString& relative_path);
|
||||||
|
|
||||||
enum class FindMode
|
|
||||||
{
|
|
||||||
Normal,
|
|
||||||
ForceAbsolute,
|
|
||||||
};
|
|
||||||
BAN::Optional<BAN::String> resolve_path(const AML::NameString& relative_base, const AML::NameString& relative_path, FindMode mode, bool check_existence = true) const;
|
|
||||||
|
|
||||||
// Find an object in the namespace. Returns nullptr if the object is not found.
|
// Find an object in the namespace. Returns nullptr if the object is not found.
|
||||||
BAN::RefPtr<NamedObject> find_object(const AML::NameString& relative_base, const AML::NameString& relative_path, FindMode mode);
|
BAN::RefPtr<NamedObject> find_object(const AML::NameString& relative_base, const AML::NameString& relative_path);
|
||||||
|
|
||||||
// Add an object to the namespace. Returns false if the parent object could not be added.
|
// Add an object to the namespace. Returns false if the parent object could not be added.
|
||||||
bool add_named_object(ParseContext&, const AML::NameString& object_path, BAN::RefPtr<NamedObject> object);
|
bool add_named_object(ParseContext&, const AML::NameString& object_path, BAN::RefPtr<NamedObject> object);
|
||||||
|
|
||||||
// Remove an object from the namespace. Returns false if the object could not be removed.
|
// Remove an object from the namespace. Returns false if the object could not be removed.
|
||||||
bool remove_named_object(const AML::NameString& absolute_path);
|
bool remove_named_object(const AML::NameString& absolute_path);
|
||||||
|
|
||||||
private:
|
|
||||||
BAN::HashMap<BAN::String, BAN::RefPtr<NamedObject>> m_objects;
|
|
||||||
mutable Mutex m_object_mutex;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,66 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <kernel/ACPI/AML/Device.h>
|
|
||||||
#include <kernel/ACPI/AML/ParseContext.h>
|
|
||||||
#include <kernel/ACPI/AML/Processor.h>
|
|
||||||
#include <kernel/ACPI/AML/ThermalZone.h>
|
|
||||||
|
|
||||||
namespace Kernel::ACPI::AML
|
|
||||||
{
|
|
||||||
|
|
||||||
struct Notify
|
|
||||||
{
|
|
||||||
static ParseResult parse(ParseContext& context)
|
|
||||||
{
|
|
||||||
ASSERT(context.aml_data.size() >= 1);
|
|
||||||
ASSERT(static_cast<Byte>(context.aml_data[0]) == Byte::NotifyOp);
|
|
||||||
context.aml_data = context.aml_data.slice(1);
|
|
||||||
|
|
||||||
auto object_result = AML::parse_object(context);
|
|
||||||
if (!object_result.success())
|
|
||||||
return ParseResult::Failure;
|
|
||||||
auto object = object_result.node();
|
|
||||||
if (!object)
|
|
||||||
{
|
|
||||||
AML_ERROR("Notify object is null");
|
|
||||||
return ParseResult::Failure;
|
|
||||||
}
|
|
||||||
|
|
||||||
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::Optional<uint64_t>();
|
|
||||||
if (!value.has_value())
|
|
||||||
{
|
|
||||||
AML_ERROR("Notify value is not an integer");
|
|
||||||
return ParseResult::Failure;
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::StringView object_type_sv;
|
|
||||||
BAN::StringView object_name_sv;
|
|
||||||
switch (object->type)
|
|
||||||
{
|
|
||||||
case AML::Node::Type::Device:
|
|
||||||
object_type_sv = "Device"sv;
|
|
||||||
object_name_sv = static_cast<AML::Device*>(object.ptr())->name.sv();
|
|
||||||
break;
|
|
||||||
case AML::Node::Type::Processor:
|
|
||||||
object_type_sv = "Processor"sv;
|
|
||||||
object_name_sv = static_cast<AML::Processor*>(object.ptr())->name.sv();
|
|
||||||
break;
|
|
||||||
case AML::Node::Type::ThermalZone:
|
|
||||||
object_type_sv = "ThermalZone"sv;
|
|
||||||
object_name_sv = static_cast<AML::ThermalZone*>(object.ptr())->name.sv();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
object_type_sv = "Unknown"sv;
|
|
||||||
object_name_sv = "????"sv;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
AML_TODO("Notify: {} {}: {2H}", object_type_sv, object_name_sv, value.value());
|
|
||||||
return ParseResult::Success;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
|
@ -32,7 +32,7 @@ namespace Kernel::ACPI::AML
|
||||||
// resolve references
|
// resolve references
|
||||||
for (auto& reference : unresolved_references)
|
for (auto& reference : unresolved_references)
|
||||||
{
|
{
|
||||||
auto object = Namespace::root_namespace()->find_object(scope, reference.name, Namespace::FindMode::Normal);
|
auto object = Namespace::root_namespace()->find_object(scope, reference.name);
|
||||||
if (!object)
|
if (!object)
|
||||||
{
|
{
|
||||||
AML_ERROR("Failed to resolve reference {} in package", reference.name);
|
AML_ERROR("Failed to resolve reference {} in package", reference.name);
|
||||||
|
@ -101,14 +101,12 @@ namespace Kernel::ACPI::AML
|
||||||
AML_DEBUG_PRINT("Package {");
|
AML_DEBUG_PRINT("Package {");
|
||||||
AML_DEBUG_PRINTLN("");
|
AML_DEBUG_PRINTLN("");
|
||||||
for (const auto& element : elements)
|
for (const auto& element : elements)
|
||||||
{
|
|
||||||
if (element)
|
|
||||||
element->debug_print(indent + 1);
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
AML_DEBUG_PRINT_INDENT(indent + 1);
|
AML_DEBUG_PRINT_INDENT(indent + 1);
|
||||||
|
if (element)
|
||||||
|
element->debug_print(0);
|
||||||
|
else
|
||||||
AML_DEBUG_PRINT("Uninitialized");
|
AML_DEBUG_PRINT("Uninitialized");
|
||||||
}
|
|
||||||
AML_DEBUG_PRINTLN("");
|
AML_DEBUG_PRINTLN("");
|
||||||
}
|
}
|
||||||
AML_DEBUG_PRINT_INDENT(indent);
|
AML_DEBUG_PRINT_INDENT(indent);
|
||||||
|
|
|
@ -68,16 +68,7 @@ namespace Kernel::ACPI::AML
|
||||||
virtual void debug_print(int indent) const override
|
virtual void debug_print(int indent) const override
|
||||||
{
|
{
|
||||||
AML_DEBUG_PRINT_INDENT(indent);
|
AML_DEBUG_PRINT_INDENT(indent);
|
||||||
AML_DEBUG_PRINTLN("Processor {} (ID: {}, PBlkAddr: 0x{H}, PBlkLen: {}) {", name, id, pblk_addr, pblk_len);
|
AML_DEBUG_PRINT("Processor {} (ID: {}, PBlkAddr: 0x{H}, PBlkLen: {})", name, id, pblk_addr, pblk_len);
|
||||||
Namespace::root_namespace()->for_each_child(scope,
|
|
||||||
[&](const auto&, const auto& child)
|
|
||||||
{
|
|
||||||
child->debug_print(indent + 1);
|
|
||||||
AML_DEBUG_PRINTLN("");
|
|
||||||
}
|
|
||||||
);
|
|
||||||
AML_DEBUG_PRINT_INDENT(indent);
|
|
||||||
AML_DEBUG_PRINT("}");
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ namespace Kernel::ACPI::AML
|
||||||
auto name = NameString::parse(context.aml_data);
|
auto name = NameString::parse(context.aml_data);
|
||||||
if (!name.has_value())
|
if (!name.has_value())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
object = Namespace::root_namespace()->find_object(context.scope, name.value(), Namespace::FindMode::Normal);
|
object = Namespace::root_namespace()->find_object(context.scope, name.value());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,8 +27,6 @@ namespace Kernel::ACPI::AML
|
||||||
uint64_t region_offset;
|
uint64_t region_offset;
|
||||||
uint64_t region_length;
|
uint64_t region_length;
|
||||||
|
|
||||||
Kernel::Mutex mutex;
|
|
||||||
|
|
||||||
OpRegion(NameSeg name, RegionSpace region_space, uint64_t region_offset, uint64_t region_length)
|
OpRegion(NameSeg name, RegionSpace region_space, uint64_t region_offset, uint64_t region_length)
|
||||||
: NamedObject(Node::Type::OpRegion, name)
|
: NamedObject(Node::Type::OpRegion, name)
|
||||||
, region_space(region_space)
|
, region_space(region_space)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <BAN/HashMap.h>
|
||||||
#include <kernel/ACPI/AML/NamedObject.h>
|
#include <kernel/ACPI/AML/NamedObject.h>
|
||||||
#include <kernel/ACPI/AML/Names.h>
|
#include <kernel/ACPI/AML/Names.h>
|
||||||
|
|
||||||
|
@ -8,6 +9,7 @@ namespace Kernel::ACPI::AML
|
||||||
|
|
||||||
struct Scope : public AML::NamedObject
|
struct Scope : public AML::NamedObject
|
||||||
{
|
{
|
||||||
|
BAN::HashMap<NameSeg, BAN::RefPtr<NamedObject>> objects;
|
||||||
AML::NameString scope;
|
AML::NameString scope;
|
||||||
|
|
||||||
Scope(Node::Type type, NameSeg name)
|
Scope(Node::Type type, NameSeg name)
|
||||||
|
@ -17,6 +19,7 @@ namespace Kernel::ACPI::AML
|
||||||
virtual bool is_scope() const override { return true; }
|
virtual bool is_scope() const override { return true; }
|
||||||
|
|
||||||
static ParseResult parse(ParseContext& context);
|
static ParseResult parse(ParseContext& context);
|
||||||
|
virtual void debug_print(int indent) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ParseResult enter_context_and_parse_term_list(ParseContext& outer_context, const AML::NameString& name, BAN::ConstByteSpan aml_data);
|
ParseResult enter_context_and_parse_term_list(ParseContext& outer_context, const AML::NameString& name, BAN::ConstByteSpan aml_data);
|
||||||
|
|
|
@ -13,11 +13,6 @@ namespace Kernel::ACPI::AML
|
||||||
|
|
||||||
String() : Node(Node::Type::String) {}
|
String() : Node(Node::Type::String) {}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> evaluate() override
|
|
||||||
{
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ParseResult parse(ParseContext& context)
|
static ParseResult parse(ParseContext& context)
|
||||||
{
|
{
|
||||||
ASSERT(context.aml_data.size() >= 1);
|
ASSERT(context.aml_data.size() >= 1);
|
||||||
|
|
|
@ -46,16 +46,7 @@ namespace Kernel::ACPI::AML
|
||||||
virtual void debug_print(int indent) const override
|
virtual void debug_print(int indent) const override
|
||||||
{
|
{
|
||||||
AML_DEBUG_PRINT_INDENT(indent);
|
AML_DEBUG_PRINT_INDENT(indent);
|
||||||
AML_DEBUG_PRINT("ThermalZone {} {", name);
|
AML_DEBUG_PRINT("ThermalZone {}", name);
|
||||||
Namespace::root_namespace()->for_each_child(scope,
|
|
||||||
[&](const auto&, const auto& child)
|
|
||||||
{
|
|
||||||
child->debug_print(indent + 1);
|
|
||||||
AML_DEBUG_PRINTLN("");
|
|
||||||
}
|
|
||||||
);
|
|
||||||
AML_DEBUG_PRINT_INDENT(indent);
|
|
||||||
AML_DEBUG_PRINT("}");
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <kernel/ACPI/AML/Node.h>
|
|
||||||
#include <kernel/ACPI/AML/ParseContext.h>
|
|
||||||
#include <kernel/ACPI/AML/Pkg.h>
|
|
||||||
|
|
||||||
namespace Kernel::ACPI::AML
|
|
||||||
{
|
|
||||||
|
|
||||||
struct While
|
|
||||||
{
|
|
||||||
static ParseResult parse(ParseContext& context)
|
|
||||||
{
|
|
||||||
ASSERT(context.aml_data.size() >= 1);
|
|
||||||
ASSERT(static_cast<Byte>(context.aml_data[0]) == Byte::WhileOp);
|
|
||||||
context.aml_data = context.aml_data.slice(1);
|
|
||||||
|
|
||||||
auto while_pkg = AML::parse_pkg(context.aml_data);
|
|
||||||
if (!while_pkg.has_value())
|
|
||||||
return ParseResult::Failure;
|
|
||||||
|
|
||||||
auto outer_aml_data = context.aml_data;
|
|
||||||
|
|
||||||
bool breaked = false;
|
|
||||||
while (!breaked)
|
|
||||||
{
|
|
||||||
context.aml_data = while_pkg.value();
|
|
||||||
|
|
||||||
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::Optional<uint64_t>();
|
|
||||||
if (!predicate.has_value())
|
|
||||||
{
|
|
||||||
AML_ERROR("While predicate is not an integer");
|
|
||||||
return ParseResult::Failure;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!predicate.value())
|
|
||||||
break;
|
|
||||||
|
|
||||||
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);
|
|
||||||
if (object_result.returned())
|
|
||||||
return ParseResult(ParseResult::Result::Returned, object_result.node());
|
|
||||||
if (!object_result.success())
|
|
||||||
return ParseResult::Failure;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
context.aml_data = outer_aml_data;
|
|
||||||
|
|
||||||
return ParseResult::Success;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
|
@ -43,7 +43,6 @@ namespace Kernel
|
||||||
ASSERT(m_lock_depth == 0);
|
ASSERT(m_lock_depth == 0);
|
||||||
}
|
}
|
||||||
m_lock_depth++;
|
m_lock_depth++;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void unlock()
|
void unlock()
|
||||||
|
|
|
@ -61,7 +61,7 @@ namespace Kernel
|
||||||
vaddr_t kernel_stack_top() const { return m_kernel_stack->vaddr() + m_kernel_stack->size(); }
|
vaddr_t kernel_stack_top() const { return m_kernel_stack->vaddr() + m_kernel_stack->size(); }
|
||||||
VirtualRange& kernel_stack() { return *m_kernel_stack; }
|
VirtualRange& kernel_stack() { return *m_kernel_stack; }
|
||||||
|
|
||||||
vaddr_t userspace_stack_bottom() const { return is_userspace() ? m_userspace_stack->vaddr() : UINTPTR_MAX; }
|
vaddr_t userspace_stack_bottom() const { return is_userspace() ? m_userspace_stack->vaddr() : 0; }
|
||||||
vaddr_t userspace_stack_top() const { return is_userspace() ? m_userspace_stack->vaddr() + m_userspace_stack->size() : 0; }
|
vaddr_t userspace_stack_top() const { return is_userspace() ? m_userspace_stack->vaddr() + m_userspace_stack->size() : 0; }
|
||||||
VirtualRange& userspace_stack() { ASSERT(is_userspace()); return *m_userspace_stack; }
|
VirtualRange& userspace_stack() { ASSERT(is_userspace()); return *m_userspace_stack; }
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,7 @@ acpi_release_global_lock:
|
||||||
{
|
{
|
||||||
if (!s_global_lock)
|
if (!s_global_lock)
|
||||||
return;
|
return;
|
||||||
|
derrorln("Acquiring ACPI global lock");
|
||||||
ASSERT(acpi_acquire_global_lock(s_global_lock));
|
ASSERT(acpi_acquire_global_lock(s_global_lock));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,6 +73,7 @@ acpi_release_global_lock:
|
||||||
{
|
{
|
||||||
if (!s_global_lock)
|
if (!s_global_lock)
|
||||||
return;
|
return;
|
||||||
|
derrorln("Releasing ACPI global lock");
|
||||||
ASSERT(!acpi_release_global_lock(s_global_lock));
|
ASSERT(!acpi_release_global_lock(s_global_lock));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,23 +129,7 @@ acpi_release_global_lock:
|
||||||
|
|
||||||
if (facs_addr)
|
if (facs_addr)
|
||||||
{
|
{
|
||||||
size_t facs_size;
|
auto* facs = reinterpret_cast<FACS*>(facs_addr);
|
||||||
PageTable::with_fast_page(facs_addr & PAGE_ADDR_MASK, [&] {
|
|
||||||
facs_size = PageTable::fast_page_as<SDTHeader>(facs_addr % PAGE_SIZE).length;
|
|
||||||
});
|
|
||||||
|
|
||||||
size_t needed_pages = range_page_count(facs_addr, facs_size);
|
|
||||||
vaddr_t facs_vaddr = PageTable::kernel().reserve_free_contiguous_pages(needed_pages, KERNEL_OFFSET);
|
|
||||||
ASSERT(facs_vaddr);
|
|
||||||
|
|
||||||
PageTable::kernel().map_range_at(
|
|
||||||
facs_addr & PAGE_ADDR_MASK,
|
|
||||||
facs_vaddr,
|
|
||||||
needed_pages * PAGE_SIZE,
|
|
||||||
PageTable::Flags::ReadWrite | PageTable::Flags::Present
|
|
||||||
);
|
|
||||||
|
|
||||||
auto* facs = reinterpret_cast<FACS*>(facs_vaddr + (facs_addr % PAGE_SIZE));
|
|
||||||
s_global_lock = &facs->global_lock;
|
s_global_lock = &facs->global_lock;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -368,7 +354,7 @@ acpi_release_global_lock:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto s5_object = m_namespace->find_object({}, AML::NameString("_S5"), AML::Namespace::FindMode::ForceAbsolute);
|
auto s5_object = m_namespace->find_object({}, AML::NameString("\\_S5"));
|
||||||
if (!s5_object)
|
if (!s5_object)
|
||||||
{
|
{
|
||||||
dwarnln("\\_S5 not found");
|
dwarnln("\\_S5 not found");
|
||||||
|
@ -400,7 +386,7 @@ acpi_release_global_lock:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pts_object = m_namespace->find_object({}, AML::NameString("_PTS"), AML::Namespace::FindMode::ForceAbsolute);
|
auto pts_object = m_namespace->find_object({}, AML::NameString("\\_PTS"));
|
||||||
if (pts_object && pts_object->type == AML::Node::Type::Method)
|
if (pts_object && pts_object->type == AML::Node::Type::Method)
|
||||||
{
|
{
|
||||||
auto* method = static_cast<AML::Method*>(pts_object.ptr());
|
auto* method = static_cast<AML::Method*>(pts_object.ptr());
|
||||||
|
@ -410,7 +396,10 @@ acpi_release_global_lock:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!method->invoke(MUST(BAN::RefPtr<AML::Integer>::create(5))).has_value())
|
AML::Method::Arguments args;
|
||||||
|
args[0] = MUST(BAN::RefPtr<AML::Register>::create(MUST(BAN::RefPtr<AML::Integer>::create(5))));
|
||||||
|
BAN::Vector<uint8_t> sync_stack;
|
||||||
|
if (!method->evaluate(args, sync_stack).has_value())
|
||||||
{
|
{
|
||||||
dwarnln("Failed to evaluate \\_PTS");
|
dwarnln("Failed to evaluate \\_PTS");
|
||||||
return;
|
return;
|
||||||
|
@ -476,7 +465,7 @@ acpi_release_global_lock:
|
||||||
dprintln("Initializing devices");
|
dprintln("Initializing devices");
|
||||||
|
|
||||||
// Initialize \\_SB
|
// Initialize \\_SB
|
||||||
auto _sb = m_namespace->find_object({}, AML::NameString("_SB"), AML::Namespace::FindMode::ForceAbsolute);
|
auto _sb = m_namespace->find_object({}, AML::NameString("\\_SB"));
|
||||||
if (_sb && _sb->is_scope())
|
if (_sb && _sb->is_scope())
|
||||||
{
|
{
|
||||||
auto* scope = static_cast<AML::Scope*>(_sb.ptr());
|
auto* scope = static_cast<AML::Scope*>(_sb.ptr());
|
||||||
|
@ -484,7 +473,7 @@ acpi_release_global_lock:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate \\_PIC (mode)
|
// Evaluate \\_PIC (mode)
|
||||||
auto _pic = m_namespace->find_object({}, AML::NameString("_PIC"), AML::Namespace::FindMode::ForceAbsolute);
|
auto _pic = m_namespace->find_object({}, AML::NameString("\\_PIC"));
|
||||||
if (_pic && _pic->type == AML::Node::Type::Method)
|
if (_pic && _pic->type == AML::Node::Type::Method)
|
||||||
{
|
{
|
||||||
auto* method = static_cast<AML::Method*>(_pic.ptr());
|
auto* method = static_cast<AML::Method*>(_pic.ptr());
|
||||||
|
@ -493,7 +482,11 @@ acpi_release_global_lock:
|
||||||
dwarnln("Method \\_PIC has {} arguments, expected 1", method->arg_count);
|
dwarnln("Method \\_PIC has {} arguments, expected 1", method->arg_count);
|
||||||
return BAN::Error::from_errno(EINVAL);
|
return BAN::Error::from_errno(EINVAL);
|
||||||
}
|
}
|
||||||
method->invoke(MUST(BAN::RefPtr<AML::Integer>::create(mode)));
|
|
||||||
|
AML::Method::Arguments args;
|
||||||
|
args[0] = MUST(BAN::RefPtr<AML::Register>::create(MUST(BAN::RefPtr<AML::Integer>::create(mode))));
|
||||||
|
BAN::Vector<uint8_t> sync_stack;
|
||||||
|
method->evaluate(args, sync_stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
dprintln("Devices are initialized");
|
dprintln("Devices are initialized");
|
||||||
|
|
|
@ -404,7 +404,7 @@ namespace Kernel::ACPI
|
||||||
if (!name_string.has_value())
|
if (!name_string.has_value())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
|
|
||||||
auto op_region = Namespace::root_namespace()->find_object(context.scope, name_string.value(), Namespace::FindMode::Normal);
|
auto op_region = Namespace::root_namespace()->find_object(context.scope, name_string.value());
|
||||||
if (!op_region || op_region->type != AML::Node::Type::OpRegion)
|
if (!op_region || op_region->type != AML::Node::Type::OpRegion)
|
||||||
{
|
{
|
||||||
AML_ERROR("FieldOp: {} does not name a valid OpRegion", name_string.value());
|
AML_ERROR("FieldOp: {} does not name a valid OpRegion", name_string.value());
|
||||||
|
@ -481,11 +481,6 @@ namespace Kernel::ACPI
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> AML::FieldElement::evaluate()
|
BAN::RefPtr<AML::Node> AML::FieldElement::evaluate()
|
||||||
{
|
{
|
||||||
op_region->mutex.lock();
|
|
||||||
BAN::ScopeGuard unlock_guard([&] {
|
|
||||||
op_region->mutex.unlock();
|
|
||||||
});
|
|
||||||
|
|
||||||
auto result = evaluate_internal();
|
auto result = evaluate_internal();
|
||||||
if (!result.has_value())
|
if (!result.has_value())
|
||||||
return {};
|
return {};
|
||||||
|
@ -501,11 +496,9 @@ namespace Kernel::ACPI
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
op_region->mutex.lock();
|
|
||||||
if (access_rules.lock_rule == FieldRules::LockRule::Lock)
|
if (access_rules.lock_rule == FieldRules::LockRule::Lock)
|
||||||
ACPI::acquire_global_lock();
|
ACPI::acquire_global_lock();
|
||||||
BAN::ScopeGuard unlock_guard([&] {
|
BAN::ScopeGuard unlock_guard([&] {
|
||||||
op_region->mutex.unlock();
|
|
||||||
if (access_rules.lock_rule == FieldRules::LockRule::Lock)
|
if (access_rules.lock_rule == FieldRules::LockRule::Lock)
|
||||||
ACPI::release_global_lock();
|
ACPI::release_global_lock();
|
||||||
});
|
});
|
||||||
|
@ -539,7 +532,7 @@ namespace Kernel::ACPI
|
||||||
auto index_field_element_name = NameString::parse(field_pkg);
|
auto index_field_element_name = NameString::parse(field_pkg);
|
||||||
if (!index_field_element_name.has_value())
|
if (!index_field_element_name.has_value())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
auto index_field_element = Namespace::root_namespace()->find_object(context.scope, index_field_element_name.value(), Namespace::FindMode::Normal);
|
auto index_field_element = Namespace::root_namespace()->find_object(context.scope, index_field_element_name.value());
|
||||||
if (!index_field_element || index_field_element->type != AML::Node::Type::FieldElement)
|
if (!index_field_element || index_field_element->type != AML::Node::Type::FieldElement)
|
||||||
{
|
{
|
||||||
AML_ERROR("IndexField IndexName does not name a valid FieldElement");
|
AML_ERROR("IndexField IndexName does not name a valid FieldElement");
|
||||||
|
@ -549,7 +542,7 @@ namespace Kernel::ACPI
|
||||||
auto data_field_element_name = NameString::parse(field_pkg);
|
auto data_field_element_name = NameString::parse(field_pkg);
|
||||||
if (!data_field_element_name.has_value())
|
if (!data_field_element_name.has_value())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
auto data_field_element = Namespace::root_namespace()->find_object(context.scope, data_field_element_name.value(), Namespace::FindMode::Normal);
|
auto data_field_element = Namespace::root_namespace()->find_object(context.scope, data_field_element_name.value());
|
||||||
if (!data_field_element || data_field_element->type != AML::Node::Type::FieldElement)
|
if (!data_field_element || data_field_element->type != AML::Node::Type::FieldElement)
|
||||||
{
|
{
|
||||||
AML_ERROR("IndexField DataName does not name a valid FieldElement");
|
AML_ERROR("IndexField DataName does not name a valid FieldElement");
|
||||||
|
@ -594,7 +587,7 @@ namespace Kernel::ACPI
|
||||||
{
|
{
|
||||||
if (access_rules.access_attrib != FieldRules::AccessAttrib::Normal)
|
if (access_rules.access_attrib != FieldRules::AccessAttrib::Normal)
|
||||||
{
|
{
|
||||||
AML_TODO("IndexFieldElement 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 access_size = determine_access_size(access_rules.access_type);
|
auto access_size = determine_access_size(access_rules.access_type);
|
||||||
|
@ -611,11 +604,9 @@ namespace Kernel::ACPI
|
||||||
return data_element->evaluate_internal();
|
return data_element->evaluate_internal();
|
||||||
};
|
};
|
||||||
|
|
||||||
index_element->op_region->mutex.lock();
|
|
||||||
if (access_rules.lock_rule == FieldRules::LockRule::Lock)
|
if (access_rules.lock_rule == FieldRules::LockRule::Lock)
|
||||||
ACPI::acquire_global_lock();
|
ACPI::acquire_global_lock();
|
||||||
BAN::ScopeGuard unlock_guard([&] {
|
BAN::ScopeGuard unlock_guard([&] {
|
||||||
index_element->op_region->mutex.unlock();
|
|
||||||
if (access_rules.lock_rule == FieldRules::LockRule::Lock)
|
if (access_rules.lock_rule == FieldRules::LockRule::Lock)
|
||||||
ACPI::release_global_lock();
|
ACPI::release_global_lock();
|
||||||
});
|
});
|
||||||
|
@ -661,11 +652,9 @@ namespace Kernel::ACPI
|
||||||
return data_element->store_internal(value);
|
return data_element->store_internal(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
index_element->op_region->mutex.lock();
|
|
||||||
if (access_rules.lock_rule == FieldRules::LockRule::Lock)
|
if (access_rules.lock_rule == FieldRules::LockRule::Lock)
|
||||||
ACPI::acquire_global_lock();
|
ACPI::acquire_global_lock();
|
||||||
BAN::ScopeGuard unlock_guard([&] {
|
BAN::ScopeGuard unlock_guard([&] {
|
||||||
index_element->op_region->mutex.unlock();
|
|
||||||
if (access_rules.lock_rule == FieldRules::LockRule::Lock)
|
if (access_rules.lock_rule == FieldRules::LockRule::Lock)
|
||||||
ACPI::release_global_lock();
|
ACPI::release_global_lock();
|
||||||
});
|
});
|
||||||
|
@ -705,7 +694,7 @@ namespace Kernel::ACPI
|
||||||
auto op_region_name = NameString::parse(field_pkg);
|
auto op_region_name = NameString::parse(field_pkg);
|
||||||
if (!op_region_name.has_value())
|
if (!op_region_name.has_value())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
auto op_region = Namespace::root_namespace()->find_object(context.scope, op_region_name.value(), Namespace::FindMode::Normal);
|
auto op_region = Namespace::root_namespace()->find_object(context.scope, op_region_name.value());
|
||||||
if (!op_region || op_region->type != AML::Node::Type::OpRegion)
|
if (!op_region || op_region->type != AML::Node::Type::OpRegion)
|
||||||
{
|
{
|
||||||
AML_ERROR("BankField RegionName {} does not name a valid OpRegion", op_region_name.value());
|
AML_ERROR("BankField RegionName {} does not name a valid OpRegion", op_region_name.value());
|
||||||
|
@ -715,17 +704,12 @@ namespace Kernel::ACPI
|
||||||
auto bank_selector_name = NameString::parse(field_pkg);
|
auto bank_selector_name = NameString::parse(field_pkg);
|
||||||
if (!bank_selector_name.has_value())
|
if (!bank_selector_name.has_value())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
auto bank_selector = Namespace::root_namespace()->find_object(context.scope, bank_selector_name.value(), Namespace::FindMode::Normal);
|
auto bank_selector = Namespace::root_namespace()->find_object(context.scope, bank_selector_name.value());
|
||||||
if (!bank_selector)
|
if (!bank_selector)
|
||||||
{
|
{
|
||||||
AML_ERROR("BankField BankSelector {} does not name a valid object", bank_selector_name.value());
|
AML_ERROR("BankField BankSelector {} does not name a valid object", bank_selector_name.value());
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
if (bank_selector->type != AML::Node::Type::FieldElement)
|
|
||||||
{
|
|
||||||
AML_TODO("BankField BankSelector {} type {2H}", static_cast<uint8_t>(bank_selector->type));
|
|
||||||
return ParseResult::Failure;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto temp_aml_data = context.aml_data;
|
auto temp_aml_data = context.aml_data;
|
||||||
context.aml_data = field_pkg;
|
context.aml_data = field_pkg;
|
||||||
|
@ -759,7 +743,7 @@ namespace Kernel::ACPI
|
||||||
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 = bank_selector;
|
||||||
element->bank_value = bank_value.value();
|
element->bank_value = bank_value.value();
|
||||||
|
|
||||||
NameString element_name;
|
NameString element_name;
|
||||||
|
@ -776,85 +760,6 @@ namespace Kernel::ACPI
|
||||||
return ParseResult::Success;
|
return ParseResult::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> AML::BankFieldElement::evaluate()
|
|
||||||
{
|
|
||||||
if (access_rules.access_attrib != FieldRules::AccessAttrib::Normal)
|
|
||||||
{
|
|
||||||
AML_TODO("BankFieldElement with access attribute {}", static_cast<uint8_t>(access_rules.access_attrib));
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
auto access_size = determine_access_size(access_rules.access_type);
|
|
||||||
if (!access_size.has_value())
|
|
||||||
return {};
|
|
||||||
auto read_func = [&](uint64_t byte_offset) -> BAN::Optional<uint64_t> {
|
|
||||||
return perform_read(op_region->region_space, byte_offset, access_size.value());
|
|
||||||
};
|
|
||||||
|
|
||||||
bank_selector->op_region->mutex.lock();
|
|
||||||
if (access_rules.lock_rule == FieldRules::LockRule::Lock)
|
|
||||||
ACPI::acquire_global_lock();
|
|
||||||
BAN::ScopeGuard unlock_guard([&] {
|
|
||||||
bank_selector->op_region->mutex.unlock();
|
|
||||||
if (access_rules.lock_rule == FieldRules::LockRule::Lock)
|
|
||||||
ACPI::release_global_lock();
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!bank_selector->store_internal(bank_value))
|
|
||||||
{
|
|
||||||
AML_ERROR("BankFieldElement failed to store BankValue");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
auto result = perform_read_general(op_region->region_offset, bit_count, bit_offset, access_size.value(), read_func);
|
|
||||||
if (!result.has_value())
|
|
||||||
return {};
|
|
||||||
return MUST(BAN::RefPtr<Integer>::create(result.value()));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AML::BankFieldElement::store(BAN::RefPtr<AML::Node> source)
|
|
||||||
{
|
|
||||||
if (access_rules.access_attrib != FieldRules::AccessAttrib::Normal)
|
|
||||||
{
|
|
||||||
AML_TODO("BankFieldElement with access attribute {}", static_cast<uint8_t>(access_rules.access_attrib));
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
auto source_integer = source->as_integer();
|
|
||||||
if (!source_integer.has_value())
|
|
||||||
{
|
|
||||||
AML_TODO("BankFieldElement store with non-integer source, type {}", static_cast<uint8_t>(source->type));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto access_size = determine_access_size(access_rules.access_type);
|
|
||||||
if (!access_size.has_value())
|
|
||||||
return false;
|
|
||||||
auto read_func = [&](uint64_t byte_offset) -> BAN::Optional<uint64_t> {
|
|
||||||
return perform_read(op_region->region_space, byte_offset, access_size.value());
|
|
||||||
};
|
|
||||||
auto write_func = [&](uint64_t byte_offset, uint64_t value) -> bool {
|
|
||||||
return perform_write(op_region->region_space, byte_offset, access_size.value(), value);
|
|
||||||
};
|
|
||||||
|
|
||||||
bank_selector->op_region->mutex.lock();
|
|
||||||
if (access_rules.lock_rule == FieldRules::LockRule::Lock)
|
|
||||||
ACPI::acquire_global_lock();
|
|
||||||
BAN::ScopeGuard unlock_guard([&] {
|
|
||||||
bank_selector->op_region->mutex.unlock();
|
|
||||||
if (access_rules.lock_rule == FieldRules::LockRule::Lock)
|
|
||||||
ACPI::release_global_lock();
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!bank_selector->store_internal(bank_value))
|
|
||||||
{
|
|
||||||
AML_ERROR("BankFieldElement failed to store BankValue");
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AML::BankFieldElement::debug_print(int indent) const
|
void AML::BankFieldElement::debug_print(int indent) const
|
||||||
{
|
{
|
||||||
AML_DEBUG_PRINT_INDENT(indent);
|
AML_DEBUG_PRINT_INDENT(indent);
|
||||||
|
|
|
@ -33,10 +33,8 @@ namespace Kernel::ACPI
|
||||||
void AML::Name::debug_print(int indent) const
|
void AML::Name::debug_print(int indent) const
|
||||||
{
|
{
|
||||||
AML_DEBUG_PRINT_INDENT(indent);
|
AML_DEBUG_PRINT_INDENT(indent);
|
||||||
AML_DEBUG_PRINTLN("Name {} { ", name);
|
AML_DEBUG_PRINT("Name {} { ", name);
|
||||||
object->debug_print(indent + 1);
|
object->debug_print(0);
|
||||||
AML_DEBUG_PRINTLN("");
|
|
||||||
AML_DEBUG_PRINT_INDENT(indent);
|
|
||||||
AML_DEBUG_PRINT("}");
|
AML_DEBUG_PRINT("}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
#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/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>
|
||||||
#include <kernel/ACPI/AML/String.h>
|
|
||||||
#include <kernel/Lock/LockGuard.h>
|
|
||||||
|
|
||||||
namespace Kernel::ACPI
|
namespace Kernel::ACPI
|
||||||
{
|
{
|
||||||
|
@ -23,31 +20,16 @@ namespace Kernel::ACPI
|
||||||
return s_root_namespace;
|
return s_root_namespace;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AML::Namespace::debug_print(int indent) const
|
BAN::Optional<AML::NameString> AML::Namespace::resolve_path(const AML::NameString& relative_base, const AML::NameString& relative_path)
|
||||||
{
|
{
|
||||||
LockGuard _(m_object_mutex);
|
|
||||||
AML_DEBUG_PRINT_INDENT(indent);
|
|
||||||
AML_DEBUG_PRINTLN("Namespace {} {", name);
|
|
||||||
for_each_child(scope, [&](const auto&, const auto& child) {
|
|
||||||
child->debug_print(indent + 1);
|
|
||||||
AML_DEBUG_PRINTLN("");
|
|
||||||
});
|
|
||||||
AML_DEBUG_PRINT_INDENT(indent);
|
|
||||||
AML_DEBUG_PRINT("}");
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::Optional<BAN::String> AML::Namespace::resolve_path(const AML::NameString& relative_base, const AML::NameString& relative_path, FindMode mode, bool check_existence) const
|
|
||||||
{
|
|
||||||
LockGuard _(m_object_mutex);
|
|
||||||
|
|
||||||
// Base must be non-empty absolute path
|
// Base must be non-empty absolute path
|
||||||
ASSERT(relative_base.prefix == "\\"sv || relative_base.path.empty());
|
ASSERT(relative_base.prefix == "\\"sv || relative_base.path.empty());
|
||||||
|
|
||||||
// Do absolute path lookup
|
// Do absolute path lookup
|
||||||
if (!relative_path.prefix.empty() || relative_path.path.size() != 1 || mode == FindMode::ForceAbsolute)
|
if (!relative_path.prefix.empty() || relative_path.path.size() != 1)
|
||||||
{
|
{
|
||||||
BAN::String absolute_path;
|
AML::NameString absolute_path;
|
||||||
MUST(absolute_path.push_back('\\'));
|
MUST(absolute_path.prefix.push_back('\\'));
|
||||||
|
|
||||||
// Resolve root and parent references
|
// Resolve root and parent references
|
||||||
if (relative_path.prefix == "\\"sv)
|
if (relative_path.prefix == "\\"sv)
|
||||||
|
@ -60,130 +42,158 @@ namespace Kernel::ACPI
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < relative_base.path.size() - relative_path.prefix.size(); i++)
|
for (size_t i = 0; i < relative_base.path.size() - relative_path.prefix.size(); i++)
|
||||||
{
|
MUST(absolute_path.path.push_back(relative_base.path[i]));
|
||||||
MUST(absolute_path.append(relative_base.path[i].sv()));
|
|
||||||
MUST(absolute_path.push_back('.'));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append relative path
|
// Append relative path
|
||||||
for (const auto& seg : relative_path.path)
|
for (const auto& seg : relative_path.path)
|
||||||
|
MUST(absolute_path.path.push_back(seg));
|
||||||
|
|
||||||
|
// Validate path
|
||||||
|
BAN::RefPtr<AML::NamedObject> current_node = this;
|
||||||
|
for (const auto& seg : absolute_path.path)
|
||||||
{
|
{
|
||||||
MUST(absolute_path.append(seg.sv()));
|
if (!current_node->is_scope())
|
||||||
MUST(absolute_path.push_back('.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (absolute_path.back() == '.')
|
|
||||||
absolute_path.pop_back();
|
|
||||||
|
|
||||||
if (!check_existence || absolute_path == "\\"sv || m_objects.contains(absolute_path))
|
|
||||||
return absolute_path;
|
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
auto* current_scope = static_cast<AML::Scope*>(current_node.ptr());
|
||||||
|
auto it = current_scope->objects.find(seg);
|
||||||
|
if (it == current_scope->objects.end())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
current_node = it->value;
|
||||||
|
}
|
||||||
|
return absolute_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Resolve with namespace search rules (ACPI Spec 6.4 - Section 5.3)
|
// Resolve with namespace search rules (ACPI Spec 6.4 - Section 5.3)
|
||||||
|
|
||||||
|
AML::NameString last_match_path;
|
||||||
AML::NameSeg target_seg = relative_path.path.back();
|
AML::NameSeg target_seg = relative_path.path.back();
|
||||||
|
|
||||||
BAN::String last_match_path;
|
BAN::RefPtr<AML::Scope> current_scope = this;
|
||||||
BAN::String current_path;
|
AML::NameString current_path;
|
||||||
MUST(current_path.push_back('\\'));
|
|
||||||
|
|
||||||
// Check root namespace
|
// Check root namespace
|
||||||
{
|
{
|
||||||
BAN::String tmp;
|
// If scope contains object with the same name as the segment, update last match
|
||||||
MUST(tmp.append(current_path));
|
if (current_scope->objects.contains(target_seg))
|
||||||
MUST(tmp.append(target_seg.sv()));
|
{
|
||||||
if (m_objects.contains(tmp))
|
last_match_path = current_path;
|
||||||
last_match_path = BAN::move(tmp);
|
MUST(last_match_path.path.push_back(target_seg));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check base base path
|
// Check base base path
|
||||||
for (const auto& seg : relative_base.path)
|
for (const auto& seg : relative_base.path)
|
||||||
{
|
{
|
||||||
MUST(current_path.append(seg.sv()));
|
auto next_node = current_scope->objects[seg];
|
||||||
MUST(current_path.push_back('.'));
|
ASSERT(next_node && next_node->is_scope());
|
||||||
|
|
||||||
BAN::String tmp;
|
current_scope = static_cast<AML::Scope*>(next_node.ptr());
|
||||||
MUST(tmp.append(current_path));
|
MUST(current_path.path.push_back(seg));
|
||||||
MUST(tmp.append(target_seg.sv()));
|
|
||||||
if (m_objects.contains(tmp))
|
// If scope contains object with the same name as the segment, update last match
|
||||||
last_match_path = BAN::move(tmp);
|
if (current_scope->objects.contains(target_seg))
|
||||||
|
{
|
||||||
|
last_match_path = current_path;
|
||||||
|
MUST(last_match_path.path.push_back(target_seg));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!last_match_path.empty())
|
if (!last_match_path.path.empty())
|
||||||
|
{
|
||||||
|
MUST(last_match_path.prefix.push_back('\\'));
|
||||||
return last_match_path;
|
return last_match_path;
|
||||||
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::RefPtr<AML::NamedObject> AML::Namespace::find_object(const AML::NameString& relative_base, const AML::NameString& relative_path, FindMode mode)
|
BAN::RefPtr<AML::NamedObject> AML::Namespace::find_object(const AML::NameString& relative_base, const AML::NameString& relative_path)
|
||||||
{
|
{
|
||||||
LockGuard _(m_object_mutex);
|
auto canonical_path = resolve_path(relative_base, relative_path);
|
||||||
|
|
||||||
auto canonical_path = resolve_path(relative_base, relative_path, mode);
|
|
||||||
if (!canonical_path.has_value())
|
if (!canonical_path.has_value())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
if (canonical_path->path.empty())
|
||||||
if (canonical_path->sv() == "\\"sv)
|
|
||||||
return this;
|
return this;
|
||||||
|
|
||||||
auto it = m_objects.find(canonical_path.value());
|
BAN::RefPtr<NamedObject> node = this;
|
||||||
if (it == m_objects.end())
|
for (const auto& seg : canonical_path->path)
|
||||||
return {};
|
{
|
||||||
return it->value;
|
// Resolve path validates that all nodes are scopes
|
||||||
|
ASSERT(node->is_scope());
|
||||||
|
node = static_cast<Scope*>(node.ptr())->objects[seg];
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AML::Namespace::add_named_object(ParseContext& parse_context, const AML::NameString& object_path, BAN::RefPtr<NamedObject> object)
|
bool AML::Namespace::add_named_object(ParseContext& parse_context, const AML::NameString& object_path, BAN::RefPtr<NamedObject> object)
|
||||||
{
|
{
|
||||||
LockGuard _(m_object_mutex);
|
|
||||||
|
|
||||||
ASSERT(!object_path.path.empty());
|
ASSERT(!object_path.path.empty());
|
||||||
ASSERT(object_path.path.back() == object->name);
|
ASSERT(object_path.path.back() == object->name);
|
||||||
|
|
||||||
auto canonical_path = resolve_path(parse_context.scope, object_path, FindMode::ForceAbsolute, false);
|
auto parent_path = object_path;
|
||||||
ASSERT(canonical_path.has_value());
|
parent_path.path.pop_back();
|
||||||
ASSERT(!canonical_path->empty());
|
|
||||||
|
|
||||||
if (m_objects.contains(canonical_path.value()))
|
auto parent_object = find_object(parse_context.scope, parent_path);
|
||||||
|
if (!parent_object)
|
||||||
{
|
{
|
||||||
AML_ERROR("Object '{}' already exists", canonical_path.value());
|
AML_ERROR("Parent object not found");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto canonical_scope = AML::NameString(canonical_path.value());
|
if (!parent_object->is_scope())
|
||||||
|
{
|
||||||
|
AML_ERROR("Parent object is not a scope");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
MUST(m_objects.insert(canonical_path.value(), object));
|
auto* parent_scope = static_cast<Scope*>(parent_object.ptr());
|
||||||
|
if (parent_scope->objects.contains(object->name))
|
||||||
|
{
|
||||||
|
AML_ERROR("Object already exists");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
object->parent = parent_scope;
|
||||||
|
|
||||||
|
MUST(parent_scope->objects.insert(object->name, object));
|
||||||
|
|
||||||
|
auto canonical_scope = resolve_path(parse_context.scope, object_path);
|
||||||
|
ASSERT(canonical_scope.has_value());
|
||||||
if (object->is_scope())
|
if (object->is_scope())
|
||||||
{
|
{
|
||||||
auto* scope = static_cast<Scope*>(object.ptr());
|
auto* scope = static_cast<Scope*>(object.ptr());
|
||||||
scope->scope = canonical_scope;
|
scope->scope = canonical_scope.value();
|
||||||
}
|
}
|
||||||
|
MUST(parse_context.created_objects.push_back(BAN::move(canonical_scope.release_value())));
|
||||||
MUST(parse_context.created_objects.push_back(canonical_scope));
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AML::Namespace::remove_named_object(const AML::NameString& absolute_path)
|
bool AML::Namespace::remove_named_object(const AML::NameString& absolute_path)
|
||||||
{
|
{
|
||||||
LockGuard _(m_object_mutex);
|
auto object = find_object({}, absolute_path);
|
||||||
|
if (!object)
|
||||||
auto canonical_path = resolve_path({}, absolute_path, FindMode::ForceAbsolute);
|
|
||||||
if (!canonical_path.has_value())
|
|
||||||
{
|
{
|
||||||
AML_ERROR("Trying to delete non-existent object '{}'", absolute_path);
|
AML_ERROR("Object {} not found", absolute_path);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canonical_path->empty())
|
if (object.ptr() == this)
|
||||||
{
|
{
|
||||||
AML_ERROR("Trying to remove root namespace");
|
AML_ERROR("Trying to remove root object");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(m_objects.contains(canonical_path.value()));
|
auto parent = object->parent;
|
||||||
m_objects.remove(canonical_path.value());
|
ASSERT(parent->is_scope());
|
||||||
|
|
||||||
|
auto* parent_scope = static_cast<Scope*>(parent.ptr());
|
||||||
|
parent_scope->objects.remove(object->name);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -192,7 +202,6 @@ namespace Kernel::ACPI
|
||||||
{
|
{
|
||||||
ASSERT(!s_root_namespace);
|
ASSERT(!s_root_namespace);
|
||||||
s_root_namespace = MUST(BAN::RefPtr<Namespace>::create(NameSeg("\\"sv)));
|
s_root_namespace = MUST(BAN::RefPtr<Namespace>::create(NameSeg("\\"sv)));
|
||||||
s_root_namespace->scope = AML::NameString("\\"sv);
|
|
||||||
|
|
||||||
Integer::Constants::Zero = MUST(BAN::RefPtr<Integer>::create(0, true));
|
Integer::Constants::Zero = MUST(BAN::RefPtr<Integer>::create(0, true));
|
||||||
Integer::Constants::One = MUST(BAN::RefPtr<Integer>::create(1, true));
|
Integer::Constants::One = MUST(BAN::RefPtr<Integer>::create(1, true));
|
||||||
|
@ -203,7 +212,7 @@ namespace Kernel::ACPI
|
||||||
|
|
||||||
// Add predefined namespaces
|
// Add predefined namespaces
|
||||||
#define ADD_PREDEFIED_NAMESPACE(NAME) \
|
#define ADD_PREDEFIED_NAMESPACE(NAME) \
|
||||||
ASSERT(s_root_namespace->add_named_object(context, AML::NameString("\\" NAME), MUST(BAN::RefPtr<AML::Device>::create(NameSeg(NAME)))));
|
ASSERT(s_root_namespace->add_named_object(context, AML::NameString("\\" NAME), MUST(BAN::RefPtr<AML::Namespace>::create(NameSeg(NAME)))));
|
||||||
ADD_PREDEFIED_NAMESPACE("_GPE"sv);
|
ADD_PREDEFIED_NAMESPACE("_GPE"sv);
|
||||||
ADD_PREDEFIED_NAMESPACE("_PR"sv);
|
ADD_PREDEFIED_NAMESPACE("_PR"sv);
|
||||||
ADD_PREDEFIED_NAMESPACE("_SB"sv);
|
ADD_PREDEFIED_NAMESPACE("_SB"sv);
|
||||||
|
@ -211,19 +220,11 @@ namespace Kernel::ACPI
|
||||||
ADD_PREDEFIED_NAMESPACE("_TZ"sv);
|
ADD_PREDEFIED_NAMESPACE("_TZ"sv);
|
||||||
#undef ADD_PREDEFIED_NAMESPACE
|
#undef ADD_PREDEFIED_NAMESPACE
|
||||||
|
|
||||||
// Add \_OSI that returns true for Linux compatibility
|
// Add dummy \_OSI
|
||||||
|
MUST(s_osi_aml_data.push_back(static_cast<uint8_t>(Byte::ReturnOp)));
|
||||||
|
MUST(s_osi_aml_data.push_back(static_cast<uint8_t>(Byte::ZeroOp)));
|
||||||
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->term_list = s_osi_aml_data.span();
|
||||||
ASSERT(context.method_args[0]);
|
|
||||||
auto arg = context.method_args[0]->evaluate();
|
|
||||||
if (!arg || arg->type != AML::Node::Type::String)
|
|
||||||
{
|
|
||||||
AML_ERROR("Invalid _OSI argument");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
auto string = static_cast<AML::String*>(arg.ptr());
|
|
||||||
return string->string == "Linux" ? AML::Integer::Constants::Ones : AML::Integer::Constants::Zero;
|
|
||||||
};
|
|
||||||
ASSERT(s_root_namespace->add_named_object(context, AML::NameString("\\_OSI"), osi));
|
ASSERT(s_root_namespace->add_named_object(context, AML::NameString("\\_OSI"), osi));
|
||||||
|
|
||||||
return s_root_namespace;
|
return s_root_namespace;
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#include <kernel/ACPI/AML/Mutex.h>
|
#include <kernel/ACPI/AML/Mutex.h>
|
||||||
#include <kernel/ACPI/AML/Names.h>
|
#include <kernel/ACPI/AML/Names.h>
|
||||||
#include <kernel/ACPI/AML/Node.h>
|
#include <kernel/ACPI/AML/Node.h>
|
||||||
#include <kernel/ACPI/AML/Notify.h>
|
|
||||||
#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/PowerResource.h>
|
#include <kernel/ACPI/AML/PowerResource.h>
|
||||||
|
@ -22,7 +21,6 @@
|
||||||
#include <kernel/ACPI/AML/String.h>
|
#include <kernel/ACPI/AML/String.h>
|
||||||
#include <kernel/ACPI/AML/ThermalZone.h>
|
#include <kernel/ACPI/AML/ThermalZone.h>
|
||||||
#include <kernel/ACPI/AML/Utils.h>
|
#include <kernel/ACPI/AML/Utils.h>
|
||||||
#include <kernel/ACPI/AML/While.h>
|
|
||||||
|
|
||||||
namespace Kernel::ACPI
|
namespace Kernel::ACPI
|
||||||
{
|
{
|
||||||
|
@ -165,8 +163,6 @@ 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::WhileOp:
|
|
||||||
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::DerefOfOp:
|
case AML::Byte::DerefOfOp:
|
||||||
|
@ -174,11 +170,6 @@ namespace Kernel::ACPI
|
||||||
return AML::Reference::parse(context);
|
return AML::Reference::parse(context);
|
||||||
case AML::Byte::IndexOp:
|
case AML::Byte::IndexOp:
|
||||||
return AML::Index::parse(context);
|
return AML::Index::parse(context);
|
||||||
case AML::Byte::NotifyOp:
|
|
||||||
return AML::Notify::parse(context);
|
|
||||||
case AML::Byte::NoopOp:
|
|
||||||
context.aml_data = context.aml_data.slice(1);
|
|
||||||
return ParseResult::Success;
|
|
||||||
case AML::Byte::ReturnOp:
|
case AML::Byte::ReturnOp:
|
||||||
{
|
{
|
||||||
context.aml_data = context.aml_data.slice(1);
|
context.aml_data = context.aml_data.slice(1);
|
||||||
|
@ -200,7 +191,7 @@ namespace Kernel::ACPI
|
||||||
auto name_string = AML::NameString::parse(context.aml_data);
|
auto name_string = AML::NameString::parse(context.aml_data);
|
||||||
if (!name_string.has_value())
|
if (!name_string.has_value())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
auto aml_object = Namespace::root_namespace()->find_object(context.scope, name_string.value(), Namespace::FindMode::Normal);
|
auto aml_object = Namespace::root_namespace()->find_object(context.scope, name_string.value());
|
||||||
if (!aml_object)
|
if (!aml_object)
|
||||||
{
|
{
|
||||||
AML_ERROR("NameString {} not found in namespace", name_string.value());
|
AML_ERROR("NameString {} not found in namespace", name_string.value());
|
||||||
|
@ -210,7 +201,7 @@ namespace Kernel::ACPI
|
||||||
{
|
{
|
||||||
auto* method = static_cast<AML::Method*>(aml_object.ptr());
|
auto* method = static_cast<AML::Method*>(aml_object.ptr());
|
||||||
|
|
||||||
BAN::Array<BAN::RefPtr<AML::Node>, 7> args;
|
Method::Arguments args;
|
||||||
for (uint8_t i = 0; i < method->arg_count; i++)
|
for (uint8_t i = 0; i < method->arg_count; i++)
|
||||||
{
|
{
|
||||||
auto arg = AML::parse_object(context);
|
auto arg = AML::parse_object(context);
|
||||||
|
@ -222,16 +213,7 @@ namespace Kernel::ACPI
|
||||||
args[i] = MUST(BAN::RefPtr<AML::Register>::create(arg.node()));
|
args[i] = MUST(BAN::RefPtr<AML::Register>::create(arg.node()));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto result = method->invoke_with_sync_stack(
|
auto result = method->evaluate(args, context.sync_stack);
|
||||||
context.sync_stack,
|
|
||||||
args[0],
|
|
||||||
args[1],
|
|
||||||
args[2],
|
|
||||||
args[3],
|
|
||||||
args[4],
|
|
||||||
args[5],
|
|
||||||
args[6]
|
|
||||||
);
|
|
||||||
if (!result.has_value())
|
if (!result.has_value())
|
||||||
{
|
{
|
||||||
AML_ERROR("Failed to evaluate {}", name_string.value());
|
AML_ERROR("Failed to evaluate {}", name_string.value());
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
#include <kernel/ACPI/AML/Device.h>
|
#include <kernel/ACPI/AML/Device.h>
|
||||||
#include <kernel/ACPI/AML/Integer.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/Region.h>
|
|
||||||
#include <kernel/ACPI/AML/Scope.h>
|
#include <kernel/ACPI/AML/Scope.h>
|
||||||
|
|
||||||
namespace Kernel::ACPI
|
namespace Kernel::ACPI
|
||||||
|
@ -22,15 +20,15 @@ namespace Kernel::ACPI
|
||||||
if (!name_string.has_value())
|
if (!name_string.has_value())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
|
|
||||||
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());
|
||||||
if (!named_object)
|
if (!named_object)
|
||||||
{
|
{
|
||||||
AML_ERROR("Scope '{}' not found in namespace", name_string.value());
|
AML_ERROR("Scope name {} not found in namespace", name_string.value());
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
if (!named_object->is_scope())
|
if (!named_object->is_scope())
|
||||||
{
|
{
|
||||||
AML_ERROR("Scope '{}' does not name a namespace", name_string.value());
|
AML_ERROR("Scope name {} does not name a namespace", name_string.value());
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,12 +38,12 @@ namespace Kernel::ACPI
|
||||||
|
|
||||||
AML::ParseResult AML::Scope::enter_context_and_parse_term_list(ParseContext& outer_context, const AML::NameString& name_string, BAN::ConstByteSpan aml_data)
|
AML::ParseResult AML::Scope::enter_context_and_parse_term_list(ParseContext& outer_context, const AML::NameString& name_string, BAN::ConstByteSpan aml_data)
|
||||||
{
|
{
|
||||||
auto resolved_scope = Namespace::root_namespace()->resolve_path(outer_context.scope, name_string, Namespace::FindMode::Normal);
|
auto resolved_scope = Namespace::root_namespace()->resolve_path(outer_context.scope, name_string);
|
||||||
if (!resolved_scope.has_value())
|
if (!resolved_scope.has_value())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
|
|
||||||
ParseContext scope_context;
|
ParseContext scope_context;
|
||||||
scope_context.scope = AML::NameString(resolved_scope.release_value());
|
scope_context.scope = resolved_scope.release_value();
|
||||||
scope_context.aml_data = aml_data;
|
scope_context.aml_data = aml_data;
|
||||||
scope_context.method_args = outer_context.method_args;
|
scope_context.method_args = outer_context.method_args;
|
||||||
while (scope_context.aml_data.size() > 0)
|
while (scope_context.aml_data.size() > 0)
|
||||||
|
@ -66,26 +64,19 @@ namespace Kernel::ACPI
|
||||||
return ParseResult::Success;
|
return ParseResult::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BAN::Optional<uint64_t> evaluate_or_invoke(BAN::RefPtr<AML::Node> object)
|
void AML::Scope::debug_print(int indent) const
|
||||||
{
|
{
|
||||||
if (object->type != AML::Node::Type::Method)
|
AML_DEBUG_PRINT_INDENT(indent);
|
||||||
return object->as_integer();
|
AML_DEBUG_PRINT("Scope ");
|
||||||
|
name.debug_print();
|
||||||
auto* method = static_cast<AML::Method*>(object.ptr());
|
AML_DEBUG_PRINTLN(" {");
|
||||||
if (method->arg_count != 0)
|
for (const auto& [name, object] : objects)
|
||||||
{
|
{
|
||||||
AML_ERROR("Method has {} arguments, expected 0", method->arg_count);
|
object->debug_print(indent + 1);
|
||||||
return {};
|
AML_DEBUG_PRINTLN("");
|
||||||
}
|
}
|
||||||
|
AML_DEBUG_PRINT_INDENT(indent);
|
||||||
auto result = method->invoke();
|
AML_DEBUG_PRINT("}");
|
||||||
if (!result.has_value())
|
|
||||||
{
|
|
||||||
AML_ERROR("Failed to evaluate method");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
return result.value() ? result.value()->as_integer() : BAN::Optional<uint64_t>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AML::initialize_scope(BAN::RefPtr<AML::Scope> scope)
|
bool AML::initialize_scope(BAN::RefPtr<AML::Scope> scope)
|
||||||
|
@ -94,100 +85,64 @@ namespace Kernel::ACPI
|
||||||
AML_DEBUG_PRINTLN("Initializing {}", scope->scope);
|
AML_DEBUG_PRINTLN("Initializing {}", scope->scope);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (auto reg = Namespace::root_namespace()->find_object(scope->scope, AML::NameString("_REG"sv), Namespace::FindMode::ForceAbsolute))
|
|
||||||
{
|
|
||||||
bool embedded_controller = false;
|
|
||||||
Namespace::for_each_child(scope->scope,
|
|
||||||
[&](const auto&, auto& child)
|
|
||||||
{
|
|
||||||
if (child->type != AML::Node::Type::OpRegion)
|
|
||||||
return;
|
|
||||||
auto* region = static_cast<AML::OpRegion*>(child.ptr());
|
|
||||||
if (region->region_space == AML::OpRegion::RegionSpace::EmbeddedController)
|
|
||||||
embedded_controller = true;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
if (embedded_controller)
|
|
||||||
{
|
|
||||||
if (reg->type != AML::Node::Type::Method)
|
|
||||||
{
|
|
||||||
AML_ERROR("Object {}._REG is not a method", scope->scope);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto* method = static_cast<Method*>(reg.ptr());
|
|
||||||
if (method->arg_count != 2)
|
|
||||||
{
|
|
||||||
AML_ERROR("Method {}._REG has {} arguments, expected 2", scope->scope, method->arg_count);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::RefPtr<AML::Node> embedded_controller = MUST(BAN::RefPtr<AML::Integer>::create(static_cast<uint64_t>(AML::OpRegion::RegionSpace::EmbeddedController)));
|
|
||||||
|
|
||||||
if (!method->invoke(embedded_controller, AML::Integer::Constants::One).has_value())
|
|
||||||
{
|
|
||||||
AML_ERROR("Failed to evaluate {}._REG(EmbeddedController, 1), ignoring device", scope->scope);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool run_ini = true;
|
bool run_ini = true;
|
||||||
bool init_children = true;
|
bool init_children = true;
|
||||||
|
|
||||||
if (auto sta = Namespace::root_namespace()->find_object(scope->scope, AML::NameString("_STA"sv), Namespace::FindMode::ForceAbsolute))
|
auto it = scope->objects.find(NameSeg("_STA"sv));
|
||||||
|
if (scope->type != AML::Node::Type::Namespace && it != scope->objects.end() && it->value->type == Node::Type::Method)
|
||||||
{
|
{
|
||||||
auto result = evaluate_or_invoke(sta);
|
auto* method = static_cast<Method*>(it->value.ptr());
|
||||||
if (!result.has_value())
|
if (method->arg_count != 0)
|
||||||
{
|
{
|
||||||
AML_ERROR("Failed to evaluate {}._STA, return value could not be resolved to integer", scope->scope);
|
AML_ERROR("Method {}._STA has {} arguments, expected 0", scope->scope, method->arg_count);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
BAN::Vector<uint8_t> sync_stack;
|
||||||
run_ini = (result.value() & 0x01);
|
auto result = method->evaluate({}, sync_stack);
|
||||||
init_children = run_ini || (result.value() & 0x02);
|
if (!result.has_value())
|
||||||
|
{
|
||||||
|
AML_ERROR("Failed to evaluate {}._STA, ignoring device", scope->scope);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
auto result_value = result.has_value() ? result.value()->as_integer() : BAN::Optional<uint64_t>();
|
||||||
|
if (!result_value.has_value())
|
||||||
|
{
|
||||||
|
AML_ERROR("Failed to evaluate {}._STA, return value could not be resolved to integer", scope->scope);
|
||||||
|
AML_ERROR(" Return value: ");
|
||||||
|
result.value()->debug_print(0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
run_ini = (result_value.value() & 0x01);
|
||||||
|
init_children = run_ini || (result_value.value() & 0x02);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (run_ini)
|
if (run_ini)
|
||||||
{
|
{
|
||||||
auto ini = Namespace::root_namespace()->find_object(scope->scope, AML::NameString("_INI"sv), Namespace::FindMode::ForceAbsolute);
|
auto it = scope->objects.find(NameSeg("_STA"sv));
|
||||||
if (ini)
|
if (it != scope->objects.end() && it->value->type == Node::Type::Method)
|
||||||
{
|
{
|
||||||
if (ini->type != AML::Node::Type::Method)
|
auto* method = static_cast<Method*>(it->value.ptr());
|
||||||
{
|
|
||||||
AML_ERROR("Object {}._INI is not a method", scope->scope);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto* method = static_cast<Method*>(ini.ptr());
|
|
||||||
if (method->arg_count != 0)
|
if (method->arg_count != 0)
|
||||||
{
|
{
|
||||||
AML_ERROR("Method {}._INI has {} arguments, expected 0", scope->scope, method->arg_count);
|
AML_ERROR("Method {}._INI has {} arguments, expected 0", scope->scope, method->arg_count);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
BAN::Vector<uint8_t> sync_stack;
|
||||||
auto result = method->invoke();
|
method->evaluate({}, sync_stack);
|
||||||
if (!result.has_value())
|
|
||||||
{
|
|
||||||
AML_ERROR("Failed to evaluate {}._INI, ignoring device", scope->scope);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool success = true;
|
bool success = true;
|
||||||
if (init_children)
|
if (init_children)
|
||||||
{
|
{
|
||||||
Namespace::root_namespace()->for_each_child(scope->scope,
|
for (auto& [_, child] : scope->objects)
|
||||||
[&](const auto&, auto& child)
|
|
||||||
{
|
{
|
||||||
if (!child->is_scope())
|
if (!child->is_scope())
|
||||||
return;
|
continue;
|
||||||
auto* child_scope = static_cast<Scope*>(child.ptr());
|
auto* child_scope = static_cast<Scope*>(child.ptr());
|
||||||
if (!initialize_scope(child_scope))
|
if (!initialize_scope(child_scope))
|
||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
|
@ -194,9 +194,6 @@ namespace Kernel
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Demand paging is only supported in userspace
|
|
||||||
if (thread.is_userspace())
|
|
||||||
{
|
|
||||||
// Try demand paging on non present pages
|
// Try demand paging on non present pages
|
||||||
PageFaultError page_fault_error;
|
PageFaultError page_fault_error;
|
||||||
page_fault_error.raw = error;
|
page_fault_error.raw = error;
|
||||||
|
@ -217,7 +214,6 @@ namespace Kernel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#if __enable_sse
|
#if __enable_sse
|
||||||
else if (isr == ISR::DeviceNotAvailable)
|
else if (isr == ISR::DeviceNotAvailable)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue