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