diff --git a/include/io/acpi.h b/include/io/acpi.h index 41b8d7c..8e0d293 100644 --- a/include/io/acpi.h +++ b/include/io/acpi.h @@ -73,8 +73,7 @@ struct SDTHeader { //----------------------------------------------------------------------------// -void IoTestAcpi(void); -RSDPDescriptor *IoFindRSDP(void); +void IoInitAcpi(void); //----------------------------------------------------------------------------// diff --git a/kaleid/kernel/init/init.c b/kaleid/kernel/init/init.c index d385631..3a4d4c1 100644 --- a/kaleid/kernel/init/init.c +++ b/kaleid/kernel/init/init.c @@ -82,7 +82,7 @@ noreturn void BtStartKern(multiboot_info_t *mbInfo, uint mbMagic, void *codeSeg) IoEnableKeyb(); // ACPI - IoTestAcpi(); + IoInitAcpi(); // Scheduler PsInitSched(); diff --git a/kaleid/kernel/io/acpi.c b/kaleid/kernel/io/acpi.c index af65be3..e4e7b64 100644 --- a/kaleid/kernel/io/acpi.c +++ b/kaleid/kernel/io/acpi.c @@ -27,8 +27,14 @@ #include #include -SDTHeader *AcpiSDHeader = NULL; +SDTHeader *AcpiSDT = NULL; +SDTHeader *AcpiFADT = NULL; +char IoACPIVersion = 1; + +// +// Returns the checksum of the given structure +// static inline char DoChecksum(void *ptr, size_t size, size_t intermediateSize, ulong reason) { @@ -41,64 +47,10 @@ static inline char DoChecksum(void *ptr, size_t size, return checksum; } -void IoTestAcpi(void) -{ - uchar checksum = 0; - - if (BtFirmwareInfo.romValid) - KernLog("\tRom Table is valid at %p\n", BtFirmwareInfo.romTable); - - if (BtFirmwareInfo.apmValid) - KernLog("\tApm Table is valid at %p\n", BtFirmwareInfo.apmTable); - - // FIND RSDP - - RSDPDescriptor *rsdp = IoFindRSDP(); - if (!rsdp) - KeStartPanic("ACPI RSDP not found in memory"); - - // Checksum calculation - checksum = DoChecksum(rsdp, (size_t)sizeof(RSDPDescriptor), - (size_t)sizeof(struct RSDPLegacy), - !rsdp->legacy.revision - ); - - if (checksum) - KeStartPanic("Invalid checksum : %d vs 0", checksum); - - if (rsdp->legacy.revision == 1 || rsdp->legacy.revision >= 3) - KeStartPanic("Invalid ACPI Revision : %d", rsdp->legacy.revision); - - KernLog("\tACPI Root System Table (OEM %s) Revision %d at %p\n", - rsdp->legacy.OEMID, - (uint)rsdp->legacy.revision, - rsdp->legacy.rsdtAddress - ); - - AcpiSDHeader = (SDTHeader *)(ulong)rsdp->legacy.rsdtAddress; - - if (rsdp->legacy.revision) { - KernLog("\tFound ACPI Extended System Table (OEM %s) Revision %d at %p\n", - rsdp->legacy.OEMID, - (uint)rsdp->legacy.revision, - rsdp->xsdtAddress - ); - - AcpiSDHeader = (SDTHeader *)rsdp->xsdtAddress; - } - - // Map the Table Header - for (ulong i = 0; i < (sizeof(AcpiSDHeader)/KPAGESIZE) + 1; i++) { - - MmMapPage((void*)((ulong)(AcpiSDHeader) + i*KPAGESIZE), - (void*)((ulong)(AcpiSDHeader) + i*KPAGESIZE), - PRESENT); - } - - return; -} - -RSDPDescriptor *IoFindRSDP() +// +// Returns the address of the RSDP +// +static inline RSDPDescriptor *IoFindRSDP() { char *rsdp = NULL; @@ -141,3 +93,108 @@ RSDPDescriptor *IoFindRSDP() return NULL; } + +// +// R/XSDT Exploration +// +static inline void IoInitRXSDT(void) +{ + char checksum = 1; + + SDTHeader *rxsdt = AcpiSDT; + + // Map the Table Header + for (ulong i = 0; i < (sizeof(SDTHeader)/KPAGESIZE) + 1; i++) { + MmMapPage((void*)((ulong)(rxsdt) + i*KPAGESIZE), + (void*)((ulong)(rxsdt) + i*KPAGESIZE), + PRESENT); + } + + // Checksum calculation + checksum = DoChecksum(rxsdt, (size_t)rxsdt->length, + 0, + 0 + ); + + if (checksum) + KeStartPanic("Invalid RSDT checksum : %d vs 0", checksum); + + if (IoACPIVersion == 1) { + KernLog("\tACPI Root System Table %s (%s) length %d [%p]\n", + rxsdt->signature, + rxsdt->OEMID, + rxsdt->length, + rxsdt + ); + } else { + KernLog("\tACPI Extended System Table %s (%s) length %d [%p]\n", + rxsdt->signature, + rxsdt->OEMID, + rxsdt->length, + rxsdt + ); + } +} + +// +// RSDP Exploration +// +static inline void IoInitRSDP(void) +{ + char checksum = 1; + + RSDPDescriptor *rsdp = IoFindRSDP(); + if (!rsdp) + KeStartPanic("ACPI RSDP not found in memory"); + + // Checksum calculation + checksum = DoChecksum(rsdp, (size_t)sizeof(RSDPDescriptor), + (size_t)sizeof(struct RSDPLegacy), + !rsdp->legacy.revision + ); + + if (checksum) + KeStartPanic("Invalid RSDP checksum : %d vs 0", checksum); + + if (rsdp->legacy.revision == 1 || rsdp->legacy.revision >= 3) + KeStartPanic("Invalid ACPI Revision : %d", rsdp->legacy.revision); + + KernLog("\tACPI Revision %d (OEM %s)\n", + (uint)rsdp->legacy.revision, + rsdp->legacy.OEMID + ); + + AcpiSDT = (void *)(ulong)rsdp->legacy.rsdtAddress; + + if (rsdp->legacy.revision) { + AcpiSDT = (void *)rsdp->xsdtAddress; + IoACPIVersion = 2; + } +} + +// +// Explore all ACPI Tables +// +static inline void IoSearchAcpiTables(void) +{ + return; +} + + +// +// Initialise the ACPI by finding tables +// +void IoInitAcpi(void) +{ + if (BtFirmwareInfo.romValid) + KernLog("\tRom Table is valid at %p\n", BtFirmwareInfo.romTable); + + if (BtFirmwareInfo.apmValid) + KernLog("\tApm Table is valid at %p\n", BtFirmwareInfo.apmTable); + + // FIND RSDP + + IoInitRSDP(); + + IoInitRXSDT(); +}