729 lines
22 KiB
C
729 lines
22 KiB
C
/** @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 CONST EFI_HANDLE ImageHandle,
|
|
IN EFI_SYSTEM_TABLE * CONST 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;
|
|
}
|