diff --git a/sdk/xtdk/bltypes.h b/sdk/xtdk/bltypes.h index 4d82aae..7761edb 100644 --- a/sdk/xtdk/bltypes.h +++ b/sdk/xtdk/bltypes.h @@ -110,6 +110,7 @@ typedef VOID (XTAPI *PBL_ZERO_MEMORY)(OUT PVOID Destination, IN SIZE_T Length); /* Module protocols routine pointers */ typedef EFI_STATUS (*PBL_ACPI_GET_ACPI_DESCRIPTION_POINTER)(OUT PVOID *AcpiTable); +typedef EFI_STATUS (*PBL_ACPI_GET_ACPI_TABLE)(IN CONST UINT Signature, IN PVOID PreviousTable, OUT PVOID *AcpiTable); typedef EFI_STATUS (*PBL_ACPI_GET_APIC_BASE)(OUT PVOID *ApicBase); typedef EFI_STATUS (*PBL_ACPI_GET_RSDP_TABLE)(OUT PVOID *AcpiTable); typedef EFI_STATUS (*PBL_ACPI_GET_SMBIOS_TABLE)(OUT PVOID *SmBiosTable); @@ -301,6 +302,7 @@ typedef struct _XTBL_FRAMEBUFFER_INFORMATION typedef struct _XTBL_ACPI_PROTOCOL { PBL_ACPI_GET_ACPI_DESCRIPTION_POINTER GetAcpiDescriptionPointer; + PBL_ACPI_GET_ACPI_TABLE GetAcpiTable; PBL_ACPI_GET_APIC_BASE GetApicBase; PBL_ACPI_GET_RSDP_TABLE GetRsdpTable; PBL_ACPI_GET_SMBIOS_TABLE GetSMBiosTable; diff --git a/sdk/xtdk/hltypes.h b/sdk/xtdk/hltypes.h index e6c907c..47b7843 100644 --- a/sdk/xtdk/hltypes.h +++ b/sdk/xtdk/hltypes.h @@ -9,9 +9,27 @@ #ifndef __XTDK_HLTYPES_H #define __XTDK_HLTYPES_H +#include #include +/* ACPI table signatures */ +#define ACPI_APIC_SIGNATURE 0x43495041 /* MADT/APIC Description Table */ +#define ACPI_BGRT_SIGNATURE 0x54524742 /* Boot Graphics Record Table */ +#define ACPI_DBGP_SIGNATURE 0x50474244 /* Debug Port Table */ +#define ACPI_DSDT_SIGNATURE 0x54445344 /* Differentiated System Description Table */ +#define ACPI_FADT_SIGNATURE 0x50434146 /* Fixed ACPI Description Table */ +#define ACPI_GTDT_SIGNATURE 0x54445447 /* Generic Timer Description Table */ +#define ACPI_HPET_SIGNATURE 0x54455048 /* High Precision Event Timer */ +#define ACPI_MCFG_SIGNATURE 0x4746434D /* Memory Mapped Configuration Space Access Table */ +#define ACPI_PSDT_SIGNATURE 0x54445350 /* Persistent System Description Table */ +#define ACPI_RSDT_SIGNATURE 0x54445352 /* Root System Description Table */ +#define ACPI_SBST_SIGNATURE 0x54534253 /* Smart Battery Subsystem Table */ +#define ACPI_SSDT_SIGNATURE 0x54445353 /* Secondary System Descriptor Table */ +#define ACPI_SRAT_SIGNATURE 0x54415253 /* Static Resource Affinity Table */ +#define ACPI_WDTT_SIGNATURE 0x54524457 /* Watchdog Timer Resource Table */ +#define ACPI_XSDT_SIGNATURE 0x54445358 /* eXtended System Descriptor Table */ + /* Default serial port settings */ #define COMPORT_CLOCK_RATE 0x1C200 #define COMPORT_WAIT_TIMEOUT 204800 @@ -134,6 +152,41 @@ typedef enum _HAL_APIC_MODE APIC_MODE_X2APIC } HAL_APIC_MODE, *PHAL_APIC_MODE; +/* Each ACPI table description header structure */ +typedef struct _ACPI_DESCRIPTION_HEADER +{ + UCHAR Signature[4]; + ULONG Length; + UCHAR Revision; + UCHAR Checksum; + UCHAR OemId[6]; + UCHAR OemTableID[8]; + ULONG OemRevision; + UCHAR CreatorID[4]; + ULONG CreatorRev; +} PACK ACPI_DESCRIPTION_HEADER, *PACPI_DESCRIPTION_HEADER; + +/* ACPI Root System Description Table Pointer structure */ +typedef struct _ACPI_RSDP +{ + UCHAR Signature[8]; + UCHAR Checksum; + UCHAR OemId[6]; + UCHAR Revision; + ULONG RsdtAddress; + ULONG Length; + ULONGLONG XsdtAddress; + UCHAR XChecksum; + UCHAR Reserved[3]; +} PACK ACPI_RSDP, *PACPI_RSDP; + +/* ACPI Root System Description Table structure */ +typedef struct _ACPI_RSDT +{ + ACPI_DESCRIPTION_HEADER Header; + UCHAR Entries[]; +} PACK ACPI_RSDT, *PACPI_RSDT; + /* Serial (COM) port initial state */ typedef struct _CPPORT { diff --git a/sdk/xtdk/xtstruct.h b/sdk/xtdk/xtstruct.h index fa7f9cd..7d80c83 100644 --- a/sdk/xtdk/xtstruct.h +++ b/sdk/xtdk/xtstruct.h @@ -52,6 +52,9 @@ typedef enum _SYSTEM_FIRMWARE_TYPE SYSTEM_FIRMWARE_TYPE, *PSYSTEM_FIRMWARE_TYPE; typedef enum _WAIT_TYPE WAIT_TYPE, *PWAIT_TYPE; /* Structures forward references */ +typedef struct _ACPI_DESCRIPTION_HEADER ACPI_DESCRIPTION_HEADER, *PACPI_DESCRIPTION_HEADER; +typedef struct _ACPI_RSDP ACPI_RSDP, *PACPI_RSDP; +typedef struct _ACPI_RSDT ACPI_RSDT, *PACPI_RSDT; typedef struct _ANSI_STRING ANSI_STRING, *PANSI_STRING; typedef struct _ANSI_STRING32 ANSI_STRING32, *PANSI_STRING32; typedef struct _ANSI_STRING64 ANSI_STRING64, *PANSI_STRING64; diff --git a/xtldr/modules/acpi/acpi.c b/xtldr/modules/acpi/acpi.c index 55ae86e..d3910eb 100644 --- a/xtldr/modules/acpi/acpi.c +++ b/xtldr/modules/acpi/acpi.c @@ -51,6 +51,115 @@ AcGetAcpiDescriptionPointer(OUT PVOID *AcpiTable) return STATUS_EFI_NOT_FOUND; } +/** + * Finds ACPI description table with given signature. + * + * @param Signature + * Supplies the signature of the desired ACPI table. + * + * @param PreviousTable + * Supplies a pointer to the table to start searching from. + * + * @param AcpiTable + * Supplies a pointer to memory area where ACPI table address will be stored, or NULL if not found. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +EFI_STATUS +AcGetAcpiTable(IN CONST UINT Signature, + IN PVOID PreviousTable, + OUT PVOID *AcpiTable) +{ + PACPI_DESCRIPTION_HEADER TableHeader; + SIZE_T RsdtIndex, TableIndex; + EFI_STATUS Status; + SIZE_T TableCount; + PACPI_RSDP Rsdp; + PACPI_RSDT Rsdt; + BOOLEAN Xsdp; + + /* Return NULL address by default if requested table not found */ + *AcpiTable = NULL; + + /* Get Root System Description Table Pointer */ + Status = AcGetAcpiDescriptionPointer((PVOID)&Rsdp); + if(Status != STATUS_EFI_SUCCESS) + { + /* ACPI tables not found, return error */ + return Status; + } + + /* Check if it is XSDP (ACPI 2.0) or RSDP (ACPI 1.0) */ + if(Rsdp->Revision >= 2 && Rsdp->XsdtAddress) + { + /* XSDP (ACPI 2.0) */ + Xsdp = TRUE; + Rsdt = (PACPI_RSDT)(UINT_PTR)Rsdp->XsdtAddress; + TableCount = (Rsdt->Header.Length - sizeof(ACPI_DESCRIPTION_HEADER)) / 8; + } + else + { + /* RSDP (ACPI 1.0) */ + Xsdp = FALSE; + Rsdt = (PACPI_RSDT)(UINT_PTR)Rsdp->RsdtAddress; + TableCount = (Rsdt->Header.Length - sizeof(ACPI_DESCRIPTION_HEADER)) / 4; + } + + /* Iterate over all ACPI tables */ + for(TableIndex = 0; TableIndex < TableCount; TableIndex++) + { + /* Get table headers in reverse order */ + RsdtIndex = TableCount - TableIndex - 1; + + /* Check if XSDP or RSDT is used */ + if(Xsdp) + { + /* Get table header from XSDT */ + TableHeader = (PACPI_DESCRIPTION_HEADER)(ULONG_PTR)((PULONGLONG)Rsdt->Entries)[RsdtIndex]; + } + else + { + /* Get table header from RSDT */ + TableHeader = (PACPI_DESCRIPTION_HEADER)(ULONG_PTR)((PULONG)Rsdt->Entries)[RsdtIndex]; + } + + /* Make sure table header exists */ + if(TableHeader == NULL) + { + /* Skip to next ACPI table */ + continue; + } + + /* Check if previous table provided */ + if(PreviousTable != NULL) + { + /* Check if this is a table previously found */ + if(TableHeader == (PVOID)PreviousTable) + { + /* Unset previous table */ + PreviousTable = NULL; + } + + /* Skip to next ACPI table */ + continue; + } + + /* Verify table signature and checksum */ + if((*(PLONG)TableHeader->Signature == Signature) && (AcpChecksumTable(TableHeader, TableHeader->Length) == 0)) + { + /* Found valid ACPI table */ + *AcpiTable = TableHeader; + return STATUS_EFI_SUCCESS; + } + } + + /* ACPI table not found */ + return STATUS_EFI_NOT_FOUND; +} + /** * Gets the Advanced Programmable Interrupt Controller (APIC) base address. * @@ -284,6 +393,7 @@ XtLdrModuleMain(IN EFI_HANDLE ImageHandle, /* Set routines available via ACPI protocol */ AcpAcpiProtocol.GetAcpiDescriptionPointer = AcGetAcpiDescriptionPointer; + AcpAcpiProtocol.GetAcpiTable = AcGetAcpiTable; AcpAcpiProtocol.GetApicBase = AcGetApicBase; AcpAcpiProtocol.GetRsdpTable = AcGetRsdpTable; AcpAcpiProtocol.GetSMBiosTable = AcGetSMBiosTable;