Changed ACPI code to start from RSDT/XSDT
This commit is contained in:
parent
c20bbe2b1a
commit
122bf7d3a3
1 changed files with 15 additions and 42 deletions
53
src/acpi.c
53
src/acpi.c
|
|
@ -8,18 +8,6 @@
|
|||
|
||||
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 {
|
||||
char Signature[4];
|
||||
uint32_t Length;
|
||||
|
|
@ -32,39 +20,24 @@ struct SDT_Header {
|
|||
uint32_t CreatorRevision;
|
||||
} __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)
|
||||
{
|
||||
struct RSDP *rsdp = pa_to_pointer(pa_from_value(bootboot.arch.x86_64.acpi_ptr));
|
||||
ASSERT(!memcmp(rsdp->Signature, "RSD PTR ", 8));
|
||||
if (rsdp->Revision >= 2) {
|
||||
struct XSDT *xsdt = pa_to_pointer(pa_from_value(rsdp->XsdtAddress));
|
||||
unsigned count = (xsdt->Header.Length - (unsigned)sizeof(struct SDT_Header)) / 8;
|
||||
struct SDT_Header *header = pa_to_pointer(pa_from_value(bootboot.arch.x86_64.acpi_ptr));
|
||||
ASSERT((header->Signature[0] == 'R' || header->Signature[0] == 'X') && !memcmp(header->Signature + 1, "SDT", 3));
|
||||
bool extended = header->Signature[0] == 'X';
|
||||
unsigned count = (header->Length - (unsigned)sizeof(struct SDT_Header));
|
||||
count >>= extended ? 3 : 2;
|
||||
for (unsigned i = 0; i < count; i++) {
|
||||
struct pa pa = pa_from_value(xsdt->Entries[i]);
|
||||
struct SDT_Header *header = pa_to_pointer(pa);
|
||||
if (!memcmp(header->Signature, table_name, 4)) {
|
||||
return (void *)header;
|
||||
}
|
||||
}
|
||||
uint64_t entry;
|
||||
if (extended) {
|
||||
entry = ((uint64_t *)(header+1))[i];
|
||||
} else {
|
||||
struct RSDT *rsdt = pa_to_pointer(pa_from_value(rsdp->RsdtAddress));
|
||||
unsigned count = (rsdt->Header.Length - (unsigned)sizeof(struct SDT_Header)) / 4;
|
||||
for (unsigned i = 0; i < count; i++) {
|
||||
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;
|
||||
entry = ((uint32_t *)(header+1))[i];
|
||||
}
|
||||
struct pa pa = pa_from_value(entry);
|
||||
struct SDT_Header *table = pa_to_pointer(pa);
|
||||
if (!memcmp(table->Signature, table_name, 4)) {
|
||||
return (void *)table;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue