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