feat: madt parsing
This commit is contained in:
parent
6c5c1f5c60
commit
7d0155d8ce
4 changed files with 227 additions and 16 deletions
|
|
@ -12,9 +12,6 @@ constexpr uint32_t fold_signature(const char (&text)[5]) {
|
|||
| static_cast<uint32_t>(static_cast<uint8_t>(text[3])) << 24;
|
||||
}
|
||||
|
||||
// Values match the folded signature stored in sdt_header_t::signature. DSDT and
|
||||
// FACS are absent on purpose: they are reached through the FADT, not listed in
|
||||
// the RSDT/XSDT.
|
||||
enum class signature : uint32_t {
|
||||
fadt = fold_signature("FACP"),
|
||||
madt = fold_signature("APIC"),
|
||||
|
|
@ -24,7 +21,6 @@ enum class signature : uint32_t {
|
|||
ssdt = fold_signature("SSDT"),
|
||||
};
|
||||
|
||||
// A folded signature, unfolded back into a null-terminated 4-character string.
|
||||
struct signature_text_t {
|
||||
char text[5];
|
||||
};
|
||||
|
|
@ -63,6 +59,8 @@ struct rsdp_t {
|
|||
} __attribute__((packed));
|
||||
static_assert(sizeof(rsdp_t) == 36);
|
||||
|
||||
struct madt_t;
|
||||
|
||||
struct Rsdp {
|
||||
explicit Rsdp(paddr_t rsdp_physical) : physical(rsdp_physical) {}
|
||||
|
||||
|
|
@ -75,20 +73,33 @@ struct Rsdp {
|
|||
for (auto index = 0u; index < count; index++) {
|
||||
uint64_t table_physical = 0;
|
||||
memcpy(&table_physical, entries + index * entry_size, entry_size);
|
||||
callback(paddr_t{table_physical});
|
||||
dispatch(paddr_t{table_physical}.access<sdt_header_t>(), callback);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename Fn>
|
||||
void find_table(signature sig, Fn&& callback) {
|
||||
for_each_table([&](paddr_t table) {
|
||||
if (table.access<sdt_header_t>()->signature == static_cast<uint32_t>(sig)) {
|
||||
callback(table);
|
||||
}
|
||||
});
|
||||
static void dispatch(const sdt_header_t* header, Fn&& fn) {
|
||||
#define ACPI_DISPATCH(signature_enum, TableType) \
|
||||
case signature::signature_enum: \
|
||||
if constexpr (requires { fn(static_cast<const TableType*>(nullptr)); }) { \
|
||||
fn(reinterpret_cast<const TableType*>(header)); \
|
||||
return; \
|
||||
} \
|
||||
break;
|
||||
|
||||
switch (static_cast<signature>(header->signature)) {
|
||||
ACPI_DISPATCH(madt, madt_t)
|
||||
default: break;
|
||||
}
|
||||
|
||||
#undef ACPI_DISPATCH
|
||||
|
||||
if constexpr (requires { fn(static_cast<const sdt_header_t*>(nullptr)); }) {
|
||||
fn(header);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool uses_xsdt() {
|
||||
return physical.access<rsdp_t>()->revision >= 2;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue