2 Provides FMP capsule dependency check services when updating the firmware
5 Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
7 SPDX-License-Identifier: BSD-2-Clause-Patent
11 #include <Library/BaseLib.h>
12 #include <Library/BaseMemoryLib.h>
13 #include <Library/DebugLib.h>
14 #include <Library/FmpDependencyLib.h>
15 #include <Library/FmpDependencyCheckLib.h>
16 #include <Library/MemoryAllocationLib.h>
17 #include <Library/UefiLib.h>
18 #include <Library/UefiBootServicesTableLib.h>
21 Check dependency for firmware update.
23 @param[in] ImageTypeId Image Type Id.
24 @param[in] Version New version.
25 @param[in] Dependencies Fmp dependency.
26 @param[in] DependenciesSize Size, in bytes, of the Fmp dependency.
28 @retval TRUE Dependencies are satisfied.
29 @retval FALSE Dependencies are unsatisfied or dependency check fails.
35 IN EFI_GUID ImageTypeId
,
37 IN EFI_FIRMWARE_IMAGE_DEP
*Dependencies
, OPTIONAL
38 IN UINT32 DependenciesSize
42 EFI_HANDLE
*HandleBuffer
;
44 EFI_FIRMWARE_MANAGEMENT_PROTOCOL
*Fmp
;
46 UINT32
*DescriptorVer
;
47 UINT8 FmpImageInfoCount
;
48 UINTN
*DescriptorSize
;
49 UINT32 PackageVersion
;
50 CHAR16
*PackageVersionName
;
51 UINTN NumberOfFmpInstance
;
52 EFI_FIRMWARE_IMAGE_DESCRIPTOR
**FmpImageInfoBuf
;
53 FMP_DEPEX_CHECK_VERSION_DATA
*FmpVersions
;
54 UINTN FmpVersionsCount
;
57 FmpImageInfoBuf
= NULL
;
59 DescriptorSize
= NULL
;
60 NumberOfFmpInstance
= 0;
64 PackageVersionName
= NULL
;
67 // Get ImageDescriptors of all FMP instances, and archive them for dependency evaluation.
69 Status
= gBS
->LocateHandleBuffer (
71 &gEfiFirmwareManagementProtocolGuid
,
76 if (EFI_ERROR (Status
)) {
77 DEBUG ((DEBUG_ERROR
, "CheckFmpDependency: Get Firmware Management Protocol failed. (%r)", Status
));
81 FmpImageInfoBuf
= AllocateZeroPool (sizeof(EFI_FIRMWARE_IMAGE_DESCRIPTOR
*) * NumberOfFmpInstance
);
82 if (FmpImageInfoBuf
== NULL
) {
87 DescriptorVer
= AllocateZeroPool (sizeof(UINT32
) * NumberOfFmpInstance
);
88 if (DescriptorVer
== NULL
) {
93 DescriptorSize
= AllocateZeroPool (sizeof(UINTN
) * NumberOfFmpInstance
);
94 if (DescriptorSize
== NULL
) {
99 FmpVersions
= AllocateZeroPool (sizeof(FMP_DEPEX_CHECK_VERSION_DATA
) * NumberOfFmpInstance
);
100 if (FmpVersions
== NULL
) {
105 for (Index
= 0; Index
< NumberOfFmpInstance
; Index
++) {
106 Status
= gBS
->HandleProtocol (
108 &gEfiFirmwareManagementProtocolGuid
,
111 if (EFI_ERROR(Status
)) {
116 Status
= Fmp
->GetImageInfo (
126 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
130 FmpImageInfoBuf
[Index
] = AllocateZeroPool (ImageInfoSize
);
131 if (FmpImageInfoBuf
[Index
] == NULL
) {
135 Status
= Fmp
->GetImageInfo (
137 &ImageInfoSize
, // ImageInfoSize
138 FmpImageInfoBuf
[Index
], // ImageInfo
139 &DescriptorVer
[Index
], // DescriptorVersion
140 &FmpImageInfoCount
, // DescriptorCount
141 &DescriptorSize
[Index
], // DescriptorSize
142 &PackageVersion
, // PackageVersion
143 &PackageVersionName
// PackageVersionName
145 if (EFI_ERROR(Status
)) {
146 FreePool (FmpImageInfoBuf
[Index
]);
147 FmpImageInfoBuf
[Index
] = NULL
;
151 if (PackageVersionName
!= NULL
) {
152 FreePool (PackageVersionName
);
153 PackageVersionName
= NULL
;
156 CopyGuid (&FmpVersions
[FmpVersionsCount
].ImageTypeId
, &FmpImageInfoBuf
[Index
]->ImageTypeId
);
157 FmpVersions
[FmpVersionsCount
].Version
= FmpImageInfoBuf
[Index
]->Version
;
162 // Evaluate firmware image's depex, against the version of other Fmp instances.
164 if (Dependencies
!= NULL
) {
165 IsSatisfied
= EvaluateDependency (Dependencies
, DependenciesSize
, FmpVersions
, FmpVersionsCount
);
169 DEBUG ((DEBUG_ERROR
, "CheckFmpDependency: %g\'s dependency is not satisfied!\n", ImageTypeId
));
174 if (FmpImageInfoBuf
!= NULL
) {
175 for (Index
= 0; Index
< NumberOfFmpInstance
; Index
++) {
176 if (FmpImageInfoBuf
[Index
] != NULL
) {
177 FreePool (FmpImageInfoBuf
[Index
]);
180 FreePool (FmpImageInfoBuf
);
183 if (DescriptorVer
!= NULL
) {
184 FreePool (DescriptorVer
);
187 if (DescriptorSize
!= NULL
) {
188 FreePool (DescriptorSize
);
191 if (FmpVersions
!= NULL
) {
192 FreePool (FmpVersions
);