//----------------------------------------------------------------------------// // GNU GPL OS/K // // // // Desc: ACPI, Hardware detection related functions // // // // // // Copyright © 2018-2019 The OS/K Team // // // // This file is part of OS/K. // // // // OS/K is free software: you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // // the Free Software Foundation, either version 3 of the License, or // // any later version. // // // // OS/K is distributed in the hope that it will be useful, // // but WITHOUT ANY WARRANTY//without even the implied warranty of // // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // // GNU General Public License for more details. // // // // You should have received a copy of the GNU General Public License // // along with OS/K. If not, see . // //----------------------------------------------------------------------------// #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); 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() { char *rsdp = NULL; // Search in EBDA for (rsdp = (char *)0x00080000; // EBDA address (ulong)rsdp < (ulong)0x0009FFFF; // EBDA end rsdp++) { if (rsdp[0] == 'R' && rsdp[1] == 'S' && rsdp[2] == 'D' && rsdp[3] == ' ' && rsdp[4] == 'P' && rsdp[5] == 'T' && rsdp[6] == 'R' && rsdp[7] == ' ' ) { return (RSDPDescriptor *)rsdp; } } // Search in BDA for (rsdp = (char *)0x000E0000; // BDA address (ulong)rsdp < (ulong)0x000FFFFF; // BDA end rsdp++) { if (rsdp[0] == 'R' && rsdp[1] == 'S' && rsdp[2] == 'D' && rsdp[3] == ' ' && rsdp[4] == 'P' && rsdp[5] == 'T' && rsdp[6] == 'R' && rsdp[7] == ' ' ) { return (RSDPDescriptor *)rsdp; } } return NULL; }