2 Esrt management implementation.
4 Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
12 Find Esrt Entry stored in ESRT repository.
14 @param[in] FwClass Firmware class guid in Esrt entry
15 @param[in] Attribute Esrt from Non FMP or FMP instance
16 @param[out] Entry Esrt entry returned
18 @retval EFI_SUCCESS Successfully find an Esrt entry
19 @retval EF_NOT_FOUND No Esrt entry found
26 OUT EFI_SYSTEM_RESOURCE_ENTRY
*Entry
31 EFI_SYSTEM_RESOURCE_ENTRY
*EsrtRepository
;
36 EsrtRepository
= NULL
;
39 // Get Esrt index buffer
41 if (Attribute
== ESRT_FROM_FMP
) {
42 VariableName
= EFI_ESRT_FMP_VARIABLE_NAME
;
44 VariableName
= EFI_ESRT_NONFMP_VARIABLE_NAME
;
47 Status
= GetVariable2 (
50 (VOID
**)&EsrtRepository
,
54 if (EFI_ERROR (Status
)) {
58 if (RepositorySize
% sizeof (EFI_SYSTEM_RESOURCE_ENTRY
) != 0) {
59 DEBUG ((DEBUG_ERROR
, "Repository Corrupt. Need to rebuild Repository.\n"));
64 Status
= EFI_NOT_FOUND
;
65 EsrtNum
= RepositorySize
/sizeof (EFI_SYSTEM_RESOURCE_ENTRY
);
66 for (Index
= 0; Index
< EsrtNum
; Index
++) {
67 if (CompareGuid (FwClass
, &EsrtRepository
[Index
].FwClass
)) {
68 CopyMem (Entry
, &EsrtRepository
[Index
], sizeof (EFI_SYSTEM_RESOURCE_ENTRY
));
75 if (EsrtRepository
!= NULL
) {
76 FreePool (EsrtRepository
);
83 Insert a new ESRT entry into ESRT Cache repository.
85 @param[in] Entry Esrt entry to be set
86 @param[in] Attribute Esrt from Esrt private protocol or FMP instance
88 @retval EFI_SUCCESS Successfully set a variable.
93 IN EFI_SYSTEM_RESOURCE_ENTRY
*Entry
,
99 EFI_SYSTEM_RESOURCE_ENTRY
*EsrtRepository
;
100 UINTN RepositorySize
;
101 EFI_SYSTEM_RESOURCE_ENTRY
*EsrtRepositoryNew
;
103 EsrtRepository
= NULL
;
104 EsrtRepositoryNew
= NULL
;
107 // Get Esrt index buffer
109 if (Attribute
== ESRT_FROM_FMP
) {
110 VariableName
= EFI_ESRT_FMP_VARIABLE_NAME
;
112 VariableName
= EFI_ESRT_NONFMP_VARIABLE_NAME
;
115 Status
= GetVariable2 (
118 (VOID
**)&EsrtRepository
,
122 if (Status
== EFI_NOT_FOUND
) {
124 // If not exist, create new Esrt cache repository
126 Status
= gRT
->SetVariable (
129 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
130 sizeof (EFI_SYSTEM_RESOURCE_ENTRY
),
134 } else if (Status
== EFI_SUCCESS
) {
136 // if exist, update Esrt cache repository
138 if (RepositorySize
% sizeof (EFI_SYSTEM_RESOURCE_ENTRY
) != 0) {
139 DEBUG ((DEBUG_ERROR
, "Repository Corrupt. Need to rebuild Repository.\n"));
141 // Repository is corrupt. Clear Repository before insert new entry
143 Status
= gRT
->SetVariable (
146 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
150 FreePool (EsrtRepository
);
152 EsrtRepository
= NULL
;
156 // Check Repository size constraint
158 if ( ((Attribute
== ESRT_FROM_FMP
) && (RepositorySize
>= PcdGet32 (PcdMaxFmpEsrtCacheNum
) * sizeof (EFI_SYSTEM_RESOURCE_ENTRY
)))
159 || ((Attribute
== ESRT_FROM_NONFMP
) && (RepositorySize
>= PcdGet32 (PcdMaxNonFmpEsrtCacheNum
) * sizeof (EFI_SYSTEM_RESOURCE_ENTRY
))))
161 Status
= EFI_OUT_OF_RESOURCES
;
165 EsrtRepositoryNew
= AllocatePool (RepositorySize
+ sizeof (EFI_SYSTEM_RESOURCE_ENTRY
));
166 if (EsrtRepositoryNew
== NULL
) {
167 Status
= EFI_OUT_OF_RESOURCES
;
171 if ((RepositorySize
!= 0) && (EsrtRepository
!= NULL
)) {
172 CopyMem (EsrtRepositoryNew
, EsrtRepository
, RepositorySize
);
175 CopyMem ((UINT8
*)EsrtRepositoryNew
+ RepositorySize
, Entry
, sizeof (EFI_SYSTEM_RESOURCE_ENTRY
));
177 Status
= gRT
->SetVariable (
180 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
181 RepositorySize
+ sizeof (EFI_SYSTEM_RESOURCE_ENTRY
),
187 if (EsrtRepository
!= NULL
) {
188 FreePool (EsrtRepository
);
191 if (EsrtRepositoryNew
!= NULL
) {
192 FreePool (EsrtRepositoryNew
);
199 Delete ESRT Entry from ESRT repository.
201 @param[in] FwClass FwClass of Esrt entry to delete
202 @param[in] Attribute Esrt from Esrt private protocol or FMP instance
204 @retval EFI_SUCCESS Insert all entries Successfully
205 @retval EFI_NOT_FOUND ESRT entry with FwClass doesn't exsit
210 IN EFI_GUID
*FwClass
,
215 CHAR16
*VariableName
;
216 EFI_SYSTEM_RESOURCE_ENTRY
*EsrtRepository
;
217 UINTN RepositorySize
;
221 EsrtRepository
= NULL
;
224 // Get Esrt index buffer
226 if (Attribute
== ESRT_FROM_FMP
) {
227 VariableName
= EFI_ESRT_FMP_VARIABLE_NAME
;
229 VariableName
= EFI_ESRT_NONFMP_VARIABLE_NAME
;
232 Status
= GetVariable2 (
235 (VOID
**)&EsrtRepository
,
239 if (EFI_ERROR (Status
)) {
243 if (EsrtRepository
== NULL
) {
244 Status
= EFI_OUT_OF_RESOURCES
;
248 if ((RepositorySize
% sizeof (EFI_SYSTEM_RESOURCE_ENTRY
)) != 0) {
249 DEBUG ((DEBUG_ERROR
, "Repository Corrupt. Need to rebuild Repository.\n"));
251 // Repository is corrupt. Clear Repository before insert new entry
253 Status
= gRT
->SetVariable (
256 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
263 Status
= EFI_NOT_FOUND
;
264 EsrtNum
= RepositorySize
/sizeof (EFI_SYSTEM_RESOURCE_ENTRY
);
265 for (Index
= 0; Index
< EsrtNum
; Index
++) {
267 // Delete Esrt entry if it is found in repository
269 if (CompareGuid (FwClass
, &EsrtRepository
[Index
].FwClass
)) {
271 // If delete Esrt entry is not at the rail
273 if (Index
< EsrtNum
- 1) {
274 CopyMem (&EsrtRepository
[Index
], &EsrtRepository
[Index
+ 1], (EsrtNum
- Index
- 1) * sizeof (EFI_SYSTEM_RESOURCE_ENTRY
));
278 // Update New Repository
280 Status
= gRT
->SetVariable (
283 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
284 (EsrtNum
- 1) * sizeof (EFI_SYSTEM_RESOURCE_ENTRY
),
292 if (EsrtRepository
!= NULL
) {
293 FreePool (EsrtRepository
);
300 Update one ESRT entry in ESRT repository
302 @param[in] Entry Esrt entry to be set
303 @param[in] Attribute Esrt from Non Esrt or FMP instance
305 @retval EFI_SUCCESS Successfully Update a variable.
306 @retval EFI_NOT_FOUND The Esrt enry doesn't exist
311 IN EFI_SYSTEM_RESOURCE_ENTRY
*Entry
,
316 CHAR16
*VariableName
;
317 EFI_SYSTEM_RESOURCE_ENTRY
*EsrtRepository
;
318 UINTN RepositorySize
;
322 EsrtRepository
= NULL
;
325 // Get Esrt index buffer
327 if (Attribute
== ESRT_FROM_FMP
) {
328 VariableName
= EFI_ESRT_FMP_VARIABLE_NAME
;
330 VariableName
= EFI_ESRT_NONFMP_VARIABLE_NAME
;
333 Status
= GetVariable2 (
336 (VOID
**)&EsrtRepository
,
340 if (EsrtRepository
== NULL
) {
341 Status
= EFI_OUT_OF_RESOURCES
;
345 if (!EFI_ERROR (Status
)) {
347 // if exist, update Esrt cache repository
349 if (RepositorySize
% sizeof (EFI_SYSTEM_RESOURCE_ENTRY
) != 0) {
350 DEBUG ((DEBUG_ERROR
, "Repository Corrupt. Need to rebuild Repository.\n"));
352 // Repository is corrupt. Clear Repository before insert new entry
354 Status
= gRT
->SetVariable (
357 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
361 Status
= EFI_NOT_FOUND
;
365 Status
= EFI_NOT_FOUND
;
366 EsrtNum
= RepositorySize
/sizeof (EFI_SYSTEM_RESOURCE_ENTRY
);
367 for (Index
= 0; Index
< EsrtNum
; Index
++) {
369 // Update Esrt entry if it is found in repository
371 if (CompareGuid (&Entry
->FwClass
, &EsrtRepository
[Index
].FwClass
)) {
372 CopyMem (&EsrtRepository
[Index
], Entry
, sizeof (EFI_SYSTEM_RESOURCE_ENTRY
));
374 // Update New Repository
376 Status
= gRT
->SetVariable (
379 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
389 if (EsrtRepository
!= NULL
) {
390 FreePool (EsrtRepository
);
397 Return if this FMP is a system FMP or a device FMP, based upon FmpImageInfo.
399 @param[in] FmpImageInfo A pointer to EFI_FIRMWARE_IMAGE_DESCRIPTOR
401 @return TRUE It is a system FMP.
402 @return FALSE It is a device FMP.
406 IN EFI_FIRMWARE_IMAGE_DESCRIPTOR
*FmpImageInfo
413 Guid
= PcdGetPtr (PcdSystemFmpCapsuleImageTypeIdGuid
);
414 Count
= PcdGetSize (PcdSystemFmpCapsuleImageTypeIdGuid
)/sizeof (GUID
);
416 for (Index
= 0; Index
< Count
; Index
++, Guid
++) {
417 if (CompareGuid (&FmpImageInfo
->ImageTypeId
, Guid
)) {
426 Init one ESRT entry according to input FmpImageInfo (V1, V2, V3) .
428 @param[in, out] EsrtEntry Esrt entry to be Init
429 @param[in] FmpImageInfo FMP image info descriptor
430 @param[in] DescriptorVersion FMP Image info descriptor version
434 SetEsrtEntryFromFmpInfo (
435 IN OUT EFI_SYSTEM_RESOURCE_ENTRY
*EsrtEntry
,
436 IN EFI_FIRMWARE_IMAGE_DESCRIPTOR
*FmpImageInfo
,
437 IN UINT32 DescriptorVersion
440 EsrtEntry
->FwVersion
= FmpImageInfo
->Version
;
441 EsrtEntry
->FwClass
= FmpImageInfo
->ImageTypeId
;
442 if (IsSystemFmp (FmpImageInfo
)) {
443 EsrtEntry
->FwType
= ESRT_FW_TYPE_SYSTEMFIRMWARE
;
445 EsrtEntry
->FwType
= ESRT_FW_TYPE_DEVICEFIRMWARE
;
448 EsrtEntry
->LowestSupportedFwVersion
= 0;
449 EsrtEntry
->CapsuleFlags
= 0;
450 EsrtEntry
->LastAttemptVersion
= 0;
451 EsrtEntry
->LastAttemptStatus
= LAST_ATTEMPT_STATUS_SUCCESS
;
453 if (DescriptorVersion
>= 2) {
455 // LowestSupportedImageVersion only available in FMP V2 or higher
457 EsrtEntry
->LowestSupportedFwVersion
= FmpImageInfo
->LowestSupportedImageVersion
;
460 if (DescriptorVersion
>= 3) {
462 // LastAttemptVersion & LastAttemptStatus only available in FMP V3 or higher
464 EsrtEntry
->LastAttemptVersion
= FmpImageInfo
->LastAttemptVersion
;
465 EsrtEntry
->LastAttemptStatus
= FmpImageInfo
->LastAttemptStatus
;
469 // Set capsule customized flag
471 if ( ((FmpImageInfo
->AttributesSupported
& IMAGE_ATTRIBUTE_RESET_REQUIRED
) != 0)
472 && ((FmpImageInfo
->AttributesSetting
& IMAGE_ATTRIBUTE_RESET_REQUIRED
) != 0))
474 EsrtEntry
->CapsuleFlags
= PcdGet16 (PcdSystemRebootAfterCapsuleProcessFlag
);