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