diff --git a/include/io/acpi.h b/include/io/acpi.h index 3228584..41b8d7c 100644 --- a/include/io/acpi.h +++ b/include/io/acpi.h @@ -32,20 +32,45 @@ //----------------------------------------------------------------------------// // -// ACPI 2.0 Legacy descriptor +// ACPI 1.0 descriptor // -struct RSDPDescriptor { +struct RSDPLegacy { char signature[8]; uchar checksum; char OEMID[6]; uchar revision; uint rsdtAddress; +} __attribute__ ((packed)); + +// +// ACPI 2.0 descriptor +// +struct RSDPDescriptor { + // RSDT ACPI 1.0 and above + struct RSDPLegacy legacy; + + // RSDT ACPI 2.0 uint length; ulong xsdtAddress; uchar extendedChecksum; uchar reserved[3]; } __attribute__ ((packed)); +// +// ACPI System Description Table +// +struct SDTHeader { + char signature[4]; + uint length; + uchar revision; + uchar checksum; + char OEMID[6]; + char OEMTableID[8]; + uint OEMRevision; + uint creatorID; + uint creatorRevision; +}; + //----------------------------------------------------------------------------// void IoTestAcpi(void); diff --git a/include/kernel.h b/include/kernel.h index 3c02075..8b9638e 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -57,6 +57,7 @@ typedef struct ISRList_t ISRList_t; typedef struct ISRFrame_t ISRFrame_t; typedef struct RSDPDescriptor RSDPDescriptor; +typedef struct SDTHeader SDTHeader; typedef struct MemoryMap_t MemoryMap_t; typedef struct MapEntry_t MapEntry_t; diff --git a/kaleid/kernel/io/acpi.c b/kaleid/kernel/io/acpi.c index df1f3fb..af65be3 100644 --- a/kaleid/kernel/io/acpi.c +++ b/kaleid/kernel/io/acpi.c @@ -25,9 +25,25 @@ #include #include #include +#include + +SDTHeader *AcpiSDHeader = NULL; + +static inline char DoChecksum(void *ptr, size_t size, + size_t intermediateSize, ulong reason) +{ + char checksum = 0; + for (ulong i=0; i < (ulong)size; i++) { + if (reason && i > (ulong)intermediateSize) + break; + checksum += (uchar)((char*)ptr)[i]; + } + return checksum; +} void IoTestAcpi(void) { + uchar checksum = 0; if (BtFirmwareInfo.romValid) KernLog("\tRom Table is valid at %p\n", BtFirmwareInfo.romTable); @@ -35,14 +51,50 @@ void IoTestAcpi(void) if (BtFirmwareInfo.apmValid) KernLog("\tApm Table is valid at %p\n", BtFirmwareInfo.apmTable); + // FIND RSDP + RSDPDescriptor *rsdp = IoFindRSDP(); if (!rsdp) - return; + KeStartPanic("ACPI RSDP not found in memory"); - KernLog("\tFound ACPI RSDP (%s) version %d at %p\n", - rsdp->OEMID, (uint)rsdp->revision, rsdp + // 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; }