From 25b913d140935f0f3116f667df4b986fcdbf17a8 Mon Sep 17 00:00:00 2001 From: Adrien Bourmault Date: Sun, 9 Feb 2020 16:52:41 +0100 Subject: [PATCH] DSDT supported ! --- include/io/acpi.h | 96 +++++++++++++++++++++++++++++++++++++++-- include/kernel.h | 5 ++- kaleid/kernel/io/acpi.c | 54 ++++++++++++++++------- 3 files changed, 134 insertions(+), 21 deletions(-) diff --git a/include/io/acpi.h b/include/io/acpi.h index 654266d..ec7b644 100644 --- a/include/io/acpi.h +++ b/include/io/acpi.h @@ -45,7 +45,7 @@ struct RSDPLegacy { // // ACPI 2.0 descriptor // -struct RSDPDescriptor { +struct RSDPDescriptor_t { // RSDT ACPI 1.0 and above struct RSDPLegacy legacy; @@ -59,7 +59,7 @@ struct RSDPDescriptor { // // ACPI System Description Table // -struct SDTHeader { +struct SDTHeader_t { char signature[4]; uint length; uchar revision; @@ -69,7 +69,19 @@ struct SDTHeader { uint OEMRevision; uint creatorID; uint creatorRevision; - uint sdtTablePtr; + uint sdtEntry; +}; + +// +// GAS type, used by ACPI tables to inform about registers +// +struct GenericAddressStructure +{ + uchar addressSpace; + uchar width; + uchar offset; + uchar accessSize; + ulong address; }; // @@ -103,13 +115,89 @@ enum { #define N_SDT_TYPES 23 +//----------------------------------------------------------------------------// +// FADT related +// +struct FADT_t +{ + char signature[4]; + uint length; + uchar revision; + uchar checksum; + char OEMID[6]; + char OEMTableID[8]; + uint OEMRevision; + uint creatorID; + uint creatorRevision; + + uint firmwareCtrlAddress; + uint dsdtAddress; + + uchar reserved; // legacy + + uchar preferredPowerManagementProfile; + ushort SCIInterrupt; + uint SMICommandPort; + uchar acpiEnable; + uchar acpiDisable; + uchar S4BIOSREQ; + uchar PSTATEControl; + uint PM1aEventBlock; + uint PM1bEventBlock; + uint PM1aControlBlock; + uint PM1bControlBlock; + uint PM2ControlBlock; + uint PMTimerBlock; + uint GPE0Block; + uint GPE1Block; + uchar PM1EventLength; + uchar PM1ControlLength; + uchar PM2ControlLength; + uchar PMTimerLength; + uchar GPE0Length; + uchar GPE1Length; + uchar GPE1Base; + uchar CStateControl; + ushort worstC2Latency; + ushort worstC3Latency; + ushort flushSize; + ushort flushStride; + uchar dutyOffset; + uchar dutyWidth; + uchar dayAlarm; + uchar monthAlarm; + uchar century; + + // reserved in ACPI1, available since ACPI2 + ushort bootArchitectureFlags; + + uchar reserved2; // legacy + uint flags; + + struct GenericAddressStructure resetReg; + uchar resetValue; + + uchar reserved3[3]; + + // 64bit pointers, available since ACPI2 + ulong xFirmwareControlAddress; + ulong xDsdtAddress; + struct GenericAddressStructure xPM1aEventBlock; + struct GenericAddressStructure xPM1bEventBlock; + struct GenericAddressStructure xPM1aControlBlock; + struct GenericAddressStructure xPM1bControlBlock; + struct GenericAddressStructure xPM2ControlBlock; + struct GenericAddressStructure xPMTimerBlock; + struct GenericAddressStructure xGPE0Block; + struct GenericAddressStructure xGPE1Block; +}; //----------------------------------------------------------------------------// void IoInitAcpi(void); -SDTHeader *IoGetAcpiTable(ulong id); +SDTHeader_t *IoGetAcpiTable(ulong id); //----------------------------------------------------------------------------// diff --git a/include/kernel.h b/include/kernel.h index a74978f..23c90a2 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -56,8 +56,9 @@ typedef struct IdtPtr_t IdtPtr_t; typedef struct ISRList_t ISRList_t; typedef struct ISRFrame_t ISRFrame_t; -typedef struct RSDPDescriptor RSDPDescriptor; -typedef struct SDTHeader SDTHeader; +typedef struct RSDPDescriptor_t RSDPDescriptor_t; +typedef struct SDTHeader_t SDTHeader_t; +typedef struct FADT_t FADT_t; 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 626b7a9..b16b603 100644 --- a/kaleid/kernel/io/acpi.c +++ b/kaleid/kernel/io/acpi.c @@ -61,7 +61,7 @@ static char *SDTChar[N_SDT_TYPES] = { }; // ACPI Tables Directory -static SDTHeader *SDTDirectory[N_SDT_TYPES] = {0}; +static SDTHeader_t *SDTDirectory[N_SDT_TYPES] = {0}; // // Returns the checksum of the given structure @@ -81,7 +81,7 @@ static char DoChecksum(const void *ptr, const size_t size, // // Returns the address of the RSDP // -static inline RSDPDescriptor *IoFindRSDP() +static inline RSDPDescriptor_t *IoFindRSDP() { char *rsdp = NULL; @@ -92,7 +92,7 @@ static inline RSDPDescriptor *IoFindRSDP() rsdp++) { if (!strncmp(rsdp, "RSD PTR", 6)) { - return (RSDPDescriptor *)rsdp; + return (RSDPDescriptor_t *)rsdp; } } @@ -102,7 +102,7 @@ static inline RSDPDescriptor *IoFindRSDP() rsdp++) { if (!strncmp(rsdp, "RSD PTR", 6)) { - return (RSDPDescriptor *)rsdp; + return (RSDPDescriptor_t *)rsdp; } } @@ -116,12 +116,12 @@ static inline void IoInitRSDP(void) { char checksum = 1; - RSDPDescriptor *rsdp = IoFindRSDP(); + RSDPDescriptor_t *rsdp = IoFindRSDP(); if (!rsdp) KeStartPanic("ACPI RSDP not found in memory"); // Checksum calculation - checksum = DoChecksum(rsdp, (size_t)sizeof(RSDPDescriptor), + checksum = DoChecksum(rsdp, (size_t)sizeof(RSDPDescriptor_t), (size_t)sizeof(struct RSDPLegacy), !rsdp->legacy.revision ); @@ -152,7 +152,7 @@ static inline void IoInitRXSDT(void) { char checksum = 1; - SDTHeader *rxsdt = SDTDirectory[SDT_RSDT]; + SDTHeader_t *rxsdt = SDTDirectory[SDT_RSDT]; if (IoACPIVersion == 2) { rxsdt = SDTDirectory[SDT_XSDT]; @@ -189,8 +189,8 @@ static inline void IoInitRXSDT(void) // static inline void IoSearchAcpiTables(void) { - SDTHeader *xrsdt = SDTDirectory[SDT_RSDT]; - SDTHeader *table = NULL; + SDTHeader_t *xrsdt = SDTDirectory[SDT_RSDT]; + SDTHeader_t *table = NULL; uint *curInt = NULL; ulong *curLong = NULL; register char checksum; @@ -205,15 +205,16 @@ static inline void IoSearchAcpiTables(void) DebugLog("ACPI detected %d entries\n", entries); - curInt = (uint*)&(xrsdt->sdtTablePtr); - curLong = (ulong*)&(xrsdt->sdtTablePtr); + curInt = (uint*)&(xrsdt->sdtEntry); + curLong = (ulong*)&(xrsdt->sdtEntry); + // Parsing R/XSDT for (int i = 0; i < entries; i++) { if (IoACPIVersion == 1) - table = (SDTHeader *)(ulong)curInt[i]; + table = (SDTHeader_t *)(ulong)curInt[i]; else - table = (SDTHeader *)(ulong)curLong[i]; + table = (SDTHeader_t *)(ulong)curLong[i]; //KernLog("\tACPI RSDT[%d] %p\n", i, table); if (MmIsBusyZone(table)) { @@ -233,8 +234,30 @@ static inline void IoSearchAcpiTables(void) } } } -} + // Parsing FADT + FADT_t *fadt = (FADT_t *)IoGetAcpiTable(SDT_FADT); + SDTHeader_t *dsdt; + + if (IoACPIVersion == 1) { + dsdt = (SDTHeader_t *)(ulong)fadt->dsdtAddress; + } else { + dsdt = (SDTHeader_t *)(ulong)fadt->xDsdtAddress; + } + + checksum = DoChecksum(dsdt, (size_t)dsdt->length, 0, 0); + if (!checksum) { + if (!strncmp(dsdt->signature, SDTChar[SDT_DSDT], 3)) { + DebugLog("ACPI System Table %s (OEM %s) length %d [%p]\n", + SDTChar[SDT_DSDT], + dsdt->OEMID, + dsdt->length, + dsdt + ); + SDTDirectory[SDT_DSDT] = dsdt; + } + } +} // -------------------------------------------------------------------------- // @@ -275,13 +298,14 @@ void IoInitAcpi(void) IoSearchAcpiTables(); } +// -------------------------------------------------------------------------- // // // Returns the addr of the submitted SDT // // Arg must be a member of the enum in acpi.h // -SDTHeader *IoGetAcpiTable(ulong id) +SDTHeader_t *IoGetAcpiTable(ulong id) { return SDTDirectory[id]; }