2 Provides FMP capsule dependency check services when updating the firmware
5 Copyright (c) Microsoft Corporation.<BR>
6 Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
8 SPDX-License-Identifier: BSD-2-Clause-Patent
12 #include <Library/BaseLib.h>
13 #include <Library/BaseMemoryLib.h>
14 #include <Library/DebugLib.h>
15 #include <Library/FmpDependencyLib.h>
16 #include <Library/FmpDependencyCheckLib.h>
17 #include <Library/MemoryAllocationLib.h>
18 #include <Library/UefiLib.h>
19 #include <Library/UefiBootServicesTableLib.h>
20 #include <Guid/SystemResourceTable.h>
21 #include <LastAttemptStatus.h>
22 #include <FmpLastAttemptStatus.h>
25 Check dependency for firmware update.
27 @param[in] ImageTypeId Image Type Id.
28 @param[in] Version New version.
29 @param[in] Dependencies Fmp dependency.
30 @param[in] DependenciesSize Size, in bytes, of the Fmp dependency.
31 @param[out] LastAttemptStatus An optional pointer to a UINT32 that holds the
32 last attempt status to report back to the caller.
33 This function will set the value to LAST_ATTEMPT_STATUS_SUCCESS
34 if an error code is not set.
36 @retval TRUE Dependencies are satisfied.
37 @retval FALSE Dependencies are unsatisfied or dependency check fails.
43 IN EFI_GUID ImageTypeId
,
45 IN EFI_FIRMWARE_IMAGE_DEP
*Dependencies OPTIONAL
,
46 IN UINT32 DependenciesSize
,
47 OUT UINT32
*LastAttemptStatus OPTIONAL
51 EFI_HANDLE
*HandleBuffer
;
53 EFI_FIRMWARE_MANAGEMENT_PROTOCOL
*Fmp
;
55 UINT32 LocalLastAttemptStatus
;
56 UINT32
*DescriptorVer
;
57 UINT8 FmpImageInfoCount
;
58 UINTN
*DescriptorSize
;
59 UINT32 PackageVersion
;
60 CHAR16
*PackageVersionName
;
61 UINTN NumberOfFmpInstance
;
62 EFI_FIRMWARE_IMAGE_DESCRIPTOR
**FmpImageInfoBuf
;
63 FMP_DEPEX_CHECK_VERSION_DATA
*FmpVersions
;
64 UINTN FmpVersionsCount
;
67 LocalLastAttemptStatus
= LAST_ATTEMPT_STATUS_SUCCESS
;
68 FmpImageInfoBuf
= NULL
;
70 DescriptorSize
= NULL
;
71 NumberOfFmpInstance
= 0;
75 PackageVersionName
= NULL
;
78 // Get ImageDescriptors of all FMP instances, and archive them for dependency evaluation.
80 Status
= gBS
->LocateHandleBuffer (
82 &gEfiFirmwareManagementProtocolGuid
,
87 if (EFI_ERROR (Status
)) {
88 DEBUG ((DEBUG_ERROR
, "CheckFmpDependency: Get Firmware Management Protocol failed. (%r)", Status
));
90 LocalLastAttemptStatus
= LAST_ATTEMPT_STATUS_DEPENDENCY_CHECK_LIB_ERROR_FMP_PROTOCOL_NOT_FOUND
;
94 FmpImageInfoBuf
= AllocateZeroPool (sizeof(EFI_FIRMWARE_IMAGE_DESCRIPTOR
*) * NumberOfFmpInstance
);
95 if (FmpImageInfoBuf
== NULL
) {
97 LocalLastAttemptStatus
= LAST_ATTEMPT_STATUS_DEPENDENCY_CHECK_LIB_ERROR_MEM_ALLOC_FMP_INFO_BUFFER_FAILED
;
101 DescriptorVer
= AllocateZeroPool (sizeof(UINT32
) * NumberOfFmpInstance
);
102 if (DescriptorVer
== NULL
) {
104 LocalLastAttemptStatus
= LAST_ATTEMPT_STATUS_DEPENDENCY_CHECK_LIB_ERROR_MEM_ALLOC_DESC_VER_BUFFER_FAILED
;
108 DescriptorSize
= AllocateZeroPool (sizeof(UINTN
) * NumberOfFmpInstance
);
109 if (DescriptorSize
== NULL
) {
111 LocalLastAttemptStatus
= LAST_ATTEMPT_STATUS_DEPENDENCY_CHECK_LIB_ERROR_MEM_ALLOC_DESC_SIZE_BUFFER_FAILED
;
115 FmpVersions
= AllocateZeroPool (sizeof(FMP_DEPEX_CHECK_VERSION_DATA
) * NumberOfFmpInstance
);
116 if (FmpVersions
== NULL
) {
118 LocalLastAttemptStatus
= LAST_ATTEMPT_STATUS_DEPENDENCY_CHECK_LIB_ERROR_MEM_ALLOC_FMP_VER_BUFFER_FAILED
;
122 for (Index
= 0; Index
< NumberOfFmpInstance
; Index
++) {
123 Status
= gBS
->HandleProtocol (
125 &gEfiFirmwareManagementProtocolGuid
,
128 if (EFI_ERROR(Status
)) {
133 Status
= Fmp
->GetImageInfo (
143 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
147 FmpImageInfoBuf
[Index
] = AllocateZeroPool (ImageInfoSize
);
148 if (FmpImageInfoBuf
[Index
] == NULL
) {
152 Status
= Fmp
->GetImageInfo (
154 &ImageInfoSize
, // ImageInfoSize
155 FmpImageInfoBuf
[Index
], // ImageInfo
156 &DescriptorVer
[Index
], // DescriptorVersion
157 &FmpImageInfoCount
, // DescriptorCount
158 &DescriptorSize
[Index
], // DescriptorSize
159 &PackageVersion
, // PackageVersion
160 &PackageVersionName
// PackageVersionName
162 if (EFI_ERROR(Status
)) {
163 FreePool (FmpImageInfoBuf
[Index
]);
164 FmpImageInfoBuf
[Index
] = NULL
;
168 if (PackageVersionName
!= NULL
) {
169 FreePool (PackageVersionName
);
170 PackageVersionName
= NULL
;
173 CopyGuid (&FmpVersions
[FmpVersionsCount
].ImageTypeId
, &FmpImageInfoBuf
[Index
]->ImageTypeId
);
174 FmpVersions
[FmpVersionsCount
].Version
= FmpImageInfoBuf
[Index
]->Version
;
179 // Evaluate firmware image's depex, against the version of other Fmp instances.
181 if (Dependencies
!= NULL
) {
182 IsSatisfied
= EvaluateDependency (Dependencies
, DependenciesSize
, FmpVersions
, FmpVersionsCount
, &LocalLastAttemptStatus
);
186 DEBUG ((DEBUG_ERROR
, "CheckFmpDependency: %g\'s dependency is not satisfied!\n", ImageTypeId
));
191 if (FmpImageInfoBuf
!= NULL
) {
192 for (Index
= 0; Index
< NumberOfFmpInstance
; Index
++) {
193 if (FmpImageInfoBuf
[Index
] != NULL
) {
194 FreePool (FmpImageInfoBuf
[Index
]);
197 FreePool (FmpImageInfoBuf
);
200 if (DescriptorVer
!= NULL
) {
201 FreePool (DescriptorVer
);
204 if (DescriptorSize
!= NULL
) {
205 FreePool (DescriptorSize
);
208 if (FmpVersions
!= NULL
) {
209 FreePool (FmpVersions
);
212 if (LastAttemptStatus
!= NULL
) {
213 *LastAttemptStatus
= LocalLastAttemptStatus
;