#ifndef __UEFI_LIB_H__\r
#define __UEFI_LIB_H__\r
\r
+#include <IndustryStandard/Acpi.h>\r
+\r
#include <Protocol/DriverBinding.h>\r
#include <Protocol/DriverConfiguration.h>\r
#include <Protocol/ComponentName.h>\r
IN UINT64 OpenMode,\r
IN UINT64 Attributes\r
);\r
+\r
+/**\r
+ This function locates next ACPI table in XSDT/RSDT based on Signature and\r
+ previous returned Table.\r
+\r
+ If PreviousTable is NULL:\r
+ This function will locate the first ACPI table in XSDT/RSDT based on\r
+ Signature in gEfiAcpi20TableGuid system configuration table first, and then\r
+ gEfiAcpi10TableGuid system configuration table.\r
+ This function will locate in XSDT first, and then RSDT.\r
+ For DSDT, this function will locate XDsdt in FADT first, and then Dsdt in\r
+ FADT.\r
+ For FACS, this function will locate XFirmwareCtrl in FADT first, and then\r
+ FirmwareCtrl in FADT.\r
+\r
+ If PreviousTable is not NULL:\r
+ 1. If it could be located in XSDT in gEfiAcpi20TableGuid system configuration\r
+ table, then this function will just locate next table in XSDT in\r
+ gEfiAcpi20TableGuid system configuration table.\r
+ 2. If it could be located in RSDT in gEfiAcpi20TableGuid system configuration\r
+ table, then this function will just locate next table in RSDT in\r
+ gEfiAcpi20TableGuid system configuration table.\r
+ 3. If it could be located in RSDT in gEfiAcpi10TableGuid system configuration\r
+ table, then this function will just locate next table in RSDT in\r
+ gEfiAcpi10TableGuid system configuration table.\r
+\r
+ It's not supported that PreviousTable is not NULL but PreviousTable->Signature\r
+ is not same with Signature, NULL will be returned.\r
+\r
+ @param Signature ACPI table signature.\r
+ @param PreviousTable Pointer to previous returned table to locate next\r
+ table, or NULL to locate first table.\r
+\r
+ @return Next ACPI table or NULL if not found.\r
+\r
+**/\r
+EFI_ACPI_COMMON_HEADER *\r
+EFIAPI\r
+EfiLocateNextAcpiTable (\r
+ IN UINT32 Signature,\r
+ IN EFI_ACPI_COMMON_HEADER *PreviousTable OPTIONAL\r
+ );\r
+\r
+/**\r
+ This function locates first ACPI table in XSDT/RSDT based on Signature.\r
+\r
+ This function will locate the first ACPI table in XSDT/RSDT based on\r
+ Signature in gEfiAcpi20TableGuid system configuration table first, and then\r
+ gEfiAcpi10TableGuid system configuration table.\r
+ This function will locate in XSDT first, and then RSDT.\r
+ For DSDT, this function will locate XDsdt in FADT first, and then Dsdt in\r
+ FADT.\r
+ For FACS, this function will locate XFirmwareCtrl in FADT first, and then\r
+ FirmwareCtrl in FADT.\r
+\r
+ @param Signature ACPI table signature.\r
+\r
+ @return First ACPI table or NULL if not found.\r
+\r
+**/\r
+EFI_ACPI_COMMON_HEADER *\r
+EFIAPI\r
+EfiLocateFirstAcpiTable (\r
+ IN UINT32 Signature\r
+ );\r
+\r
#endif\r
--- /dev/null
+/** @file\r
+ This module provides help function for finding ACPI table.\r
+\r
+ Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php.\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "UefiLibInternal.h"\r
+#include <IndustryStandard/Acpi.h>\r
+#include <Guid/Acpi.h>\r
+\r
+/**\r
+ This function scans ACPI table in XSDT/RSDT.\r
+\r
+ @param Sdt ACPI XSDT/RSDT.\r
+ @param TablePointerSize Size of table pointer: 8(XSDT) or 4(RSDT).\r
+ @param Signature ACPI table signature.\r
+ @param PreviousTable Pointer to previous returned table to locate\r
+ next table, or NULL to locate first table.\r
+ @param PreviousTableLocated Pointer to the indicator about whether the\r
+ previous returned table could be located, or\r
+ NULL if PreviousTable is NULL.\r
+\r
+ If PreviousTable is NULL and PreviousTableLocated is not NULL, then ASSERT().\r
+ If PreviousTable is not NULL and PreviousTableLocated is NULL, then ASSERT().\r
+\r
+ @return ACPI table or NULL if not found.\r
+\r
+**/\r
+EFI_ACPI_COMMON_HEADER *\r
+ScanTableInSDT (\r
+ IN EFI_ACPI_DESCRIPTION_HEADER *Sdt,\r
+ IN UINTN TablePointerSize,\r
+ IN UINT32 Signature,\r
+ IN EFI_ACPI_COMMON_HEADER *PreviousTable, OPTIONAL\r
+ OUT BOOLEAN *PreviousTableLocated OPTIONAL\r
+ )\r
+{\r
+ UINTN Index;\r
+ UINTN EntryCount;\r
+ UINT64 EntryPtr;\r
+ UINTN BasePtr;\r
+ EFI_ACPI_COMMON_HEADER *Table;\r
+\r
+ if (PreviousTableLocated != NULL) {\r
+ ASSERT (PreviousTable != NULL);\r
+ *PreviousTableLocated = FALSE;\r
+ } else {\r
+ ASSERT (PreviousTable == NULL);\r
+ }\r
+\r
+ if (Sdt == NULL) {\r
+ return NULL;\r
+ }\r
+\r
+ EntryCount = (Sdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / TablePointerSize;\r
+\r
+ BasePtr = (UINTN)(Sdt + 1);\r
+ for (Index = 0; Index < EntryCount; Index ++) {\r
+ EntryPtr = 0;\r
+ CopyMem (&EntryPtr, (VOID *)(BasePtr + Index * TablePointerSize), TablePointerSize);\r
+ Table = (EFI_ACPI_COMMON_HEADER *)((UINTN)(EntryPtr));\r
+ if (Table->Signature == Signature) {\r
+ if (PreviousTable != NULL) {\r
+ if (Table == PreviousTable) {\r
+ *PreviousTableLocated = TRUE;\r
+ } else if (*PreviousTableLocated) {\r
+ //\r
+ // Return next table.\r
+ //\r
+ return Table;\r
+ }\r
+ } else {\r
+ //\r
+ // Return first table.\r
+ //\r
+ return Table;\r
+ }\r
+\r
+ }\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+/**\r
+ To locate FACS in FADT.\r
+\r
+ @param Fadt FADT table pointer.\r
+\r
+ @return FACS table pointer or NULL if not found.\r
+\r
+**/\r
+EFI_ACPI_COMMON_HEADER *\r
+LocateAcpiFacsFromFadt (\r
+ IN EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt\r
+ )\r
+{\r
+ EFI_ACPI_COMMON_HEADER *Facs;\r
+ UINT64 Data64;\r
+\r
+ if (Fadt == NULL) {\r
+ return NULL;\r
+ }\r
+\r
+ if (Fadt->Header.Revision < EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION) {\r
+ Facs = (EFI_ACPI_COMMON_HEADER *)(UINTN)Fadt->FirmwareCtrl;\r
+ } else {\r
+ CopyMem (&Data64, &Fadt->XFirmwareCtrl, sizeof(UINT64));\r
+ if (Data64 != 0) {\r
+ Facs = (EFI_ACPI_COMMON_HEADER *)(UINTN)Data64;\r
+ } else {\r
+ Facs = (EFI_ACPI_COMMON_HEADER *)(UINTN)Fadt->FirmwareCtrl;\r
+ }\r
+ }\r
+ return Facs;\r
+}\r
+\r
+/**\r
+ To locate DSDT in FADT.\r
+\r
+ @param Fadt FADT table pointer.\r
+\r
+ @return DSDT table pointer or NULL if not found.\r
+\r
+**/\r
+EFI_ACPI_COMMON_HEADER *\r
+LocateAcpiDsdtFromFadt (\r
+ IN EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt\r
+ )\r
+{\r
+ EFI_ACPI_COMMON_HEADER *Dsdt;\r
+ UINT64 Data64;\r
+\r
+ if (Fadt == NULL) {\r
+ return NULL;\r
+ }\r
+\r
+ if (Fadt->Header.Revision < EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION) {\r
+ Dsdt = (EFI_ACPI_COMMON_HEADER *)(UINTN)Fadt->Dsdt;\r
+ } else {\r
+ CopyMem (&Data64, &Fadt->XDsdt, sizeof(UINT64));\r
+ if (Data64 != 0) {\r
+ Dsdt = (EFI_ACPI_COMMON_HEADER *)(UINTN)Data64;\r
+ } else {\r
+ Dsdt = (EFI_ACPI_COMMON_HEADER *)(UINTN)Fadt->Dsdt;\r
+ }\r
+ }\r
+ return Dsdt;\r
+}\r
+\r
+/**\r
+ To locate ACPI table in ACPI ConfigurationTable.\r
+\r
+ @param AcpiGuid The GUID used to get ACPI ConfigurationTable.\r
+ @param Signature ACPI table signature.\r
+ @param PreviousTable Pointer to previous returned table to locate\r
+ next table, or NULL to locate first table.\r
+ @param PreviousTableLocated Pointer to the indicator to return whether the\r
+ previous returned table could be located or not,\r
+ or NULL if PreviousTable is NULL.\r
+\r
+ If PreviousTable is NULL and PreviousTableLocated is not NULL, then ASSERT().\r
+ If PreviousTable is not NULL and PreviousTableLocated is NULL, then ASSERT().\r
+ If AcpiGuid is NULL, then ASSERT().\r
+\r
+ @return ACPI table or NULL if not found.\r
+\r
+**/\r
+EFI_ACPI_COMMON_HEADER *\r
+LocateAcpiTableInAcpiConfigurationTable (\r
+ IN EFI_GUID *AcpiGuid,\r
+ IN UINT32 Signature,\r
+ IN EFI_ACPI_COMMON_HEADER *PreviousTable, OPTIONAL\r
+ OUT BOOLEAN *PreviousTableLocated OPTIONAL\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_ACPI_COMMON_HEADER *Table;\r
+ EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp;\r
+ EFI_ACPI_DESCRIPTION_HEADER *Rsdt;\r
+ EFI_ACPI_DESCRIPTION_HEADER *Xsdt;\r
+ EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt;\r
+\r
+ if (PreviousTableLocated != NULL) {\r
+ ASSERT (PreviousTable != NULL);\r
+ *PreviousTableLocated = FALSE;\r
+ } else {\r
+ ASSERT (PreviousTable == NULL);\r
+ }\r
+\r
+ Rsdp = NULL;\r
+ //\r
+ // Get ACPI ConfigurationTable (RSD_PTR)\r
+ //\r
+ Status = EfiGetSystemConfigurationTable(AcpiGuid, (VOID **)&Rsdp);\r
+ if (EFI_ERROR (Status) || (Rsdp == NULL)) {\r
+ return NULL;\r
+ }\r
+\r
+ Table = NULL;\r
+\r
+ //\r
+ // Search XSDT\r
+ //\r
+ if (Rsdp->Revision >= EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION) {\r
+ Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) Rsdp->XsdtAddress;\r
+ if (Signature == EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) {\r
+ ASSERT (PreviousTable == NULL);\r
+ //\r
+ // It is to locate DSDT,\r
+ // need to locate FADT first.\r
+ //\r
+ Fadt = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *) ScanTableInSDT (\r
+ Xsdt,\r
+ sizeof (UINT64),\r
+ EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,\r
+ NULL,\r
+ NULL\r
+ );\r
+ Table = LocateAcpiDsdtFromFadt (Fadt);\r
+ } else if (Signature == EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) {\r
+ ASSERT (PreviousTable == NULL);\r
+ //\r
+ // It is to locate FACS,\r
+ // need to locate FADT first.\r
+ //\r
+ Fadt = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *) ScanTableInSDT (\r
+ Xsdt,\r
+ sizeof (UINT64),\r
+ EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,\r
+ NULL,\r
+ NULL\r
+ );\r
+ Table = LocateAcpiFacsFromFadt (Fadt);\r
+ } else {\r
+ Table = ScanTableInSDT (\r
+ Xsdt,\r
+ sizeof (UINT64),\r
+ Signature,\r
+ PreviousTable,\r
+ PreviousTableLocated\r
+ );\r
+ }\r
+ }\r
+\r
+ if (Table != NULL) {\r
+ return Table;\r
+ } else if ((PreviousTableLocated != NULL) &&\r
+ *PreviousTableLocated) {\r
+ //\r
+ // PreviousTable could be located in XSDT,\r
+ // but next table could not be located in XSDT.\r
+ //\r
+ return NULL;\r
+ }\r
+\r
+ //\r
+ // Search RSDT\r
+ //\r
+ Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) Rsdp->RsdtAddress;\r
+ if (Signature == EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) {\r
+ ASSERT (PreviousTable == NULL);\r
+ //\r
+ // It is to locate DSDT,\r
+ // need to locate FADT first.\r
+ //\r
+ Fadt = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *) ScanTableInSDT (\r
+ Rsdt,\r
+ sizeof (UINT32),\r
+ EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,\r
+ NULL,\r
+ NULL\r
+ );\r
+ Table = LocateAcpiDsdtFromFadt (Fadt);\r
+ } else if (Signature == EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) {\r
+ ASSERT (PreviousTable == NULL);\r
+ //\r
+ // It is to locate FACS,\r
+ // need to locate FADT first.\r
+ //\r
+ Fadt = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *) ScanTableInSDT (\r
+ Rsdt,\r
+ sizeof (UINT32),\r
+ EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,\r
+ NULL,\r
+ NULL\r
+ );\r
+ Table = LocateAcpiFacsFromFadt (Fadt);\r
+ } else {\r
+ Table = ScanTableInSDT (\r
+ Rsdt,\r
+ sizeof (UINT32),\r
+ Signature,\r
+ PreviousTable,\r
+ PreviousTableLocated\r
+ );\r
+ }\r
+\r
+ return Table;\r
+}\r
+\r
+/**\r
+ This function locates next ACPI table in XSDT/RSDT based on Signature and\r
+ previous returned Table.\r
+\r
+ If PreviousTable is NULL:\r
+ This function will locate the first ACPI table in XSDT/RSDT based on\r
+ Signature in gEfiAcpi20TableGuid system configuration table first, and then\r
+ gEfiAcpi10TableGuid system configuration table.\r
+ This function will locate in XSDT first, and then RSDT.\r
+ For DSDT, this function will locate XDsdt in FADT first, and then Dsdt in\r
+ FADT.\r
+ For FACS, this function will locate XFirmwareCtrl in FADT first, and then\r
+ FirmwareCtrl in FADT.\r
+\r
+ If PreviousTable is not NULL:\r
+ 1. If it could be located in XSDT in gEfiAcpi20TableGuid system configuration\r
+ table, then this function will just locate next table in XSDT in\r
+ gEfiAcpi20TableGuid system configuration table.\r
+ 2. If it could be located in RSDT in gEfiAcpi20TableGuid system configuration\r
+ table, then this function will just locate next table in RSDT in\r
+ gEfiAcpi20TableGuid system configuration table.\r
+ 3. If it could be located in RSDT in gEfiAcpi10TableGuid system configuration\r
+ table, then this function will just locate next table in RSDT in\r
+ gEfiAcpi10TableGuid system configuration table.\r
+\r
+ It's not supported that PreviousTable is not NULL but PreviousTable->Signature\r
+ is not same with Signature, NULL will be returned.\r
+\r
+ @param Signature ACPI table signature.\r
+ @param PreviousTable Pointer to previous returned table to locate next\r
+ table, or NULL to locate first table.\r
+\r
+ @return Next ACPI table or NULL if not found.\r
+\r
+**/\r
+EFI_ACPI_COMMON_HEADER *\r
+EFIAPI\r
+EfiLocateNextAcpiTable (\r
+ IN UINT32 Signature,\r
+ IN EFI_ACPI_COMMON_HEADER *PreviousTable OPTIONAL\r
+ )\r
+{\r
+ EFI_ACPI_COMMON_HEADER *Table;\r
+ BOOLEAN TempPreviousTableLocated;\r
+ BOOLEAN *PreviousTableLocated;\r
+\r
+ if (PreviousTable != NULL) {\r
+ if (PreviousTable->Signature != Signature) {\r
+ //\r
+ // PreviousTable->Signature is not same with Signature.\r
+ //\r
+ return NULL;\r
+ } else if ((Signature == EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) ||\r
+ (Signature == EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) ||\r
+ (Signature == EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE)) {\r
+ //\r
+ // There is only one FADT/DSDT/FACS table,\r
+ // so don't try to locate next one.\r
+ //\r
+ return NULL;\r
+ }\r
+\r
+ PreviousTableLocated = &TempPreviousTableLocated;\r
+ *PreviousTableLocated = FALSE;\r
+ } else {\r
+ PreviousTableLocated = NULL;\r
+ }\r
+\r
+ Table = LocateAcpiTableInAcpiConfigurationTable (\r
+ &gEfiAcpi20TableGuid,\r
+ Signature,\r
+ PreviousTable,\r
+ PreviousTableLocated\r
+ );\r
+ if (Table != NULL) {\r
+ return Table;\r
+ } else if ((PreviousTableLocated != NULL) &&\r
+ *PreviousTableLocated) {\r
+ //\r
+ // PreviousTable could be located in gEfiAcpi20TableGuid system\r
+ // configuration table, but next table could not be located in\r
+ // gEfiAcpi20TableGuid system configuration table.\r
+ //\r
+ return NULL;\r
+ }\r
+\r
+ return LocateAcpiTableInAcpiConfigurationTable (\r
+ &gEfiAcpi10TableGuid,\r
+ Signature,\r
+ PreviousTable,\r
+ PreviousTableLocated\r
+ );\r
+}\r
+\r
+/**\r
+ This function locates first ACPI table in XSDT/RSDT based on Signature.\r
+\r
+ This function will locate the first ACPI table in XSDT/RSDT based on\r
+ Signature in gEfiAcpi20TableGuid system configuration table first, and then\r
+ gEfiAcpi10TableGuid system configuration table.\r
+ This function will locate in XSDT first, and then RSDT.\r
+ For DSDT, this function will locate XDsdt in FADT first, and then Dsdt in\r
+ FADT.\r
+ For FACS, this function will locate XFirmwareCtrl in FADT first, and then\r
+ FirmwareCtrl in FADT.\r
+\r
+ @param Signature ACPI table signature.\r
+\r
+ @return First ACPI table or NULL if not found.\r
+\r
+**/\r
+EFI_ACPI_COMMON_HEADER *\r
+EFIAPI\r
+EfiLocateFirstAcpiTable (\r
+ IN UINT32 Signature\r
+ )\r
+{\r
+ return EfiLocateNextAcpiTable (Signature, NULL);\r
+}\r