Nucleus
Barry ACPI DSDT + PCI 53a772a (3 years, 3 months ago)
diff --git a/kernel/acpi/acpi.c b/kernel/acpi/acpi.c
index 2774dbe..431d471 100644
--- a/kernel/acpi/acpi.c
+++ b/kernel/acpi/acpi.c
@@ -1,5 +1,6 @@
/*
- * This file controls the ACPI.
+ * This file controls ACPI. It finds the ACPI Root System Descriptor Table then
+ * searches it for more tables, which can be initialised separately.
*/
#include <stdint.h>
@@ -18,24 +19,42 @@ struct RSDPDesc {
} __attribute__((packed));
void init_apic(struct SDTHeader *);
+void init_fadt(struct SDTHeader *);
+void init_dsdt(struct SDTHeader *);
/* Table handlers */
struct TableHandler {
char *sig;
void (*handler)(struct SDTHeader *);
} handlers[] = {
- {"APIC", init_apic},
+ { "APIC", init_apic },
+ { "FACP", init_fadt },
+ { "DSDT", init_dsdt },
};
-/* Calculate the ACPI checksum */
-static uint32_t
-checksum(struct SDTHeader *header)
+/* Match a signature to a handler */
+void
+init_table(struct SDTHeader *table)
{
- char *byte = (void *) header;
uint32_t i, check = 0;
- for (i = 0; i < header->length; i++)
+ char *byte = (void *) table;
+
+ set_page((uintptr_t) table, PAGE_ADDR((uintptr_t) table) |
+ PTE_PRESENT | PTE_WRITE);
+ flush_tlb((uintptr_t) table);
+
+ /* Checksum */
+ for (i = 0; i < table->length; i++)
check += byte[i];
- return ((check % 0x100) == 0);
+ if (check % 0x100)
+ return;
+
+ /* Match handler */
+ for (i = 0; i < sizeof(handlers) / sizeof(handlers[0]); i++) {
+ if (memcmp(table->signature, handlers[i].sig, 4))
+ continue;
+ handlers[i].handler(table);
+ }
}
/* Initialise ACPI */
@@ -65,14 +84,6 @@ init_acpi(void *ebda)
set_page((uintptr_t) rsdt, PAGE_ADDR((uintptr_t) rsdt) |
PTE_PRESENT | PTE_WRITE);
flush_tlb((uintptr_t) rsdt);
- for (i = 0; i < (rsdt->length - sizeof(struct SDTHeader)) / 4; i++) {
- if (!checksum(table[i]))
- continue;
- /* Try to match to a handler */
- for (j = 0; j < sizeof(handlers)/sizeof(handlers[0]); j++) {
- if (memcmp(table[i]->signature, handlers[j].sig, 4))
- continue;
- handlers[j].handler(table[i]);
- }
- }
+ for (i = 0; i < (rsdt->length - sizeof(struct SDTHeader)) / 4; i++)
+ init_table(table[i]);
}