/** @file | |
Configuration Manager Dxe | |
Copyright (c) 2021 - 2022, Arm Limited. All rights reserved.<BR> | |
SPDX-License-Identifier: BSD-2-Clause-Patent | |
@par Glossary: | |
- Cm or CM - Configuration Manager | |
- Obj or OBJ - Object | |
**/ | |
#include <IndustryStandard/DebugPort2Table.h> | |
#include <IndustryStandard/IoRemappingTable.h> | |
#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h> | |
#include <IndustryStandard/SerialPortConsoleRedirectionTable.h> | |
#include <Library/BaseMemoryLib.h> | |
#include <Library/DebugLib.h> | |
#include <Library/DynamicPlatRepoLib.h> | |
#include <Library/HobLib.h> | |
#include <Library/HwInfoParserLib.h> | |
#include <Library/IoLib.h> | |
#include <Library/PcdLib.h> | |
#include <Library/TableHelperLib.h> | |
#include <Library/UefiBootServicesTableLib.h> | |
#include <Protocol/AcpiTable.h> | |
#include <Protocol/ConfigurationManagerProtocol.h> | |
#include "ConfigurationManager.h" | |
// | |
// The platform configuration repository information. | |
// | |
STATIC | |
EDKII_PLATFORM_REPOSITORY_INFO mKvmtoolPlatRepositoryInfo = { | |
// | |
// Configuration Manager information | |
// | |
{ CONFIGURATION_MANAGER_REVISION, CFG_MGR_OEM_ID }, | |
// | |
// ACPI Table List | |
// | |
{ | |
// | |
// FADT Table | |
// | |
{ | |
EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, | |
EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_REVISION, | |
CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdFadt), | |
NULL | |
}, | |
// | |
// GTDT Table | |
// | |
{ | |
EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE, | |
EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_REVISION, | |
CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdGtdt), | |
NULL | |
}, | |
// | |
// MADT Table | |
// | |
{ | |
EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE, | |
EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION, | |
CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdMadt), | |
NULL | |
}, | |
// | |
// SPCR Table | |
// | |
{ | |
EFI_ACPI_6_3_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE, | |
EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_REVISION, | |
CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSpcr), | |
NULL | |
}, | |
// | |
// DSDT Table | |
// | |
{ | |
EFI_ACPI_6_3_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, | |
0, // Unused | |
CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdDsdt), | |
(EFI_ACPI_DESCRIPTION_HEADER *)dsdt_aml_code | |
}, | |
// | |
// SSDT Cpu Hierarchy Table | |
// | |
{ | |
EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, | |
0, // Unused | |
CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSsdtCpuTopology), | |
NULL | |
}, | |
// | |
// DBG2 Table | |
// | |
{ | |
EFI_ACPI_6_3_DEBUG_PORT_2_TABLE_SIGNATURE, | |
EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION, | |
CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdDbg2), | |
NULL | |
}, | |
// | |
// PCI MCFG Table | |
// | |
{ | |
EFI_ACPI_6_3_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE, | |
EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION, | |
CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdMcfg), | |
NULL | |
}, | |
// | |
// SSDT table describing the PCI root complex | |
// | |
{ | |
EFI_ACPI_6_3_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, | |
0, // Unused | |
CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSsdtPciExpress), | |
NULL | |
}, | |
// | |
// IORT Table | |
// | |
{ | |
EFI_ACPI_6_3_IO_REMAPPING_TABLE_SIGNATURE, | |
EFI_ACPI_IO_REMAPPING_TABLE_REVISION_00, | |
CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdIort), | |
NULL | |
}, | |
}, | |
// | |
// Power management profile information | |
// | |
{ EFI_ACPI_6_3_PM_PROFILE_ENTERPRISE_SERVER }, // PowerManagement Profile | |
// | |
// ITS group node | |
// | |
{ | |
// | |
// Reference token for this Iort node | |
// | |
REFERENCE_TOKEN (ItsGroupInfo), | |
// | |
// The number of ITS identifiers in the ITS node. | |
// | |
1, | |
// | |
// Reference token for the ITS identifier array | |
// | |
REFERENCE_TOKEN (ItsIdentifierArray) | |
}, | |
// | |
// ITS identifier array | |
// | |
{ | |
{ 0 }, // The ITS Identifier | |
}, | |
// | |
// Root Complex node info | |
// | |
{ | |
// | |
// Reference token for this Iort node | |
// | |
REFERENCE_TOKEN (RootComplexInfo), | |
// | |
// Number of ID mappings | |
// | |
1, | |
// | |
// Reference token for the ID mapping array | |
// | |
REFERENCE_TOKEN (DeviceIdMapping[0]), | |
// | |
// Memory access properties : Cache coherent attributes | |
// | |
EFI_ACPI_IORT_MEM_ACCESS_PROP_CCA, | |
// | |
// Memory access properties : Allocation hints | |
// | |
0, | |
// | |
// Memory access properties : Memory access flags | |
// | |
0, | |
// | |
// ATS attributes | |
// | |
EFI_ACPI_IORT_ROOT_COMPLEX_ATS_UNSUPPORTED, | |
// | |
// PCI segment number | |
// | |
0, | |
/// | |
/// Memory address size limit | |
/// | |
MEMORY_ADDRESS_SIZE_LIMIT | |
}, | |
// | |
// Array of Device ID mappings | |
// | |
{ | |
// | |
// Device ID mapping for Root complex node | |
// RootComplex -> ITS Group | |
// | |
{ | |
// | |
// Input base | |
// | |
0x0, | |
// | |
// Number of input IDs | |
// | |
0x0000FFFF, | |
// | |
// Output Base | |
// | |
0x0, | |
// | |
// Output reference | |
// | |
REFERENCE_TOKEN (ItsGroupInfo), | |
// | |
// Flags | |
// | |
0 | |
}, | |
}, | |
}; | |
/** | |
A helper function for returning the Configuration Manager Objects. | |
@param [in] CmObjectId The Configuration Manager Object ID. | |
@param [in] Object Pointer to the Object(s). | |
@param [in] ObjectSize Total size of the Object(s). | |
@param [in] ObjectCount Number of Objects. | |
@param [in, out] CmObjectDesc Pointer to the Configuration Manager Object | |
descriptor describing the requested Object. | |
@retval EFI_SUCCESS Success. | |
**/ | |
STATIC | |
EFI_STATUS | |
EFIAPI | |
HandleCmObject ( | |
IN CONST CM_OBJECT_ID CmObjectId, | |
IN VOID *Object, | |
IN CONST UINTN ObjectSize, | |
IN CONST UINTN ObjectCount, | |
IN OUT CM_OBJ_DESCRIPTOR *CONST CmObjectDesc | |
) | |
{ | |
CmObjectDesc->ObjectId = CmObjectId; | |
CmObjectDesc->Size = ObjectSize; | |
CmObjectDesc->Data = Object; | |
CmObjectDesc->Count = ObjectCount; | |
DEBUG (( | |
DEBUG_INFO, | |
"INFO: CmObjectId = " FMT_CM_OBJECT_ID ", " | |
"Ptr = 0x%p, Size = %lu, Count = %lu\n", | |
CmObjectId, | |
CmObjectDesc->Data, | |
CmObjectDesc->Size, | |
CmObjectDesc->Count | |
)); | |
return EFI_SUCCESS; | |
} | |
/** | |
A helper function for returning the Configuration Manager Objects that | |
match the token. | |
@param [in] This Pointer to the Configuration Manager Protocol. | |
@param [in] CmObjectId The Configuration Manager Object ID. | |
@param [in] Object Pointer to the Object(s). | |
@param [in] ObjectSize Total size of the Object(s). | |
@param [in] ObjectCount Number of Objects. | |
@param [in] Token A token identifying the object. | |
@param [in] HandlerProc A handler function to search the object | |
referenced by the token. | |
@param [in, out] CmObjectDesc Pointer to the Configuration Manager Object | |
descriptor describing the requested Object. | |
@retval EFI_SUCCESS Success. | |
@retval EFI_INVALID_PARAMETER A parameter is invalid. | |
@retval EFI_NOT_FOUND The required object information is not found. | |
**/ | |
STATIC | |
EFI_STATUS | |
EFIAPI | |
HandleCmObjectRefByToken ( | |
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST This, | |
IN CONST CM_OBJECT_ID CmObjectId, | |
IN VOID *Object, | |
IN CONST UINTN ObjectSize, | |
IN CONST UINTN ObjectCount, | |
IN CONST CM_OBJECT_TOKEN Token, | |
IN CONST CM_OBJECT_HANDLER_PROC HandlerProc, | |
IN OUT CM_OBJ_DESCRIPTOR *CONST CmObjectDesc | |
) | |
{ | |
EFI_STATUS Status; | |
CmObjectDesc->ObjectId = CmObjectId; | |
if (Token == CM_NULL_TOKEN) { | |
CmObjectDesc->Size = ObjectSize; | |
CmObjectDesc->Data = Object; | |
CmObjectDesc->Count = ObjectCount; | |
Status = EFI_SUCCESS; | |
} else { | |
Status = HandlerProc (This, CmObjectId, Token, CmObjectDesc); | |
} | |
DEBUG (( | |
DEBUG_INFO, | |
"INFO: Token = 0x%p, CmObjectId = " FMT_CM_OBJECT_ID ", " | |
"Ptr = 0x%p, Size = %lu, Count = %lu\n", | |
(VOID *)Token, | |
CmObjectId, | |
CmObjectDesc->Data, | |
CmObjectDesc->Size, | |
CmObjectDesc->Count | |
)); | |
return Status; | |
} | |
/** | |
Return an ITS identifier array. | |
@param [in] This Pointer to the Configuration Manager Protocol. | |
@param [in] CmObjectId The Configuration Manager Object ID. | |
@param [in] Token A token for identifying the object | |
@param [out] CmObject Pointer to the Configuration Manager Object | |
descriptor describing the requested Object. | |
@retval EFI_SUCCESS Success. | |
@retval EFI_INVALID_PARAMETER A parameter is invalid. | |
@retval EFI_NOT_FOUND The required object information is not found. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
GetItsIdentifierArray ( | |
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST This, | |
IN CONST CM_OBJECT_ID CmObjectId, | |
IN CONST CM_OBJECT_TOKEN Token, | |
OUT CM_OBJ_DESCRIPTOR *CONST CmObject | |
) | |
{ | |
EDKII_PLATFORM_REPOSITORY_INFO *PlatformRepo; | |
if ((This == NULL) || (CmObject == NULL)) { | |
ASSERT (This != NULL); | |
ASSERT (CmObject != NULL); | |
return EFI_INVALID_PARAMETER; | |
} | |
PlatformRepo = This->PlatRepoInfo; | |
if (Token != (CM_OBJECT_TOKEN)&PlatformRepo->ItsIdentifierArray) { | |
return EFI_NOT_FOUND; | |
} | |
CmObject->ObjectId = CmObjectId; | |
CmObject->Size = sizeof (PlatformRepo->ItsIdentifierArray); | |
CmObject->Data = (VOID *)&PlatformRepo->ItsIdentifierArray; | |
CmObject->Count = ARRAY_SIZE (PlatformRepo->ItsIdentifierArray); | |
return EFI_SUCCESS; | |
} | |
/** | |
Return a device Id mapping array. | |
@param [in] This Pointer to the Configuration Manager Protocol. | |
@param [in] CmObjectId The Configuration Manager Object ID. | |
@param [in] Token A token for identifying the object | |
@param [out] CmObject Pointer to the Configuration Manager Object | |
descriptor describing the requested Object. | |
@retval EFI_SUCCESS Success. | |
@retval EFI_INVALID_PARAMETER A parameter is invalid. | |
@retval EFI_NOT_FOUND The required object information is not found. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
GetDeviceIdMappingArray ( | |
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST This, | |
IN CONST CM_OBJECT_ID CmObjectId, | |
IN CONST CM_OBJECT_TOKEN Token, | |
OUT CM_OBJ_DESCRIPTOR *CONST CmObject | |
) | |
{ | |
EDKII_PLATFORM_REPOSITORY_INFO *PlatformRepo; | |
if ((This == NULL) || (CmObject == NULL)) { | |
ASSERT (This != NULL); | |
ASSERT (CmObject != NULL); | |
return EFI_INVALID_PARAMETER; | |
} | |
PlatformRepo = This->PlatRepoInfo; | |
if (Token != (CM_OBJECT_TOKEN)&PlatformRepo->DeviceIdMapping[0]) { | |
return EFI_NOT_FOUND; | |
} | |
CmObject->ObjectId = CmObjectId; | |
CmObject->Size = sizeof (CM_ARM_ID_MAPPING); | |
CmObject->Data = (VOID *)Token; | |
CmObject->Count = 1; | |
return EFI_SUCCESS; | |
} | |
/** | |
Function pointer called by the parser to add information. | |
Callback function that the parser can use to add new | |
CmObj. This function must copy the CmObj data and not rely on | |
the parser preserving the CmObj memory. | |
This function is responsible of the Token allocation. | |
@param [in] ParserHandle A handle to the parser instance. | |
@param [in] Context A pointer to the caller's context provided in | |
HwInfoParserInit (). | |
@param [in] CmObjDesc CM_OBJ_DESCRIPTOR containing the CmObj(s) to add. | |
@param [out] Token If provided and success, contain the token | |
generated for the CmObj. | |
@retval EFI_SUCCESS The function completed successfully. | |
@retval EFI_INVALID_PARAMETER Invalid parameter. | |
**/ | |
STATIC | |
EFI_STATUS | |
EFIAPI | |
HwInfoAdd ( | |
IN HW_INFO_PARSER_HANDLE ParserHandle, | |
IN VOID *Context, | |
IN CONST CM_OBJ_DESCRIPTOR *CmObjDesc, | |
OUT CM_OBJECT_TOKEN *Token OPTIONAL | |
) | |
{ | |
EFI_STATUS Status; | |
EDKII_PLATFORM_REPOSITORY_INFO *PlatformRepo; | |
if ((ParserHandle == NULL) || | |
(Context == NULL) || | |
(CmObjDesc == NULL)) | |
{ | |
ASSERT (ParserHandle != NULL); | |
ASSERT (Context != NULL); | |
ASSERT (CmObjDesc != NULL); | |
return EFI_INVALID_PARAMETER; | |
} | |
PlatformRepo = (EDKII_PLATFORM_REPOSITORY_INFO *)Context; | |
DEBUG_CODE_BEGIN (); | |
// | |
// Print the received objects. | |
// | |
ParseCmObjDesc (CmObjDesc); | |
DEBUG_CODE_END (); | |
Status = DynPlatRepoAddObject ( | |
PlatformRepo->DynamicPlatformRepo, | |
CmObjDesc, | |
Token | |
); | |
if (EFI_ERROR (Status)) { | |
ASSERT_EFI_ERROR (Status); | |
} | |
return Status; | |
} | |
/** | |
Cleanup the platform configuration repository. | |
@param [in] This Pointer to the Configuration Manager Protocol. | |
@retval EFI_SUCCESS Success | |
@retval EFI_INVALID_PARAMETER A parameter is invalid. | |
**/ | |
STATIC | |
EFI_STATUS | |
EFIAPI | |
CleanupPlatformRepository ( | |
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST This | |
) | |
{ | |
EFI_STATUS Status; | |
EDKII_PLATFORM_REPOSITORY_INFO *PlatformRepo; | |
if (This == NULL) { | |
ASSERT (This != NULL); | |
return EFI_INVALID_PARAMETER; | |
} | |
PlatformRepo = This->PlatRepoInfo; | |
// | |
// Shutdown the dynamic repo and free all objects. | |
// | |
Status = DynamicPlatRepoShutdown (PlatformRepo->DynamicPlatformRepo); | |
if (EFI_ERROR (Status)) { | |
ASSERT_EFI_ERROR (Status); | |
return Status; | |
} | |
// | |
// Shutdown parser. | |
// | |
Status = HwInfoParserShutdown (PlatformRepo->FdtParserHandle); | |
if (EFI_ERROR (Status)) { | |
ASSERT_EFI_ERROR (Status); | |
} | |
return Status; | |
} | |
/** | |
Initialize the platform configuration repository. | |
@param [in] This Pointer to the Configuration Manager Protocol. | |
@retval EFI_SUCCESS Success | |
@retval EFI_INVALID_PARAMETER A parameter is invalid. | |
@retval EFI_OUT_OF_RESOURCES An allocation has failed. | |
**/ | |
STATIC | |
EFI_STATUS | |
EFIAPI | |
InitializePlatformRepository ( | |
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST This | |
) | |
{ | |
EFI_STATUS Status; | |
EDKII_PLATFORM_REPOSITORY_INFO *PlatformRepo; | |
VOID *Hob; | |
if (This == NULL) { | |
ASSERT (This != NULL); | |
return EFI_INVALID_PARAMETER; | |
} | |
Hob = GetFirstGuidHob (&gFdtHobGuid); | |
if ((Hob == NULL) || (GET_GUID_HOB_DATA_SIZE (Hob) != sizeof (UINT64))) { | |
ASSERT (FALSE); | |
ASSERT (GET_GUID_HOB_DATA_SIZE (Hob) != sizeof (UINT64)); | |
return EFI_NOT_FOUND; | |
} | |
PlatformRepo = This->PlatRepoInfo; | |
PlatformRepo->FdtBase = (VOID *)*(UINTN *)GET_GUID_HOB_DATA (Hob); | |
// | |
// Initialise the dynamic platform repository. | |
// | |
Status = DynamicPlatRepoInit (&PlatformRepo->DynamicPlatformRepo); | |
if (EFI_ERROR (Status)) { | |
ASSERT_EFI_ERROR (Status); | |
return Status; | |
} | |
// | |
// Initialise the FDT parser | |
// | |
Status = HwInfoParserInit ( | |
PlatformRepo->FdtBase, | |
PlatformRepo, | |
HwInfoAdd, | |
&PlatformRepo->FdtParserHandle | |
); | |
if (EFI_ERROR (Status)) { | |
ASSERT_EFI_ERROR (Status); | |
goto ErrorHandler; | |
} | |
Status = HwInfoParse (PlatformRepo->FdtParserHandle); | |
if (EFI_ERROR (Status)) { | |
ASSERT_EFI_ERROR (Status); | |
goto ErrorHandler; | |
} | |
Status = DynamicPlatRepoFinalise (PlatformRepo->DynamicPlatformRepo); | |
if (EFI_ERROR (Status)) { | |
ASSERT_EFI_ERROR (Status); | |
goto ErrorHandler; | |
} | |
return EFI_SUCCESS; | |
ErrorHandler: | |
CleanupPlatformRepository (This); | |
return Status; | |
} | |
/** | |
Return a standard namespace object. | |
@param [in] This Pointer to the Configuration Manager Protocol. | |
@param [in] CmObjectId The Configuration Manager Object ID. | |
@param [in] Token An optional token identifying the object. If | |
unused this must be CM_NULL_TOKEN. | |
@param [in, out] CmObject Pointer to the Configuration Manager Object | |
descriptor describing the requested Object. | |
@retval EFI_SUCCESS Success. | |
@retval EFI_INVALID_PARAMETER A parameter is invalid. | |
@retval EFI_NOT_FOUND The required object information is not found. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
GetStandardNameSpaceObject ( | |
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST This, | |
IN CONST CM_OBJECT_ID CmObjectId, | |
IN CONST CM_OBJECT_TOKEN Token OPTIONAL, | |
IN OUT CM_OBJ_DESCRIPTOR *CONST CmObject | |
) | |
{ | |
EFI_STATUS Status; | |
EDKII_PLATFORM_REPOSITORY_INFO *PlatformRepo; | |
UINTN AcpiTableCount; | |
CM_OBJ_DESCRIPTOR CmObjDesc; | |
if ((This == NULL) || (CmObject == NULL)) { | |
ASSERT (This != NULL); | |
ASSERT (CmObject != NULL); | |
return EFI_INVALID_PARAMETER; | |
} | |
Status = EFI_NOT_FOUND; | |
PlatformRepo = This->PlatRepoInfo; | |
switch (GET_CM_OBJECT_ID (CmObjectId)) { | |
case EStdObjCfgMgrInfo: | |
Status = HandleCmObject ( | |
CmObjectId, | |
&PlatformRepo->CmInfo, | |
sizeof (PlatformRepo->CmInfo), | |
1, | |
CmObject | |
); | |
break; | |
case EStdObjAcpiTableList: | |
AcpiTableCount = ARRAY_SIZE (PlatformRepo->CmAcpiTableList); | |
// | |
// Get Pci config space information. | |
// | |
Status = DynamicPlatRepoGetObject ( | |
PlatformRepo->DynamicPlatformRepo, | |
CREATE_CM_ARM_OBJECT_ID (EArmObjPciConfigSpaceInfo), | |
CM_NULL_TOKEN, | |
&CmObjDesc | |
); | |
if (Status == EFI_NOT_FOUND) { | |
// | |
// The last 3 tables are for PCIe. If PCIe information is not | |
// present, Kvmtool was launched without the PCIe option. | |
// Therefore, reduce the table count by 3. | |
// | |
AcpiTableCount -= 3; | |
} else if (EFI_ERROR (Status)) { | |
ASSERT_EFI_ERROR (Status); | |
return Status; | |
} | |
// | |
// Get the Gic version. | |
// | |
Status = DynamicPlatRepoGetObject ( | |
PlatformRepo->DynamicPlatformRepo, | |
CREATE_CM_ARM_OBJECT_ID (EArmObjGicDInfo), | |
CM_NULL_TOKEN, | |
&CmObjDesc | |
); | |
if (EFI_ERROR (Status)) { | |
ASSERT_EFI_ERROR (Status); | |
return Status; | |
} | |
if (((CM_ARM_GICD_INFO *)CmObjDesc.Data)->GicVersion < 3) { | |
// | |
// IORT is only required for GicV3/4 | |
// | |
AcpiTableCount -= 1; | |
} | |
Status = HandleCmObject ( | |
CmObjectId, | |
PlatformRepo->CmAcpiTableList, | |
(sizeof (PlatformRepo->CmAcpiTableList[0]) * AcpiTableCount), | |
AcpiTableCount, | |
CmObject | |
); | |
break; | |
default: | |
Status = EFI_NOT_FOUND; | |
DEBUG (( | |
DEBUG_ERROR, | |
"ERROR: CmObjectId " FMT_CM_OBJECT_ID ". Status = %r\n", | |
CmObjectId, | |
Status | |
)); | |
break; | |
} | |
return Status; | |
} | |
/** | |
Return an ARM namespace object. | |
@param [in] This Pointer to the Configuration Manager Protocol. | |
@param [in] CmObjectId The Configuration Manager Object ID. | |
@param [in] Token An optional token identifying the object. If | |
unused this must be CM_NULL_TOKEN. | |
@param [in, out] CmObject Pointer to the Configuration Manager Object | |
descriptor describing the requested Object. | |
@retval EFI_SUCCESS Success. | |
@retval EFI_INVALID_PARAMETER A parameter is invalid. | |
@retval EFI_NOT_FOUND The required object information is not found. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
GetArmNameSpaceObject ( | |
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST This, | |
IN CONST CM_OBJECT_ID CmObjectId, | |
IN CONST CM_OBJECT_TOKEN Token OPTIONAL, | |
IN OUT CM_OBJ_DESCRIPTOR *CONST CmObject | |
) | |
{ | |
EFI_STATUS Status; | |
EDKII_PLATFORM_REPOSITORY_INFO *PlatformRepo; | |
if ((This == NULL) || (CmObject == NULL)) { | |
ASSERT (This != NULL); | |
ASSERT (CmObject != NULL); | |
return EFI_INVALID_PARAMETER; | |
} | |
Status = EFI_NOT_FOUND; | |
PlatformRepo = This->PlatRepoInfo; | |
// | |
// First check among the static objects. | |
// | |
switch (GET_CM_OBJECT_ID (CmObjectId)) { | |
case EArmObjPowerManagementProfileInfo: | |
Status = HandleCmObject ( | |
CmObjectId, | |
&PlatformRepo->PmProfileInfo, | |
sizeof (PlatformRepo->PmProfileInfo), | |
1, | |
CmObject | |
); | |
break; | |
case EArmObjItsGroup: | |
Status = HandleCmObject ( | |
CmObjectId, | |
&PlatformRepo->ItsGroupInfo, | |
sizeof (PlatformRepo->ItsGroupInfo), | |
1, | |
CmObject | |
); | |
break; | |
case EArmObjGicItsIdentifierArray: | |
Status = HandleCmObjectRefByToken ( | |
This, | |
CmObjectId, | |
PlatformRepo->ItsIdentifierArray, | |
sizeof (PlatformRepo->ItsIdentifierArray), | |
ARRAY_SIZE (PlatformRepo->ItsIdentifierArray), | |
Token, | |
GetItsIdentifierArray, | |
CmObject | |
); | |
break; | |
case EArmObjRootComplex: | |
Status = HandleCmObject ( | |
CmObjectId, | |
&PlatformRepo->RootComplexInfo, | |
sizeof (PlatformRepo->RootComplexInfo), | |
1, | |
CmObject | |
); | |
break; | |
case EArmObjIdMappingArray: | |
Status = HandleCmObjectRefByToken ( | |
This, | |
CmObjectId, | |
PlatformRepo->DeviceIdMapping, | |
sizeof (PlatformRepo->DeviceIdMapping), | |
ARRAY_SIZE (PlatformRepo->DeviceIdMapping), | |
Token, | |
GetDeviceIdMappingArray, | |
CmObject | |
); | |
break; | |
default: | |
// | |
// No match found among the static objects. | |
// Check the dynamic objects. | |
// | |
Status = DynamicPlatRepoGetObject ( | |
PlatformRepo->DynamicPlatformRepo, | |
CmObjectId, | |
Token, | |
CmObject | |
); | |
break; | |
} // switch | |
if (Status == EFI_NOT_FOUND) { | |
DEBUG (( | |
DEBUG_INFO, | |
"INFO: CmObjectId " FMT_CM_OBJECT_ID ". Status = %r\n", | |
CmObjectId, | |
Status | |
)); | |
} else { | |
ASSERT_EFI_ERROR (Status); | |
} | |
return Status; | |
} | |
/** | |
Return an OEM namespace object. | |
@param [in] This Pointer to the Configuration Manager Protocol. | |
@param [in] CmObjectId The Configuration Manager Object ID. | |
@param [in] Token An optional token identifying the object. If | |
unused this must be CM_NULL_TOKEN. | |
@param [in, out] CmObject Pointer to the Configuration Manager Object | |
descriptor describing the requested Object. | |
@retval EFI_SUCCESS Success. | |
@retval EFI_INVALID_PARAMETER A parameter is invalid. | |
@retval EFI_NOT_FOUND The required object information is not found. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
GetOemNameSpaceObject ( | |
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST This, | |
IN CONST CM_OBJECT_ID CmObjectId, | |
IN CONST CM_OBJECT_TOKEN Token OPTIONAL, | |
IN OUT CM_OBJ_DESCRIPTOR *CONST CmObject | |
) | |
{ | |
EFI_STATUS Status; | |
Status = EFI_SUCCESS; | |
if ((This == NULL) || (CmObject == NULL)) { | |
ASSERT (This != NULL); | |
ASSERT (CmObject != NULL); | |
return EFI_INVALID_PARAMETER; | |
} | |
switch (GET_CM_OBJECT_ID (CmObjectId)) { | |
default: | |
Status = EFI_NOT_FOUND; | |
DEBUG (( | |
DEBUG_ERROR, | |
"ERROR: CmObjectId " FMT_CM_OBJECT_ID ". Status = %r\n", | |
CmObjectId, | |
Status | |
)); | |
break; | |
} | |
return Status; | |
} | |
/** | |
The GetObject function defines the interface implemented by the | |
Configuration Manager Protocol for returning the Configuration | |
Manager Objects. | |
@param [in] This Pointer to the Configuration Manager Protocol. | |
@param [in] CmObjectId The Configuration Manager Object ID. | |
@param [in] Token An optional token identifying the object. If | |
unused this must be CM_NULL_TOKEN. | |
@param [in, out] CmObject Pointer to the Configuration Manager Object | |
descriptor describing the requested Object. | |
@retval EFI_SUCCESS Success. | |
@retval EFI_INVALID_PARAMETER A parameter is invalid. | |
@retval EFI_NOT_FOUND The required object information is not found. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
ArmKvmtoolPlatformGetObject ( | |
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST This, | |
IN CONST CM_OBJECT_ID CmObjectId, | |
IN CONST CM_OBJECT_TOKEN Token OPTIONAL, | |
IN OUT CM_OBJ_DESCRIPTOR *CONST CmObject | |
) | |
{ | |
EFI_STATUS Status; | |
if ((This == NULL) || (CmObject == NULL)) { | |
ASSERT (This != NULL); | |
ASSERT (CmObject != NULL); | |
return EFI_INVALID_PARAMETER; | |
} | |
switch (GET_CM_NAMESPACE_ID (CmObjectId)) { | |
case EObjNameSpaceStandard: | |
Status = GetStandardNameSpaceObject (This, CmObjectId, Token, CmObject); | |
break; | |
case EObjNameSpaceArm: | |
Status = GetArmNameSpaceObject (This, CmObjectId, Token, CmObject); | |
break; | |
case EObjNameSpaceOem: | |
Status = GetOemNameSpaceObject (This, CmObjectId, Token, CmObject); | |
break; | |
default: | |
Status = EFI_INVALID_PARAMETER; | |
DEBUG (( | |
DEBUG_ERROR, | |
"ERROR: Unknown Namespace CmObjectId " FMT_CM_OBJECT_ID ". " | |
"Status = %r\n", | |
CmObjectId, | |
Status | |
)); | |
break; | |
} | |
return Status; | |
} | |
/** | |
The SetObject function defines the interface implemented by the | |
Configuration Manager Protocol for updating the Configuration | |
Manager Objects. | |
@param [in] This Pointer to the Configuration Manager Protocol. | |
@param [in] CmObjectId The Configuration Manager Object ID. | |
@param [in] Token An optional token identifying the object. If | |
unused this must be CM_NULL_TOKEN. | |
@param [in] CmObject Pointer to the Configuration Manager Object | |
descriptor describing the Object. | |
@retval EFI_UNSUPPORTED This operation is not supported. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
ArmKvmtoolPlatformSetObject ( | |
IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST This, | |
IN CONST CM_OBJECT_ID CmObjectId, | |
IN CONST CM_OBJECT_TOKEN Token OPTIONAL, | |
IN CM_OBJ_DESCRIPTOR *CONST CmObject | |
) | |
{ | |
return EFI_UNSUPPORTED; | |
} | |
// | |
// A structure describing the configuration manager protocol interface. | |
// | |
STATIC | |
CONST | |
EDKII_CONFIGURATION_MANAGER_PROTOCOL mKvmtoolPlatformConfigManagerProtocol = { | |
CREATE_REVISION (1, 0), | |
ArmKvmtoolPlatformGetObject, | |
ArmKvmtoolPlatformSetObject, | |
&mKvmtoolPlatRepositoryInfo | |
}; | |
/** | |
Entrypoint of Configuration Manager Dxe. | |
@param ImageHandle | |
@param SystemTable | |
@retval EFI_SUCCESS | |
@retval EFI_LOAD_ERROR | |
@retval EFI_OUT_OF_RESOURCES | |
**/ | |
EFI_STATUS | |
EFIAPI | |
ConfigurationManagerDxeInitialize ( | |
IN EFI_HANDLE ImageHandle, | |
IN EFI_SYSTEM_TABLE *SystemTable | |
) | |
{ | |
EFI_STATUS Status; | |
Status = gBS->InstallProtocolInterface ( | |
&ImageHandle, | |
&gEdkiiConfigurationManagerProtocolGuid, | |
EFI_NATIVE_INTERFACE, | |
(VOID *)&mKvmtoolPlatformConfigManagerProtocol | |
); | |
if (EFI_ERROR (Status)) { | |
DEBUG (( | |
DEBUG_ERROR, | |
"ERROR: Failed to get Install Configuration Manager Protocol." \ | |
" Status = %r\n", | |
Status | |
)); | |
return Status; | |
} | |
Status = InitializePlatformRepository ( | |
&mKvmtoolPlatformConfigManagerProtocol | |
); | |
if (EFI_ERROR (Status)) { | |
DEBUG (( | |
DEBUG_ERROR, | |
"ERROR: Failed to initialize the Platform Configuration Repository." \ | |
" Status = %r\n", | |
Status | |
)); | |
goto ErrorHandler; | |
} | |
return Status; | |
ErrorHandler: | |
gBS->UninstallProtocolInterface ( | |
&ImageHandle, | |
&gEdkiiConfigurationManagerProtocolGuid, | |
(VOID *)&mKvmtoolPlatformConfigManagerProtocol | |
); | |
return Status; | |
} | |
/** | |
Unload function for this image. | |
@param ImageHandle Handle for the image of this driver. | |
@retval EFI_SUCCESS Driver unloaded successfully. | |
@retval other Driver can not unloaded. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
ConfigurationManagerDxeUnloadImage ( | |
IN EFI_HANDLE ImageHandle | |
) | |
{ | |
return CleanupPlatformRepository (&mKvmtoolPlatformConfigManagerProtocol); | |
} |