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
57
src/acpi.c
57
src/acpi.c
|
|
@ -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;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue