TianoCore EDK2 master
Loading...
Searching...
No Matches
EsrtImpl.c
Go to the documentation of this file.
1
9#include "EsrtImpl.h"
10
24 IN EFI_GUID *FwClass,
25 IN UINTN Attribute,
27 )
28{
29 EFI_STATUS Status;
30 CHAR16 *VariableName;
31 EFI_SYSTEM_RESOURCE_ENTRY *EsrtRepository;
32 UINTN RepositorySize;
33 UINTN Index;
34 UINTN EsrtNum;
35
36 EsrtRepository = NULL;
37
38 //
39 // Get Esrt index buffer
40 //
41 if (Attribute == ESRT_FROM_FMP) {
42 VariableName = EFI_ESRT_FMP_VARIABLE_NAME;
43 } else {
44 VariableName = EFI_ESRT_NONFMP_VARIABLE_NAME;
45 }
46
47 Status = GetVariable2 (
48 VariableName,
49 &gEfiCallerIdGuid,
50 (VOID **)&EsrtRepository,
51 &RepositorySize
52 );
53
54 if (EFI_ERROR (Status)) {
55 goto EXIT;
56 }
57
58 if (RepositorySize % sizeof (EFI_SYSTEM_RESOURCE_ENTRY) != 0) {
59 DEBUG ((DEBUG_ERROR, "Repository Corrupt. Need to rebuild Repository.\n"));
60 Status = EFI_ABORTED;
61 goto EXIT;
62 }
63
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));
69 Status = EFI_SUCCESS;
70 break;
71 }
72 }
73
74EXIT:
75 if (EsrtRepository != NULL) {
76 FreePool (EsrtRepository);
77 }
78
79 return Status;
80}
81
94 UINTN Attribute
95 )
96{
97 EFI_STATUS Status;
98 CHAR16 *VariableName;
99 EFI_SYSTEM_RESOURCE_ENTRY *EsrtRepository;
100 UINTN RepositorySize;
101 EFI_SYSTEM_RESOURCE_ENTRY *EsrtRepositoryNew;
102
103 EsrtRepository = NULL;
104 EsrtRepositoryNew = NULL;
105
106 //
107 // Get Esrt index buffer
108 //
109 if (Attribute == ESRT_FROM_FMP) {
110 VariableName = EFI_ESRT_FMP_VARIABLE_NAME;
111 } else {
112 VariableName = EFI_ESRT_NONFMP_VARIABLE_NAME;
113 }
114
115 Status = GetVariable2 (
116 VariableName,
117 &gEfiCallerIdGuid,
118 (VOID **)&EsrtRepository,
119 &RepositorySize
120 );
121
122 if (Status == EFI_NOT_FOUND) {
123 //
124 // If not exist, create new Esrt cache repository
125 //
126 Status = gRT->SetVariable (
127 VariableName,
128 &gEfiCallerIdGuid,
129 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
131 Entry
132 );
133 return Status;
134 } else if (Status == EFI_SUCCESS) {
135 //
136 // if exist, update Esrt cache repository
137 //
138 if (RepositorySize % sizeof (EFI_SYSTEM_RESOURCE_ENTRY) != 0) {
139 DEBUG ((DEBUG_ERROR, "Repository Corrupt. Need to rebuild Repository.\n"));
140 //
141 // Repository is corrupt. Clear Repository before insert new entry
142 //
143 Status = gRT->SetVariable (
144 VariableName,
145 &gEfiCallerIdGuid,
146 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
147 0,
148 EsrtRepository
149 );
150 FreePool (EsrtRepository);
151 RepositorySize = 0;
152 EsrtRepository = NULL;
153 }
154
155 //
156 // Check Repository size constraint
157 //
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))))
160 {
161 Status = EFI_OUT_OF_RESOURCES;
162 goto EXIT;
163 }
164
165 EsrtRepositoryNew = AllocatePool (RepositorySize + sizeof (EFI_SYSTEM_RESOURCE_ENTRY));
166 if (EsrtRepositoryNew == NULL) {
167 Status = EFI_OUT_OF_RESOURCES;
168 goto EXIT;
169 }
170
171 if ((RepositorySize != 0) && (EsrtRepository != NULL)) {
172 CopyMem (EsrtRepositoryNew, EsrtRepository, RepositorySize);
173 }
174
175 CopyMem ((UINT8 *)EsrtRepositoryNew + RepositorySize, Entry, sizeof (EFI_SYSTEM_RESOURCE_ENTRY));
176
177 Status = gRT->SetVariable (
178 VariableName,
179 &gEfiCallerIdGuid,
180 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
181 RepositorySize + sizeof (EFI_SYSTEM_RESOURCE_ENTRY),
182 EsrtRepositoryNew
183 );
184 }
185
186EXIT:
187 if (EsrtRepository != NULL) {
188 FreePool (EsrtRepository);
189 }
190
191 if (EsrtRepositoryNew != NULL) {
192 FreePool (EsrtRepositoryNew);
193 }
194
195 return Status;
196}
197
210 IN EFI_GUID *FwClass,
211 IN UINTN Attribute
212 )
213{
214 EFI_STATUS Status;
215 CHAR16 *VariableName;
216 EFI_SYSTEM_RESOURCE_ENTRY *EsrtRepository;
217 UINTN RepositorySize;
218 UINTN Index;
219 UINTN EsrtNum;
220
221 EsrtRepository = NULL;
222
223 //
224 // Get Esrt index buffer
225 //
226 if (Attribute == ESRT_FROM_FMP) {
227 VariableName = EFI_ESRT_FMP_VARIABLE_NAME;
228 } else {
229 VariableName = EFI_ESRT_NONFMP_VARIABLE_NAME;
230 }
231
232 Status = GetVariable2 (
233 VariableName,
234 &gEfiCallerIdGuid,
235 (VOID **)&EsrtRepository,
236 &RepositorySize
237 );
238
239 if (EFI_ERROR (Status)) {
240 goto EXIT;
241 }
242
243 if (EsrtRepository == NULL) {
244 Status = EFI_OUT_OF_RESOURCES;
245 goto EXIT;
246 }
247
248 if ((RepositorySize % sizeof (EFI_SYSTEM_RESOURCE_ENTRY)) != 0) {
249 DEBUG ((DEBUG_ERROR, "Repository Corrupt. Need to rebuild Repository.\n"));
250 //
251 // Repository is corrupt. Clear Repository before insert new entry
252 //
253 Status = gRT->SetVariable (
254 VariableName,
255 &gEfiCallerIdGuid,
256 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
257 0,
258 EsrtRepository
259 );
260 goto EXIT;
261 }
262
263 Status = EFI_NOT_FOUND;
264 EsrtNum = RepositorySize/sizeof (EFI_SYSTEM_RESOURCE_ENTRY);
265 for (Index = 0; Index < EsrtNum; Index++) {
266 //
267 // Delete Esrt entry if it is found in repository
268 //
269 if (CompareGuid (FwClass, &EsrtRepository[Index].FwClass)) {
270 //
271 // If delete Esrt entry is not at the rail
272 //
273 if (Index < EsrtNum - 1) {
274 CopyMem (&EsrtRepository[Index], &EsrtRepository[Index + 1], (EsrtNum - Index - 1) * sizeof (EFI_SYSTEM_RESOURCE_ENTRY));
275 }
276
277 //
278 // Update New Repository
279 //
280 Status = gRT->SetVariable (
281 VariableName,
282 &gEfiCallerIdGuid,
283 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
284 (EsrtNum - 1) * sizeof (EFI_SYSTEM_RESOURCE_ENTRY),
285 EsrtRepository
286 );
287 break;
288 }
289 }
290
291EXIT:
292 if (EsrtRepository != NULL) {
293 FreePool (EsrtRepository);
294 }
295
296 return Status;
297}
298
312 UINTN Attribute
313 )
314{
315 EFI_STATUS Status;
316 CHAR16 *VariableName;
317 EFI_SYSTEM_RESOURCE_ENTRY *EsrtRepository;
318 UINTN RepositorySize;
319 UINTN Index;
320 UINTN EsrtNum;
321
322 EsrtRepository = NULL;
323
324 //
325 // Get Esrt index buffer
326 //
327 if (Attribute == ESRT_FROM_FMP) {
328 VariableName = EFI_ESRT_FMP_VARIABLE_NAME;
329 } else {
330 VariableName = EFI_ESRT_NONFMP_VARIABLE_NAME;
331 }
332
333 Status = GetVariable2 (
334 VariableName,
335 &gEfiCallerIdGuid,
336 (VOID **)&EsrtRepository,
337 &RepositorySize
338 );
339
340 if (EsrtRepository == NULL) {
341 Status = EFI_OUT_OF_RESOURCES;
342 goto EXIT;
343 }
344
345 if (!EFI_ERROR (Status)) {
346 //
347 // if exist, update Esrt cache repository
348 //
349 if (RepositorySize % sizeof (EFI_SYSTEM_RESOURCE_ENTRY) != 0) {
350 DEBUG ((DEBUG_ERROR, "Repository Corrupt. Need to rebuild Repository.\n"));
351 //
352 // Repository is corrupt. Clear Repository before insert new entry
353 //
354 Status = gRT->SetVariable (
355 VariableName,
356 &gEfiCallerIdGuid,
357 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
358 0,
359 EsrtRepository
360 );
361 Status = EFI_NOT_FOUND;
362 goto EXIT;
363 }
364
365 Status = EFI_NOT_FOUND;
366 EsrtNum = RepositorySize/sizeof (EFI_SYSTEM_RESOURCE_ENTRY);
367 for (Index = 0; Index < EsrtNum; Index++) {
368 //
369 // Update Esrt entry if it is found in repository
370 //
371 if (CompareGuid (&Entry->FwClass, &EsrtRepository[Index].FwClass)) {
372 CopyMem (&EsrtRepository[Index], Entry, sizeof (EFI_SYSTEM_RESOURCE_ENTRY));
373 //
374 // Update New Repository
375 //
376 Status = gRT->SetVariable (
377 VariableName,
378 &gEfiCallerIdGuid,
379 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
380 RepositorySize,
381 EsrtRepository
382 );
383 break;
384 }
385 }
386 }
387
388EXIT:
389 if (EsrtRepository != NULL) {
390 FreePool (EsrtRepository);
391 }
392
393 return Status;
394}
395
404BOOLEAN
407 )
408{
409 GUID *Guid;
410 UINTN Count;
411 UINTN Index;
412
413 Guid = PcdGetPtr (PcdSystemFmpCapsuleImageTypeIdGuid);
414 Count = PcdGetSize (PcdSystemFmpCapsuleImageTypeIdGuid)/sizeof (GUID);
415
416 for (Index = 0; Index < Count; Index++, Guid++) {
417 if (CompareGuid (&FmpImageInfo->ImageTypeId, Guid)) {
418 return TRUE;
419 }
420 }
421
422 return FALSE;
423}
424
433VOID
436 IN EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfo,
437 IN UINT32 DescriptorVersion
438 )
439{
440 EsrtEntry->FwVersion = FmpImageInfo->Version;
441 EsrtEntry->FwClass = FmpImageInfo->ImageTypeId;
442 if (IsSystemFmp (FmpImageInfo)) {
443 EsrtEntry->FwType = ESRT_FW_TYPE_SYSTEMFIRMWARE;
444 } else {
445 EsrtEntry->FwType = ESRT_FW_TYPE_DEVICEFIRMWARE;
446 }
447
448 EsrtEntry->LowestSupportedFwVersion = 0;
449 EsrtEntry->CapsuleFlags = 0;
450 EsrtEntry->LastAttemptVersion = 0;
451 EsrtEntry->LastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS;
452
453 if (DescriptorVersion >= 2) {
454 //
455 // LowestSupportedImageVersion only available in FMP V2 or higher
456 //
457 EsrtEntry->LowestSupportedFwVersion = FmpImageInfo->LowestSupportedImageVersion;
458 }
459
460 if (DescriptorVersion >= 3) {
461 //
462 // LastAttemptVersion & LastAttemptStatus only available in FMP V3 or higher
463 //
464 EsrtEntry->LastAttemptVersion = FmpImageInfo->LastAttemptVersion;
465 EsrtEntry->LastAttemptStatus = FmpImageInfo->LastAttemptStatus;
466 }
467
468 //
469 // Set capsule customized flag
470 //
471 if ( ((FmpImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_RESET_REQUIRED) != 0)
472 && ((FmpImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_RESET_REQUIRED) != 0))
473 {
474 EsrtEntry->CapsuleFlags = PcdGet16 (PcdSystemRebootAfterCapsuleProcessFlag);
475 }
476}
UINT64 UINTN
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID SetEsrtEntryFromFmpInfo(IN OUT EFI_SYSTEM_RESOURCE_ENTRY *EsrtEntry, IN EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfo, IN UINT32 DescriptorVersion)
Definition: EsrtImpl.c:434
EFI_STATUS DeleteEsrtEntry(IN EFI_GUID *FwClass, IN UINTN Attribute)
Definition: EsrtImpl.c:209
EFI_STATUS GetEsrtEntry(IN EFI_GUID *FwClass, IN UINTN Attribute, OUT EFI_SYSTEM_RESOURCE_ENTRY *Entry)
Definition: EsrtImpl.c:23
EFI_STATUS UpdateEsrtEntry(IN EFI_SYSTEM_RESOURCE_ENTRY *Entry, UINTN Attribute)
Definition: EsrtImpl.c:310
BOOLEAN IsSystemFmp(IN EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfo)
Definition: EsrtImpl.c:405
EFI_STATUS InsertEsrtEntry(IN EFI_SYSTEM_RESOURCE_ENTRY *Entry, UINTN Attribute)
Definition: EsrtImpl.c:92
#define IMAGE_ATTRIBUTE_RESET_REQUIRED
EFI_RUNTIME_SERVICES * gRT
#define NULL
Definition: Base.h:319
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define PcdGet16(TokenName)
Definition: PcdLib.h:349
#define PcdGetSize(TokenName)
Definition: PcdLib.h:440
#define PcdGet32(TokenName)
Definition: PcdLib.h:362
#define PcdGetPtr(TokenName)
Definition: PcdLib.h:388
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
#define LAST_ATTEMPT_STATUS_SUCCESS
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_STATUS EFIAPI GetVariable2(IN CONST CHAR16 *Name, IN CONST EFI_GUID *Guid, OUT VOID **Value, OUT UINTN *Size OPTIONAL)
Definition: UefiLib.c:1317
#define EFI_VARIABLE_NON_VOLATILE
Definition: Base.h:213