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_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)

View File

@ -481,6 +481,11 @@ 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 {};
@ -496,9 +501,11 @@ 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();
}); });
@ -587,7 +594,7 @@ namespace Kernel::ACPI
{ {
if (access_rules.access_attrib != FieldRules::AccessAttrib::Normal) 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 {}; return {};
} }
auto access_size = determine_access_size(access_rules.access_type); auto access_size = determine_access_size(access_rules.access_type);
@ -604,9 +611,11 @@ 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();
}); });
@ -652,9 +661,11 @@ 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();
}); });