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((EFI_D_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
),
135 } else if (Status
== EFI_SUCCESS
) {
137 // if exist, update Esrt cache repository
139 if (RepositorySize
% sizeof(EFI_SYSTEM_RESOURCE_ENTRY
) != 0) {
140 DEBUG((EFI_D_ERROR
, "Repository Corrupt. Need to rebuild Repository.\n"));
142 // Repository is corrupt. Clear Repository before insert new entry
144 Status
= gRT
->SetVariable(
147 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
151 FreePool(EsrtRepository
);
153 EsrtRepository
= NULL
;
157 // Check Repository size constraint
159 if ((Attribute
== ESRT_FROM_FMP
&& RepositorySize
>= PcdGet32(PcdMaxFmpEsrtCacheNum
) * sizeof(EFI_SYSTEM_RESOURCE_ENTRY
))
160 ||(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
);
174 CopyMem((UINT8
*)EsrtRepositoryNew
+ RepositorySize
, Entry
, sizeof(EFI_SYSTEM_RESOURCE_ENTRY
));
176 Status
= gRT
->SetVariable(
179 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
180 RepositorySize
+ sizeof(EFI_SYSTEM_RESOURCE_ENTRY
),
186 if (EsrtRepository
!= NULL
) {
187 FreePool(EsrtRepository
);
190 if (EsrtRepositoryNew
!= NULL
) {
191 FreePool(EsrtRepositoryNew
);
198 Delete ESRT Entry from ESRT repository.
200 @param[in] FwClass FwClass of Esrt entry to delete
201 @param[in] Attribute Esrt from Esrt private protocol or FMP instance
203 @retval EFI_SUCCESS Insert all entries Successfully
204 @retval EFI_NOT_FOUND ESRT entry with FwClass doesn't exsit
209 IN EFI_GUID
*FwClass
,
214 CHAR16
*VariableName
;
215 EFI_SYSTEM_RESOURCE_ENTRY
*EsrtRepository
;
216 UINTN RepositorySize
;
220 EsrtRepository
= NULL
;
223 // Get Esrt index buffer
225 if (Attribute
== ESRT_FROM_FMP
) {
226 VariableName
= EFI_ESRT_FMP_VARIABLE_NAME
;
228 VariableName
= EFI_ESRT_NONFMP_VARIABLE_NAME
;
231 Status
= GetVariable2 (
234 (VOID
**) &EsrtRepository
,
238 if (EFI_ERROR(Status
)) {
242 if (EsrtRepository
== NULL
) {
243 Status
= EFI_OUT_OF_RESOURCES
;
247 if ((RepositorySize
% sizeof(EFI_SYSTEM_RESOURCE_ENTRY
)) != 0) {
248 DEBUG((EFI_D_ERROR
, "Repository Corrupt. Need to rebuild Repository.\n"));
250 // Repository is corrupt. Clear Repository before insert new entry
252 Status
= gRT
->SetVariable(
255 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
262 Status
= EFI_NOT_FOUND
;
263 EsrtNum
= RepositorySize
/sizeof(EFI_SYSTEM_RESOURCE_ENTRY
);
264 for (Index
= 0; Index
< EsrtNum
; Index
++) {
266 // Delete Esrt entry if it is found in repository
268 if (CompareGuid(FwClass
, &EsrtRepository
[Index
].FwClass
)) {
270 // If delete Esrt entry is not at the rail
272 if (Index
< EsrtNum
- 1) {
273 CopyMem(&EsrtRepository
[Index
], &EsrtRepository
[Index
+ 1], (EsrtNum
- Index
- 1) * sizeof(EFI_SYSTEM_RESOURCE_ENTRY
));
277 // Update New Repository
279 Status
= gRT
->SetVariable(
282 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
283 (EsrtNum
- 1) * sizeof(EFI_SYSTEM_RESOURCE_ENTRY
),
291 if (EsrtRepository
!= NULL
) {
292 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((EFI_D_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
)) {
373 CopyMem(&EsrtRepository
[Index
], Entry
, sizeof(EFI_SYSTEM_RESOURCE_ENTRY
));
375 // Update New Repository
377 Status
= gRT
->SetVariable(
380 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
390 if (EsrtRepository
!= NULL
) {
391 FreePool(EsrtRepository
);
398 Return if this FMP is a system FMP or a device FMP, based upon FmpImageInfo.
400 @param[in] FmpImageInfo A pointer to EFI_FIRMWARE_IMAGE_DESCRIPTOR
402 @return TRUE It is a system FMP.
403 @return FALSE It is a device FMP.
407 IN EFI_FIRMWARE_IMAGE_DESCRIPTOR
*FmpImageInfo
414 Guid
= PcdGetPtr(PcdSystemFmpCapsuleImageTypeIdGuid
);
415 Count
= PcdGetSize(PcdSystemFmpCapsuleImageTypeIdGuid
)/sizeof(GUID
);
417 for (Index
= 0; Index
< Count
; Index
++, Guid
++) {
418 if (CompareGuid(&FmpImageInfo
->ImageTypeId
, Guid
)) {
427 Init one ESRT entry according to input FmpImageInfo (V1, V2, V3) .
429 @param[in, out] EsrtEntry Esrt entry to be Init
430 @param[in] FmpImageInfo FMP image info descriptor
431 @param[in] DescriptorVersion FMP Image info descriptor version
435 SetEsrtEntryFromFmpInfo (
436 IN OUT EFI_SYSTEM_RESOURCE_ENTRY
*EsrtEntry
,
437 IN EFI_FIRMWARE_IMAGE_DESCRIPTOR
*FmpImageInfo
,
438 IN UINT32 DescriptorVersion
441 EsrtEntry
->FwVersion
= FmpImageInfo
->Version
;
442 EsrtEntry
->FwClass
= FmpImageInfo
->ImageTypeId
;
443 if (IsSystemFmp(FmpImageInfo
)) {
444 EsrtEntry
->FwType
= ESRT_FW_TYPE_SYSTEMFIRMWARE
;
446 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) {
473 EsrtEntry
->CapsuleFlags
= PcdGet16(PcdSystemRebootAfterCapsuleProcessFlag
);