Kernel: Implement proper synchronization for AML opregions

This commit is contained in:
Bananymous 2024-04-17 14:59:26 +03:00
parent b268293402
commit e38b2cff4f
2 changed files with 14 additions and 1 deletions

View File

@ -27,6 +27,8 @@ namespace Kernel::ACPI::AML
uint64_t region_offset;
uint64_t region_length;
Kernel::Mutex mutex;
OpRegion(NameSeg name, RegionSpace region_space, uint64_t region_offset, uint64_t region_length)
: NamedObject(Node::Type::OpRegion, name)
, region_space(region_space)

View File

@ -481,6 +481,11 @@ namespace Kernel::ACPI
BAN::RefPtr<AML::Node> AML::FieldElement::evaluate()
{
op_region->mutex.lock();
BAN::ScopeGuard unlock_guard([&] {
op_region->mutex.unlock();
});
auto result = evaluate_internal();
if (!result.has_value())
return {};
@ -496,9 +501,11 @@ namespace Kernel::ACPI
return false;
}
op_region->mutex.lock();
if (access_rules.lock_rule == FieldRules::LockRule::Lock)
ACPI::acquire_global_lock();
BAN::ScopeGuard unlock_guard([&] {
op_region->mutex.unlock();
if (access_rules.lock_rule == FieldRules::LockRule::Lock)
ACPI::release_global_lock();
});
@ -587,7 +594,7 @@ namespace Kernel::ACPI
{
if (access_rules.access_attrib != FieldRules::AccessAttrib::Normal)
{
AML_TODO("FieldElement with access attribute {}", static_cast<uint8_t>(access_rules.access_attrib));
AML_TODO("IndexFieldElement with access attribute {}", static_cast<uint8_t>(access_rules.access_attrib));
return {};
}
auto access_size = determine_access_size(access_rules.access_type);
@ -604,9 +611,11 @@ namespace Kernel::ACPI
return data_element->evaluate_internal();
};
index_element->op_region->mutex.lock();
if (access_rules.lock_rule == FieldRules::LockRule::Lock)
ACPI::acquire_global_lock();
BAN::ScopeGuard unlock_guard([&] {
index_element->op_region->mutex.unlock();
if (access_rules.lock_rule == FieldRules::LockRule::Lock)
ACPI::release_global_lock();
});
@ -652,9 +661,11 @@ namespace Kernel::ACPI
return data_element->store_internal(value);
};
index_element->op_region->mutex.lock();
if (access_rules.lock_rule == FieldRules::LockRule::Lock)
ACPI::acquire_global_lock();
BAN::ScopeGuard unlock_guard([&] {
index_element->op_region->mutex.unlock();
if (access_rules.lock_rule == FieldRules::LockRule::Lock)
ACPI::release_global_lock();
});