mirror of
				https://gitlab.com/qemu-project/edk2.git
				synced 2025-10-30 07:56:39 +08:00 
			
		
		
		
	FmpDevicePkg: Add FmpDependencyCheck library class and instances
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2696 * This library class provides platform specific services to support dependency check during updating firmware image. Platform can perform dependency check in platform specific manner by implementing its own FmpDependencyCheckLib. * Add FmpDependencyCheck instance to provide a sample of dependency check. The sample instance only checks the dependency from capsule image. The dependency from other FMP instances isn't checked here. * Add NULL instance as an option to skip the dependency check. Cc: Michael D Kinney <michael.d.kinney@intel.com> Cc: Liming Gao <liming.gao@intel.com> Cc: Sean Brogan <sean.brogan@microsoft.com> Signed-off-by: Wei6 Xu <wei6.xu@intel.com> Reviewed-by: Sean Brogan <sean.brogan@microsoft.com> Reviewed-by: Liming Gao <liming.gao@intel.com>
This commit is contained in:
		| @ -39,6 +39,10 @@ | ||||
|   #                  expression evaluation. | ||||
|   FmpDependencyLib|Include/Library/FmpDependencyLib.h | ||||
|  | ||||
|   ##  @libraryclass  Provides platform specific services to support dependency | ||||
|   #                  check during update of firmware image. | ||||
|   FmpDependencyCheckLib|Include/Library/FmpDependencyCheckLib.h | ||||
|  | ||||
| [LibraryClasses.Common.Private] | ||||
|   ##  @libraryclass  Provides services to retrieve values from a capsule's FMP | ||||
|   #                  Payload Header.  The structure is not included in the | ||||
|  | ||||
| @ -63,6 +63,7 @@ | ||||
|   FmpPayloadHeaderLib|FmpDevicePkg/Library/FmpPayloadHeaderLibV1/FmpPayloadHeaderLibV1.inf | ||||
|   FmpDeviceLib|FmpDevicePkg/Library/FmpDeviceLibNull/FmpDeviceLibNull.inf | ||||
|   FmpDependencyLib|FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.inf | ||||
|   FmpDependencyCheckLib|FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.inf | ||||
|   TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf | ||||
|  | ||||
| [LibraryClasses.ARM, LibraryClasses.AARCH64] | ||||
| @ -92,6 +93,8 @@ | ||||
|   FmpDevicePkg/Library/FmpPayloadHeaderLibV1/FmpPayloadHeaderLibV1.inf | ||||
|   FmpDevicePkg/Library/FmpDeviceLibNull/FmpDeviceLibNull.inf | ||||
|   FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.inf | ||||
|   FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.inf | ||||
|   FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.inf | ||||
|   FmpDevicePkg/FmpDxe/FmpDxeLib.inf | ||||
|  | ||||
|   # | ||||
|  | ||||
							
								
								
									
										38
									
								
								FmpDevicePkg/Include/Library/FmpDependencyCheckLib.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								FmpDevicePkg/Include/Library/FmpDependencyCheckLib.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | ||||
| /** @file | ||||
|   Fmp Capsule Dependency check functions for Firmware Management Protocol based | ||||
|   firmware updates. | ||||
|  | ||||
|   Copyright (c) 2020, Intel Corporation. All rights reserved.<BR> | ||||
|  | ||||
|   SPDX-License-Identifier: BSD-2-Clause-Patent | ||||
|  | ||||
| **/ | ||||
|  | ||||
| #ifndef __FMP_DEPENDENCY_CHECK_LIB__ | ||||
| #define __FMP_DEPENDENCY_CHECK_LIB__ | ||||
|  | ||||
| #include <PiDxe.h> | ||||
| #include <Protocol/FirmwareManagement.h> | ||||
|  | ||||
| /** | ||||
|   Check dependency for firmware update. | ||||
|  | ||||
|   @param[in]  ImageTypeId        Image Type Id. | ||||
|   @param[in]  Version            New version. | ||||
|   @param[in]  Dependencies       Fmp dependency. | ||||
|   @param[in]  DependenciesSize   Size, in bytes, of the Fmp dependency. | ||||
|  | ||||
|   @retval  TRUE    Dependencies are satisfied. | ||||
|   @retval  FALSE   Dependencies are unsatisfied or dependency check fails. | ||||
|  | ||||
| **/ | ||||
| BOOLEAN | ||||
| EFIAPI | ||||
| CheckFmpDependency ( | ||||
|   IN  EFI_GUID                ImageTypeId, | ||||
|   IN  UINT32                  Version, | ||||
|   IN  EFI_FIRMWARE_IMAGE_DEP  *Dependencies,    OPTIONAL | ||||
|   IN  UINT32                  DependenciesSize | ||||
|   ); | ||||
|  | ||||
| #endif | ||||
| @ -0,0 +1,196 @@ | ||||
| /** @file | ||||
|   Provides FMP capsule dependency check services when updating the firmware | ||||
|   image of a FMP device. | ||||
|  | ||||
|   Copyright (c) 2020, Intel Corporation. All rights reserved.<BR> | ||||
|  | ||||
|   SPDX-License-Identifier: BSD-2-Clause-Patent | ||||
|  | ||||
| **/ | ||||
| #include <PiDxe.h> | ||||
| #include <Library/BaseLib.h> | ||||
| #include <Library/BaseMemoryLib.h> | ||||
| #include <Library/DebugLib.h> | ||||
| #include <Library/FmpDependencyLib.h> | ||||
| #include <Library/FmpDependencyCheckLib.h> | ||||
| #include <Library/MemoryAllocationLib.h> | ||||
| #include <Library/UefiLib.h> | ||||
| #include <Library/UefiBootServicesTableLib.h> | ||||
|  | ||||
| /** | ||||
|   Check dependency for firmware update. | ||||
|  | ||||
|   @param[in]  ImageTypeId        Image Type Id. | ||||
|   @param[in]  Version            New version. | ||||
|   @param[in]  Dependencies       Fmp dependency. | ||||
|   @param[in]  DependenciesSize   Size, in bytes, of the Fmp dependency. | ||||
|  | ||||
|   @retval  TRUE    Dependencies are satisfied. | ||||
|   @retval  FALSE   Dependencies are unsatisfied or dependency check fails. | ||||
|  | ||||
| **/ | ||||
| BOOLEAN | ||||
| EFIAPI | ||||
| CheckFmpDependency ( | ||||
|   IN  EFI_GUID                ImageTypeId, | ||||
|   IN  UINT32                  Version, | ||||
|   IN  EFI_FIRMWARE_IMAGE_DEP  *Dependencies,    OPTIONAL | ||||
|   IN  UINT32                  DependenciesSize | ||||
|   ) | ||||
| { | ||||
|   EFI_STATUS                        Status; | ||||
|   EFI_HANDLE                        *HandleBuffer; | ||||
|   UINTN                             Index; | ||||
|   EFI_FIRMWARE_MANAGEMENT_PROTOCOL  *Fmp; | ||||
|   UINTN                             ImageInfoSize; | ||||
|   UINT32                            *DescriptorVer; | ||||
|   UINT8                             FmpImageInfoCount; | ||||
|   UINTN                             *DescriptorSize; | ||||
|   UINT32                            PackageVersion; | ||||
|   CHAR16                            *PackageVersionName; | ||||
|   UINTN                             NumberOfFmpInstance; | ||||
|   EFI_FIRMWARE_IMAGE_DESCRIPTOR     **FmpImageInfoBuf; | ||||
|   FMP_DEPEX_CHECK_VERSION_DATA      *FmpVersions; | ||||
|   UINTN                             FmpVersionsCount; | ||||
|   BOOLEAN                           IsSatisfied; | ||||
|  | ||||
|   FmpImageInfoBuf     = NULL; | ||||
|   DescriptorVer       = NULL; | ||||
|   DescriptorSize      = NULL; | ||||
|   NumberOfFmpInstance = 0; | ||||
|   FmpVersions         = NULL; | ||||
|   FmpVersionsCount    = 0; | ||||
|   IsSatisfied         = TRUE; | ||||
|   PackageVersionName  = NULL; | ||||
|  | ||||
|   // | ||||
|   // Get ImageDescriptors of all FMP instances, and archive them for dependency evaluation. | ||||
|   // | ||||
|   Status = gBS->LocateHandleBuffer ( | ||||
|                 ByProtocol, | ||||
|                 &gEfiFirmwareManagementProtocolGuid, | ||||
|                 NULL, | ||||
|                 &NumberOfFmpInstance, | ||||
|                 &HandleBuffer | ||||
|                 ); | ||||
|   if (EFI_ERROR (Status)) { | ||||
|     DEBUG ((DEBUG_ERROR, "CheckFmpDependency: Get Firmware Management Protocol failed. (%r)", Status)); | ||||
|     goto cleanup; | ||||
|   } | ||||
|  | ||||
|   FmpImageInfoBuf = AllocateZeroPool (sizeof(EFI_FIRMWARE_IMAGE_DESCRIPTOR *) * NumberOfFmpInstance); | ||||
|   if (FmpImageInfoBuf == NULL) { | ||||
|     IsSatisfied = FALSE; | ||||
|     goto cleanup; | ||||
|   } | ||||
|  | ||||
|   DescriptorVer = AllocateZeroPool (sizeof(UINT32) * NumberOfFmpInstance); | ||||
|   if (DescriptorVer == NULL ) { | ||||
|     IsSatisfied = FALSE; | ||||
|     goto cleanup; | ||||
|   } | ||||
|  | ||||
|   DescriptorSize = AllocateZeroPool (sizeof(UINTN) * NumberOfFmpInstance); | ||||
|   if (DescriptorSize == NULL ) { | ||||
|     IsSatisfied = FALSE; | ||||
|     goto cleanup; | ||||
|   } | ||||
|  | ||||
|   FmpVersions = AllocateZeroPool (sizeof(FMP_DEPEX_CHECK_VERSION_DATA) * NumberOfFmpInstance); | ||||
|   if (FmpVersions == NULL) { | ||||
|     IsSatisfied = FALSE; | ||||
|     goto cleanup; | ||||
|   } | ||||
|  | ||||
|   for (Index = 0; Index < NumberOfFmpInstance; Index ++) { | ||||
|     Status = gBS->HandleProtocol ( | ||||
|                     HandleBuffer[Index], | ||||
|                     &gEfiFirmwareManagementProtocolGuid, | ||||
|                     (VOID **) &Fmp | ||||
|                     ); | ||||
|     if (EFI_ERROR(Status)) { | ||||
|       continue; | ||||
|     } | ||||
|  | ||||
|     ImageInfoSize = 0; | ||||
|     Status = Fmp->GetImageInfo ( | ||||
|                     Fmp, | ||||
|                     &ImageInfoSize, | ||||
|                     NULL, | ||||
|                     NULL, | ||||
|                     NULL, | ||||
|                     NULL, | ||||
|                     NULL, | ||||
|                     NULL | ||||
|                     ); | ||||
|     if (Status != EFI_BUFFER_TOO_SMALL) { | ||||
|       continue; | ||||
|     } | ||||
|  | ||||
|     FmpImageInfoBuf[Index] = AllocateZeroPool (ImageInfoSize); | ||||
|     if (FmpImageInfoBuf[Index] == NULL) { | ||||
|       continue; | ||||
|     } | ||||
|  | ||||
|     Status = Fmp->GetImageInfo ( | ||||
|                     Fmp, | ||||
|                     &ImageInfoSize,               // ImageInfoSize | ||||
|                     FmpImageInfoBuf[Index],       // ImageInfo | ||||
|                     &DescriptorVer[Index],        // DescriptorVersion | ||||
|                     &FmpImageInfoCount,           // DescriptorCount | ||||
|                     &DescriptorSize[Index],       // DescriptorSize | ||||
|                     &PackageVersion,              // PackageVersion | ||||
|                     &PackageVersionName           // PackageVersionName | ||||
|                     ); | ||||
|     if (EFI_ERROR(Status)) { | ||||
|       FreePool (FmpImageInfoBuf[Index]); | ||||
|       FmpImageInfoBuf[Index] = NULL; | ||||
|       continue; | ||||
|     } | ||||
|  | ||||
|     if (PackageVersionName != NULL) { | ||||
|       FreePool (PackageVersionName); | ||||
|       PackageVersionName = NULL; | ||||
|     } | ||||
|  | ||||
|     CopyGuid (&FmpVersions[FmpVersionsCount].ImageTypeId, &FmpImageInfoBuf[Index]->ImageTypeId); | ||||
|     FmpVersions[FmpVersionsCount].Version = FmpImageInfoBuf[Index]->Version; | ||||
|     FmpVersionsCount ++; | ||||
|   } | ||||
|  | ||||
|   // | ||||
|   // Evaluate firmware image's depex, against the version of other Fmp instances. | ||||
|   // | ||||
|   if (Dependencies != NULL) { | ||||
|     IsSatisfied = EvaluateDependency (Dependencies, DependenciesSize, FmpVersions, FmpVersionsCount); | ||||
|   } | ||||
|  | ||||
|   if (!IsSatisfied) { | ||||
|     DEBUG ((DEBUG_ERROR, "CheckFmpDependency: %g\'s dependency is not satisfied!\n", ImageTypeId)); | ||||
|     goto cleanup; | ||||
|   } | ||||
|  | ||||
| cleanup: | ||||
|   if (FmpImageInfoBuf != NULL) { | ||||
|     for (Index = 0; Index < NumberOfFmpInstance; Index ++) { | ||||
|       if (FmpImageInfoBuf[Index] != NULL) { | ||||
|         FreePool (FmpImageInfoBuf[Index]); | ||||
|       } | ||||
|     } | ||||
|     FreePool (FmpImageInfoBuf); | ||||
|   } | ||||
|  | ||||
|   if (DescriptorVer != NULL) { | ||||
|     FreePool (DescriptorVer); | ||||
|   } | ||||
|  | ||||
|   if (DescriptorSize != NULL) { | ||||
|     FreePool (DescriptorSize); | ||||
|   } | ||||
|  | ||||
|   if (FmpVersions != NULL) { | ||||
|     FreePool (FmpVersions); | ||||
|   } | ||||
|  | ||||
|   return IsSatisfied; | ||||
| } | ||||
| @ -0,0 +1,43 @@ | ||||
| ## @file | ||||
| #  Provides FMP capsule dependency check services when updating the firmware | ||||
| #  image of a FMP device. | ||||
| # | ||||
| #  Copyright (c) 2020, Intel Corporation. All rights reserved.<BR> | ||||
| # | ||||
| #  SPDX-License-Identifier: BSD-2-Clause-Patent | ||||
| ## | ||||
|  | ||||
| [Defines] | ||||
|   INF_VERSION     = 0x00010005 | ||||
|   BASE_NAME       = FmpDependencyCheckLib | ||||
|   MODULE_UNI_FILE = FmpDependencyCheckLib.uni | ||||
|   FILE_GUID       = 8296D425-3095-4CFE-88D8-B0A44DB174A8 | ||||
|   MODULE_TYPE     = DXE_DRIVER | ||||
|   VERSION_STRING  = 1.0 | ||||
|   LIBRARY_CLASS   = FmpDependencyCheckLib|DXE_DRIVER UEFI_DRIVER UEFI_APPLICATION | ||||
|  | ||||
| # | ||||
| # The following information is for reference only and not required by the build tools. | ||||
| # | ||||
| #  VALID_ARCHITECTURES           = IA32 X64 ARM AARCH64 | ||||
| # | ||||
|  | ||||
| [Sources] | ||||
|   FmpDependencyCheckLib.c | ||||
|  | ||||
| [Packages] | ||||
|   MdePkg/MdePkg.dec | ||||
|   MdeModulePkg/MdeModulePkg.dec | ||||
|   FmpDevicePkg/FmpDevicePkg.dec | ||||
|  | ||||
| [LibraryClasses] | ||||
|   BaseLib | ||||
|   BaseMemoryLib | ||||
|   DebugLib | ||||
|   FmpDependencyLib | ||||
|   MemoryAllocationLib | ||||
|   UefiLib | ||||
|   UefiBootServicesTableLib | ||||
|  | ||||
| [Protocols] | ||||
|   gEfiFirmwareManagementProtocolGuid  ## CONSUMES | ||||
| @ -0,0 +1,13 @@ | ||||
| // /** @file | ||||
| // Provides FMP capsule dependency check services when updating the firmware | ||||
| // image of a FMP device. | ||||
| // | ||||
| // Copyright (c) 2020, Intel Corporation. All rights reserved.<BR> | ||||
| // | ||||
| // SPDX-License-Identifier: BSD-2-Clause-Patent | ||||
| // | ||||
| // **/ | ||||
|  | ||||
| #string STR_MODULE_ABSTRACT     #language en-US  "FMP Dependency Check Lib" | ||||
|  | ||||
| #string STR_MODULE_DESCRIPTION  #language en-US  "Provides FMP capsule dependency check services when updating the firmware image of a FMP device." | ||||
| @ -0,0 +1,34 @@ | ||||
| /** @file | ||||
|   Null instance of FmpDependencyCheckLib. | ||||
|  | ||||
|   Copyright (c) 2020, Intel Corporation. All rights reserved.<BR> | ||||
|  | ||||
|   SPDX-License-Identifier: BSD-2-Clause-Patent | ||||
|  | ||||
| **/ | ||||
| #include <PiDxe.h> | ||||
| #include <Library/FmpDependencyCheckLib.h> | ||||
|  | ||||
| /** | ||||
|   Check dependency for firmware update. | ||||
|  | ||||
|   @param[in]  ImageTypeId        Image Type Id. | ||||
|   @param[in]  Version            New version. | ||||
|   @param[in]  Dependencies       Fmp dependency. | ||||
|   @param[in]  DependenciesSize   Size, in bytes, of the Fmp dependency. | ||||
|  | ||||
|   @retval  TRUE    Dependencies are satisfied. | ||||
|   @retval  FALSE   Dependencies are unsatisfied or dependency check fails. | ||||
|  | ||||
| **/ | ||||
| BOOLEAN | ||||
| EFIAPI | ||||
| CheckFmpDependency ( | ||||
|   IN  EFI_GUID                ImageTypeId, | ||||
|   IN  UINT32                  Version, | ||||
|   IN  EFI_FIRMWARE_IMAGE_DEP  *Dependencies,    OPTIONAL | ||||
|   IN  UINT32                  DependenciesSize | ||||
|   ) | ||||
| { | ||||
|   return TRUE; | ||||
| } | ||||
| @ -0,0 +1,30 @@ | ||||
| ## @file | ||||
| #  Null instance of FmpDependencyCheckLib as an option to skip the dependency | ||||
| #  check when updating the firmware image of a FMP device. | ||||
| # | ||||
| #  Copyright (c) 2020, Intel Corporation. All rights reserved.<BR> | ||||
| # | ||||
| #  SPDX-License-Identifier: BSD-2-Clause-Patent | ||||
| ## | ||||
|  | ||||
| [Defines] | ||||
|   INF_VERSION     = 0x00010005 | ||||
|   BASE_NAME       = FmpDependencyCheckLibNull | ||||
|   MODULE_UNI_FILE = FmpDependencyCheckLibNull.uni | ||||
|   FILE_GUID       = D63F3166-9CBC-4AC2-8F23-8818E42EA2BD | ||||
|   MODULE_TYPE     = DXE_DRIVER | ||||
|   VERSION_STRING  = 1.0 | ||||
|   LIBRARY_CLASS   = FmpDependencyCheckLib|DXE_DRIVER UEFI_DRIVER UEFI_APPLICATION | ||||
|  | ||||
| # | ||||
| # The following information is for reference only and not required by the build tools. | ||||
| # | ||||
| #  VALID_ARCHITECTURES           = IA32 X64 ARM AARCH64 | ||||
| # | ||||
|  | ||||
| [Sources] | ||||
|   FmpDependencyCheckLibNull.c | ||||
|  | ||||
| [Packages] | ||||
|   MdePkg/MdePkg.dec | ||||
|   FmpDevicePkg/FmpDevicePkg.dec | ||||
| @ -0,0 +1,13 @@ | ||||
| // /** @file | ||||
| // Null instance of FmpDependencyCheckLib as an option to skip the dependency | ||||
| // check when updating the firmware image of a FMP device. | ||||
| // | ||||
| // Copyright (c) 2020, Intel Corporation. All rights reserved.<BR> | ||||
| // | ||||
| // SPDX-License-Identifier: BSD-2-Clause-Patent | ||||
| // | ||||
| // **/ | ||||
|  | ||||
| #string STR_MODULE_ABSTRACT     #language en-US  "FMP Dependency Check Library NULL instance" | ||||
|  | ||||
| #string STR_MODULE_DESCRIPTION  #language en-US  "Null instance of FmpDependencyCheckLib as an option to skip the dependency check when updating the firmware image of a FMP device." | ||||
		Reference in New Issue
	
	Block a user
	 Wei6 Xu
					Wei6 Xu