|
@@ -0,0 +1,1065 @@
|
|
|
+/** @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,
|
|
|
+ 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);
|
|
|
+}
|