/** @file | |
Dynamic Table Manager Dxe | |
Copyright (c) 2017 - 2019, ARM Limited. All rights reserved. | |
SPDX-License-Identifier: BSD-2-Clause-Patent | |
**/ | |
#include <Library/DebugLib.h> | |
#include <Library/PcdLib.h> | |
#include <Library/UefiBootServicesTableLib.h> | |
#include <Protocol/AcpiTable.h> | |
// Module specific include files. | |
#include <AcpiTableGenerator.h> | |
#include <ConfigurationManagerObject.h> | |
#include <ConfigurationManagerHelper.h> | |
#include <DeviceTreeTableGenerator.h> | |
#include <Library/TableHelperLib.h> | |
#include <Protocol/ConfigurationManagerProtocol.h> | |
#include <Protocol/DynamicTableFactoryProtocol.h> | |
#include <SmbiosTableGenerator.h> | |
/** This macro expands to a function that retrieves the ACPI Table | |
List from the Configuration Manager. | |
*/ | |
GET_OBJECT_LIST ( | |
EObjNameSpaceStandard, | |
EStdObjAcpiTableList, | |
CM_STD_OBJ_ACPI_TABLE_INFO | |
) | |
/** A helper function to build and install a single ACPI table. | |
This is a helper function that invokes the Table generator interface | |
for building an ACPI table. It uses the AcpiTableProtocol to install the | |
table, then frees the resources allocated for generating it. | |
@param [in] TableFactoryProtocol Pointer to the Table Factory Protocol | |
interface. | |
@param [in] CfgMgrProtocol Pointer to the Configuration Manager | |
Protocol Interface. | |
@param [in] Generator Pointer to the AcpiTable generator. | |
@param [in] AcpiTableProtocol Pointer to the AcpiTable protocol. | |
@param [in] AcpiTableInfo Pointer to the ACPI table Info. | |
@retval EFI_SUCCESS Success. | |
@retval EFI_INVALID_PARAMETER A parameter is invalid. | |
@retval EFI_NOT_FOUND Required object is not found. | |
@retval EFI_BAD_BUFFER_SIZE Size returned by the Configuration Manager | |
is less than the Object size for the | |
requested object. | |
**/ | |
STATIC | |
EFI_STATUS | |
EFIAPI | |
BuildAndInstallSingleAcpiTable ( | |
IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol, | |
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, | |
IN CONST ACPI_TABLE_GENERATOR *CONST Generator, | |
IN EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol, | |
IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo | |
) | |
{ | |
EFI_STATUS Status; | |
EFI_STATUS Status1; | |
EFI_ACPI_DESCRIPTION_HEADER *AcpiTable; | |
UINTN TableHandle; | |
AcpiTable = NULL; | |
Status = Generator->BuildAcpiTable ( | |
Generator, | |
AcpiTableInfo, | |
CfgMgrProtocol, | |
&AcpiTable | |
); | |
if (EFI_ERROR (Status)) { | |
DEBUG (( | |
DEBUG_ERROR, | |
"ERROR: Failed to Build Table." \ | |
" TableGeneratorId = 0x%x. Status = %r\n", | |
AcpiTableInfo->TableGeneratorId, | |
Status | |
)); | |
// Free any allocated resources. | |
goto exit_handler; | |
} | |
if (AcpiTable == NULL) { | |
Status = EFI_NOT_FOUND; | |
goto exit_handler; | |
} | |
// Dump ACPI Table Header | |
DUMP_ACPI_TABLE_HEADER (AcpiTable); | |
// Install ACPI table | |
Status = AcpiTableProtocol->InstallAcpiTable ( | |
AcpiTableProtocol, | |
AcpiTable, | |
AcpiTable->Length, | |
&TableHandle | |
); | |
if (EFI_ERROR (Status)) { | |
DEBUG (( | |
DEBUG_ERROR, | |
"ERROR: Failed to Install ACPI Table. Status = %r\n", | |
Status | |
)); | |
// Free any allocated resources. | |
goto exit_handler; | |
} | |
DEBUG (( | |
DEBUG_INFO, | |
"INFO: ACPI Table installed. Status = %r\n", | |
Status | |
)); | |
exit_handler: | |
// Free any resources allocated for generating the tables. | |
if (Generator->FreeTableResources != NULL) { | |
Status1 = Generator->FreeTableResources ( | |
Generator, | |
AcpiTableInfo, | |
CfgMgrProtocol, | |
&AcpiTable | |
); | |
if (EFI_ERROR (Status1)) { | |
DEBUG (( | |
DEBUG_ERROR, | |
"ERROR: Failed to Free Table Resources." \ | |
"TableGeneratorId = 0x%x. Status = %r\n", | |
AcpiTableInfo->TableGeneratorId, | |
Status1 | |
)); | |
} | |
// Return the first error status in case of failure | |
if (!EFI_ERROR (Status)) { | |
Status = Status1; | |
} | |
} | |
return Status; | |
} | |
/** A helper function to build and install multiple ACPI tables. | |
This is a helper function that invokes the Table generator interface | |
for building an ACPI table. It uses the AcpiTableProtocol to install the | |
table, then frees the resources allocated for generating it. | |
@param [in] TableFactoryProtocol Pointer to the Table Factory Protocol | |
interface. | |
@param [in] CfgMgrProtocol Pointer to the Configuration Manager | |
Protocol Interface. | |
@param [in] Generator Pointer to the AcpiTable generator. | |
@param [in] AcpiTableProtocol Pointer to the AcpiTable protocol. | |
@param [in] AcpiTableInfo Pointer to the ACPI table Info. | |
@retval EFI_SUCCESS Success. | |
@retval EFI_INVALID_PARAMETER A parameter is invalid. | |
@retval EFI_NOT_FOUND Required object is not found. | |
@retval EFI_BAD_BUFFER_SIZE Size returned by the Configuration Manager | |
is less than the Object size for the | |
requested object. | |
**/ | |
STATIC | |
EFI_STATUS | |
EFIAPI | |
BuildAndInstallMultipleAcpiTable ( | |
IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol, | |
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, | |
IN CONST ACPI_TABLE_GENERATOR *CONST Generator, | |
IN EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol, | |
IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo | |
) | |
{ | |
EFI_STATUS Status; | |
EFI_STATUS Status1; | |
EFI_ACPI_DESCRIPTION_HEADER **AcpiTable; | |
UINTN TableCount; | |
UINTN TableHandle; | |
UINTN Index; | |
AcpiTable = NULL; | |
TableCount = 0; | |
Status = Generator->BuildAcpiTableEx ( | |
Generator, | |
AcpiTableInfo, | |
CfgMgrProtocol, | |
&AcpiTable, | |
&TableCount | |
); | |
if (EFI_ERROR (Status)) { | |
DEBUG (( | |
DEBUG_ERROR, | |
"ERROR: Failed to Build Table." \ | |
" TableGeneratorId = 0x%x. Status = %r\n", | |
AcpiTableInfo->TableGeneratorId, | |
Status | |
)); | |
// Free any allocated resources. | |
goto exit_handler; | |
} | |
if ((AcpiTable == NULL) || (TableCount == 0)) { | |
Status = EFI_NOT_FOUND; | |
goto exit_handler; | |
} | |
for (Index = 0; Index < TableCount; Index++) { | |
// Dump ACPI Table Header | |
DUMP_ACPI_TABLE_HEADER (AcpiTable[Index]); | |
// Install ACPI table | |
Status = AcpiTableProtocol->InstallAcpiTable ( | |
AcpiTableProtocol, | |
AcpiTable[Index], | |
AcpiTable[Index]->Length, | |
&TableHandle | |
); | |
if (EFI_ERROR (Status)) { | |
DEBUG (( | |
DEBUG_ERROR, | |
"ERROR: Failed to Install ACPI Table. Status = %r\n", | |
Status | |
)); | |
// Free any allocated resources. | |
goto exit_handler; | |
} | |
DEBUG (( | |
DEBUG_INFO, | |
"INFO: ACPI Table installed. Status = %r\n", | |
Status | |
)); | |
} | |
exit_handler: | |
// Free any resources allocated for generating the tables. | |
if (Generator->FreeTableResourcesEx != NULL) { | |
Status1 = Generator->FreeTableResourcesEx ( | |
Generator, | |
AcpiTableInfo, | |
CfgMgrProtocol, | |
&AcpiTable, | |
TableCount | |
); | |
if (EFI_ERROR (Status1)) { | |
DEBUG (( | |
DEBUG_ERROR, | |
"ERROR: Failed to Free Table Resources." \ | |
"TableGeneratorId = 0x%x. Status = %r\n", | |
AcpiTableInfo->TableGeneratorId, | |
Status1 | |
)); | |
} | |
// Return the first error status in case of failure | |
if (!EFI_ERROR (Status)) { | |
Status = Status1; | |
} | |
} | |
return Status; | |
} | |
/** A helper function to invoke a Table generator | |
This is a helper function that invokes the Table generator interface | |
for building an ACPI table. It uses the AcpiTableProtocol to install the | |
table, then frees the resources allocated for generating it. | |
@param [in] TableFactoryProtocol Pointer to the Table Factory Protocol | |
interface. | |
@param [in] CfgMgrProtocol Pointer to the Configuration Manager | |
Protocol Interface. | |
@param [in] AcpiTableProtocol Pointer to the AcpiTable protocol. | |
@param [in] AcpiTableInfo Pointer to the ACPI table Info. | |
@retval EFI_SUCCESS Success. | |
@retval EFI_INVALID_PARAMETER A parameter is invalid. | |
@retval EFI_NOT_FOUND Required object is not found. | |
@retval EFI_BAD_BUFFER_SIZE Size returned by the Configuration Manager | |
is less than the Object size for the | |
requested object. | |
**/ | |
STATIC | |
EFI_STATUS | |
EFIAPI | |
BuildAndInstallAcpiTable ( | |
IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol, | |
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, | |
IN EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol, | |
IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo | |
) | |
{ | |
EFI_STATUS Status; | |
CONST ACPI_TABLE_GENERATOR *Generator; | |
ASSERT (TableFactoryProtocol != NULL); | |
ASSERT (CfgMgrProtocol != NULL); | |
ASSERT (AcpiTableProtocol != NULL); | |
ASSERT (AcpiTableInfo != NULL); | |
DEBUG (( | |
DEBUG_INFO, | |
"INFO: EStdObjAcpiTableList: Address = 0x%p," \ | |
" TableGeneratorId = 0x%x\n", | |
AcpiTableInfo, | |
AcpiTableInfo->TableGeneratorId | |
)); | |
Generator = NULL; | |
Status = TableFactoryProtocol->GetAcpiTableGenerator ( | |
TableFactoryProtocol, | |
AcpiTableInfo->TableGeneratorId, | |
&Generator | |
); | |
if (EFI_ERROR (Status)) { | |
DEBUG (( | |
DEBUG_ERROR, | |
"ERROR: Table Generator not found." \ | |
" TableGeneratorId = 0x%x. Status = %r\n", | |
AcpiTableInfo->TableGeneratorId, | |
Status | |
)); | |
return Status; | |
} | |
if (Generator == NULL) { | |
return EFI_NOT_FOUND; | |
} | |
DEBUG (( | |
DEBUG_INFO, | |
"INFO: Generator found : %s\n", | |
Generator->Description | |
)); | |
if (Generator->BuildAcpiTableEx != NULL) { | |
Status = BuildAndInstallMultipleAcpiTable ( | |
TableFactoryProtocol, | |
CfgMgrProtocol, | |
Generator, | |
AcpiTableProtocol, | |
AcpiTableInfo | |
); | |
if (EFI_ERROR (Status)) { | |
DEBUG (( | |
DEBUG_ERROR, | |
"ERROR: Failed to find build and install ACPI Table." \ | |
" Status = %r\n", | |
Status | |
)); | |
} | |
} else if (Generator->BuildAcpiTable != NULL) { | |
Status = BuildAndInstallSingleAcpiTable ( | |
TableFactoryProtocol, | |
CfgMgrProtocol, | |
Generator, | |
AcpiTableProtocol, | |
AcpiTableInfo | |
); | |
if (EFI_ERROR (Status)) { | |
DEBUG (( | |
DEBUG_ERROR, | |
"ERROR: Failed to find build and install ACPI Table." \ | |
" Status = %r\n", | |
Status | |
)); | |
} | |
} else { | |
Status = EFI_INVALID_PARAMETER; | |
DEBUG (( | |
DEBUG_ERROR, | |
"ERROR: Table Generator does not implement the" \ | |
" ACPI_TABLE_GENERATOR_BUILD_TABLE interface." \ | |
" TableGeneratorId = 0x%x. Status = %r\n", | |
AcpiTableInfo->TableGeneratorId, | |
Status | |
)); | |
} | |
return Status; | |
} | |
/** The function checks if the Configuration Manager has provided the | |
mandatory ACPI tables for installation. | |
@param [in] AcpiTableInfo Pointer to the ACPI Table Info list. | |
@param [in] AcpiTableCount Count of ACPI Table Info. | |
@retval EFI_SUCCESS Success. | |
@retval EFI_NOT_FOUND If mandatory table is not found. | |
**/ | |
STATIC | |
EFI_STATUS | |
EFIAPI | |
VerifyMandatoryTablesArePresent ( | |
IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, | |
IN UINT32 AcpiTableCount | |
) | |
{ | |
EFI_STATUS Status; | |
BOOLEAN FadtFound; | |
BOOLEAN MadtFound; | |
BOOLEAN GtdtFound; | |
BOOLEAN DsdtFound; | |
BOOLEAN Dbg2Found; | |
BOOLEAN SpcrFound; | |
Status = EFI_SUCCESS; | |
FadtFound = FALSE; | |
MadtFound = FALSE; | |
GtdtFound = FALSE; | |
DsdtFound = FALSE; | |
Dbg2Found = FALSE; | |
SpcrFound = FALSE; | |
ASSERT (AcpiTableInfo != NULL); | |
while (AcpiTableCount-- != 0) { | |
switch (AcpiTableInfo[AcpiTableCount].AcpiTableSignature) { | |
case EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE: | |
FadtFound = TRUE; | |
break; | |
case EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE: | |
MadtFound = TRUE; | |
break; | |
case EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE: | |
GtdtFound = TRUE; | |
break; | |
case EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE: | |
DsdtFound = TRUE; | |
break; | |
case EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE: | |
Dbg2Found = TRUE; | |
break; | |
case EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE: | |
SpcrFound = TRUE; | |
break; | |
default: | |
break; | |
} | |
} | |
// We need at least the FADT, MADT, GTDT and the DSDT tables to boot | |
if (!FadtFound) { | |
DEBUG ((DEBUG_ERROR, "ERROR: FADT Table not found\n")); | |
Status = EFI_NOT_FOUND; | |
} | |
if (!MadtFound) { | |
DEBUG ((DEBUG_ERROR, "ERROR: MADT Table not found.\n")); | |
Status = EFI_NOT_FOUND; | |
} | |
if (!GtdtFound) { | |
DEBUG ((DEBUG_ERROR, "ERROR: GTDT Table not found.\n")); | |
Status = EFI_NOT_FOUND; | |
} | |
if (!DsdtFound) { | |
DEBUG ((DEBUG_ERROR, "ERROR: DSDT Table not found.\n")); | |
Status = EFI_NOT_FOUND; | |
} | |
if (!Dbg2Found) { | |
DEBUG ((DEBUG_WARN, "WARNING: DBG2 Table not found.\n")); | |
} | |
if (!SpcrFound) { | |
DEBUG ((DEBUG_WARN, "WARNING: SPCR Table not found.\n")); | |
} | |
return Status; | |
} | |
/** Generate and install ACPI tables. | |
The function gathers the information necessary for installing the | |
ACPI tables from the Configuration Manager, invokes the generators | |
and installs them (via BuildAndInstallAcpiTable). | |
@param [in] TableFactoryProtocol Pointer to the Table Factory Protocol | |
interface. | |
@param [in] CfgMgrProtocol Pointer to the Configuration Manager | |
Protocol Interface. | |
@retval EFI_SUCCESS Success. | |
@retval EFI_NOT_FOUND If a mandatory table or a generator is not found. | |
**/ | |
STATIC | |
EFI_STATUS | |
EFIAPI | |
ProcessAcpiTables ( | |
IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol, | |
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol | |
) | |
{ | |
EFI_STATUS Status; | |
EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol; | |
CM_STD_OBJ_ACPI_TABLE_INFO *AcpiTableInfo; | |
UINT32 AcpiTableCount; | |
UINT32 Idx; | |
ASSERT (TableFactoryProtocol != NULL); | |
ASSERT (CfgMgrProtocol != NULL); | |
// Find the AcpiTable protocol | |
Status = gBS->LocateProtocol ( | |
&gEfiAcpiTableProtocolGuid, | |
NULL, | |
(VOID **)&AcpiTableProtocol | |
); | |
if (EFI_ERROR (Status)) { | |
DEBUG (( | |
DEBUG_ERROR, | |
"ERROR: Failed to find AcpiTable protocol. Status = %r\n", | |
Status | |
)); | |
return Status; | |
} | |
Status = GetEStdObjAcpiTableList ( | |
CfgMgrProtocol, | |
CM_NULL_TOKEN, | |
&AcpiTableInfo, | |
&AcpiTableCount | |
); | |
if (EFI_ERROR (Status)) { | |
DEBUG (( | |
DEBUG_ERROR, | |
"ERROR: Failed to get ACPI Table List. Status = %r\n", | |
Status | |
)); | |
return Status; | |
} | |
if (0 == AcpiTableCount) { | |
DEBUG (( | |
DEBUG_ERROR, | |
"ERROR: EStdObjAcpiTableList: AcpiTableCount = %d\n", | |
AcpiTableCount | |
)); | |
return EFI_NOT_FOUND; | |
} | |
DEBUG (( | |
DEBUG_INFO, | |
"INFO: EStdObjAcpiTableList: AcpiTableCount = %d\n", | |
AcpiTableCount | |
)); | |
// Check if mandatory ACPI tables are present. | |
Status = VerifyMandatoryTablesArePresent ( | |
AcpiTableInfo, | |
AcpiTableCount | |
); | |
if (EFI_ERROR (Status)) { | |
DEBUG (( | |
DEBUG_ERROR, | |
"ERROR: Failed to find mandatory ACPI Table(s)." | |
" Status = %r\n", | |
Status | |
)); | |
return Status; | |
} | |
// Add the FADT Table first. | |
for (Idx = 0; Idx < AcpiTableCount; Idx++) { | |
if (CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdFadt) == | |
AcpiTableInfo[Idx].TableGeneratorId) | |
{ | |
Status = BuildAndInstallAcpiTable ( | |
TableFactoryProtocol, | |
CfgMgrProtocol, | |
AcpiTableProtocol, | |
&AcpiTableInfo[Idx] | |
); | |
if (EFI_ERROR (Status)) { | |
DEBUG (( | |
DEBUG_ERROR, | |
"ERROR: Failed to find build and install ACPI FADT Table." \ | |
" Status = %r\n", | |
Status | |
)); | |
return Status; | |
} | |
break; | |
} | |
} // for | |
// Add remaining ACPI Tables | |
for (Idx = 0; Idx < AcpiTableCount; Idx++) { | |
DEBUG (( | |
DEBUG_INFO, | |
"INFO: AcpiTableInfo[%d].TableGeneratorId = 0x%x\n", | |
Idx, | |
AcpiTableInfo[Idx].TableGeneratorId | |
)); | |
// Skip FADT Table since we have already added | |
if (CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdFadt) == | |
AcpiTableInfo[Idx].TableGeneratorId) | |
{ | |
continue; | |
} | |
// Skip the Reserved table Generator ID for standard generators | |
if ((IS_GENERATOR_NAMESPACE_STD (AcpiTableInfo[Idx].TableGeneratorId)) && | |
((CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdReserved) >= | |
AcpiTableInfo[Idx].TableGeneratorId) || | |
(CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdMax) <= | |
AcpiTableInfo[Idx].TableGeneratorId))) | |
{ | |
DEBUG (( | |
DEBUG_WARN, | |
"WARNING: Invalid ACPI Generator table ID = 0x%x, Skipping...\n", | |
AcpiTableInfo[Idx].TableGeneratorId | |
)); | |
continue; | |
} | |
Status = BuildAndInstallAcpiTable ( | |
TableFactoryProtocol, | |
CfgMgrProtocol, | |
AcpiTableProtocol, | |
&AcpiTableInfo[Idx] | |
); | |
if (EFI_ERROR (Status)) { | |
DEBUG (( | |
DEBUG_ERROR, | |
"ERROR: Failed to find, build, and install ACPI Table." \ | |
" Status = %r\n", | |
Status | |
)); | |
return Status; | |
} | |
} // for | |
return Status; | |
} | |
/** Entrypoint of Dynamic Table Manager Dxe. | |
The Dynamic Table Manager uses the Configuration Manager Protocol | |
to get the list of ACPI and SMBIOS tables to install. For each table | |
in the list it requests the corresponding ACPI/SMBIOS table factory for | |
a generator capable of building the ACPI/SMBIOS table. | |
If a suitable table generator is found, it invokes the generator interface | |
to build the table. The Dynamic Table Manager then installs the | |
table and invokes another generator interface to free any resources | |
allocated for building the table. | |
@param ImageHandle | |
@param SystemTable | |
@retval EFI_SUCCESS Success. | |
@retval EFI_OUT_OF_RESOURCES Memory allocation failed. | |
@retval EFI_NOT_FOUND Required interface/object was not found. | |
@retval EFI_INVALID_PARAMETER Some parameter is incorrect/invalid. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
DynamicTableManagerDxeInitialize ( | |
IN EFI_HANDLE ImageHandle, | |
IN EFI_SYSTEM_TABLE *SystemTable | |
) | |
{ | |
EFI_STATUS Status; | |
EDKII_CONFIGURATION_MANAGER_PROTOCOL *CfgMgrProtocol; | |
CM_STD_OBJ_CONFIGURATION_MANAGER_INFO *CfgMfrInfo; | |
EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *TableFactoryProtocol; | |
// Locate the Dynamic Table Factory | |
Status = gBS->LocateProtocol ( | |
&gEdkiiDynamicTableFactoryProtocolGuid, | |
NULL, | |
(VOID **)&TableFactoryProtocol | |
); | |
if (EFI_ERROR (Status)) { | |
DEBUG (( | |
DEBUG_ERROR, | |
"ERROR: Failed to find Dynamic Table Factory protocol." \ | |
" Status = %r\n", | |
Status | |
)); | |
return Status; | |
} | |
// Locate the Configuration Manager for the Platform | |
Status = gBS->LocateProtocol ( | |
&gEdkiiConfigurationManagerProtocolGuid, | |
NULL, | |
(VOID **)&CfgMgrProtocol | |
); | |
if (EFI_ERROR (Status)) { | |
DEBUG (( | |
DEBUG_ERROR, | |
"ERROR: Failed to find Configuration Manager protocol. Status = %r\n", | |
Status | |
)); | |
return Status; | |
} | |
Status = GetCgfMgrInfo (CfgMgrProtocol, &CfgMfrInfo); | |
if (EFI_ERROR (Status)) { | |
DEBUG (( | |
DEBUG_ERROR, | |
"ERROR: Failed to get Configuration Manager info. Status = %r\n", | |
Status | |
)); | |
return Status; | |
} | |
DEBUG (( | |
DEBUG_INFO, | |
"INFO: Configuration Manager Version = 0x%x, OemID = %c%c%c%c%c%c\n", | |
CfgMfrInfo->Revision, | |
CfgMfrInfo->OemId[0], | |
CfgMfrInfo->OemId[1], | |
CfgMfrInfo->OemId[2], | |
CfgMfrInfo->OemId[3], | |
CfgMfrInfo->OemId[4], | |
CfgMfrInfo->OemId[5] | |
)); | |
Status = ProcessAcpiTables (TableFactoryProtocol, CfgMgrProtocol); | |
if (EFI_ERROR (Status)) { | |
DEBUG (( | |
DEBUG_ERROR, | |
"ERROR: ACPI Table processing failure. Status = %r\n", | |
Status | |
)); | |
} | |
return Status; | |
} |