Changed ACPI code to start from RSDT/XSDT

This commit is contained in:
Thomas Oltmann 2025-06-18 20:15:43 +02:00
parent c20bbe2b1a
commit 122bf7d3a3

View file

@ -8,18 +8,6 @@
extern BOOTBOOT bootboot; extern BOOTBOOT bootboot;
struct RSDP {
char Signature[8];
uint8_t Checksum;
char OemId[6];
uint8_t Revision;
uint32_t RsdtAddress;
// The following fields only exist if Revision >= 2
uint32_t Length;
uint64_t XsdtAddress;
uint8_t ExtendedChecksum;
} __attribute__((packed));
struct SDT_Header { struct SDT_Header {
char Signature[4]; char Signature[4];
uint32_t Length; uint32_t Length;
@ -32,39 +20,24 @@ struct SDT_Header {
uint32_t CreatorRevision; uint32_t CreatorRevision;
} __attribute__((packed)); } __attribute__((packed));
struct RSDT {
struct SDT_Header Header;
uint32_t Entries[];
} __attribute__ ((packed));
struct XSDT {
struct SDT_Header Header;
uint64_t Entries[];
} __attribute__ ((packed));
void *acpi_find_table(const char *table_name) void *acpi_find_table(const char *table_name)
{ {
struct RSDP *rsdp = pa_to_pointer(pa_from_value(bootboot.arch.x86_64.acpi_ptr)); struct SDT_Header *header = pa_to_pointer(pa_from_value(bootboot.arch.x86_64.acpi_ptr));
ASSERT(!memcmp(rsdp->Signature, "RSD PTR ", 8)); ASSERT((header->Signature[0] == 'R' || header->Signature[0] == 'X') && !memcmp(header->Signature + 1, "SDT", 3));
if (rsdp->Revision >= 2) { bool extended = header->Signature[0] == 'X';
struct XSDT *xsdt = pa_to_pointer(pa_from_value(rsdp->XsdtAddress)); unsigned count = (header->Length - (unsigned)sizeof(struct SDT_Header));
unsigned count = (xsdt->Header.Length - (unsigned)sizeof(struct SDT_Header)) / 8; count >>= extended ? 3 : 2;
for (unsigned i = 0; i < count; i++) { for (unsigned i = 0; i < count; i++) {
struct pa pa = pa_from_value(xsdt->Entries[i]); uint64_t entry;
struct SDT_Header *header = pa_to_pointer(pa); if (extended) {
if (!memcmp(header->Signature, table_name, 4)) { entry = ((uint64_t *)(header+1))[i];
return (void *)header; } else {
} entry = ((uint32_t *)(header+1))[i];
} }
} else { struct pa pa = pa_from_value(entry);
struct RSDT *rsdt = pa_to_pointer(pa_from_value(rsdp->RsdtAddress)); struct SDT_Header *table = pa_to_pointer(pa);
unsigned count = (rsdt->Header.Length - (unsigned)sizeof(struct SDT_Header)) / 4; if (!memcmp(table->Signature, table_name, 4)) {
for (unsigned i = 0; i < count; i++) { return (void *)table;
struct pa pa = pa_from_value(rsdt->Entries[i]);
struct SDT_Header *header = pa_to_pointer(pa);
if (!memcmp(header->Signature, table_name, 4)) {
return (void *)header;
}
} }
} }
return NULL; return NULL;