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 ((RepositorySize
% sizeof(EFI_SYSTEM_RESOURCE_ENTRY
)) != 0) {
243 DEBUG((EFI_D_ERROR
, "Repository Corrupt. Need to rebuild Repository.\n"));
245 // Repository is corrupt. Clear Repository before insert new entry
247 Status
= gRT
->SetVariable(
250 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
257 Status
= EFI_NOT_FOUND
;
258 EsrtNum
= RepositorySize
/sizeof(EFI_SYSTEM_RESOURCE_ENTRY
);
259 for (Index
= 0; Index
< EsrtNum
; Index
++) {
261 // Delete Esrt entry if it is found in repository
263 if (CompareGuid(FwClass
, &EsrtRepository
[Index
].FwClass
)) {
265 // If delete Esrt entry is not at the rail
267 if (Index
< EsrtNum
- 1) {
268 CopyMem(&EsrtRepository
[Index
], &EsrtRepository
[Index
+ 1], (EsrtNum
- Index
- 1) * sizeof(EFI_SYSTEM_RESOURCE_ENTRY
));
272 // Update New Repository
274 Status
= gRT
->SetVariable(
277 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
278 (EsrtNum
- 1) * sizeof(EFI_SYSTEM_RESOURCE_ENTRY
),
286 if (EsrtRepository
!= NULL
) {
287 FreePool(EsrtRepository
);
295 Update one ESRT entry in ESRT repository
297 @param[in] Entry Esrt entry to be set
298 @param[in] Attribute Esrt from Non Esrt or FMP instance
300 @retval EFI_SUCCESS Successfully Update a variable.
301 @retval EFI_NOT_FOUND The Esrt enry doesn't exist
306 IN EFI_SYSTEM_RESOURCE_ENTRY
*Entry
,
311 CHAR16
*VariableName
;
312 EFI_SYSTEM_RESOURCE_ENTRY
*EsrtRepository
;
313 UINTN RepositorySize
;
317 EsrtRepository
= NULL
;
320 // Get Esrt index buffer
322 if (Attribute
== ESRT_FROM_FMP
) {
323 VariableName
= EFI_ESRT_FMP_VARIABLE_NAME
;
325 VariableName
= EFI_ESRT_NONFMP_VARIABLE_NAME
;
328 Status
= GetVariable2 (
331 (VOID
**) &EsrtRepository
,
335 if (!EFI_ERROR(Status
)) {
337 // if exist, update Esrt cache repository
339 if (RepositorySize
% sizeof(EFI_SYSTEM_RESOURCE_ENTRY
) != 0) {
340 DEBUG((EFI_D_ERROR
, "Repository Corrupt. Need to rebuild Repository.\n"));
342 // Repository is corrupt. Clear Repository before insert new entry
344 Status
= gRT
->SetVariable(
347 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
351 Status
= EFI_NOT_FOUND
;
355 Status
= EFI_NOT_FOUND
;
356 EsrtNum
= RepositorySize
/sizeof(EFI_SYSTEM_RESOURCE_ENTRY
);
357 for (Index
= 0; Index
< EsrtNum
; Index
++) {
359 // Update Esrt entry if it is found in repository
361 if (CompareGuid(&Entry
->FwClass
, &EsrtRepository
[Index
].FwClass
)) {
363 CopyMem(&EsrtRepository
[Index
], Entry
, sizeof(EFI_SYSTEM_RESOURCE_ENTRY
));
365 // Update New Repository
367 Status
= gRT
->SetVariable(
370 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
380 if (EsrtRepository
!= NULL
) {
381 FreePool(EsrtRepository
);
388 Return if this FMP is a system FMP or a device FMP, based upon FmpImageInfo.
390 @param[in] FmpImageInfo A pointer to EFI_FIRMWARE_IMAGE_DESCRIPTOR
392 @return TRUE It is a system FMP.
393 @return FALSE It is a device FMP.
397 IN EFI_FIRMWARE_IMAGE_DESCRIPTOR
*FmpImageInfo
404 Guid
= PcdGetPtr(PcdSystemFmpCapsuleImageTypeIdGuid
);
405 Count
= PcdGetSize(PcdSystemFmpCapsuleImageTypeIdGuid
)/sizeof(GUID
);
407 for (Index
= 0; Index
< Count
; Index
++, Guid
++) {
408 if (CompareGuid(&FmpImageInfo
->ImageTypeId
, Guid
)) {
417 Init one ESRT entry according to input FmpImageInfo (V1, V2, V3) .
419 @param[in, out] EsrtEntry Esrt entry to be Init
420 @param[in] FmpImageInfo FMP image info descriptor
421 @param[in] DescriptorVersion FMP Image info descriptor version
425 SetEsrtEntryFromFmpInfo (
426 IN OUT EFI_SYSTEM_RESOURCE_ENTRY
*EsrtEntry
,
427 IN EFI_FIRMWARE_IMAGE_DESCRIPTOR
*FmpImageInfo
,
428 IN UINT32 DescriptorVersion
431 EsrtEntry
->FwVersion
= FmpImageInfo
->Version
;
432 EsrtEntry
->FwClass
= FmpImageInfo
->ImageTypeId
;
433 if (IsSystemFmp(FmpImageInfo
)) {
434 EsrtEntry
->FwType
= ESRT_FW_TYPE_SYSTEMFIRMWARE
;
436 EsrtEntry
->FwType
= ESRT_FW_TYPE_DEVICEFIRMWARE
;
438 EsrtEntry
->LowestSupportedFwVersion
= 0;
439 EsrtEntry
->CapsuleFlags
= 0;
440 EsrtEntry
->LastAttemptVersion
= 0;
441 EsrtEntry
->LastAttemptStatus
= LAST_ATTEMPT_STATUS_SUCCESS
;
443 if (DescriptorVersion
>= 2) {
445 // LowestSupportedImageVersion only available in FMP V2 or higher
447 EsrtEntry
->LowestSupportedFwVersion
= FmpImageInfo
->LowestSupportedImageVersion
;
450 if (DescriptorVersion
>= 3) {
452 // LastAttemptVersion & LastAttemptStatus only available in FMP V3 or higher
454 EsrtEntry
->LastAttemptVersion
= FmpImageInfo
->LastAttemptVersion
;
455 EsrtEntry
->LastAttemptStatus
= FmpImageInfo
->LastAttemptStatus
;
459 // Set capsule customized flag
461 if ((FmpImageInfo
->AttributesSupported
& IMAGE_ATTRIBUTE_RESET_REQUIRED
) != 0
462 && (FmpImageInfo
->AttributesSetting
& IMAGE_ATTRIBUTE_RESET_REQUIRED
) != 0) {
463 EsrtEntry
->CapsuleFlags
= PcdGet16(PcdSystemRebootAfterCapsuleProcessFlag
);