]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/EsrtDxe/EsrtImpl.c
MdeModulePkg: Change use of EFI_D_* to DEBUG_*
[mirror_edk2.git] / MdeModulePkg / Universal / EsrtDxe / EsrtImpl.c
CommitLineData
acd32208
CZ
1/** @file\r
2 Esrt management implementation.\r
3\r
d1102dba 4Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>\r
9d510e61 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
acd32208
CZ
6\r
7**/\r
8\r
9#include "EsrtImpl.h"\r
10\r
11/**\r
d1102dba 12 Find Esrt Entry stored in ESRT repository.\r
acd32208
CZ
13\r
14 @param[in] FwClass Firmware class guid in Esrt entry\r
15 @param[in] Attribute Esrt from Non FMP or FMP instance\r
16 @param[out] Entry Esrt entry returned\r
d1102dba 17\r
acd32208
CZ
18 @retval EFI_SUCCESS Successfully find an Esrt entry\r
19 @retval EF_NOT_FOUND No Esrt entry found\r
20\r
21**/\r
22EFI_STATUS\r
23GetEsrtEntry (\r
24 IN EFI_GUID *FwClass,\r
25 IN UINTN Attribute,\r
26 OUT EFI_SYSTEM_RESOURCE_ENTRY *Entry\r
27 )\r
28{\r
29 EFI_STATUS Status;\r
30 CHAR16 *VariableName;\r
31 EFI_SYSTEM_RESOURCE_ENTRY *EsrtRepository;\r
32 UINTN RepositorySize;\r
33 UINTN Index;\r
34 UINTN EsrtNum;\r
35\r
36 EsrtRepository = NULL;\r
37\r
38 //\r
39 // Get Esrt index buffer\r
40 //\r
41 if (Attribute == ESRT_FROM_FMP) {\r
42 VariableName = EFI_ESRT_FMP_VARIABLE_NAME;\r
43 } else {\r
44 VariableName = EFI_ESRT_NONFMP_VARIABLE_NAME;\r
45 }\r
d1102dba 46\r
acd32208
CZ
47 Status = GetVariable2 (\r
48 VariableName,\r
49 &gEfiCallerIdGuid,\r
50 (VOID **) &EsrtRepository,\r
51 &RepositorySize\r
52 );\r
53\r
54 if (EFI_ERROR(Status)) {\r
55 goto EXIT;\r
56 }\r
57\r
58 if (RepositorySize % sizeof(EFI_SYSTEM_RESOURCE_ENTRY) != 0) {\r
87000d77 59 DEBUG((DEBUG_ERROR, "Repository Corrupt. Need to rebuild Repository.\n"));\r
acd32208
CZ
60 Status = EFI_ABORTED;\r
61 goto EXIT;\r
62 }\r
63\r
64 Status = EFI_NOT_FOUND;\r
65 EsrtNum = RepositorySize/sizeof(EFI_SYSTEM_RESOURCE_ENTRY);\r
66 for (Index = 0; Index < EsrtNum; Index++) {\r
67 if (CompareGuid(FwClass, &EsrtRepository[Index].FwClass)) {\r
68 CopyMem(Entry, &EsrtRepository[Index], sizeof(EFI_SYSTEM_RESOURCE_ENTRY));\r
69 Status = EFI_SUCCESS;\r
70 break;\r
71 }\r
72 }\r
73\r
74EXIT:\r
75 if (EsrtRepository != NULL) {\r
76 FreePool(EsrtRepository);\r
77 }\r
78\r
79 return Status;\r
80}\r
81\r
82/**\r
83 Insert a new ESRT entry into ESRT Cache repository.\r
84\r
85 @param[in] Entry Esrt entry to be set\r
86 @param[in] Attribute Esrt from Esrt private protocol or FMP instance\r
d1102dba 87\r
acd32208
CZ
88 @retval EFI_SUCCESS Successfully set a variable.\r
89\r
90**/\r
91EFI_STATUS\r
92InsertEsrtEntry(\r
93 IN EFI_SYSTEM_RESOURCE_ENTRY *Entry,\r
94 UINTN Attribute\r
95 )\r
96{\r
97 EFI_STATUS Status;\r
98 CHAR16 *VariableName;\r
99 EFI_SYSTEM_RESOURCE_ENTRY *EsrtRepository;\r
100 UINTN RepositorySize;\r
101 EFI_SYSTEM_RESOURCE_ENTRY *EsrtRepositoryNew;\r
102\r
103 EsrtRepository = NULL;\r
104 EsrtRepositoryNew = NULL;\r
105\r
106 //\r
107 // Get Esrt index buffer\r
108 //\r
109 if (Attribute == ESRT_FROM_FMP) {\r
110 VariableName = EFI_ESRT_FMP_VARIABLE_NAME;\r
111 } else {\r
112 VariableName = EFI_ESRT_NONFMP_VARIABLE_NAME;\r
113 }\r
114\r
115 Status = GetVariable2 (\r
116 VariableName,\r
117 &gEfiCallerIdGuid,\r
118 (VOID **) &EsrtRepository,\r
119 &RepositorySize\r
120 );\r
121\r
122 if (Status == EFI_NOT_FOUND) {\r
123 //\r
124 // If not exist, create new Esrt cache repository\r
125 //\r
126 Status = gRT->SetVariable(\r
127 VariableName,\r
128 &gEfiCallerIdGuid,\r
129 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
130 sizeof(EFI_SYSTEM_RESOURCE_ENTRY),\r
131 Entry\r
132 );\r
133 return Status;\r
134\r
135 } else if (Status == EFI_SUCCESS) {\r
136 //\r
137 // if exist, update Esrt cache repository\r
138 //\r
139 if (RepositorySize % sizeof(EFI_SYSTEM_RESOURCE_ENTRY) != 0) {\r
87000d77 140 DEBUG((DEBUG_ERROR, "Repository Corrupt. Need to rebuild Repository.\n"));\r
acd32208
CZ
141 //\r
142 // Repository is corrupt. Clear Repository before insert new entry\r
143 //\r
144 Status = gRT->SetVariable(\r
145 VariableName,\r
146 &gEfiCallerIdGuid,\r
147 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
148 0,\r
149 EsrtRepository\r
150 );\r
151 FreePool(EsrtRepository);\r
152 RepositorySize = 0;\r
153 EsrtRepository = NULL;\r
154 }\r
155\r
156 //\r
157 // Check Repository size constraint\r
158 //\r
159 if ((Attribute == ESRT_FROM_FMP && RepositorySize >= PcdGet32(PcdMaxFmpEsrtCacheNum) * sizeof(EFI_SYSTEM_RESOURCE_ENTRY))\r
160 ||(Attribute == ESRT_FROM_NONFMP && RepositorySize >= PcdGet32(PcdMaxNonFmpEsrtCacheNum) * sizeof(EFI_SYSTEM_RESOURCE_ENTRY)) ) {\r
161 Status = EFI_OUT_OF_RESOURCES;\r
162 goto EXIT;\r
163 }\r
164\r
165 EsrtRepositoryNew = AllocatePool(RepositorySize + sizeof(EFI_SYSTEM_RESOURCE_ENTRY));\r
166 if (EsrtRepositoryNew == NULL) {\r
167 Status = EFI_OUT_OF_RESOURCES;\r
168 goto EXIT;\r
169 }\r
170\r
a3ac2587 171 if (RepositorySize != 0 && EsrtRepository != NULL) {\r
acd32208
CZ
172 CopyMem(EsrtRepositoryNew, EsrtRepository, RepositorySize);\r
173 }\r
174 CopyMem((UINT8 *)EsrtRepositoryNew + RepositorySize, Entry, sizeof(EFI_SYSTEM_RESOURCE_ENTRY));\r
175\r
176 Status = gRT->SetVariable(\r
177 VariableName,\r
178 &gEfiCallerIdGuid,\r
179 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
180 RepositorySize + sizeof(EFI_SYSTEM_RESOURCE_ENTRY),\r
181 EsrtRepositoryNew\r
182 );\r
183 }\r
184\r
185EXIT:\r
186 if (EsrtRepository != NULL) {\r
187 FreePool(EsrtRepository);\r
188 }\r
189\r
190 if (EsrtRepositoryNew != NULL) {\r
191 FreePool(EsrtRepositoryNew);\r
192 }\r
193\r
194 return Status;\r
195}\r
196\r
197/**\r
d1102dba 198 Delete ESRT Entry from ESRT repository.\r
acd32208 199\r
d1102dba 200 @param[in] FwClass FwClass of Esrt entry to delete\r
acd32208 201 @param[in] Attribute Esrt from Esrt private protocol or FMP instance\r
d1102dba
LG
202\r
203 @retval EFI_SUCCESS Insert all entries Successfully\r
acd32208 204 @retval EFI_NOT_FOUND ESRT entry with FwClass doesn't exsit\r
d1102dba 205\r
acd32208
CZ
206**/\r
207EFI_STATUS\r
208DeleteEsrtEntry(\r
209 IN EFI_GUID *FwClass,\r
210 IN UINTN Attribute\r
211 )\r
d1102dba 212{\r
acd32208
CZ
213 EFI_STATUS Status;\r
214 CHAR16 *VariableName;\r
215 EFI_SYSTEM_RESOURCE_ENTRY *EsrtRepository;\r
216 UINTN RepositorySize;\r
217 UINTN Index;\r
218 UINTN EsrtNum;\r
219\r
220 EsrtRepository = NULL;\r
d1102dba 221\r
acd32208
CZ
222 //\r
223 // Get Esrt index buffer\r
224 //\r
225 if (Attribute == ESRT_FROM_FMP) {\r
226 VariableName = EFI_ESRT_FMP_VARIABLE_NAME;\r
227 } else {\r
228 VariableName = EFI_ESRT_NONFMP_VARIABLE_NAME;\r
229 }\r
d1102dba 230\r
acd32208
CZ
231 Status = GetVariable2 (\r
232 VariableName,\r
233 &gEfiCallerIdGuid,\r
234 (VOID **) &EsrtRepository,\r
235 &RepositorySize\r
236 );\r
237\r
238 if (EFI_ERROR(Status)) {\r
239 goto EXIT;\r
240 }\r
241\r
3fb7e094
SZ
242 if (EsrtRepository == NULL) {\r
243 Status = EFI_OUT_OF_RESOURCES;\r
244 goto EXIT;\r
245 }\r
246\r
acd32208 247 if ((RepositorySize % sizeof(EFI_SYSTEM_RESOURCE_ENTRY)) != 0) {\r
87000d77 248 DEBUG((DEBUG_ERROR, "Repository Corrupt. Need to rebuild Repository.\n"));\r
acd32208
CZ
249 //\r
250 // Repository is corrupt. Clear Repository before insert new entry\r
251 //\r
252 Status = gRT->SetVariable(\r
253 VariableName,\r
254 &gEfiCallerIdGuid,\r
255 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
256 0,\r
257 EsrtRepository\r
258 );\r
259 goto EXIT;\r
260 }\r
261\r
262 Status = EFI_NOT_FOUND;\r
263 EsrtNum = RepositorySize/sizeof(EFI_SYSTEM_RESOURCE_ENTRY);\r
264 for (Index = 0; Index < EsrtNum; Index++) {\r
265 //\r
266 // Delete Esrt entry if it is found in repository\r
267 //\r
268 if (CompareGuid(FwClass, &EsrtRepository[Index].FwClass)) {\r
269 //\r
270 // If delete Esrt entry is not at the rail\r
271 //\r
272 if (Index < EsrtNum - 1) {\r
273 CopyMem(&EsrtRepository[Index], &EsrtRepository[Index + 1], (EsrtNum - Index - 1) * sizeof(EFI_SYSTEM_RESOURCE_ENTRY));\r
274 }\r
275\r
276 //\r
277 // Update New Repository\r
278 //\r
279 Status = gRT->SetVariable(\r
280 VariableName,\r
281 &gEfiCallerIdGuid,\r
282 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
283 (EsrtNum - 1) * sizeof(EFI_SYSTEM_RESOURCE_ENTRY),\r
284 EsrtRepository\r
285 );\r
286 break;\r
287 }\r
288 }\r
289\r
290EXIT:\r
291 if (EsrtRepository != NULL) {\r
292 FreePool(EsrtRepository);\r
293 }\r
294\r
295 return Status;\r
296\r
297}\r
298\r
299/**\r
300 Update one ESRT entry in ESRT repository\r
301\r
302 @param[in] Entry Esrt entry to be set\r
303 @param[in] Attribute Esrt from Non Esrt or FMP instance\r
d1102dba 304\r
acd32208
CZ
305 @retval EFI_SUCCESS Successfully Update a variable.\r
306 @retval EFI_NOT_FOUND The Esrt enry doesn't exist\r
307\r
308**/\r
309EFI_STATUS\r
310UpdateEsrtEntry(\r
311 IN EFI_SYSTEM_RESOURCE_ENTRY *Entry,\r
312 UINTN Attribute\r
313 )\r
314{\r
315 EFI_STATUS Status;\r
316 CHAR16 *VariableName;\r
317 EFI_SYSTEM_RESOURCE_ENTRY *EsrtRepository;\r
318 UINTN RepositorySize;\r
319 UINTN Index;\r
320 UINTN EsrtNum;\r
321\r
322 EsrtRepository = NULL;\r
323\r
324 //\r
325 // Get Esrt index buffer\r
326 //\r
327 if (Attribute == ESRT_FROM_FMP) {\r
328 VariableName = EFI_ESRT_FMP_VARIABLE_NAME;\r
329 } else {\r
330 VariableName = EFI_ESRT_NONFMP_VARIABLE_NAME;\r
331 }\r
332\r
333 Status = GetVariable2 (\r
334 VariableName,\r
335 &gEfiCallerIdGuid,\r
336 (VOID **) &EsrtRepository,\r
337 &RepositorySize\r
338 );\r
339\r
3fb7e094
SZ
340 if (EsrtRepository == NULL) {\r
341 Status = EFI_OUT_OF_RESOURCES;\r
342 goto EXIT;\r
343 }\r
344\r
acd32208
CZ
345 if (!EFI_ERROR(Status)) {\r
346 //\r
347 // if exist, update Esrt cache repository\r
348 //\r
349 if (RepositorySize % sizeof(EFI_SYSTEM_RESOURCE_ENTRY) != 0) {\r
87000d77 350 DEBUG((DEBUG_ERROR, "Repository Corrupt. Need to rebuild Repository.\n"));\r
acd32208
CZ
351 //\r
352 // Repository is corrupt. Clear Repository before insert new entry\r
353 //\r
354 Status = gRT->SetVariable(\r
355 VariableName,\r
356 &gEfiCallerIdGuid,\r
357 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
358 0,\r
359 EsrtRepository\r
360 );\r
361 Status = EFI_NOT_FOUND;\r
362 goto EXIT;\r
363 }\r
364\r
365 Status = EFI_NOT_FOUND;\r
366 EsrtNum = RepositorySize/sizeof(EFI_SYSTEM_RESOURCE_ENTRY);\r
367 for (Index = 0; Index < EsrtNum; Index++) {\r
368 //\r
369 // Update Esrt entry if it is found in repository\r
370 //\r
371 if (CompareGuid(&Entry->FwClass, &EsrtRepository[Index].FwClass)) {\r
372\r
373 CopyMem(&EsrtRepository[Index], Entry, sizeof(EFI_SYSTEM_RESOURCE_ENTRY));\r
374 //\r
375 // Update New Repository\r
376 //\r
377 Status = gRT->SetVariable(\r
378 VariableName,\r
379 &gEfiCallerIdGuid,\r
380 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
381 RepositorySize,\r
382 EsrtRepository\r
383 );\r
384 break;\r
385 }\r
386 }\r
387 }\r
388\r
389EXIT:\r
390 if (EsrtRepository != NULL) {\r
391 FreePool(EsrtRepository);\r
392 }\r
393\r
394 return Status;\r
395}\r
396\r
ab3aac14
JY
397/**\r
398 Return if this FMP is a system FMP or a device FMP, based upon FmpImageInfo.\r
399\r
400 @param[in] FmpImageInfo A pointer to EFI_FIRMWARE_IMAGE_DESCRIPTOR\r
401\r
402 @return TRUE It is a system FMP.\r
403 @return FALSE It is a device FMP.\r
404**/\r
405BOOLEAN\r
406IsSystemFmp (\r
407 IN EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfo\r
408 )\r
409{\r
410 GUID *Guid;\r
411 UINTN Count;\r
412 UINTN Index;\r
413\r
414 Guid = PcdGetPtr(PcdSystemFmpCapsuleImageTypeIdGuid);\r
415 Count = PcdGetSize(PcdSystemFmpCapsuleImageTypeIdGuid)/sizeof(GUID);\r
416\r
417 for (Index = 0; Index < Count; Index++, Guid++) {\r
418 if (CompareGuid(&FmpImageInfo->ImageTypeId, Guid)) {\r
419 return TRUE;\r
420 }\r
421 }\r
422\r
423 return FALSE;\r
424}\r
425\r
acd32208
CZ
426/**\r
427 Init one ESRT entry according to input FmpImageInfo (V1, V2, V3) .\r
428\r
a3ac2587
CZ
429 @param[in, out] EsrtEntry Esrt entry to be Init\r
430 @param[in] FmpImageInfo FMP image info descriptor\r
431 @param[in] DescriptorVersion FMP Image info descriptor version\r
d1102dba 432\r
acd32208 433**/\r
d1102dba 434VOID\r
acd32208
CZ
435SetEsrtEntryFromFmpInfo (\r
436 IN OUT EFI_SYSTEM_RESOURCE_ENTRY *EsrtEntry,\r
437 IN EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfo,\r
438 IN UINT32 DescriptorVersion\r
439 )\r
440{\r
441 EsrtEntry->FwVersion = FmpImageInfo->Version;\r
442 EsrtEntry->FwClass = FmpImageInfo->ImageTypeId;\r
ab3aac14
JY
443 if (IsSystemFmp(FmpImageInfo)) {\r
444 EsrtEntry->FwType = ESRT_FW_TYPE_SYSTEMFIRMWARE;\r
445 } else {\r
446 EsrtEntry->FwType = ESRT_FW_TYPE_DEVICEFIRMWARE;\r
447 }\r
acd32208
CZ
448 EsrtEntry->LowestSupportedFwVersion = 0;\r
449 EsrtEntry->CapsuleFlags = 0;\r
450 EsrtEntry->LastAttemptVersion = 0;\r
451 EsrtEntry->LastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS;\r
452\r
453 if (DescriptorVersion >= 2) {\r
454 //\r
455 // LowestSupportedImageVersion only available in FMP V2 or higher\r
456 //\r
457 EsrtEntry->LowestSupportedFwVersion = FmpImageInfo->LowestSupportedImageVersion;\r
d1102dba 458 }\r
acd32208
CZ
459\r
460 if (DescriptorVersion >= 3) {\r
461 //\r
462 // LastAttemptVersion & LastAttemptStatus only available in FMP V3 or higher\r
463 //\r
464 EsrtEntry->LastAttemptVersion = FmpImageInfo->LastAttemptVersion;\r
465 EsrtEntry->LastAttemptStatus = FmpImageInfo->LastAttemptStatus;\r
d1102dba 466 }\r
acd32208
CZ
467\r
468 //\r
469 // Set capsule customized flag\r
470 //\r
471 if ((FmpImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_RESET_REQUIRED) != 0\r
472 && (FmpImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_RESET_REQUIRED) != 0) {\r
473 EsrtEntry->CapsuleFlags = PcdGet16(PcdSystemRebootAfterCapsuleProcessFlag);\r
474 }\r
475}\r