2 Esrt management implementation.
4 Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 Find Esrt Entry stored in ESRT repository.
20 @param[in] FwClass Firmware class guid in Esrt entry
21 @param[in] Attribute Esrt from Non FMP or FMP instance
22 @param[out] Entry Esrt entry returned
24 @retval EFI_SUCCESS Successfully find an Esrt entry
25 @retval EF_NOT_FOUND No Esrt entry found
32 OUT EFI_SYSTEM_RESOURCE_ENTRY
*Entry
37 EFI_SYSTEM_RESOURCE_ENTRY
*EsrtRepository
;
42 EsrtRepository
= NULL
;
45 // Get Esrt index buffer
47 if (Attribute
== ESRT_FROM_FMP
) {
48 VariableName
= EFI_ESRT_FMP_VARIABLE_NAME
;
50 VariableName
= EFI_ESRT_NONFMP_VARIABLE_NAME
;
53 Status
= GetVariable2 (
56 (VOID
**) &EsrtRepository
,
60 if (EFI_ERROR(Status
)) {
64 if (RepositorySize
% sizeof(EFI_SYSTEM_RESOURCE_ENTRY
) != 0) {
65 DEBUG((EFI_D_ERROR
, "Repository Corrupt. Need to rebuild Repository.\n"));
70 Status
= EFI_NOT_FOUND
;
71 EsrtNum
= RepositorySize
/sizeof(EFI_SYSTEM_RESOURCE_ENTRY
);
72 for (Index
= 0; Index
< EsrtNum
; Index
++) {
73 if (CompareGuid(FwClass
, &EsrtRepository
[Index
].FwClass
)) {
74 CopyMem(Entry
, &EsrtRepository
[Index
], sizeof(EFI_SYSTEM_RESOURCE_ENTRY
));
81 if (EsrtRepository
!= NULL
) {
82 FreePool(EsrtRepository
);
89 Insert a new ESRT entry into ESRT Cache repository.
91 @param[in] Entry Esrt entry to be set
92 @param[in] Attribute Esrt from Esrt private protocol or FMP instance
94 @retval EFI_SUCCESS Successfully set a variable.
99 IN EFI_SYSTEM_RESOURCE_ENTRY
*Entry
,
104 CHAR16
*VariableName
;
105 EFI_SYSTEM_RESOURCE_ENTRY
*EsrtRepository
;
106 UINTN RepositorySize
;
107 EFI_SYSTEM_RESOURCE_ENTRY
*EsrtRepositoryNew
;
109 EsrtRepository
= NULL
;
110 EsrtRepositoryNew
= NULL
;
113 // Get Esrt index buffer
115 if (Attribute
== ESRT_FROM_FMP
) {
116 VariableName
= EFI_ESRT_FMP_VARIABLE_NAME
;
118 VariableName
= EFI_ESRT_NONFMP_VARIABLE_NAME
;
121 Status
= GetVariable2 (
124 (VOID
**) &EsrtRepository
,
128 if (Status
== EFI_NOT_FOUND
) {
130 // If not exist, create new Esrt cache repository
132 Status
= gRT
->SetVariable(
135 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
136 sizeof(EFI_SYSTEM_RESOURCE_ENTRY
),
141 } else if (Status
== EFI_SUCCESS
) {
143 // if exist, update Esrt cache repository
145 if (RepositorySize
% sizeof(EFI_SYSTEM_RESOURCE_ENTRY
) != 0) {
146 DEBUG((EFI_D_ERROR
, "Repository Corrupt. Need to rebuild Repository.\n"));
148 // Repository is corrupt. Clear Repository before insert new entry
150 Status
= gRT
->SetVariable(
153 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
157 FreePool(EsrtRepository
);
159 EsrtRepository
= NULL
;
163 // Check Repository size constraint
165 if ((Attribute
== ESRT_FROM_FMP
&& RepositorySize
>= PcdGet32(PcdMaxFmpEsrtCacheNum
) * sizeof(EFI_SYSTEM_RESOURCE_ENTRY
))
166 ||(Attribute
== ESRT_FROM_NONFMP
&& RepositorySize
>= PcdGet32(PcdMaxNonFmpEsrtCacheNum
) * sizeof(EFI_SYSTEM_RESOURCE_ENTRY
)) ) {
167 Status
= EFI_OUT_OF_RESOURCES
;
171 EsrtRepositoryNew
= AllocatePool(RepositorySize
+ sizeof(EFI_SYSTEM_RESOURCE_ENTRY
));
172 if (EsrtRepositoryNew
== NULL
) {
173 Status
= EFI_OUT_OF_RESOURCES
;
177 if (RepositorySize
!= 0 && EsrtRepository
!= NULL
) {
178 CopyMem(EsrtRepositoryNew
, EsrtRepository
, RepositorySize
);
180 CopyMem((UINT8
*)EsrtRepositoryNew
+ RepositorySize
, Entry
, sizeof(EFI_SYSTEM_RESOURCE_ENTRY
));
182 Status
= gRT
->SetVariable(
185 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
186 RepositorySize
+ sizeof(EFI_SYSTEM_RESOURCE_ENTRY
),
192 if (EsrtRepository
!= NULL
) {
193 FreePool(EsrtRepository
);
196 if (EsrtRepositoryNew
!= NULL
) {
197 FreePool(EsrtRepositoryNew
);
204 Delete ESRT Entry from ESRT repository.
206 @param[in] FwClass FwClass of Esrt entry to delete
207 @param[in] Attribute Esrt from Esrt private protocol or FMP instance
209 @retval EFI_SUCCESS Insert all entries Successfully
210 @retval EFI_NOT_FOUND ESRT entry with FwClass doesn't exsit
215 IN EFI_GUID
*FwClass
,
220 CHAR16
*VariableName
;
221 EFI_SYSTEM_RESOURCE_ENTRY
*EsrtRepository
;
222 UINTN RepositorySize
;
226 EsrtRepository
= NULL
;
229 // Get Esrt index buffer
231 if (Attribute
== ESRT_FROM_FMP
) {
232 VariableName
= EFI_ESRT_FMP_VARIABLE_NAME
;
234 VariableName
= EFI_ESRT_NONFMP_VARIABLE_NAME
;
237 Status
= GetVariable2 (
240 (VOID
**) &EsrtRepository
,
244 if (EFI_ERROR(Status
)) {
248 if ((RepositorySize
% sizeof(EFI_SYSTEM_RESOURCE_ENTRY
)) != 0) {
249 DEBUG((EFI_D_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
);
301 Update one ESRT entry in ESRT repository
303 @param[in] Entry Esrt entry to be set
304 @param[in] Attribute Esrt from Non Esrt or FMP instance
306 @retval EFI_SUCCESS Successfully Update a variable.
307 @retval EFI_NOT_FOUND The Esrt enry doesn't exist
312 IN EFI_SYSTEM_RESOURCE_ENTRY
*Entry
,
317 CHAR16
*VariableName
;
318 EFI_SYSTEM_RESOURCE_ENTRY
*EsrtRepository
;
319 UINTN RepositorySize
;
323 EsrtRepository
= NULL
;
326 // Get Esrt index buffer
328 if (Attribute
== ESRT_FROM_FMP
) {
329 VariableName
= EFI_ESRT_FMP_VARIABLE_NAME
;
331 VariableName
= EFI_ESRT_NONFMP_VARIABLE_NAME
;
334 Status
= GetVariable2 (
337 (VOID
**) &EsrtRepository
,
341 if (!EFI_ERROR(Status
)) {
343 // if exist, update Esrt cache repository
345 if (RepositorySize
% sizeof(EFI_SYSTEM_RESOURCE_ENTRY
) != 0) {
346 DEBUG((EFI_D_ERROR
, "Repository Corrupt. Need to rebuild Repository.\n"));
348 // Repository is corrupt. Clear Repository before insert new entry
350 Status
= gRT
->SetVariable(
353 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
357 Status
= EFI_NOT_FOUND
;
361 Status
= EFI_NOT_FOUND
;
362 EsrtNum
= RepositorySize
/sizeof(EFI_SYSTEM_RESOURCE_ENTRY
);
363 for (Index
= 0; Index
< EsrtNum
; Index
++) {
365 // Update Esrt entry if it is found in repository
367 if (CompareGuid(&Entry
->FwClass
, &EsrtRepository
[Index
].FwClass
)) {
369 CopyMem(&EsrtRepository
[Index
], Entry
, sizeof(EFI_SYSTEM_RESOURCE_ENTRY
));
371 // Update New Repository
373 Status
= gRT
->SetVariable(
376 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
,
386 if (EsrtRepository
!= NULL
) {
387 FreePool(EsrtRepository
);
394 Init one ESRT entry according to input FmpImageInfo (V1, V2, V3) .
396 @param[in, out] EsrtEntry Esrt entry to be Init
397 @param[in] FmpImageInfo FMP image info descriptor
398 @param[in] DescriptorVersion FMP Image info descriptor version
402 SetEsrtEntryFromFmpInfo (
403 IN OUT EFI_SYSTEM_RESOURCE_ENTRY
*EsrtEntry
,
404 IN EFI_FIRMWARE_IMAGE_DESCRIPTOR
*FmpImageInfo
,
405 IN UINT32 DescriptorVersion
408 EsrtEntry
->FwVersion
= FmpImageInfo
->Version
;
409 EsrtEntry
->FwClass
= FmpImageInfo
->ImageTypeId
;
410 EsrtEntry
->FwType
= ESRT_FW_TYPE_DEVICEFIRMWARE
;
411 EsrtEntry
->LowestSupportedFwVersion
= 0;
412 EsrtEntry
->CapsuleFlags
= 0;
413 EsrtEntry
->LastAttemptVersion
= 0;
414 EsrtEntry
->LastAttemptStatus
= LAST_ATTEMPT_STATUS_SUCCESS
;
416 if (DescriptorVersion
>= 2) {
418 // LowestSupportedImageVersion only available in FMP V2 or higher
420 EsrtEntry
->LowestSupportedFwVersion
= FmpImageInfo
->LowestSupportedImageVersion
;
423 if (DescriptorVersion
>= 3) {
425 // LastAttemptVersion & LastAttemptStatus only available in FMP V3 or higher
427 EsrtEntry
->LastAttemptVersion
= FmpImageInfo
->LastAttemptVersion
;
428 EsrtEntry
->LastAttemptStatus
= FmpImageInfo
->LastAttemptStatus
;
432 // Set capsule customized flag
434 if ((FmpImageInfo
->AttributesSupported
& IMAGE_ATTRIBUTE_RESET_REQUIRED
) != 0
435 && (FmpImageInfo
->AttributesSetting
& IMAGE_ATTRIBUTE_RESET_REQUIRED
) != 0) {
436 EsrtEntry
->CapsuleFlags
= PcdGet16(PcdSystemRebootAfterCapsuleProcessFlag
);