Kernel: AML implement CreateFieldOp
This commit is contained in:
parent
723e458bd7
commit
dd79db6383
|
@ -91,17 +91,11 @@ namespace Kernel::ACPI::AML
|
||||||
|
|
||||||
uint64_t value = 0;
|
uint64_t value = 0;
|
||||||
|
|
||||||
const size_t byte_offset = field_bit_offset / 8;
|
// TODO: optimize for whole byte accesses
|
||||||
const size_t bit_offset = field_bit_offset % 8;
|
for (size_t i = 0; i < field_bit_size; i++)
|
||||||
if (field_bit_size == 1)
|
|
||||||
{
|
{
|
||||||
value = (buffer[byte_offset] >> bit_offset) & 1;
|
const size_t bit = field_bit_offset + i;
|
||||||
}
|
value |= ((buffer[bit / 8] >> (bit % 8)) & 1) << i;
|
||||||
else
|
|
||||||
{
|
|
||||||
ASSERT(bit_offset == 0);
|
|
||||||
for (size_t byte = 0; byte < field_bit_size / 8; byte++)
|
|
||||||
value |= buffer[byte_offset + byte] << byte;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return MUST(BAN::RefPtr<AML::Integer>::create(value));
|
return MUST(BAN::RefPtr<AML::Integer>::create(value));
|
||||||
|
@ -120,18 +114,12 @@ 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;
|
// TODO: optimize for whole byte accesses
|
||||||
const size_t bit_offset = field_bit_offset % 8;
|
for (size_t i = 0; i < field_bit_size; i++)
|
||||||
if (field_bit_size == 1)
|
|
||||||
{
|
{
|
||||||
buffer[byte_offset] &= ~(1 << bit_offset);
|
const size_t bit = field_bit_offset + 1;
|
||||||
buffer[byte_offset] |= (value.value() & 1) << bit_offset;
|
buffer[bit / 8] &= ~(1 << (bit % 8));
|
||||||
}
|
buffer[bit / 8] |= ((value.value() >> i) & 1) << (bit % 8);
|
||||||
else
|
|
||||||
{
|
|
||||||
ASSERT(bit_offset == 0);
|
|
||||||
for (size_t byte = 0; byte < field_bit_size / 8; byte++)
|
|
||||||
buffer[byte_offset + byte] = (value.value() >> (byte * 8)) & 0xFF;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -142,7 +130,7 @@ namespace Kernel::ACPI::AML
|
||||||
ASSERT(context.aml_data.size() >= 1);
|
ASSERT(context.aml_data.size() >= 1);
|
||||||
|
|
||||||
size_t field_bit_size = 0;
|
size_t field_bit_size = 0;
|
||||||
switch (static_cast<Byte>(context.aml_data[0]))
|
switch (static_cast<AML::Byte>(context.aml_data[0]))
|
||||||
{
|
{
|
||||||
case AML::Byte::CreateBitFieldOp:
|
case AML::Byte::CreateBitFieldOp:
|
||||||
field_bit_size = 1;
|
field_bit_size = 1;
|
||||||
|
@ -159,10 +147,14 @@ namespace Kernel::ACPI::AML
|
||||||
case AML::Byte::CreateQWordFieldOp:
|
case AML::Byte::CreateQWordFieldOp:
|
||||||
field_bit_size = 64;
|
field_bit_size = 64;
|
||||||
break;
|
break;
|
||||||
|
case AML::Byte::ExtOpPrefix:
|
||||||
|
ASSERT(context.aml_data.size() >= 2);
|
||||||
|
ASSERT(static_cast<AML::ExtOp>(context.aml_data[1]) == AML::ExtOp::CreateFieldOp);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
context.aml_data = context.aml_data.slice(1);
|
context.aml_data = context.aml_data.slice(1 + (static_cast<AML::Byte>(context.aml_data[0]) == AML::Byte::ExtOpPrefix));
|
||||||
|
|
||||||
auto buffer_result = AML::parse_object(context);
|
auto buffer_result = AML::parse_object(context);
|
||||||
if (!buffer_result.success())
|
if (!buffer_result.success())
|
||||||
|
@ -188,6 +180,20 @@ namespace Kernel::ACPI::AML
|
||||||
if (field_bit_size != 1)
|
if (field_bit_size != 1)
|
||||||
field_bit_offset *= 8;
|
field_bit_offset *= 8;
|
||||||
|
|
||||||
|
if (field_bit_size == 0)
|
||||||
|
{
|
||||||
|
auto bit_count_result = AML::parse_object(context);
|
||||||
|
if (!index_result.success())
|
||||||
|
return ParseResult::Failure;
|
||||||
|
auto bit_count = bit_count_result.node() ? bit_count_result.node()->as_integer() : BAN::Optional<uint64_t>();
|
||||||
|
if (!bit_count.has_value())
|
||||||
|
{
|
||||||
|
AML_ERROR("Failed to parse bit count for BufferField");
|
||||||
|
return ParseResult::Failure;
|
||||||
|
}
|
||||||
|
field_bit_size = bit_count.value();
|
||||||
|
}
|
||||||
|
|
||||||
auto field_name = AML::NameString::parse(context.aml_data);
|
auto field_name = AML::NameString::parse(context.aml_data);
|
||||||
if (!field_name.has_value())
|
if (!field_name.has_value())
|
||||||
return ParseResult::Failure;
|
return ParseResult::Failure;
|
||||||
|
|
|
@ -63,6 +63,8 @@ namespace Kernel::ACPI
|
||||||
return AML::IndexField::parse(context);
|
return AML::IndexField::parse(context);
|
||||||
case AML::ExtOp::BankFieldOp:
|
case AML::ExtOp::BankFieldOp:
|
||||||
return AML::BankField::parse(context);
|
return AML::BankField::parse(context);
|
||||||
|
case AML::ExtOp::CreateFieldOp:
|
||||||
|
return AML::BufferField::parse(context);
|
||||||
case AML::ExtOp::OpRegionOp:
|
case AML::ExtOp::OpRegionOp:
|
||||||
return AML::OpRegion::parse(context);
|
return AML::OpRegion::parse(context);
|
||||||
case AML::ExtOp::DeviceOp:
|
case AML::ExtOp::DeviceOp:
|
||||||
|
|
Loading…
Reference in New Issue