Kernel: Implement evaluate and store for BankFieldElement
This commit is contained in:
parent
e38b2cff4f
commit
701fc600cd
|
@ -73,6 +73,7 @@ namespace Kernel::ACPI::AML
|
|||
bool store_internal(uint64_t value);
|
||||
|
||||
friend struct IndexFieldElement;
|
||||
friend struct BankFieldElement;
|
||||
};
|
||||
|
||||
struct Field
|
||||
|
@ -116,7 +117,7 @@ namespace Kernel::ACPI::AML
|
|||
FieldRules access_rules;
|
||||
|
||||
BAN::RefPtr<OpRegion> op_region;
|
||||
BAN::RefPtr<NamedObject> bank_selector;
|
||||
BAN::RefPtr<FieldElement> bank_selector;
|
||||
uint64_t bank_value;
|
||||
|
||||
BankFieldElement(NameSeg name, uint64_t bit_offset, uint64_t bit_count, FieldRules access_rules)
|
||||
|
@ -126,6 +127,9 @@ namespace Kernel::ACPI::AML
|
|||
, access_rules(access_rules)
|
||||
{}
|
||||
|
||||
BAN::RefPtr<Node> evaluate() override;
|
||||
bool store(BAN::RefPtr<Node> source) override;
|
||||
|
||||
void debug_print(int indent) const override;
|
||||
};
|
||||
|
||||
|
|
|
@ -721,6 +721,11 @@ namespace Kernel::ACPI
|
|||
AML_ERROR("BankField BankSelector {} does not name a valid object", bank_selector_name.value());
|
||||
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;
|
||||
context.aml_data = field_pkg;
|
||||
|
@ -754,7 +759,7 @@ namespace Kernel::ACPI
|
|||
for (auto& [_, element] : field_context.elements)
|
||||
{
|
||||
element->op_region = static_cast<OpRegion*>(op_region.ptr());
|
||||
element->bank_selector = bank_selector;
|
||||
element->bank_selector = static_cast<FieldElement*>(bank_selector.ptr());
|
||||
element->bank_value = bank_value.value();
|
||||
|
||||
NameString element_name;
|
||||
|
@ -771,6 +776,85 @@ namespace Kernel::ACPI
|
|||
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
|
||||
{
|
||||
AML_DEBUG_PRINT_INDENT(indent);
|
||||
|
|
Loading…
Reference in New Issue