]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Application/CapsuleApp/CapsuleDump.c
MdeModulePkg CapsuleApp: Check capsule header for -D and -N options
[mirror_edk2.git] / MdeModulePkg / Application / CapsuleApp / CapsuleDump.c
CommitLineData
592bad04
JY
1/** @file\r
2 Dump Capsule image information.\r
3\r
2e3032b4 4 Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>\r
592bad04
JY
5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include <PiDxe.h>\r
16#include <Library/BaseLib.h>\r
17#include <Library/DebugLib.h>\r
18#include <Library/BaseMemoryLib.h>\r
19#include <Library/MemoryAllocationLib.h>\r
20#include <Library/UefiBootServicesTableLib.h>\r
21#include <Library/UefiRuntimeServicesTableLib.h>\r
22#include <Library/UefiLib.h>\r
23#include <Library/PrintLib.h>\r
24#include <Protocol/FirmwareManagement.h>\r
25#include <Guid/ImageAuthentication.h>\r
26#include <Guid/CapsuleReport.h>\r
27#include <Guid/SystemResourceTable.h>\r
28#include <Guid/FmpCapsule.h>\r
29#include <IndustryStandard/WindowsUxCapsule.h>\r
30\r
31/**\r
32 Read a file.\r
33\r
11ee1bc9
DB
34 @param[in] FileName The file to be read.\r
35 @param[out] BufferSize The file buffer size\r
36 @param[out] Buffer The file buffer\r
592bad04
JY
37\r
38 @retval EFI_SUCCESS Read file successfully\r
39 @retval EFI_NOT_FOUND File not found\r
40**/\r
41EFI_STATUS\r
42ReadFileToBuffer (\r
43 IN CHAR16 *FileName,\r
44 OUT UINTN *BufferSize,\r
45 OUT VOID **Buffer\r
46 );\r
47\r
1e09ec09
JY
48/**\r
49 Write a file.\r
50\r
51 @param[in] FileName The file to be written.\r
52 @param[in] BufferSize The file buffer size\r
53 @param[in] Buffer The file buffer\r
54\r
55 @retval EFI_SUCCESS Write file successfully\r
56**/\r
57EFI_STATUS\r
58WriteFileFromBuffer (\r
59 IN CHAR16 *FileName,\r
60 IN UINTN BufferSize,\r
61 IN VOID *Buffer\r
62 );\r
63\r
fb57c30b
SZ
64/**\r
65 Validate if it is valid capsule header\r
66\r
67 This function assumes the caller provided correct CapsuleHeader pointer\r
68 and CapsuleSize.\r
69\r
70 This function validates the fields in EFI_CAPSULE_HEADER.\r
71\r
72 @param[in] CapsuleHeader Points to a capsule header.\r
73 @param[in] CapsuleSize Size of the whole capsule image.\r
74\r
75**/\r
76BOOLEAN\r
77IsValidCapsuleHeader (\r
78 IN EFI_CAPSULE_HEADER *CapsuleHeader,\r
79 IN UINT64 CapsuleSize\r
80 );\r
81\r
592bad04
JY
82/**\r
83 Dump UX capsule information.\r
84\r
85 @param[in] CapsuleHeader The UX capsule header\r
86**/\r
87VOID\r
88DumpUxCapsule (\r
89 IN EFI_CAPSULE_HEADER *CapsuleHeader\r
90 )\r
91{\r
92 EFI_DISPLAY_CAPSULE *DisplayCapsule;\r
93 DisplayCapsule = (EFI_DISPLAY_CAPSULE *)CapsuleHeader;\r
94 Print(L"[UxCapusule]\n");\r
95 Print(L"CapsuleHeader:\n");\r
96 Print(L" CapsuleGuid - %g\n", &DisplayCapsule->CapsuleHeader.CapsuleGuid);\r
97 Print(L" HeaderSize - 0x%x\n", DisplayCapsule->CapsuleHeader.HeaderSize);\r
98 Print(L" Flags - 0x%x\n", DisplayCapsule->CapsuleHeader.Flags);\r
99 Print(L" CapsuleImageSize - 0x%x\n", DisplayCapsule->CapsuleHeader.CapsuleImageSize);\r
100 Print(L"ImagePayload:\n");\r
101 Print(L" Version - 0x%x\n", DisplayCapsule->ImagePayload.Version);\r
102 Print(L" Checksum - 0x%x\n", DisplayCapsule->ImagePayload.Checksum);\r
103 Print(L" ImageType - 0x%x\n", DisplayCapsule->ImagePayload.ImageType);\r
104 Print(L" Mode - 0x%x\n", DisplayCapsule->ImagePayload.Mode);\r
105 Print(L" OffsetX - 0x%x\n", DisplayCapsule->ImagePayload.OffsetX);\r
106 Print(L" OffsetY - 0x%x\n", DisplayCapsule->ImagePayload.OffsetY);\r
107}\r
108\r
109/**\r
110 Dump FMP image authentication information.\r
111\r
112 @param[in] Image The FMP capsule image\r
113 @param[in] ImageSize The size of the FMP capsule image in bytes.\r
114\r
115 @return the size of FMP authentication.\r
116**/\r
117UINTN\r
118DumpImageAuthentication (\r
119 IN VOID *Image,\r
120 IN UINTN ImageSize\r
121 )\r
122{\r
123 EFI_FIRMWARE_IMAGE_AUTHENTICATION *ImageAuthentication;\r
124\r
125 ImageAuthentication = Image;\r
126 if (CompareGuid(&ImageAuthentication->AuthInfo.CertType, &gEfiCertPkcs7Guid) ||\r
127 CompareGuid(&ImageAuthentication->AuthInfo.CertType, &gEfiCertTypeRsa2048Sha256Guid)) {\r
128 Print(L"[ImageAuthentication]\n");\r
129 Print(L" MonotonicCount - 0x%lx\n", ImageAuthentication->MonotonicCount);\r
130 Print(L"WIN_CERTIFICATE:\n");\r
131 Print(L" dwLength - 0x%x\n", ImageAuthentication->AuthInfo.Hdr.dwLength);\r
132 Print(L" wRevision - 0x%x\n", ImageAuthentication->AuthInfo.Hdr.wRevision);\r
133 Print(L" wCertificateType - 0x%x\n", ImageAuthentication->AuthInfo.Hdr.wCertificateType);\r
134 Print(L" CertType - %g\n", &ImageAuthentication->AuthInfo.CertType);\r
135 return sizeof(ImageAuthentication->MonotonicCount) + ImageAuthentication->AuthInfo.Hdr.dwLength;\r
136 } else {\r
137 return 0;\r
138 }\r
139}\r
140\r
141/**\r
142 Dump a non-nested FMP capsule.\r
143\r
144 @param[in] CapsuleHeader A pointer to CapsuleHeader\r
145**/\r
146VOID\r
147DumpFmpCapsule (\r
148 IN EFI_CAPSULE_HEADER *CapsuleHeader\r
149 )\r
150{\r
151 EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER *FmpCapsuleHeader;\r
152 UINT64 *ItemOffsetList;\r
153 UINTN Index;\r
154 UINTN Count;\r
155 EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *FmpImageHeader;\r
156\r
157 Print(L"[FmpCapusule]\n");\r
158 Print(L"CapsuleHeader:\n");\r
159 Print(L" CapsuleGuid - %g\n", &CapsuleHeader->CapsuleGuid);\r
160 Print(L" HeaderSize - 0x%x\n", CapsuleHeader->HeaderSize);\r
161 Print(L" Flags - 0x%x\n", CapsuleHeader->Flags);\r
162 Print(L" CapsuleImageSize - 0x%x\n", CapsuleHeader->CapsuleImageSize);\r
163\r
164 FmpCapsuleHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER *)((UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize);\r
165 ItemOffsetList = (UINT64 *)(FmpCapsuleHeader + 1);\r
166 Print(L"FmpHeader:\n");\r
167 Print(L" Version - 0x%x\n", FmpCapsuleHeader->Version);\r
168 Print(L" EmbeddedDriverCount - 0x%x\n", FmpCapsuleHeader->EmbeddedDriverCount);\r
169 Print(L" PayloadItemCount - 0x%x\n", FmpCapsuleHeader->PayloadItemCount);\r
170 Count = FmpCapsuleHeader->EmbeddedDriverCount + FmpCapsuleHeader->PayloadItemCount;\r
171 for (Index = 0; Index < Count; Index++) {\r
172 Print(L" Offset[%d] - 0x%x\n", Index, ItemOffsetList[Index]);\r
173 }\r
174\r
175 for (Index = FmpCapsuleHeader->EmbeddedDriverCount; Index < Count; Index++) {\r
176 Print(L"FmpPayload[%d] ImageHeader:\n", Index);\r
177 FmpImageHeader = (EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER *)((UINT8 *)FmpCapsuleHeader + ItemOffsetList[Index]);\r
178 Print(L" Version - 0x%x\n", FmpImageHeader->Version);\r
179 Print(L" UpdateImageTypeId - %g\n", &FmpImageHeader->UpdateImageTypeId);\r
180 Print(L" UpdateImageIndex - 0x%x\n", FmpImageHeader->UpdateImageIndex);\r
181 Print(L" UpdateImageSize - 0x%x\n", FmpImageHeader->UpdateImageSize);\r
182 Print(L" UpdateVendorCodeSize - 0x%x\n", FmpImageHeader->UpdateVendorCodeSize);\r
183 if (FmpImageHeader->Version >= EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION) {\r
184 Print(L" UpdateHardwareInstance - 0x%lx\n", FmpImageHeader->UpdateHardwareInstance);\r
185 }\r
186 }\r
187}\r
188\r
189/**\r
190 Return if there is a FMP header below capsule header.\r
191\r
192 @param[in] CapsuleHeader A pointer to EFI_CAPSULE_HEADER\r
193\r
194 @retval TRUE There is a FMP header below capsule header.\r
195 @retval FALSE There is not a FMP header below capsule header\r
196**/\r
197BOOLEAN\r
198IsNestedFmpCapsule (\r
199 IN EFI_CAPSULE_HEADER *CapsuleHeader\r
200 )\r
201{\r
202 EFI_STATUS Status;\r
203 EFI_SYSTEM_RESOURCE_TABLE *Esrt;\r
204 EFI_SYSTEM_RESOURCE_ENTRY *EsrtEntry;\r
205 UINTN Index;\r
206 BOOLEAN EsrtGuidFound;\r
207 EFI_CAPSULE_HEADER *NestedCapsuleHeader;\r
208 UINTN NestedCapsuleSize;\r
209\r
210 //\r
211 // Check ESRT\r
212 //\r
213 EsrtGuidFound = FALSE;\r
214 Status = EfiGetSystemConfigurationTable(&gEfiSystemResourceTableGuid, (VOID **)&Esrt);\r
215 if (!EFI_ERROR(Status)) {\r
216 ASSERT (Esrt != NULL);\r
217 EsrtEntry = (VOID *)(Esrt + 1);\r
218 for (Index = 0; Index < Esrt->FwResourceCount; Index++, EsrtEntry++) {\r
219 if (CompareGuid(&EsrtEntry->FwClass, &CapsuleHeader->CapsuleGuid)) {\r
220 EsrtGuidFound = TRUE;\r
221 break;\r
222 }\r
223 }\r
224 }\r
225\r
226 if (!EsrtGuidFound) {\r
227 return FALSE;\r
228 }\r
229\r
230 //\r
231 // Check nested capsule header\r
232 // FMP GUID after ESRT one\r
233 //\r
234 NestedCapsuleHeader = (EFI_CAPSULE_HEADER *)((UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize);\r
23d08334 235 NestedCapsuleSize = (UINTN)CapsuleHeader + CapsuleHeader->CapsuleImageSize- (UINTN)NestedCapsuleHeader;\r
592bad04
JY
236 if (NestedCapsuleSize < sizeof(EFI_CAPSULE_HEADER)) {\r
237 return FALSE;\r
238 }\r
239 if (!CompareGuid(&NestedCapsuleHeader->CapsuleGuid, &gEfiFmpCapsuleGuid)) {\r
240 return FALSE;\r
241 }\r
242 return TRUE;\r
243}\r
244\r
245/**\r
246 Dump capsule information\r
247\r
248 @param[in] CapsuleName The name of the capsule image.\r
249\r
250 @retval EFI_SUCCESS The capsule information is dumped.\r
251 @retval EFI_UNSUPPORTED Input parameter is not valid.\r
252**/\r
253EFI_STATUS\r
254DumpCapsule (\r
255 IN CHAR16 *CapsuleName\r
256 )\r
257{\r
258 VOID *Buffer;\r
259 UINTN FileSize;\r
260 EFI_CAPSULE_HEADER *CapsuleHeader;\r
261 EFI_STATUS Status;\r
262\r
2e3032b4 263 Buffer = NULL;\r
592bad04
JY
264 Status = ReadFileToBuffer(CapsuleName, &FileSize, &Buffer);\r
265 if (EFI_ERROR(Status)) {\r
266 Print(L"CapsuleApp: Capsule (%s) is not found.\n", CapsuleName);\r
267 goto Done;\r
268 }\r
fb57c30b
SZ
269 if (!IsValidCapsuleHeader (Buffer, FileSize)) {\r
270 Print(L"CapsuleApp: Capsule image (%s) is not a valid capsule.\n", CapsuleName);\r
271 Status = EFI_INVALID_PARAMETER;\r
272 goto Done;\r
273 }\r
592bad04
JY
274\r
275 CapsuleHeader = Buffer;\r
276 if (CompareGuid(&CapsuleHeader->CapsuleGuid, &gWindowsUxCapsuleGuid)) {\r
277 DumpUxCapsule(CapsuleHeader);\r
278 Status = EFI_SUCCESS;\r
279 goto Done;\r
280 }\r
281\r
282 if (CompareGuid(&CapsuleHeader->CapsuleGuid, &gEfiFmpCapsuleGuid)) {\r
283 DumpFmpCapsule(CapsuleHeader);\r
284 }\r
285 if (IsNestedFmpCapsule(CapsuleHeader)) {\r
286 Print(L"[NestedCapusule]\n");\r
287 Print(L"CapsuleHeader:\n");\r
288 Print(L" CapsuleGuid - %g\n", &CapsuleHeader->CapsuleGuid);\r
289 Print(L" HeaderSize - 0x%x\n", CapsuleHeader->HeaderSize);\r
290 Print(L" Flags - 0x%x\n", CapsuleHeader->Flags);\r
291 Print(L" CapsuleImageSize - 0x%x\n", CapsuleHeader->CapsuleImageSize);\r
292 DumpFmpCapsule((EFI_CAPSULE_HEADER *)((UINTN)CapsuleHeader + CapsuleHeader->HeaderSize));\r
293 }\r
294\r
295Done:\r
2e3032b4
SZ
296 if (Buffer != NULL) {\r
297 FreePool(Buffer);\r
298 }\r
592bad04
JY
299 return Status;\r
300}\r
301\r
302/**\r
303 Dump capsule status variable.\r
304\r
305 @retval EFI_SUCCESS The capsule status variable is dumped.\r
306 @retval EFI_UNSUPPORTED Input parameter is not valid.\r
307**/\r
308EFI_STATUS\r
8b03c82d 309DumpCapsuleStatusVariable (\r
592bad04
JY
310 VOID\r
311 )\r
312{\r
313 EFI_STATUS Status;\r
314 UINT32 Index;\r
315 CHAR16 CapsuleVarName[20];\r
316 CHAR16 *TempVarName;\r
317 EFI_CAPSULE_RESULT_VARIABLE_HEADER *CapsuleResult;\r
318 EFI_CAPSULE_RESULT_VARIABLE_FMP *CapsuleResultFmp;\r
319 UINTN CapsuleFileNameSize;\r
320 CHAR16 CapsuleIndexData[12];\r
321 CHAR16 *CapsuleIndex;\r
de5209d5
JY
322 CHAR16 *CapsuleFileName;\r
323 CHAR16 *CapsuleTarget;\r
592bad04
JY
324\r
325 Status = GetVariable2(\r
326 L"CapsuleMax",\r
327 &gEfiCapsuleReportGuid,\r
328 (VOID **)&CapsuleIndex,\r
329 NULL\r
330 );\r
331 if (!EFI_ERROR(Status)) {\r
a522ad7c 332 ASSERT (CapsuleIndex != NULL);\r
592bad04
JY
333 CopyMem(CapsuleIndexData, CapsuleIndex, 11 * sizeof(CHAR16));\r
334 CapsuleIndexData[11] = 0;\r
335 Print(L"CapsuleMax - %s\n", CapsuleIndexData);\r
336 FreePool(CapsuleIndex);\r
337 }\r
338 Status = GetVariable2(\r
339 L"CapsuleLast",\r
340 &gEfiCapsuleReportGuid,\r
341 (VOID **)&CapsuleIndex,\r
342 NULL\r
343 );\r
344 if (!EFI_ERROR(Status)) {\r
a522ad7c 345 ASSERT (CapsuleIndex != NULL);\r
592bad04
JY
346 CopyMem(CapsuleIndexData, CapsuleIndex, 11 * sizeof(CHAR16));\r
347 CapsuleIndexData[11] = 0;\r
348 Print(L"CapsuleLast - %s\n", CapsuleIndexData);\r
349 FreePool(CapsuleIndex);\r
350 }\r
351\r
352\r
353 StrCpyS (CapsuleVarName, sizeof(CapsuleVarName)/sizeof(CapsuleVarName[0]), L"Capsule");\r
354 TempVarName = CapsuleVarName + StrLen (CapsuleVarName);\r
355 Index = 0;\r
356\r
357 while (TRUE) {\r
358 UnicodeSPrint (TempVarName, 5 * sizeof(CHAR16), L"%04x", Index);\r
359\r
360 Status = GetVariable2 (\r
361 CapsuleVarName,\r
362 &gEfiCapsuleReportGuid,\r
363 (VOID **) &CapsuleResult,\r
364 NULL\r
365 );\r
366 if (Status == EFI_NOT_FOUND) {\r
367 break;\r
368 } else if (EFI_ERROR(Status)) {\r
369 continue;\r
370 }\r
371 ASSERT (CapsuleResult != NULL);\r
372\r
373 //\r
374 // display capsule process status\r
375 //\r
376 if (CapsuleResult->VariableTotalSize >= sizeof(EFI_CAPSULE_RESULT_VARIABLE_HEADER)) {\r
377 Print (L"CapsuleName: %s\n", CapsuleVarName);\r
378 Print (L" Capsule Guid: %g\n", &CapsuleResult->CapsuleGuid);\r
379 Print (L" Capsule ProcessedTime: %t\n", &CapsuleResult->CapsuleProcessed);\r
380 Print (L" Capsule Status: %r\n", CapsuleResult->CapsuleStatus);\r
381 }\r
382\r
383 if (CompareGuid(&CapsuleResult->CapsuleGuid, &gEfiFmpCapsuleGuid)) {\r
de5209d5 384 if (CapsuleResult->VariableTotalSize >= sizeof(EFI_CAPSULE_RESULT_VARIABLE_HEADER) + sizeof(EFI_CAPSULE_RESULT_VARIABLE_FMP) + sizeof(CHAR16) * 2) {\r
592bad04
JY
385 CapsuleResultFmp = (EFI_CAPSULE_RESULT_VARIABLE_FMP *)(CapsuleResult + 1);\r
386 Print(L" Capsule FMP Version: 0x%x\n", CapsuleResultFmp->Version);\r
387 Print(L" Capsule FMP PayloadIndex: 0x%x\n", CapsuleResultFmp->PayloadIndex);\r
388 Print(L" Capsule FMP UpdateImageIndex: 0x%x\n", CapsuleResultFmp->UpdateImageIndex);\r
389 Print(L" Capsule FMP UpdateImageTypeId: %g\n", &CapsuleResultFmp->UpdateImageTypeId);\r
de5209d5
JY
390 CapsuleFileName = (CHAR16 *)(CapsuleResultFmp + 1);\r
391 Print(L" Capsule FMP CapsuleFileName: \"%s\"\n", CapsuleFileName);\r
392 CapsuleFileNameSize = StrSize(CapsuleFileName);\r
393 CapsuleTarget = (CHAR16 *)((UINTN)CapsuleFileName + CapsuleFileNameSize);\r
394 Print(L" Capsule FMP CapsuleTarget: \"%s\"\n", CapsuleTarget);\r
592bad04
JY
395 }\r
396 }\r
397\r
398 FreePool(CapsuleResult);\r
399\r
400 Index++;\r
401 if (Index > 0xFFFF) {\r
402 break;\r
403 }\r
404 }\r
405\r
406 return EFI_SUCCESS;\r
407}\r
408\r
409CHAR8 *mFwTypeString[] = {\r
410 "Unknown",\r
411 "SystemFirmware",\r
412 "DeviceFirmware",\r
413 "UefiDriver",\r
414};\r
415\r
416CHAR8 *mLastAttemptStatusString[] = {\r
417 "Success",\r
418 "Error: Unsuccessful",\r
419 "Error: Insufficient Resources",\r
420 "Error: Incorrect Version",\r
421 "Error: Invalid Format",\r
422 "Error: Auth Error",\r
423 "Error: Power Event AC",\r
424 "Error: Power Event Battery",\r
425};\r
426\r
427/**\r
428 Convert FwType to a string.\r
429\r
430 @param[in] FwType FwType in ESRT\r
431\r
432 @return a string for FwType.\r
433**/\r
434CHAR8 *\r
435FwTypeToString (\r
436 IN UINT32 FwType\r
437 )\r
438{\r
439 if (FwType < sizeof(mFwTypeString) / sizeof(mFwTypeString[0])) {\r
440 return mFwTypeString[FwType];\r
441 } else {\r
442 return "Invalid";\r
443 }\r
444}\r
445\r
446/**\r
447 Convert LastAttemptStatus to a string.\r
448\r
449 @param[in] LastAttemptStatus LastAttemptStatus in FMP or ESRT\r
450\r
451 @return a string for LastAttemptStatus.\r
452**/\r
453CHAR8 *\r
454LastAttemptStatusToString (\r
455 IN UINT32 LastAttemptStatus\r
456 )\r
457{\r
458 if (LastAttemptStatus < sizeof(mLastAttemptStatusString) / sizeof(mLastAttemptStatusString[0])) {\r
459 return mLastAttemptStatusString[LastAttemptStatus];\r
460 } else {\r
461 return "Error: Unknown";\r
462 }\r
463}\r
464\r
465/**\r
466 Dump ESRT entry.\r
467\r
468 @param[in] EsrtEntry ESRT entry\r
469**/\r
470VOID\r
471DumpEsrtEntry (\r
472 IN EFI_SYSTEM_RESOURCE_ENTRY *EsrtEntry\r
473 )\r
474{\r
475 Print(L" FwClass - %g\n", &EsrtEntry->FwClass);\r
476 Print(L" FwType - 0x%x (%a)\n", EsrtEntry->FwType, FwTypeToString(EsrtEntry->FwType));\r
477 Print(L" FwVersion - 0x%x\n", EsrtEntry->FwVersion);\r
478 Print(L" LowestSupportedFwVersion - 0x%x\n", EsrtEntry->LowestSupportedFwVersion);\r
479 Print(L" CapsuleFlags - 0x%x\n", EsrtEntry->CapsuleFlags);\r
592bad04
JY
480 Print(L" LastAttemptVersion - 0x%x\n", EsrtEntry->LastAttemptVersion);\r
481 Print(L" LastAttemptStatus - 0x%x (%a)\n", EsrtEntry->LastAttemptStatus, LastAttemptStatusToString(EsrtEntry->LastAttemptStatus));\r
482}\r
483\r
484/**\r
485 Dump ESRT table.\r
486\r
487 @param[in] Esrt ESRT table\r
488**/\r
489VOID\r
490DumpEsrt (\r
491 IN EFI_SYSTEM_RESOURCE_TABLE *Esrt\r
492 )\r
493{\r
494 UINTN Index;\r
495 EFI_SYSTEM_RESOURCE_ENTRY *EsrtEntry;\r
496\r
497 if (Esrt == NULL) {\r
498 return ;\r
499 }\r
500\r
501 Print(L"EFI_SYSTEM_RESOURCE_TABLE:\n");\r
502 Print(L"FwResourceCount - 0x%x\n", Esrt->FwResourceCount);\r
503 Print(L"FwResourceCountMax - 0x%x\n", Esrt->FwResourceCountMax);\r
504 Print(L"FwResourceVersion - 0x%lx\n", Esrt->FwResourceVersion);\r
505\r
506 EsrtEntry = (VOID *)(Esrt + 1);\r
507 for (Index = 0; Index < Esrt->FwResourceCount; Index++) {\r
508 Print(L"EFI_SYSTEM_RESOURCE_ENTRY (%d):\n", Index);\r
509 DumpEsrtEntry(EsrtEntry);\r
510 EsrtEntry++;\r
511 }\r
512}\r
513\r
514/**\r
515 Dump ESRT info.\r
516**/\r
517VOID\r
518DumpEsrtData (\r
519 VOID\r
520 )\r
521{\r
522 EFI_STATUS Status;\r
523 EFI_SYSTEM_RESOURCE_TABLE *Esrt;\r
524\r
525 Print(L"##############\n");\r
526 Print(L"# ESRT TABLE #\n");\r
527 Print(L"##############\n");\r
528\r
529 Status = EfiGetSystemConfigurationTable (&gEfiSystemResourceTableGuid, (VOID **)&Esrt);\r
530 if (EFI_ERROR(Status)) {\r
531 Print(L"ESRT - %r\n", Status);\r
532 return;\r
533 }\r
534 DumpEsrt(Esrt);\r
535 Print(L"\n");\r
536}\r
537\r
538/**\r
539 Dump FMP information.\r
540\r
541 @param[in] ImageInfoSize The size of ImageInfo, in bytes.\r
542 @param[in] ImageInfo A pointer to EFI_FIRMWARE_IMAGE_DESCRIPTOR.\r
543 @param[in] DescriptorVersion The version of EFI_FIRMWARE_IMAGE_DESCRIPTOR.\r
544 @param[in] DescriptorCount The count of EFI_FIRMWARE_IMAGE_DESCRIPTOR.\r
545 @param[in] DescriptorSize The size of an individual EFI_FIRMWARE_IMAGE_DESCRIPTOR, in bytes.\r
546 @param[in] PackageVersion The version of package.\r
547 @param[in] PackageVersionName The version name of package.\r
548**/\r
549VOID\r
550DumpFmpImageInfo (\r
551 IN UINTN ImageInfoSize,\r
552 IN EFI_FIRMWARE_IMAGE_DESCRIPTOR *ImageInfo,\r
553 IN UINT32 DescriptorVersion,\r
554 IN UINT8 DescriptorCount,\r
555 IN UINTN DescriptorSize,\r
556 IN UINT32 PackageVersion,\r
557 IN CHAR16 *PackageVersionName\r
558 )\r
559{\r
560 EFI_FIRMWARE_IMAGE_DESCRIPTOR *CurrentImageInfo;\r
561 UINTN Index;\r
562\r
563 Print(L" DescriptorVersion - 0x%x\n", DescriptorVersion);\r
564 Print(L" DescriptorCount - 0x%x\n", DescriptorCount);\r
565 Print(L" DescriptorSize - 0x%x\n", DescriptorSize);\r
566 Print(L" PackageVersion - 0x%x\n", PackageVersion);\r
567 Print(L" PackageVersionName - \"%s\"\n", PackageVersionName);\r
568 CurrentImageInfo = ImageInfo;\r
569 for (Index = 0; Index < DescriptorCount; Index++) {\r
570 Print(L" ImageDescriptor (%d)\n", Index);\r
571 Print(L" ImageIndex - 0x%x\n", CurrentImageInfo->ImageIndex);\r
572 Print(L" ImageTypeId - %g\n", &CurrentImageInfo->ImageTypeId);\r
573 Print(L" ImageId - 0x%lx\n", CurrentImageInfo->ImageId);\r
574 Print(L" ImageIdName - \"%s\"\n", CurrentImageInfo->ImageIdName);\r
575 Print(L" Version - 0x%x\n", CurrentImageInfo->Version);\r
576 Print(L" VersionName - \"%s\"\n", CurrentImageInfo->VersionName);\r
577 Print(L" Size - 0x%x\n", CurrentImageInfo->Size);\r
578 Print(L" AttributesSupported - 0x%lx\n", CurrentImageInfo->AttributesSupported);\r
579 Print(L" IMAGE_UPDATABLE - 0x%lx\n", CurrentImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_IMAGE_UPDATABLE);\r
580 Print(L" RESET_REQUIRED - 0x%lx\n", CurrentImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_RESET_REQUIRED);\r
581 Print(L" AUTHENTICATION_REQUIRED - 0x%lx\n", CurrentImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED);\r
582 Print(L" IN_USE - 0x%lx\n", CurrentImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_IN_USE);\r
583 Print(L" UEFI_IMAGE - 0x%lx\n", CurrentImageInfo->AttributesSupported & IMAGE_ATTRIBUTE_UEFI_IMAGE);\r
584 Print(L" AttributesSetting - 0x%lx\n", CurrentImageInfo->AttributesSetting);\r
585 Print(L" IMAGE_UPDATABLE - 0x%lx\n", CurrentImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_IMAGE_UPDATABLE);\r
586 Print(L" RESET_REQUIRED - 0x%lx\n", CurrentImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_RESET_REQUIRED);\r
587 Print(L" AUTHENTICATION_REQUIRED - 0x%lx\n", CurrentImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED);\r
588 Print(L" IN_USE - 0x%lx\n", CurrentImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_IN_USE);\r
589 Print(L" UEFI_IMAGE - 0x%lx\n", CurrentImageInfo->AttributesSetting & IMAGE_ATTRIBUTE_UEFI_IMAGE);\r
590 Print(L" Compatibilities - 0x%lx\n", CurrentImageInfo->Compatibilities);\r
591 Print(L" COMPATIB_CHECK_SUPPORTED - 0x%lx\n", CurrentImageInfo->Compatibilities & IMAGE_COMPATIBILITY_CHECK_SUPPORTED);\r
592 if (DescriptorVersion > 1) {\r
593 Print(L" LowestSupportedImageVersion - 0x%x\n", CurrentImageInfo->LowestSupportedImageVersion);\r
594 if (DescriptorVersion > 2) {\r
595 Print(L" LastAttemptVersion - 0x%x\n", CurrentImageInfo->LastAttemptVersion);\r
596 Print(L" LastAttemptStatus - 0x%x (%a)\n", CurrentImageInfo->LastAttemptStatus, LastAttemptStatusToString(CurrentImageInfo->LastAttemptStatus));\r
597 Print(L" HardwareInstance - 0x%lx\n", CurrentImageInfo->HardwareInstance);\r
598 }\r
599 }\r
600 //\r
601 // Use DescriptorSize to move ImageInfo Pointer to stay compatible with different ImageInfo version\r
602 //\r
603 CurrentImageInfo = (EFI_FIRMWARE_IMAGE_DESCRIPTOR *)((UINT8 *)CurrentImageInfo + DescriptorSize);\r
604 }\r
605}\r
606\r
607/**\r
608 Dump FMP package information.\r
609\r
610 @param[in] PackageVersion The version of package.\r
611 @param[in] PackageVersionName The version name of package.\r
612 @param[in] PackageVersionNameMaxLen The maximum length of PackageVersionName.\r
613 @param[in] AttributesSupported Package attributes that are supported by this device.\r
614 @param[in] AttributesSetting Package attributes.\r
615**/\r
616VOID\r
617DumpFmpPackageInfo (\r
618 IN UINT32 PackageVersion,\r
619 IN CHAR16 *PackageVersionName,\r
620 IN UINT32 PackageVersionNameMaxLen,\r
621 IN UINT64 AttributesSupported,\r
622 IN UINT64 AttributesSetting\r
623 )\r
624{\r
625 Print(L" PackageVersion - 0x%x\n", PackageVersion);\r
626 Print(L" PackageVersionName - \"%s\"\n", PackageVersionName);\r
627 Print(L" PackageVersionNameMaxLen - 0x%x\n", PackageVersionNameMaxLen);\r
628 Print(L" AttributesSupported - 0x%lx\n", AttributesSupported);\r
629 Print(L" IMAGE_UPDATABLE - 0x%lx\n", AttributesSupported & IMAGE_ATTRIBUTE_IMAGE_UPDATABLE);\r
630 Print(L" RESET_REQUIRED - 0x%lx\n", AttributesSupported & IMAGE_ATTRIBUTE_RESET_REQUIRED);\r
631 Print(L" AUTHENTICATION_REQUIRED - 0x%lx\n", AttributesSupported & IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED);\r
632 Print(L" AttributesSetting - 0x%lx\n", AttributesSetting);\r
633 Print(L" IMAGE_UPDATABLE - 0x%lx\n", AttributesSetting & IMAGE_ATTRIBUTE_IMAGE_UPDATABLE);\r
634 Print(L" RESET_REQUIRED - 0x%lx\n", AttributesSetting & IMAGE_ATTRIBUTE_RESET_REQUIRED);\r
635 Print(L" AUTHENTICATION_REQUIRED - 0x%lx\n", AttributesSetting & IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED);\r
636}\r
637\r
638/**\r
639 Dump FMP protocol info.\r
640**/\r
641VOID\r
642DumpFmpData (\r
643 VOID\r
644 )\r
645{\r
646 EFI_STATUS Status;\r
647 EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp;\r
648 EFI_HANDLE *HandleBuffer;\r
649 UINTN NumberOfHandles;\r
650 UINTN Index;\r
651 EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf;\r
652 UINTN ImageInfoSize;\r
653 UINT32 FmpImageInfoDescriptorVer;\r
654 UINT8 FmpImageInfoCount;\r
655 UINTN DescriptorSize;\r
656 UINT32 PackageVersion;\r
657 CHAR16 *PackageVersionName;\r
658 UINT32 PackageVersionNameMaxLen;\r
659 UINT64 AttributesSupported;\r
660 UINT64 AttributesSetting;\r
661\r
662 Print(L"############\n");\r
663 Print(L"# FMP DATA #\n");\r
664 Print(L"############\n");\r
665 Status = gBS->LocateHandleBuffer (\r
666 ByProtocol,\r
667 &gEfiFirmwareManagementProtocolGuid,\r
668 NULL,\r
669 &NumberOfHandles,\r
670 &HandleBuffer\r
671 );\r
672 if (EFI_ERROR(Status)) {\r
673 Print(L"FMP protocol - %r\n", EFI_NOT_FOUND);\r
674 return;\r
675 }\r
676\r
677 for (Index = 0; Index < NumberOfHandles; Index++) {\r
678 Status = gBS->HandleProtocol(\r
679 HandleBuffer[Index],\r
680 &gEfiFirmwareManagementProtocolGuid,\r
681 (VOID **)&Fmp\r
682 );\r
683 if (EFI_ERROR(Status)) {\r
684 continue;\r
685 }\r
686\r
687 ImageInfoSize = 0;\r
688 Status = Fmp->GetImageInfo (\r
689 Fmp,\r
690 &ImageInfoSize,\r
691 NULL,\r
692 NULL,\r
693 NULL,\r
694 NULL,\r
695 NULL,\r
696 NULL\r
697 );\r
698 if (Status != EFI_BUFFER_TOO_SMALL) {\r
699 continue;\r
700 }\r
701\r
702 FmpImageInfoBuf = NULL;\r
703 FmpImageInfoBuf = AllocateZeroPool (ImageInfoSize);\r
704 if (FmpImageInfoBuf == NULL) {\r
705 Status = EFI_OUT_OF_RESOURCES;\r
706 goto EXIT;\r
707 }\r
708\r
709 PackageVersionName = NULL;\r
710 Status = Fmp->GetImageInfo (\r
711 Fmp,\r
712 &ImageInfoSize, // ImageInfoSize\r
713 FmpImageInfoBuf, // ImageInfo\r
714 &FmpImageInfoDescriptorVer, // DescriptorVersion\r
715 &FmpImageInfoCount, // DescriptorCount\r
716 &DescriptorSize, // DescriptorSize\r
717 &PackageVersion, // PackageVersion\r
718 &PackageVersionName // PackageVersionName\r
719 );\r
720\r
721 //\r
722 // If FMP GetInformation interface failed, skip this resource\r
723 //\r
724 if (EFI_ERROR(Status)) {\r
725 Print(L"FMP (%d) ImageInfo - %r\n", Index, Status);\r
726 FreePool(FmpImageInfoBuf);\r
727 continue;\r
728 }\r
729\r
730 Print(L"FMP (%d) ImageInfo:\n", Index);\r
731 DumpFmpImageInfo(\r
732 ImageInfoSize, // ImageInfoSize\r
733 FmpImageInfoBuf, // ImageInfo\r
734 FmpImageInfoDescriptorVer, // DescriptorVersion\r
735 FmpImageInfoCount, // DescriptorCount\r
736 DescriptorSize, // DescriptorSize\r
737 PackageVersion, // PackageVersion\r
738 PackageVersionName // PackageVersionName\r
739 );\r
740\r
741 if (PackageVersionName != NULL) {\r
742 FreePool(PackageVersionName);\r
743 }\r
744 FreePool(FmpImageInfoBuf);\r
745\r
746 //\r
747 // Get package info\r
748 //\r
749 PackageVersionName = NULL;\r
750 Status = Fmp->GetPackageInfo (\r
751 Fmp,\r
752 &PackageVersion, // PackageVersion\r
753 &PackageVersionName, // PackageVersionName\r
754 &PackageVersionNameMaxLen, // PackageVersionNameMaxLen\r
755 &AttributesSupported, // AttributesSupported\r
756 &AttributesSetting // AttributesSetting\r
757 );\r
758 if (EFI_ERROR(Status)) {\r
759 Print(L"FMP (%d) PackageInfo - %r\n", Index, Status);\r
760 } else {\r
761 Print(L"FMP (%d) ImageInfo:\n", Index);\r
762 DumpFmpPackageInfo(\r
763 PackageVersion, // PackageVersion\r
764 PackageVersionName, // PackageVersionName\r
765 PackageVersionNameMaxLen, // PackageVersionNameMaxLen\r
766 AttributesSupported, // AttributesSupported\r
767 AttributesSetting // AttributesSetting\r
768 );\r
769\r
770 if (PackageVersionName != NULL) {\r
771 FreePool(PackageVersionName);\r
772 }\r
773 }\r
774 }\r
775 Print(L"\n");\r
776\r
777EXIT:\r
778 FreePool(HandleBuffer);\r
779}\r
1e09ec09
JY
780\r
781/**\r
782 Check if the ImageInfo includes the ImageTypeId.\r
783\r
784 @param[in] ImageInfo A pointer to EFI_FIRMWARE_IMAGE_DESCRIPTOR.\r
785 @param[in] DescriptorCount The count of EFI_FIRMWARE_IMAGE_DESCRIPTOR.\r
786 @param[in] DescriptorSize The size of an individual EFI_FIRMWARE_IMAGE_DESCRIPTOR, in bytes.\r
787 @param[in] ImageTypeId A unique GUID identifying the firmware image type.\r
788\r
789 @return TRUE This ImageInfo includes the ImageTypeId\r
790 @return FALSE This ImageInfo does not include the ImageTypeId\r
791**/\r
792BOOLEAN\r
793IsThisFmpImageInfo (\r
794 IN EFI_FIRMWARE_IMAGE_DESCRIPTOR *ImageInfo,\r
795 IN UINT8 DescriptorCount,\r
796 IN UINTN DescriptorSize,\r
797 IN EFI_GUID *ImageTypeId\r
798 )\r
799{\r
800 EFI_FIRMWARE_IMAGE_DESCRIPTOR *CurrentImageInfo;\r
801 UINTN Index;\r
802\r
803 CurrentImageInfo = ImageInfo;\r
804 for (Index = 0; Index < DescriptorCount; Index++) {\r
805 if (CompareGuid (&CurrentImageInfo->ImageTypeId, ImageTypeId)) {\r
806 return TRUE;\r
807 }\r
808 CurrentImageInfo = (EFI_FIRMWARE_IMAGE_DESCRIPTOR *)((UINT8 *)CurrentImageInfo + DescriptorSize);\r
809 }\r
810 return FALSE;\r
811}\r
812\r
813/**\r
814 return the FMP whoes ImageInfo includes the ImageTypeId.\r
815\r
816 @param[in] ImageTypeId A unique GUID identifying the firmware image type.\r
817\r
818 @return The FMP whoes ImageInfo includes the ImageTypeId\r
819**/\r
820EFI_FIRMWARE_MANAGEMENT_PROTOCOL *\r
821FindFmpFromImageTypeId (\r
822 IN EFI_GUID *ImageTypeId\r
823 )\r
824{\r
825 EFI_STATUS Status;\r
826 EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp;\r
827 EFI_FIRMWARE_MANAGEMENT_PROTOCOL *TargetFmp;\r
828 EFI_HANDLE *HandleBuffer;\r
829 UINTN NumberOfHandles;\r
830 UINTN Index;\r
831 EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf;\r
832 UINTN ImageInfoSize;\r
833 UINT32 FmpImageInfoDescriptorVer;\r
834 UINT8 FmpImageInfoCount;\r
835 UINTN DescriptorSize;\r
836 UINT32 PackageVersion;\r
837 CHAR16 *PackageVersionName;\r
838\r
839 Status = gBS->LocateHandleBuffer (\r
840 ByProtocol,\r
841 &gEfiFirmwareManagementProtocolGuid,\r
842 NULL,\r
843 &NumberOfHandles,\r
844 &HandleBuffer\r
845 );\r
846 if (EFI_ERROR(Status)) {\r
847 Print(L"FMP protocol - %r\n", EFI_NOT_FOUND);\r
848 return NULL;\r
849 }\r
850\r
851 TargetFmp = NULL;\r
852 for (Index = 0; Index < NumberOfHandles; Index++) {\r
853 Status = gBS->HandleProtocol(\r
854 HandleBuffer[Index],\r
855 &gEfiFirmwareManagementProtocolGuid,\r
856 (VOID **)&Fmp\r
857 );\r
858 if (EFI_ERROR(Status)) {\r
859 continue;\r
860 }\r
861\r
862 ImageInfoSize = 0;\r
863 Status = Fmp->GetImageInfo (\r
864 Fmp,\r
865 &ImageInfoSize,\r
866 NULL,\r
867 NULL,\r
868 NULL,\r
869 NULL,\r
870 NULL,\r
871 NULL\r
872 );\r
873 if (Status != EFI_BUFFER_TOO_SMALL) {\r
874 continue;\r
875 }\r
876\r
877 FmpImageInfoBuf = NULL;\r
878 FmpImageInfoBuf = AllocateZeroPool (ImageInfoSize);\r
879 if (FmpImageInfoBuf == NULL) {\r
880 FreePool(HandleBuffer);\r
881 Print(L"Out of resource\n");\r
882 return NULL;\r
883 }\r
884\r
885 PackageVersionName = NULL;\r
886 Status = Fmp->GetImageInfo (\r
887 Fmp,\r
888 &ImageInfoSize, // ImageInfoSize\r
889 FmpImageInfoBuf, // ImageInfo\r
890 &FmpImageInfoDescriptorVer, // DescriptorVersion\r
891 &FmpImageInfoCount, // DescriptorCount\r
892 &DescriptorSize, // DescriptorSize\r
893 &PackageVersion, // PackageVersion\r
894 &PackageVersionName // PackageVersionName\r
895 );\r
896\r
897 //\r
898 // If FMP GetInformation interface failed, skip this resource\r
899 //\r
900 if (EFI_ERROR(Status)) {\r
901 FreePool(FmpImageInfoBuf);\r
902 continue;\r
903 }\r
904\r
905 if (PackageVersionName != NULL) {\r
906 FreePool(PackageVersionName);\r
907 }\r
908\r
909 if (IsThisFmpImageInfo (FmpImageInfoBuf, FmpImageInfoCount, DescriptorSize, ImageTypeId)) {\r
910 TargetFmp = Fmp;\r
911 }\r
912 FreePool(FmpImageInfoBuf);\r
913 if (TargetFmp != NULL) {\r
914 break;\r
915 }\r
916 }\r
917 FreePool(HandleBuffer);\r
918 return TargetFmp;\r
919}\r
920\r
921/**\r
922 Dump FMP image data.\r
923\r
924 @param[in] ImageTypeId The ImageTypeId of the FMP image.\r
925 It is used to identify the FMP protocol.\r
926 @param[in] ImageIndex The ImageIndex of the FMP image.\r
927 It is the input parameter for FMP->GetImage().\r
928 @param[in] ImageName The file name to hold the output FMP image.\r
929**/\r
930VOID\r
931DumpFmpImage (\r
932 IN EFI_GUID *ImageTypeId,\r
933 IN UINTN ImageIndex,\r
934 IN CHAR16 *ImageName\r
935 )\r
936{\r
937 EFI_STATUS Status;\r
938 EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp;\r
939 VOID *Image;\r
940 UINTN ImageSize;\r
941\r
942 Fmp = FindFmpFromImageTypeId (ImageTypeId);\r
943 if (Fmp == NULL) {\r
944 Print(L"No FMP include ImageTypeId %g\n", ImageTypeId);\r
945 return ;\r
946 }\r
947\r
948 if (ImageIndex > 0xFF) {\r
949 Print(L"ImageIndex 0x%x too big\n", ImageIndex);\r
950 return ;\r
951 }\r
952\r
953 Image = Fmp;\r
954 ImageSize = 0;\r
955 Status = Fmp->GetImage (Fmp, (UINT8)ImageIndex, Image, &ImageSize);\r
956 if (Status != EFI_BUFFER_TOO_SMALL) {\r
957 Print(L"Fmp->GetImage - %r\n", Status);\r
958 return ;\r
959 }\r
960\r
961 Image = AllocatePool (ImageSize);\r
962 if (Image == NULL) {\r
963 Print(L"Allocate FmpImage 0x%x - %r\n", ImageSize, EFI_OUT_OF_RESOURCES);\r
964 return ;\r
965 }\r
966\r
967 Status = Fmp->GetImage (Fmp, (UINT8)ImageIndex, Image, &ImageSize);\r
968 if (EFI_ERROR(Status)) {\r
969 Print(L"Fmp->GetImage - %r\n", Status);\r
970 return ;\r
971 }\r
972\r
973 Status = WriteFileFromBuffer(ImageName, ImageSize, Image);\r
974 Print(L"CapsuleApp: Dump %g ImageIndex (0x%x) to %s %r\n", ImageTypeId, ImageIndex, ImageName, Status);\r
975\r
d4d91167
SZ
976 FreePool (Image);\r
977\r
1e09ec09
JY
978 return ;\r
979}\r