/** @file\r
ACPI Sdt Protocol Driver\r
\r
- Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved. <BR>\r
+ Copyright (c) 2010 - 2021, Intel Corporation. All rights reserved. <BR>\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
/**\r
Returns a requested ACPI table.\r
\r
- The GetAcpiTable() function returns a pointer to a buffer containing the ACPI table associated\r
- with the Index that was input. The following structures are not considered elements in the list of\r
+ The following structures are not considered elements in the list of\r
ACPI tables:\r
- Root System Description Pointer (RSD_PTR)\r
- Root System Description Table (RSDT)\r
member. For tables installed via the EFI_ACPI_TABLE_PROTOCOL.InstallAcpiTable() interface,\r
the function returns the value of EFI_ACPI_STD_PROTOCOL.AcpiVersion.\r
\r
- @param[in] Index The zero-based index of the table to retrieve.\r
- @param[out] Table Pointer for returning the table buffer.\r
- @param[out] Version On return, updated with the ACPI versions to which this table belongs. Type\r
- EFI_ACPI_TABLE_VERSION is defined in "Related Definitions" in the\r
- EFI_ACPI_SDT_PROTOCOL.\r
- @param[out] TableKey On return, points to the table key for the specified ACPI system definition table.\r
- This is identical to the table key used in the EFI_ACPI_TABLE_PROTOCOL.\r
- The TableKey can be passed to EFI_ACPI_TABLE_PROTOCOL.UninstallAcpiTable()\r
- to uninstall the table.\r
- @retval EFI_SUCCESS The function completed successfully.\r
- @retval EFI_NOT_FOUND The requested index is too large and a table was not found.\r
+ @param[in] AcpiTableInstance ACPI table Instance.\r
+ @param[in] Index The zero-based index of the table to retrieve.\r
+ @param[out] Table Pointer for returning the table buffer.\r
+ @param[out] Version On return, updated with the ACPI versions to which this table belongs. Type\r
+ EFI_ACPI_TABLE_VERSION is defined in "Related Definitions" in the\r
+ EFI_ACPI_SDT_PROTOCOL.\r
+ @param[out] TableKey On return, points to the table key for the specified ACPI system definition table.\r
+ This is identical to the table key used in the EFI_ACPI_TABLE_PROTOCOL.\r
+ The TableKey can be passed to EFI_ACPI_TABLE_PROTOCOL.UninstallAcpiTable()\r
+ to uninstall the table.\r
+ @retval EFI_SUCCESS The function completed successfully.\r
+ @retval EFI_NOT_FOUND The requested index is too large and a table was not found.\r
**/\r
EFI_STATUS\r
-EFIAPI\r
-GetAcpiTable2 (\r
+SdtGetAcpiTable (\r
+ IN EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance,\r
IN UINTN Index,\r
OUT EFI_ACPI_SDT_HEADER **Table,\r
OUT EFI_ACPI_TABLE_VERSION *Version,\r
OUT UINTN *TableKey\r
)\r
{\r
- EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance;\r
UINTN TableIndex;\r
LIST_ENTRY *CurrentLink;\r
LIST_ENTRY *StartLink;\r
EFI_ACPI_TABLE_LIST *CurrentTable;\r
-\r
- ASSERT (Table != NULL);\r
- ASSERT (Version != NULL);\r
- ASSERT (TableKey != NULL);\r
-\r
- //\r
- // Get the instance of the ACPI Table\r
- //\r
- AcpiTableInstance = SdtGetAcpiTableInstance ();\r
-\r
//\r
// Find the table\r
//\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Returns a requested ACPI table.\r
+\r
+ The GetAcpiTable() function returns a pointer to a buffer containing the ACPI table associated\r
+ with the Index that was input. The following structures are not considered elements in the list of\r
+ ACPI tables:\r
+ - Root System Description Pointer (RSD_PTR)\r
+ - Root System Description Table (RSDT)\r
+ - Extended System Description Table (XSDT)\r
+ Version is updated with a bit map containing all the versions of ACPI of which the table is a\r
+ member. For tables installed via the EFI_ACPI_TABLE_PROTOCOL.InstallAcpiTable() interface,\r
+ the function returns the value of EFI_ACPI_STD_PROTOCOL.AcpiVersion.\r
+\r
+ @param[in] Index The zero-based index of the table to retrieve.\r
+ @param[out] Table Pointer for returning the table buffer.\r
+ @param[out] Version On return, updated with the ACPI versions to which this table belongs. Type\r
+ EFI_ACPI_TABLE_VERSION is defined in "Related Definitions" in the\r
+ EFI_ACPI_SDT_PROTOCOL.\r
+ @param[out] TableKey On return, points to the table key for the specified ACPI system definition table.\r
+ This is identical to the table key used in the EFI_ACPI_TABLE_PROTOCOL.\r
+ The TableKey can be passed to EFI_ACPI_TABLE_PROTOCOL.UninstallAcpiTable()\r
+ to uninstall the table.\r
+ @retval EFI_SUCCESS The function completed successfully.\r
+ @retval EFI_NOT_FOUND The requested index is too large and a table was not found.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetAcpiTable2 (\r
+ IN UINTN Index,\r
+ OUT EFI_ACPI_SDT_HEADER **Table,\r
+ OUT EFI_ACPI_TABLE_VERSION *Version,\r
+ OUT UINTN *TableKey\r
+ )\r
+{\r
+ EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance;\r
+\r
+ ASSERT (Table != NULL);\r
+ ASSERT (Version != NULL);\r
+ ASSERT (TableKey != NULL);\r
+\r
+ //\r
+ // Get the instance of the ACPI Table\r
+ //\r
+ AcpiTableInstance = SdtGetAcpiTableInstance ();\r
+\r
+ return SdtGetAcpiTable (AcpiTableInstance, Index, Table, Version, TableKey);\r
+}\r
+\r
+\r
/**\r
Register a callback when an ACPI table is installed.\r
\r
/** @file\r
ACPI Table Protocol Driver\r
\r
- Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.<BR>\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
#include <Library/MemoryAllocationLib.h>\r
#include <Library/UefiBootServicesTableLib.h>\r
#include <Library/PcdLib.h>\r
+#include <Library/HobLib.h>\r
+#include <UniversalPayload/AcpiTable.h>\r
\r
//\r
// Statements that include other files\r
IN EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance\r
);\r
\r
+/**\r
+ Returns a requested ACPI table.\r
+\r
+ The following structures are not considered elements in the list of\r
+ ACPI tables:\r
+ - Root System Description Pointer (RSD_PTR)\r
+ - Root System Description Table (RSDT)\r
+ - Extended System Description Table (XSDT)\r
+ Version is updated with a bit map containing all the versions of ACPI of which the table is a\r
+ member. For tables installed via the EFI_ACPI_TABLE_PROTOCOL.InstallAcpiTable() interface,\r
+ the function returns the value of EFI_ACPI_STD_PROTOCOL.AcpiVersion.\r
+\r
+ @param[in] AcpiTableInstance ACPI table Instance.\r
+ @param[in] Index The zero-based index of the table to retrieve.\r
+ @param[out] Table Pointer for returning the table buffer.\r
+ @param[out] Version On return, updated with the ACPI versions to which this table belongs. Type\r
+ EFI_ACPI_TABLE_VERSION is defined in "Related Definitions" in the\r
+ EFI_ACPI_SDT_PROTOCOL.\r
+ @param[out] TableKey On return, points to the table key for the specified ACPI system definition table.\r
+ This is identical to the table key used in the EFI_ACPI_TABLE_PROTOCOL.\r
+ The TableKey can be passed to EFI_ACPI_TABLE_PROTOCOL.UninstallAcpiTable()\r
+ to uninstall the table.\r
+ @retval EFI_SUCCESS The function completed successfully.\r
+ @retval EFI_NOT_FOUND The requested index is too large and a table was not found.\r
+**/\r
+EFI_STATUS\r
+SdtGetAcpiTable (\r
+ IN EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance,\r
+ IN UINTN Index,\r
+ OUT EFI_ACPI_SDT_HEADER **Table,\r
+ OUT EFI_ACPI_TABLE_VERSION *Version,\r
+ OUT UINTN *TableKey\r
+ );\r
+\r
//\r
// export PrivateData symbol, because we need that in AcpiSdtProtol implementation\r
//\r
# This driver initializes ACPI tables (Rsdp, Rsdt and Xsdt) and produces UEFI/PI\r
# services to install/uninstall/manage ACPI tables.\r
#\r
-# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.<BR>\r
# Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>\r
# SPDX-License-Identifier: BSD-2-Clause-Patent\r
#\r
DebugLib\r
BaseLib\r
PcdLib\r
+ HobLib\r
\r
[Guids]\r
- gEfiAcpi10TableGuid ## PRODUCES ## SystemTable\r
- gEfiAcpiTableGuid ## PRODUCES ## SystemTable\r
+ gEfiAcpi10TableGuid ## PRODUCES ## SystemTable\r
+ gEfiAcpiTableGuid ## PRODUCES ## SystemTable\r
+ gUniversalPayloadAcpiTableGuid ## SOMETIMES_CONSUMES ## HOB\r
\r
[FeaturePcd]\r
gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol ## CONSUMES\r
/** @file\r
ACPI Table Protocol Implementation\r
\r
- Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.<BR>\r
Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
@param Table Table to add.\r
@param Checksum Does the table require checksumming.\r
@param Version The version of the list to add the table to.\r
+ @param IsFromHob True, if add Apci Table from Hob List.\r
@param Handle Pointer for returning the handle.\r
\r
@return EFI_SUCCESS The function completed successfully.\r
IN VOID *Table,\r
IN BOOLEAN Checksum,\r
IN EFI_ACPI_TABLE_VERSION Version,\r
+ IN BOOLEAN IsFromHob,\r
OUT UINTN *Handle\r
);\r
\r
AcpiTableBufferConst,\r
TRUE,\r
Version,\r
+ FALSE,\r
TableKey\r
);\r
if (!EFI_ERROR (Status)) {\r
@param Table Table to add.\r
@param Checksum Does the table require checksumming.\r
@param Version The version of the list to add the table to.\r
+ @param IsFromHob True, if add Apci Table from Hob List.\r
@param Handle Pointer for returning the handle.\r
\r
@return EFI_SUCCESS The function completed successfully.\r
IN VOID *Table,\r
IN BOOLEAN Checksum,\r
IN EFI_ACPI_TABLE_VERSION Version,\r
+ IN BOOLEAN IsFromHob,\r
OUT UINTN *Handle\r
)\r
{\r
// SMM communication ACPI table.\r
//\r
ASSERT ((EFI_PAGE_SIZE % 64) == 0);\r
- Status = gBS->AllocatePages (\r
- AllocateMaxAddress,\r
- EfiACPIMemoryNVS,\r
- EFI_SIZE_TO_PAGES (CurrentTableList->TableSize),\r
- &AllocPhysAddress\r
- );\r
+ if (IsFromHob){\r
+ AllocPhysAddress = (UINTN)Table;\r
+ Status = EFI_SUCCESS;\r
+ } else {\r
+ Status = gBS->AllocatePages (\r
+ AllocateMaxAddress,\r
+ EfiACPIMemoryNVS,\r
+ EFI_SIZE_TO_PAGES (CurrentTableList->TableSize),\r
+ &AllocPhysAddress\r
+ );\r
+ }\r
} else if (mAcpiTableAllocType == AllocateAnyPages) {\r
//\r
// If there is no allocation limit, there is also no need to use page\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ This function will find gUniversalPayloadAcpiTableGuid Guid Hob, and install Acpi table from it.\r
+\r
+ @param AcpiTableInstance Protocol instance private data.\r
+\r
+ @return EFI_SUCCESS The function completed successfully.\r
+ @return EFI_NOT_FOUND The function doesn't find the gEfiAcpiTableGuid Guid Hob.\r
+ @return EFI_ABORTED The function could not complete successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+InstallAcpiTableFromHob (\r
+ EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance\r
+ )\r
+{\r
+ EFI_HOB_GUID_TYPE *GuidHob;\r
+ EFI_ACPI_TABLE_VERSION Version;\r
+ EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp;\r
+ EFI_ACPI_DESCRIPTION_HEADER *Rsdt;\r
+ EFI_ACPI_DESCRIPTION_HEADER *ChildTable;\r
+ UINT64 ChildTableAddress;\r
+ UINTN Count;\r
+ UINTN Index;\r
+ UINTN TableKey;\r
+ EFI_STATUS Status;\r
+ UINTN EntrySize;\r
+ UNIVERSAL_PAYLOAD_ACPI_TABLE *AcpiTableAdress;\r
+ VOID *TableToInstall;\r
+ EFI_ACPI_SDT_HEADER *Table;\r
+ UNIVERSAL_PAYLOAD_GENERIC_HEADER *GenericHeader;\r
+\r
+ TableKey = 0;\r
+ Version = PcdGet32 (PcdAcpiExposedTableVersions);\r
+ Status = EFI_SUCCESS;\r
+ //\r
+ // HOB only contains the ACPI table in 2.0+ format.\r
+ //\r
+ GuidHob = GetFirstGuidHob (&gUniversalPayloadAcpiTableGuid);\r
+ if (GuidHob == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ GenericHeader = (UNIVERSAL_PAYLOAD_GENERIC_HEADER *) GET_GUID_HOB_DATA (GuidHob);\r
+ if ((sizeof (UNIVERSAL_PAYLOAD_GENERIC_HEADER) > GET_GUID_HOB_DATA_SIZE (GuidHob)) || (GenericHeader->Length > GET_GUID_HOB_DATA_SIZE (GuidHob))) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ if (GenericHeader->Revision == UNIVERSAL_PAYLOAD_ACPI_TABLE_REVISION) {\r
+ //\r
+ // UNIVERSAL_PAYLOAD_ACPI_TABLE structure is used when Revision equals to UNIVERSAL_PAYLOAD_ACPI_TABLE_REVISION\r
+ //\r
+ AcpiTableAdress = (UNIVERSAL_PAYLOAD_ACPI_TABLE *) GET_GUID_HOB_DATA (GuidHob);\r
+ if (AcpiTableAdress->Header.Length < UNIVERSAL_PAYLOAD_SIZEOF_THROUGH_FIELD (UNIVERSAL_PAYLOAD_ACPI_TABLE, Rsdp)) {\r
+ //\r
+ // Retrun if can't find the ACPI Info Hob with enough length\r
+ //\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ Rsdp = (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *) (UINTN) (AcpiTableAdress->Rsdp);\r
+\r
+ //\r
+ // An ACPI-compatible OS must use the XSDT if present.\r
+ // It shouldn't happen that XsdtAddress points beyond 4G range in 32-bit environment.\r
+ //\r
+ ASSERT ((UINTN) Rsdp->XsdtAddress == Rsdp->XsdtAddress);\r
+\r
+ EntrySize = sizeof (UINT64);\r
+ Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) Rsdp->XsdtAddress;\r
+ if (Rsdt == NULL) {\r
+ //\r
+ // XsdtAddress is zero, then we use Rsdt which has 32 bit entry\r
+ //\r
+ Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) Rsdp->RsdtAddress;\r
+ EntrySize = sizeof (UINT32);\r
+ }\r
+\r
+ if (Rsdt->Length <= sizeof (EFI_ACPI_DESCRIPTION_HEADER)) {\r
+ return EFI_ABORTED;\r
+ }\r
+\r
+ Count = (Rsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / EntrySize;\r
+\r
+ for (Index = 0; Index < Count; Index++){\r
+ ChildTableAddress = 0;\r
+ CopyMem (&ChildTableAddress, (UINT8 *) (Rsdt + 1) + EntrySize * Index, EntrySize);\r
+ //\r
+ // If the address is of UINT64 while this module runs at 32 bits,\r
+ // make sure the upper bits are all-zeros.\r
+ //\r
+ ASSERT (ChildTableAddress == (UINTN) ChildTableAddress);\r
+ if (ChildTableAddress != (UINTN) ChildTableAddress) {\r
+ Status = EFI_ABORTED;\r
+ break;\r
+ }\r
+\r
+ ChildTable = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) ChildTableAddress;\r
+ Status = AddTableToList (AcpiTableInstance, ChildTable, TRUE, Version, TRUE, &TableKey);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "InstallAcpiTableFromHob: Fail to add ACPI table at 0x%p\n", ChildTable));\r
+ ASSERT_EFI_ERROR (Status);\r
+ break;\r
+ }\r
+ if (ChildTable->Signature == EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE){\r
+ //\r
+ // Add the FACS and DSDT tables if it is not NULL.\r
+ //\r
+ if (((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *) ChildTable)->FirmwareCtrl != 0) {\r
+ TableToInstall = (VOID *) (UINTN) ((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *) ChildTable)->FirmwareCtrl;\r
+ Status = AddTableToList (AcpiTableInstance, TableToInstall, TRUE, Version, TRUE, &TableKey);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "InstallAcpiTableFromHob: Fail to add ACPI table FACS\n"));\r
+ ASSERT_EFI_ERROR (Status);\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *) ChildTable)->Dsdt != 0) {\r
+ TableToInstall = (VOID *) (UINTN) ((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *) ChildTable)->Dsdt;\r
+ Status = AddTableToList (AcpiTableInstance, TableToInstall, TRUE, Version, TRUE, &TableKey);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_ERROR, "InstallAcpiTableFromHob: Fail to add ACPI table DSDT\n"));\r
+ ASSERT_EFI_ERROR (Status);\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ } else {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // Error happens when trying to add ACPI table to the list.\r
+ // Remove all of them from list because at this time, no other tables except from HOB are in the list\r
+ //\r
+ while (SdtGetAcpiTable (AcpiTableInstance, 0, &Table, &Version, &TableKey) == EFI_SUCCESS) {\r
+ RemoveTableFromList (AcpiTableInstance, Version, TableKey);\r
+ }\r
+ } else {\r
+ Status = PublishTables (AcpiTableInstance, Version);\r
+ }\r
+\r
+ ASSERT_EFI_ERROR (Status);\r
+ return Status;\r
+}\r
\r
/**\r
Constructor for the ACPI table protocol. Initializes instance\r
\r
ChecksumCommonTables (AcpiTableInstance);\r
\r
+ InstallAcpiTableFromHob (AcpiTableInstance);\r
+\r
//\r
// Completed successfully\r
//\r