forked from Bananymous/banan-os
Kernel: Implement locking for AML
Now global lock uses the actual global lock. Currenly if no lock can be acquired, we just panic the kernel so that I remember to implement it properly once AML is running concurrently.
This commit is contained in:
parent
0184e5beb5
commit
93ddee5956
|
@ -14,6 +14,9 @@ namespace Kernel::ACPI
|
||||||
static BAN::ErrorOr<void> initialize();
|
static BAN::ErrorOr<void> initialize();
|
||||||
static ACPI& get();
|
static ACPI& get();
|
||||||
|
|
||||||
|
static void acquire_global_lock();
|
||||||
|
static void release_global_lock();
|
||||||
|
|
||||||
const SDTHeader* get_header(BAN::StringView signature, uint32_t index);
|
const SDTHeader* get_header(BAN::StringView signature, uint32_t index);
|
||||||
|
|
||||||
// mode
|
// mode
|
||||||
|
|
|
@ -69,20 +69,26 @@ namespace Kernel::ACPI::AML
|
||||||
return ParseResult::Success;
|
return ParseResult::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::Optional<BAN::RefPtr<AML::Node>> evaluate(Arguments args, uint8_t old_sync_level = 0)
|
BAN::Optional<BAN::RefPtr<AML::Node>> evaluate(Arguments args, BAN::Vector<uint8_t>& current_sync_stack)
|
||||||
{
|
{
|
||||||
|
if (serialized && !current_sync_stack.empty() && sync_level < current_sync_stack.back())
|
||||||
|
{
|
||||||
|
AML_ERROR("Trying to evaluate method {} with lower sync level than current sync level", scope);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
ParseContext context;
|
ParseContext context;
|
||||||
context.aml_data = term_list;
|
context.aml_data = term_list;
|
||||||
context.scope = scope;
|
context.scope = scope;
|
||||||
context.method_args = args;
|
context.method_args = args;
|
||||||
context.sync_level = old_sync_level;
|
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());
|
||||||
|
|
||||||
if (serialized)
|
if (serialized)
|
||||||
{
|
{
|
||||||
mutex.lock();
|
mutex.lock();
|
||||||
context.sync_level = BAN::Math::max(sync_level, old_sync_level);
|
MUST(context.sync_stack.push_back(sync_level));
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::Optional<BAN::RefPtr<AML::Node>> return_value;
|
BAN::Optional<BAN::RefPtr<AML::Node>> return_value;
|
||||||
|
@ -108,7 +114,12 @@ namespace Kernel::ACPI::AML
|
||||||
}
|
}
|
||||||
|
|
||||||
if (serialized)
|
if (serialized)
|
||||||
|
{
|
||||||
|
context.sync_stack.pop_back();
|
||||||
mutex.unlock();
|
mutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
current_sync_stack = BAN::move(context.sync_stack);
|
||||||
|
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,18 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <kernel/ACPI/AML/Bytes.h>
|
#include <kernel/ACPI/AML/Bytes.h>
|
||||||
|
#include <kernel/ACPI/AML/Integer.h>
|
||||||
#include <kernel/ACPI/AML/NamedObject.h>
|
#include <kernel/ACPI/AML/NamedObject.h>
|
||||||
#include <kernel/ACPI/AML/ParseContext.h>
|
#include <kernel/ACPI/AML/ParseContext.h>
|
||||||
|
#include <kernel/Lock/Mutex.h>
|
||||||
|
#include <kernel/Timer/Timer.h>
|
||||||
|
|
||||||
namespace Kernel::ACPI::AML
|
namespace Kernel::ACPI::AML
|
||||||
{
|
{
|
||||||
|
|
||||||
struct Mutex : public AML::NamedObject
|
struct Mutex : public AML::NamedObject
|
||||||
{
|
{
|
||||||
|
Kernel::Mutex mutex;
|
||||||
uint8_t sync_level;
|
uint8_t sync_level;
|
||||||
|
|
||||||
Mutex(NameSeg name, uint8_t sync_level)
|
Mutex(NameSeg name, uint8_t sync_level)
|
||||||
|
@ -17,6 +21,33 @@ namespace Kernel::ACPI::AML
|
||||||
{}
|
{}
|
||||||
|
|
||||||
static ParseResult parse(ParseContext& context)
|
static ParseResult parse(ParseContext& context)
|
||||||
|
{
|
||||||
|
ASSERT(context.aml_data.size() >= 2);
|
||||||
|
ASSERT(static_cast<AML::Byte>(context.aml_data[0]) == AML::Byte::ExtOpPrefix);
|
||||||
|
|
||||||
|
switch (static_cast<AML::ExtOp>(context.aml_data[1]))
|
||||||
|
{
|
||||||
|
case AML::ExtOp::MutexOp:
|
||||||
|
return parse_mutex(context);
|
||||||
|
case AML::ExtOp::AcquireOp:
|
||||||
|
return parse_acquire(context);
|
||||||
|
case AML::ExtOp::ReleaseOp:
|
||||||
|
return parse_release(context);
|
||||||
|
default:
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void debug_print(int indent) const override
|
||||||
|
{
|
||||||
|
AML_DEBUG_PRINT_INDENT(indent);
|
||||||
|
AML_DEBUG_PRINT("Mutex ");
|
||||||
|
name.debug_print();
|
||||||
|
AML_DEBUG_PRINT(" (SyncLevel: {})", sync_level);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static ParseResult parse_mutex(ParseContext& context)
|
||||||
{
|
{
|
||||||
ASSERT(context.aml_data.size() >= 2);
|
ASSERT(context.aml_data.size() >= 2);
|
||||||
ASSERT(static_cast<AML::Byte>(context.aml_data[0]) == AML::Byte::ExtOpPrefix);
|
ASSERT(static_cast<AML::Byte>(context.aml_data[0]) == AML::Byte::ExtOpPrefix);
|
||||||
|
@ -50,13 +81,86 @@ namespace Kernel::ACPI::AML
|
||||||
return ParseResult::Success;
|
return ParseResult::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void debug_print(int indent) const override
|
static ParseResult parse_acquire(ParseContext& context)
|
||||||
{
|
{
|
||||||
AML_DEBUG_PRINT_INDENT(indent);
|
ASSERT(context.aml_data.size() >= 2);
|
||||||
AML_DEBUG_PRINT("Mutex ");
|
ASSERT(static_cast<AML::Byte>(context.aml_data[0]) == AML::Byte::ExtOpPrefix);
|
||||||
name.debug_print();
|
ASSERT(static_cast<AML::ExtOp>(context.aml_data[1]) == AML::ExtOp::AcquireOp);
|
||||||
AML_DEBUG_PRINT(" (SyncLevel: {})", sync_level);
|
context.aml_data = context.aml_data.slice(2);
|
||||||
|
|
||||||
|
auto mutex_result = AML::parse_object(context);
|
||||||
|
if (!mutex_result.success() || !mutex_result.node() || mutex_result.node()->type != AML::Node::Type::Mutex)
|
||||||
|
{
|
||||||
|
AML_ERROR("Acquire does not name a valid mutex");
|
||||||
|
return ParseResult::Failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* mutex = static_cast<AML::Mutex*>(mutex_result.node().ptr());
|
||||||
|
if (mutex->sync_level < context.sync_level())
|
||||||
|
{
|
||||||
|
AML_ERROR("Trying to acquire mutex with lower sync level than current sync level");
|
||||||
|
return ParseResult::Failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context.aml_data.size() < 2)
|
||||||
|
{
|
||||||
|
AML_ERROR("Missing timeout value");
|
||||||
|
return ParseResult::Failure;
|
||||||
|
}
|
||||||
|
uint16_t timeout = context.aml_data[0] | (context.aml_data[1] << 8);
|
||||||
|
context.aml_data = context.aml_data.slice(2);
|
||||||
|
|
||||||
|
if (timeout >= 0xFFFF)
|
||||||
|
mutex->mutex.lock();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// FIXME: This is a very inefficient way to wait for a mutex
|
||||||
|
uint64_t wake_time = SystemTimer::get().ms_since_boot() + timeout;
|
||||||
|
while (!mutex->mutex.try_lock())
|
||||||
|
{
|
||||||
|
if (SystemTimer::get().ms_since_boot() >= wake_time)
|
||||||
|
return ParseResult(MUST(BAN::RefPtr<AML::Integer>::create(AML::Integer::Ones)));
|
||||||
|
SystemTimer::get().sleep(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MUST(context.sync_stack.push_back(mutex->sync_level));
|
||||||
|
return ParseResult(MUST(BAN::RefPtr<AML::Integer>::create(0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ParseResult parse_release(ParseContext& context)
|
||||||
|
{
|
||||||
|
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::ReleaseOp);
|
||||||
|
context.aml_data = context.aml_data.slice(2);
|
||||||
|
|
||||||
|
auto mutex_result = AML::parse_object(context);
|
||||||
|
if (!mutex_result.success() || !mutex_result.node() || mutex_result.node()->type != AML::Node::Type::Mutex)
|
||||||
|
{
|
||||||
|
AML_ERROR("Release does not name a valid mutex");
|
||||||
|
return ParseResult::Failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context.sync_stack.empty())
|
||||||
|
{
|
||||||
|
AML_ERROR("Trying to release mutex without having acquired it");
|
||||||
|
return ParseResult::Failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* mutex = static_cast<AML::Mutex*>(mutex_result.node().ptr());
|
||||||
|
if (mutex->sync_level != context.sync_level())
|
||||||
|
{
|
||||||
|
AML_ERROR("Trying to release mutex with different sync level than current sync level");
|
||||||
|
return ParseResult::Failure;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex->mutex.unlock();
|
||||||
|
context.sync_stack.pop_back();
|
||||||
|
|
||||||
|
return ParseResult::Success;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,6 @@ namespace Kernel::ACPI::AML
|
||||||
|
|
||||||
struct Namespace : public AML::Scope
|
struct Namespace : public AML::Scope
|
||||||
{
|
{
|
||||||
Mutex global_lock;
|
|
||||||
|
|
||||||
static BAN::RefPtr<AML::Namespace> root_namespace();
|
static BAN::RefPtr<AML::Namespace> root_namespace();
|
||||||
|
|
||||||
Namespace(NameSeg name) : AML::Scope(Node::Type::Namespace, name) {}
|
Namespace(NameSeg name) : AML::Scope(Node::Type::Namespace, name) {}
|
||||||
|
|
|
@ -20,7 +20,9 @@ namespace Kernel::ACPI::AML
|
||||||
// we don't really need large contiguous memory
|
// we don't really need large contiguous memory
|
||||||
BAN::LinkedList<AML::NameString> created_objects;
|
BAN::LinkedList<AML::NameString> created_objects;
|
||||||
|
|
||||||
uint8_t sync_level { 0 };
|
uint8_t sync_level() const { return !sync_stack.empty() ? sync_stack.back() : 0; }
|
||||||
|
BAN::Vector<uint8_t> sync_stack;
|
||||||
|
|
||||||
BAN::Array<BAN::RefPtr<Register>, 7> method_args;
|
BAN::Array<BAN::RefPtr<Register>, 7> method_args;
|
||||||
BAN::Array<BAN::RefPtr<Register>, 8> method_locals;
|
BAN::Array<BAN::RefPtr<Register>, 8> method_locals;
|
||||||
};
|
};
|
||||||
|
|
|
@ -71,7 +71,7 @@ namespace Kernel::ACPI
|
||||||
uint8_t reset_value;
|
uint8_t reset_value;
|
||||||
uint16_t arm_boot_arch;
|
uint16_t arm_boot_arch;
|
||||||
uint8_t fadt_minor_version;
|
uint8_t fadt_minor_version;
|
||||||
uint64_t x_firmware_version;
|
uint64_t x_firmware_ctrl;
|
||||||
uint64_t x_dsdt;
|
uint64_t x_dsdt;
|
||||||
uint8_t x_pm1a_evt_blk[12];
|
uint8_t x_pm1a_evt_blk[12];
|
||||||
uint8_t x_pm1b_evt_blk[12];
|
uint8_t x_pm1b_evt_blk[12];
|
||||||
|
@ -100,6 +100,22 @@ namespace Kernel::ACPI
|
||||||
uint8_t page_protection_and_oem_attribute;
|
uint8_t page_protection_and_oem_attribute;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct FACS
|
||||||
|
{
|
||||||
|
uint8_t signature[4];
|
||||||
|
uint32_t length;
|
||||||
|
uint32_t hardware_signature;
|
||||||
|
uint32_t firmware_waking_vector;
|
||||||
|
uint32_t global_lock;
|
||||||
|
uint32_t flags;
|
||||||
|
uint64_t x_firmware_waking_vector;
|
||||||
|
uint8_t version;
|
||||||
|
uint8_t reserved[3];
|
||||||
|
uint32_t ospm_flags;
|
||||||
|
uint8_t reserved2[24];
|
||||||
|
};
|
||||||
|
static_assert(sizeof(FACS) == 64);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace BAN::Formatter
|
namespace BAN::Formatter
|
||||||
|
|
|
@ -17,6 +17,64 @@
|
||||||
namespace Kernel::ACPI
|
namespace Kernel::ACPI
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
static uint32_t* s_global_lock { nullptr };
|
||||||
|
|
||||||
|
// https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/05_ACPI_Software_Programming_Model/ACPI_Software_Programming_Model.html#global-lock
|
||||||
|
asm(R"(
|
||||||
|
.global acpi_acquire_global_lock
|
||||||
|
acpi_acquire_global_lock:
|
||||||
|
movl (%rdi), %edx
|
||||||
|
andl $(~1), %edx
|
||||||
|
btsl $1, %edx
|
||||||
|
adcl $0, %edx
|
||||||
|
|
||||||
|
lock cmpxchgl %edx, (%rdi)
|
||||||
|
jnz acpi_acquire_global_lock
|
||||||
|
|
||||||
|
cmpb $3, %dl
|
||||||
|
sbbq %rax, %rax
|
||||||
|
negq %rax
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
.global acpi_release_global_lock
|
||||||
|
acpi_release_global_lock:
|
||||||
|
movl (%rdi), %eax
|
||||||
|
movl %eax, %edx
|
||||||
|
|
||||||
|
andl $(~3), %edx
|
||||||
|
|
||||||
|
lock cmpxchgl %edx, (%rdi)
|
||||||
|
jnz acpi_release_global_lock
|
||||||
|
|
||||||
|
andq $1, %rax
|
||||||
|
|
||||||
|
ret
|
||||||
|
)");
|
||||||
|
|
||||||
|
// returns true if lock was acquired successfully
|
||||||
|
extern "C" bool acpi_acquire_global_lock(uint32_t* lock);
|
||||||
|
|
||||||
|
// returns true if lock was pending
|
||||||
|
extern "C" bool acpi_release_global_lock(uint32_t* lock);
|
||||||
|
|
||||||
|
void ACPI::acquire_global_lock()
|
||||||
|
{
|
||||||
|
if (!s_global_lock)
|
||||||
|
return;
|
||||||
|
derrorln("Acquiring ACPI global lock");
|
||||||
|
ASSERT(acpi_acquire_global_lock(s_global_lock));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ACPI::release_global_lock()
|
||||||
|
{
|
||||||
|
if (!s_global_lock)
|
||||||
|
return;
|
||||||
|
derrorln("Releasing ACPI global lock");
|
||||||
|
ASSERT(!acpi_release_global_lock(s_global_lock));
|
||||||
|
}
|
||||||
|
|
||||||
enum PM1Event : uint16_t
|
enum PM1Event : uint16_t
|
||||||
{
|
{
|
||||||
PM1_EVN_TMR_EN = 1 << 0,
|
PM1_EVN_TMR_EN = 1 << 0,
|
||||||
|
@ -58,6 +116,22 @@ namespace Kernel::ACPI
|
||||||
return BAN::Error::from_errno(ENOMEM);
|
return BAN::Error::from_errno(ENOMEM);
|
||||||
TRY(s_instance->initialize_impl());
|
TRY(s_instance->initialize_impl());
|
||||||
|
|
||||||
|
{
|
||||||
|
ASSERT(!s_global_lock);
|
||||||
|
const auto* fadt = static_cast<const FADT*>(ACPI::get().get_header("FACP"sv, 0));
|
||||||
|
ASSERT(fadt);
|
||||||
|
|
||||||
|
uintptr_t facs_addr = fadt->firmware_ctrl;
|
||||||
|
if (fadt->length >= sizeof(FADT) && fadt->x_firmware_ctrl)
|
||||||
|
facs_addr = fadt->x_firmware_ctrl;
|
||||||
|
|
||||||
|
if (facs_addr)
|
||||||
|
{
|
||||||
|
auto* facs = reinterpret_cast<FACS*>(facs_addr);
|
||||||
|
s_global_lock = &facs->global_lock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
s_instance->m_namespace = AML::initialize_namespace();
|
s_instance->m_namespace = AML::initialize_namespace();
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
|
@ -318,7 +392,8 @@ namespace Kernel::ACPI
|
||||||
|
|
||||||
AML::Method::Arguments args;
|
AML::Method::Arguments args;
|
||||||
args[0] = MUST(BAN::RefPtr<AML::Register>::create(MUST(BAN::RefPtr<AML::Integer>::create(5))));
|
args[0] = MUST(BAN::RefPtr<AML::Register>::create(MUST(BAN::RefPtr<AML::Integer>::create(5))));
|
||||||
if (!method->evaluate(args).has_value())
|
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;
|
||||||
|
@ -397,7 +472,8 @@ namespace Kernel::ACPI
|
||||||
dwarnln("Method \\_SB._INI has {} arguments, expected 0", method->arg_count);
|
dwarnln("Method \\_SB._INI has {} arguments, expected 0", method->arg_count);
|
||||||
return BAN::Error::from_errno(EINVAL);
|
return BAN::Error::from_errno(EINVAL);
|
||||||
}
|
}
|
||||||
method->evaluate({});
|
BAN::Vector<uint8_t> sync_stack;
|
||||||
|
method->evaluate({}, sync_stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize devices
|
// Initialize devices
|
||||||
|
@ -423,7 +499,8 @@ namespace Kernel::ACPI
|
||||||
|
|
||||||
AML::Method::Arguments args;
|
AML::Method::Arguments args;
|
||||||
args[0] = MUST(BAN::RefPtr<AML::Register>::create(MUST(BAN::RefPtr<AML::Integer>::create(mode))));
|
args[0] = MUST(BAN::RefPtr<AML::Register>::create(MUST(BAN::RefPtr<AML::Integer>::create(mode))));
|
||||||
method->evaluate(args);
|
BAN::Vector<uint8_t> sync_stack;
|
||||||
|
method->evaluate(args, sync_stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
dprintln("Devices are initialized");
|
dprintln("Devices are initialized");
|
||||||
|
|
|
@ -21,7 +21,8 @@ namespace Kernel::ACPI
|
||||||
AML_ERROR("Method {}._STA has {} arguments, expected 0", scope, method->arg_count);
|
AML_ERROR("Method {}._STA has {} arguments, expected 0", scope, method->arg_count);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto result = method->evaluate({});
|
BAN::Vector<uint8_t> sync_stack;
|
||||||
|
auto result = method->evaluate({}, sync_stack);
|
||||||
if (!result.has_value())
|
if (!result.has_value())
|
||||||
{
|
{
|
||||||
AML_ERROR("Failed to evaluate {}._STA", scope);
|
AML_ERROR("Failed to evaluate {}._STA", scope);
|
||||||
|
@ -55,7 +56,8 @@ namespace Kernel::ACPI
|
||||||
AML_ERROR("Method {}._INI has {} arguments, expected 0", scope, method->arg_count);
|
AML_ERROR("Method {}._INI has {} arguments, expected 0", scope, method->arg_count);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
method->evaluate({});
|
BAN::Vector<uint8_t> sync_stack;
|
||||||
|
method->evaluate({}, sync_stack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include <BAN/ScopeGuard.h>
|
#include <BAN/ScopeGuard.h>
|
||||||
|
#include <kernel/ACPI/ACPI.h>
|
||||||
#include <kernel/ACPI/AML/Field.h>
|
#include <kernel/ACPI/AML/Field.h>
|
||||||
#include <kernel/ACPI/AML/Integer.h>
|
#include <kernel/ACPI/AML/Integer.h>
|
||||||
#include <kernel/IO.h>
|
#include <kernel/IO.h>
|
||||||
|
@ -436,10 +437,10 @@ namespace Kernel::ACPI
|
||||||
}
|
}
|
||||||
|
|
||||||
if (access_rules.lock_rule == FieldRules::LockRule::Lock)
|
if (access_rules.lock_rule == FieldRules::LockRule::Lock)
|
||||||
Namespace::root_namespace()->global_lock.lock();
|
ACPI::acquire_global_lock();
|
||||||
BAN::ScopeGuard unlock_guard([&] {
|
BAN::ScopeGuard unlock_guard([&] {
|
||||||
if (access_rules.lock_rule == FieldRules::LockRule::Lock)
|
if (access_rules.lock_rule == FieldRules::LockRule::Lock)
|
||||||
Namespace::root_namespace()->global_lock.unlock();
|
ACPI::release_global_lock();
|
||||||
});
|
});
|
||||||
|
|
||||||
return store_internal(source_integer.value());
|
return store_internal(source_integer.value());
|
||||||
|
@ -539,10 +540,10 @@ namespace Kernel::ACPI
|
||||||
};
|
};
|
||||||
|
|
||||||
if (access_rules.lock_rule == FieldRules::LockRule::Lock)
|
if (access_rules.lock_rule == FieldRules::LockRule::Lock)
|
||||||
Namespace::root_namespace()->global_lock.lock();
|
ACPI::acquire_global_lock();
|
||||||
BAN::ScopeGuard unlock_guard([&] {
|
BAN::ScopeGuard unlock_guard([&] {
|
||||||
if (access_rules.lock_rule == FieldRules::LockRule::Lock)
|
if (access_rules.lock_rule == FieldRules::LockRule::Lock)
|
||||||
Namespace::root_namespace()->global_lock.unlock();
|
ACPI::release_global_lock();
|
||||||
});
|
});
|
||||||
|
|
||||||
auto result = perform_read_general(0, bit_count, bit_offset, access_size.value(), read_func);
|
auto result = perform_read_general(0, bit_count, bit_offset, access_size.value(), read_func);
|
||||||
|
@ -582,10 +583,10 @@ namespace Kernel::ACPI
|
||||||
};
|
};
|
||||||
|
|
||||||
if (access_rules.lock_rule == FieldRules::LockRule::Lock)
|
if (access_rules.lock_rule == FieldRules::LockRule::Lock)
|
||||||
Namespace::root_namespace()->global_lock.lock();
|
ACPI::acquire_global_lock();
|
||||||
BAN::ScopeGuard unlock_guard([&] {
|
BAN::ScopeGuard unlock_guard([&] {
|
||||||
if (access_rules.lock_rule == FieldRules::LockRule::Lock)
|
if (access_rules.lock_rule == FieldRules::LockRule::Lock)
|
||||||
Namespace::root_namespace()->global_lock.unlock();
|
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))
|
||||||
|
|
|
@ -56,6 +56,8 @@ namespace Kernel::ACPI
|
||||||
case AML::ExtOp::DeviceOp:
|
case AML::ExtOp::DeviceOp:
|
||||||
return AML::Device::parse(context);
|
return AML::Device::parse(context);
|
||||||
case AML::ExtOp::MutexOp:
|
case AML::ExtOp::MutexOp:
|
||||||
|
case AML::ExtOp::AcquireOp:
|
||||||
|
case AML::ExtOp::ReleaseOp:
|
||||||
return AML::Mutex::parse(context);
|
return AML::Mutex::parse(context);
|
||||||
case AML::ExtOp::ProcessorOp:
|
case AML::ExtOp::ProcessorOp:
|
||||||
return AML::Processor::parse(context);
|
return AML::Processor::parse(context);
|
||||||
|
@ -183,7 +185,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->evaluate(args, context.sync_level);
|
auto result = method->evaluate(args, context.sync_stack);
|
||||||
if (!result.has_value())
|
if (!result.has_value())
|
||||||
{
|
{
|
||||||
AML_ERROR("Failed to evaluate {}", name_string.value());
|
AML_ERROR("Failed to evaluate {}", name_string.value());
|
||||||
|
|
Loading…
Reference in New Issue