]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfo.c
ShellPkg/UefiShellLib: Avoid reading undefined content before string
[mirror_edk2.git] / MdeModulePkg / Application / SmiHandlerProfileInfo / SmiHandlerProfileInfo.c
CommitLineData
216b942d
JY
1/** @file\r
2 Shell application to dump SMI handler profile information.\r
3\r
4Copyright (c) 2017, 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 <PiDxe.h>\r
16#include <Library/BaseLib.h>\r
17#include <Library/BaseMemoryLib.h>\r
18#include <Library/MemoryAllocationLib.h>\r
19#include <Library/UefiBootServicesTableLib.h>\r
20#include <Library/UefiRuntimeServicesTableLib.h>\r
21#include <Library/DebugLib.h>\r
22#include <Library/PrintLib.h>\r
23#include <Library/UefiLib.h>\r
24#include <Library/DevicePathLib.h>\r
25#include <Library/PeCoffGetEntryPointLib.h>\r
26#include <Library/DxeServicesLib.h>\r
27#include <Protocol/SmmCommunication.h>\r
28#include <Guid/PiSmmCommunicationRegionTable.h>\r
29\r
30#include <Guid/SmiHandlerProfile.h>\r
31\r
32#define PROFILE_NAME_STRING_LENGTH 64\r
33CHAR8 mNameString[PROFILE_NAME_STRING_LENGTH + 1];\r
34\r
35VOID *mSmiHandlerProfileDatabase;\r
36UINTN mSmiHandlerProfileDatabaseSize;\r
37\r
38/**\r
39 This function dump raw data.\r
40\r
41 @param Data raw data\r
42 @param Size raw data size\r
43**/\r
44VOID\r
45InternalDumpData (\r
46 IN UINT8 *Data,\r
47 IN UINTN Size\r
48 )\r
49{\r
50 UINTN Index;\r
51 for (Index = 0; Index < Size; Index++) {\r
52 Print (L"%02x", (UINTN)Data[Index]);\r
53 if ((Index + 1) != Size) {\r
54 Print (L" ");\r
55 }\r
56 }\r
57}\r
58\r
59/**\r
60 Get SMI handler profile database.\r
61**/\r
62VOID\r
63GetSmiHandlerProfileDatabase(\r
64 VOID\r
65 )\r
66{\r
67 EFI_STATUS Status;\r
68 UINTN CommSize;\r
69 UINT8 *CommBuffer;\r
70 EFI_SMM_COMMUNICATE_HEADER *CommHeader;\r
71 SMI_HANDLER_PROFILE_PARAMETER_GET_INFO *CommGetInfo;\r
72 SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET *CommGetData;\r
73 EFI_SMM_COMMUNICATION_PROTOCOL *SmmCommunication;\r
74 UINTN MinimalSizeNeeded;\r
75 EDKII_PI_SMM_COMMUNICATION_REGION_TABLE *PiSmmCommunicationRegionTable;\r
76 UINT32 Index;\r
77 EFI_MEMORY_DESCRIPTOR *Entry;\r
78 VOID *Buffer;\r
79 UINTN Size;\r
80 UINTN Offset;\r
81\r
82 Status = gBS->LocateProtocol(&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **)&SmmCommunication);\r
83 if (EFI_ERROR(Status)) {\r
84 Print(L"SmiHandlerProfile: Locate SmmCommunication protocol - %r\n", Status);\r
85 return ;\r
86 }\r
87\r
88 MinimalSizeNeeded = EFI_PAGE_SIZE;\r
89\r
90 Status = EfiGetSystemConfigurationTable(\r
91 &gEdkiiPiSmmCommunicationRegionTableGuid,\r
92 (VOID **)&PiSmmCommunicationRegionTable\r
93 );\r
94 if (EFI_ERROR(Status)) {\r
95 Print(L"SmiHandlerProfile: Get PiSmmCommunicationRegionTable - %r\n", Status);\r
96 return ;\r
97 }\r
98 ASSERT(PiSmmCommunicationRegionTable != NULL);\r
99 Entry = (EFI_MEMORY_DESCRIPTOR *)(PiSmmCommunicationRegionTable + 1);\r
100 Size = 0;\r
101 for (Index = 0; Index < PiSmmCommunicationRegionTable->NumberOfEntries; Index++) {\r
102 if (Entry->Type == EfiConventionalMemory) {\r
103 Size = EFI_PAGES_TO_SIZE((UINTN)Entry->NumberOfPages);\r
104 if (Size >= MinimalSizeNeeded) {\r
105 break;\r
106 }\r
107 }\r
108 Entry = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)Entry + PiSmmCommunicationRegionTable->DescriptorSize);\r
109 }\r
110 ASSERT(Index < PiSmmCommunicationRegionTable->NumberOfEntries);\r
111 CommBuffer = (UINT8 *)(UINTN)Entry->PhysicalStart;\r
112\r
113 //\r
114 // Get Size\r
115 //\r
116 CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0];\r
117 CopyMem(&CommHeader->HeaderGuid, &gSmiHandlerProfileGuid, sizeof(gSmiHandlerProfileGuid));\r
118 CommHeader->MessageLength = sizeof(SMI_HANDLER_PROFILE_PARAMETER_GET_INFO);\r
119\r
120 CommGetInfo = (SMI_HANDLER_PROFILE_PARAMETER_GET_INFO *)&CommBuffer[OFFSET_OF(EFI_SMM_COMMUNICATE_HEADER, Data)];\r
121 CommGetInfo->Header.Command = SMI_HANDLER_PROFILE_COMMAND_GET_INFO;\r
122 CommGetInfo->Header.DataLength = sizeof(*CommGetInfo);\r
123 CommGetInfo->Header.ReturnStatus = (UINT64)-1;\r
124 CommGetInfo->DataSize = 0;\r
125\r
126 CommSize = sizeof(EFI_GUID) + sizeof(UINTN) + CommHeader->MessageLength;\r
127 Status = SmmCommunication->Communicate(SmmCommunication, CommBuffer, &CommSize);\r
128 if (EFI_ERROR(Status)) {\r
129 Print(L"SmiHandlerProfile: SmmCommunication - %r\n", Status);\r
130 return ;\r
131 }\r
132\r
133 if (CommGetInfo->Header.ReturnStatus != 0) {\r
134 Print(L"SmiHandlerProfile: GetInfo - 0x%0x\n", CommGetInfo->Header.ReturnStatus);\r
135 return ;\r
136 }\r
137\r
138 mSmiHandlerProfileDatabaseSize = (UINTN)CommGetInfo->DataSize;\r
139\r
140 //\r
141 // Get Data\r
142 //\r
143 mSmiHandlerProfileDatabase = AllocateZeroPool(mSmiHandlerProfileDatabaseSize);\r
144 if (mSmiHandlerProfileDatabase == NULL) {\r
145 Status = EFI_OUT_OF_RESOURCES;\r
146 Print(L"SmiHandlerProfile: AllocateZeroPool (0x%x) for dump buffer - %r\n", mSmiHandlerProfileDatabaseSize, Status);\r
147 return ;\r
148 }\r
149\r
150 CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0];\r
151 CopyMem(&CommHeader->HeaderGuid, &gSmiHandlerProfileGuid, sizeof(gSmiHandlerProfileGuid));\r
152 CommHeader->MessageLength = sizeof(SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET);\r
153\r
154 CommGetData = (SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET *)&CommBuffer[OFFSET_OF(EFI_SMM_COMMUNICATE_HEADER, Data)];\r
155 CommGetData->Header.Command = SMI_HANDLER_PROFILE_COMMAND_GET_DATA_BY_OFFSET;\r
156 CommGetData->Header.DataLength = sizeof(*CommGetData);\r
157 CommGetData->Header.ReturnStatus = (UINT64)-1;\r
158\r
159 CommSize = sizeof(EFI_GUID) + sizeof(UINTN) + CommHeader->MessageLength;\r
160 Buffer = (UINT8 *)CommHeader + CommSize;\r
161 Size -= CommSize;\r
162\r
163 CommGetData->DataBuffer = (PHYSICAL_ADDRESS)(UINTN)Buffer;\r
164 CommGetData->DataOffset = 0;\r
165 while (CommGetData->DataOffset < mSmiHandlerProfileDatabaseSize) {\r
166 Offset = (UINTN)CommGetData->DataOffset;\r
167 if (Size <= (mSmiHandlerProfileDatabaseSize - CommGetData->DataOffset)) {\r
168 CommGetData->DataSize = (UINT64)Size;\r
169 } else {\r
170 CommGetData->DataSize = (UINT64)(mSmiHandlerProfileDatabaseSize - CommGetData->DataOffset);\r
171 }\r
172 Status = SmmCommunication->Communicate(SmmCommunication, CommBuffer, &CommSize);\r
173 ASSERT_EFI_ERROR(Status);\r
174\r
175 if (CommGetData->Header.ReturnStatus != 0) {\r
176 FreePool(mSmiHandlerProfileDatabase);\r
177 mSmiHandlerProfileDatabase = NULL;\r
178 Print(L"SmiHandlerProfile: GetData - 0x%x\n", CommGetData->Header.ReturnStatus);\r
179 return ;\r
180 }\r
181 CopyMem((UINT8 *)mSmiHandlerProfileDatabase + Offset, (VOID *)(UINTN)CommGetData->DataBuffer, (UINTN)CommGetData->DataSize);\r
182 }\r
183\r
184 DEBUG ((DEBUG_INFO, "SmiHandlerProfileSize - 0x%x\n", mSmiHandlerProfileDatabaseSize));\r
185\r
186 return ;\r
187}\r
188\r
189/**\r
190 Get the file name portion of the Pdb File Name.\r
191\r
192 The portion of the Pdb File Name between the last backslash and\r
193 either a following period or the end of the string is copied into\r
194 AsciiBuffer. The name is truncated, if necessary, to ensure that\r
195 AsciiBuffer is not overrun.\r
196\r
197 @param[in] PdbFileName Pdb file name.\r
198 @param[out] AsciiBuffer The resultant Ascii File Name.\r
199\r
200**/\r
201VOID\r
202GetShortPdbFileName (\r
203 IN CHAR8 *PdbFileName,\r
204 OUT CHAR8 *AsciiBuffer\r
205 )\r
206{\r
207 UINTN IndexPdb; // Current work location within a Pdb string.\r
208 UINTN IndexBuffer; // Current work location within a Buffer string.\r
209 UINTN StartIndex;\r
210 UINTN EndIndex;\r
211\r
212 ZeroMem (AsciiBuffer, PROFILE_NAME_STRING_LENGTH + 1);\r
213\r
214 if (PdbFileName == NULL) {\r
215 AsciiStrnCpyS (AsciiBuffer, PROFILE_NAME_STRING_LENGTH + 1, " ", 1);\r
216 } else {\r
217 StartIndex = 0;\r
218 for (EndIndex = 0; PdbFileName[EndIndex] != 0; EndIndex++);\r
219 for (IndexPdb = 0; PdbFileName[IndexPdb] != 0; IndexPdb++) {\r
220 if ((PdbFileName[IndexPdb] == '\\') || (PdbFileName[IndexPdb] == '/')) {\r
221 StartIndex = IndexPdb + 1;\r
222 }\r
223\r
224 if (PdbFileName[IndexPdb] == '.') {\r
225 EndIndex = IndexPdb;\r
226 }\r
227 }\r
228\r
229 IndexBuffer = 0;\r
230 for (IndexPdb = StartIndex; IndexPdb < EndIndex; IndexPdb++) {\r
231 AsciiBuffer[IndexBuffer] = PdbFileName[IndexPdb];\r
232 IndexBuffer++;\r
233 if (IndexBuffer >= PROFILE_NAME_STRING_LENGTH) {\r
234 AsciiBuffer[PROFILE_NAME_STRING_LENGTH] = 0;\r
235 break;\r
236 }\r
237 }\r
238 }\r
239}\r
240\r
241/**\r
242 Get a human readable name for an image.\r
243 The following methods will be tried orderly:\r
244 1. Image PDB\r
245 2. FFS UI section\r
246 3. Image GUID\r
247\r
c325e415 248 @param[in] ImageStruct Point to the image structure.\r
216b942d
JY
249\r
250 @return The resulting Ascii name string is stored in the mNameString global array.\r
251\r
252**/\r
253CHAR8 *\r
254GetDriverNameString (\r
255 IN SMM_CORE_IMAGE_DATABASE_STRUCTURE *ImageStruct\r
256 )\r
257{\r
258 EFI_STATUS Status;\r
259 CHAR16 *NameString;\r
260 UINTN StringSize;\r
261\r
262 if (ImageStruct == NULL) {\r
263 return "???";\r
264 }\r
265\r
266 //\r
267 // Method 1: Get the name string from image PDB\r
268 //\r
269 if (ImageStruct->Header.Length > sizeof (SMM_CORE_IMAGE_DATABASE_STRUCTURE)) {\r
270 GetShortPdbFileName ((CHAR8 *) (ImageStruct + 1), mNameString);\r
271 return mNameString;\r
272 }\r
273\r
274 if (!IsZeroGuid (&ImageStruct->FileGuid)) {\r
275 //\r
276 // Try to get the image's FFS UI section by image GUID\r
277 //\r
278 NameString = NULL;\r
279 StringSize = 0;\r
280 Status = GetSectionFromAnyFv (\r
281 &ImageStruct->FileGuid,\r
282 EFI_SECTION_USER_INTERFACE,\r
283 0,\r
284 (VOID **) &NameString,\r
285 &StringSize\r
286 );\r
287 if (!EFI_ERROR (Status)) {\r
288 //\r
289 // Method 2: Get the name string from FFS UI section\r
290 //\r
291 if (StrLen (NameString) > PROFILE_NAME_STRING_LENGTH) {\r
292 NameString[PROFILE_NAME_STRING_LENGTH] = 0;\r
293 }\r
294 UnicodeStrToAsciiStrS (NameString, mNameString, sizeof (mNameString));\r
295 FreePool (NameString);\r
296 return mNameString;\r
297 }\r
298 }\r
299\r
300 //\r
301 // Method 3: Get the name string from image GUID\r
302 //\r
303 AsciiSPrint (mNameString, sizeof (mNameString), "%g", &ImageStruct->FileGuid);\r
304 return mNameString;\r
305}\r
306\r
307/**\r
308 Get image structure from reference index.\r
309\r
310 @param ImageRef the image reference index\r
311\r
312 @return image structure\r
313**/\r
314SMM_CORE_IMAGE_DATABASE_STRUCTURE *\r
315GetImageFromRef (\r
316 IN UINTN ImageRef\r
317 )\r
318{\r
319 SMM_CORE_IMAGE_DATABASE_STRUCTURE *ImageStruct;\r
320\r
321 ImageStruct = (VOID *)mSmiHandlerProfileDatabase;\r
322 while ((UINTN)ImageStruct < (UINTN)mSmiHandlerProfileDatabase + mSmiHandlerProfileDatabaseSize) {\r
323 if (ImageStruct->Header.Signature == SMM_CORE_IMAGE_DATABASE_SIGNATURE) {\r
324 if (ImageStruct->ImageRef == ImageRef) {\r
325 return ImageStruct;\r
326 }\r
327 }\r
328 ImageStruct = (VOID *)((UINTN)ImageStruct + ImageStruct->Header.Length);\r
329 }\r
330\r
331 return NULL;\r
332}\r
333\r
334/**\r
335 Dump SMM loaded image information.\r
336**/\r
337VOID\r
338DumpSmmLoadedImage(\r
339 VOID\r
340 )\r
341{\r
342 SMM_CORE_IMAGE_DATABASE_STRUCTURE *ImageStruct;\r
343 CHAR8 *PdbString;\r
344 CHAR8 *NameString;\r
345\r
346 ImageStruct = (VOID *)mSmiHandlerProfileDatabase;\r
347 while ((UINTN)ImageStruct < (UINTN)mSmiHandlerProfileDatabase + mSmiHandlerProfileDatabaseSize) {\r
348 if (ImageStruct->Header.Signature == SMM_CORE_IMAGE_DATABASE_SIGNATURE) {\r
349 NameString = GetDriverNameString (ImageStruct);\r
350 Print(L" <Image Name=\"%a\"", NameString);\r
351 Print(L" Base=\"0x%x\" Size=\"0x%x\"", ImageStruct->ImageBase, ImageStruct->ImageSize);\r
352 if (ImageStruct->EntryPoint != 0) {\r
353 Print(L" EntryPoint=\"0x%x\"", ImageStruct->EntryPoint);\r
354 }\r
355 Print(L" FvFile=\"%g\"", &ImageStruct->FileGuid);\r
356 Print(L" RefId=\"0x%x\"", ImageStruct->ImageRef);\r
357 Print(L">\n");\r
358 PdbString = (CHAR8 *)((UINTN)ImageStruct + ImageStruct->PdbStringOffset);\r
359 Print(L" <Pdb>%a</Pdb>\n", PdbString);\r
360 Print(L" </Image>\n");\r
361 }\r
362\r
363 ImageStruct = (VOID *)((UINTN)ImageStruct + ImageStruct->Header.Length);\r
364 }\r
365\r
366 return;\r
367}\r
368\r
369CHAR8 *mSxTypeString[] = {\r
370 "SxS0",\r
371 "SxS1",\r
372 "SxS2",\r
373 "SxS3",\r
374 "SxS4",\r
375 "SxS5",\r
376};\r
377\r
378/**\r
379 Convert SxType to a string.\r
380\r
381 @param Type SxType\r
382\r
383 @return SxType string\r
384**/\r
385CHAR8 *\r
386SxTypeToString (\r
387 IN EFI_SLEEP_TYPE Type\r
388 )\r
389{\r
390 if (Type >= 0 && Type <= ARRAY_SIZE(mSxTypeString)) {\r
391 return mSxTypeString[Type];\r
392 } else {\r
393 AsciiSPrint (mNameString, sizeof(mNameString), "0x%x", Type);\r
394 return mNameString;\r
395 }\r
396}\r
397\r
398CHAR8 *mSxPhaseString[] = {\r
399 "SxEntry",\r
400 "SxExit",\r
401};\r
402\r
403/**\r
404 Convert SxPhase to a string.\r
405\r
406 @param Phase SxPhase\r
407\r
408 @return SxPhase string\r
409**/\r
410CHAR8 *\r
411SxPhaseToString (\r
412 IN EFI_SLEEP_PHASE Phase\r
413 )\r
414{\r
415 if (Phase >= 0 && Phase <= ARRAY_SIZE(mSxPhaseString)) {\r
416 return mSxPhaseString[Phase];\r
417 } else {\r
418 AsciiSPrint (mNameString, sizeof(mNameString), "0x%x", Phase);\r
419 return mNameString;\r
420 }\r
421}\r
422\r
423CHAR8 *mPowerButtonPhaseString[] = {\r
424 "PowerButtonEntry",\r
425 "PowerButtonExit",\r
426};\r
427\r
428/**\r
429 Convert PowerButtonPhase to a string.\r
430\r
431 @param Phase PowerButtonPhase\r
432\r
433 @return PowerButtonPhase string\r
434**/\r
435CHAR8 *\r
436PowerButtonPhaseToString (\r
437 IN EFI_POWER_BUTTON_PHASE Phase\r
438 )\r
439{\r
440 if (Phase >= 0 && Phase <= ARRAY_SIZE(mPowerButtonPhaseString)) {\r
441 return mPowerButtonPhaseString[Phase];\r
442 } else {\r
443 AsciiSPrint (mNameString, sizeof(mNameString), "0x%x", Phase);\r
444 return mNameString;\r
445 }\r
446}\r
447\r
448CHAR8 *mStandbyButtonPhaseString[] = {\r
449 "StandbyButtonEntry",\r
450 "StandbyButtonExit",\r
451};\r
452\r
453/**\r
454 Convert StandbyButtonPhase to a string.\r
455\r
456 @param Phase StandbyButtonPhase\r
457\r
458 @return StandbyButtonPhase string\r
459**/\r
460CHAR8 *\r
461StandbyButtonPhaseToString (\r
462 IN EFI_STANDBY_BUTTON_PHASE Phase\r
463 )\r
464{\r
465 if (Phase >= 0 && Phase <= ARRAY_SIZE(mStandbyButtonPhaseString)) {\r
466 return mStandbyButtonPhaseString[Phase];\r
467 } else {\r
468 AsciiSPrint (mNameString, sizeof(mNameString), "0x%x", Phase);\r
469 return mNameString;\r
470 }\r
471}\r
472\r
473CHAR8 *mIoTrapTypeString[] = {\r
474 "WriteTrap",\r
475 "ReadTrap",\r
476 "ReadWriteTrap",\r
477};\r
478\r
479/**\r
480 Convert IoTrapType to a string.\r
481\r
482 @param Type IoTrapType\r
483\r
484 @return IoTrapType string\r
485**/\r
486CHAR8 *\r
487IoTrapTypeToString (\r
488 IN EFI_SMM_IO_TRAP_DISPATCH_TYPE Type\r
489 )\r
490{\r
491 if (Type >= 0 && Type <= ARRAY_SIZE(mIoTrapTypeString)) {\r
492 return mIoTrapTypeString[Type];\r
493 } else {\r
494 AsciiSPrint (mNameString, sizeof(mNameString), "0x%x", Type);\r
495 return mNameString;\r
496 }\r
497}\r
498\r
499CHAR8 *mUsbTypeString[] = {\r
500 "UsbLegacy",\r
501 "UsbWake",\r
502};\r
503\r
504/**\r
505 Convert UsbType to a string.\r
506\r
507 @param Type UsbType\r
508\r
509 @return UsbType string\r
510**/\r
511CHAR8 *\r
512UsbTypeToString (\r
513 IN EFI_USB_SMI_TYPE Type\r
514 )\r
515{\r
516 if (Type >= 0 && Type <= ARRAY_SIZE(mUsbTypeString)) {\r
517 return mUsbTypeString[Type];\r
518 } else {\r
519 AsciiSPrint (mNameString, sizeof(mNameString), "0x%x", Type);\r
520 return mNameString;\r
521 }\r
522}\r
523\r
524/**\r
525 Dump SMI child context.\r
526\r
527 @param HandlerType the handler type\r
528 @param Context the handler context\r
529 @param ContextSize the handler context size\r
530**/\r
531VOID\r
532DumpSmiChildContext (\r
533 IN EFI_GUID *HandlerType,\r
534 IN VOID *Context,\r
535 IN UINTN ContextSize\r
536 )\r
537{\r
fb1c81a1
SZ
538 CHAR16 *Str;\r
539\r
216b942d
JY
540 if (CompareGuid (HandlerType, &gEfiSmmSwDispatch2ProtocolGuid)) {\r
541 Print(L" SwSmi=\"0x%x\"", ((EFI_SMM_SW_REGISTER_CONTEXT *)Context)->SwSmiInputValue);\r
542 } else if (CompareGuid (HandlerType, &gEfiSmmSxDispatch2ProtocolGuid)) {\r
543 Print(L" SxType=\"%a\"", SxTypeToString(((EFI_SMM_SX_REGISTER_CONTEXT *)Context)->Type));\r
544 Print(L" SxPhase=\"%a\"", SxPhaseToString(((EFI_SMM_SX_REGISTER_CONTEXT *)Context)->Phase));\r
545 } else if (CompareGuid (HandlerType, &gEfiSmmPowerButtonDispatch2ProtocolGuid)) {\r
546 Print(L" PowerButtonPhase=\"%a\"", PowerButtonPhaseToString(((EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT *)Context)->Phase));\r
547 } else if (CompareGuid (HandlerType, &gEfiSmmStandbyButtonDispatch2ProtocolGuid)) {\r
548 Print(L" StandbyButtonPhase=\"%a\"", StandbyButtonPhaseToString(((EFI_SMM_STANDBY_BUTTON_REGISTER_CONTEXT *)Context)->Phase));\r
549 } else if (CompareGuid (HandlerType, &gEfiSmmPeriodicTimerDispatch2ProtocolGuid)) {\r
550 Print(L" PeriodicTimerPeriod=\"%ld\"", ((EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT *)Context)->Period);\r
551 Print(L" PeriodicTimerSmiTickInterval=\"%ld\"", ((EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT *)Context)->SmiTickInterval);\r
552 } else if (CompareGuid (HandlerType, &gEfiSmmGpiDispatch2ProtocolGuid)) {\r
553 Print(L" GpiNum=\"0x%lx\"", ((EFI_SMM_GPI_REGISTER_CONTEXT *)Context)->GpiNum);\r
554 } else if (CompareGuid (HandlerType, &gEfiSmmIoTrapDispatch2ProtocolGuid)) {\r
555 Print(L" IoTrapAddress=\"0x%x\"", ((EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Context)->Address);\r
556 Print(L" IoTrapLength=\"0x%x\"", ((EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Context)->Length);\r
557 Print(L" IoTrapType=\"%a\"", IoTrapTypeToString(((EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Context)->Type));\r
558 } else if (CompareGuid (HandlerType, &gEfiSmmUsbDispatch2ProtocolGuid)) {\r
559 Print(L" UsbType=\"0x%x\"", UsbTypeToString(((SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT *)Context)->Type));\r
fb1c81a1
SZ
560 Str = ConvertDevicePathToText((EFI_DEVICE_PATH_PROTOCOL *)(((SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT *)Context) + 1), TRUE, TRUE);\r
561 Print(L" UsbDevicePath=\"%s\"", Str);\r
562 if (Str != NULL) {\r
563 FreePool (Str);\r
564 }\r
216b942d
JY
565 } else {\r
566 Print(L" Context=\"");\r
567 InternalDumpData (Context, ContextSize);\r
568 Print(L"\"");\r
569 }\r
570}\r
571\r
572/**\r
573 Dump SMI handler in HandlerCategory.\r
574\r
575 @param HandlerCategory SMI handler category\r
576**/\r
577VOID\r
578DumpSmiHandler(\r
579 IN UINT32 HandlerCategory\r
580 )\r
581{\r
582 SMM_CORE_SMI_DATABASE_STRUCTURE *SmiStruct;\r
583 SMM_CORE_SMI_HANDLER_STRUCTURE *SmiHandlerStruct;\r
584 UINTN Index;\r
585 SMM_CORE_IMAGE_DATABASE_STRUCTURE *ImageStruct;\r
586 CHAR8 *NameString;\r
587\r
588 SmiStruct = (VOID *)mSmiHandlerProfileDatabase;\r
589 while ((UINTN)SmiStruct < (UINTN)mSmiHandlerProfileDatabase + mSmiHandlerProfileDatabaseSize) {\r
590 if ((SmiStruct->Header.Signature == SMM_CORE_SMI_DATABASE_SIGNATURE) && (SmiStruct->HandlerCategory == HandlerCategory)) {\r
591 SmiHandlerStruct = (VOID *)(SmiStruct + 1);\r
592 Print(L" <SmiEntry");\r
593 if (!IsZeroGuid (&SmiStruct->HandlerType)) {\r
594 Print(L" HandlerType=\"%g\"", &SmiStruct->HandlerType);\r
595 }\r
596 Print(L">\n");\r
597 for (Index = 0; Index < SmiStruct->HandlerCount; Index++) {\r
598 Print(L" <SmiHandler");\r
599 if (SmiHandlerStruct->ContextBufferSize != 0) {\r
600 DumpSmiChildContext (&SmiStruct->HandlerType, (UINT8 *)SmiHandlerStruct + SmiHandlerStruct->ContextBufferOffset, SmiHandlerStruct->ContextBufferSize);\r
601 }\r
602 Print(L">\n");\r
603 ImageStruct = GetImageFromRef((UINTN)SmiHandlerStruct->ImageRef);\r
604 NameString = GetDriverNameString (ImageStruct);\r
605 Print(L" <Module RefId=\"0x%x\" Name=\"%a\">\n", SmiHandlerStruct->ImageRef, NameString);\r
606 if ((ImageStruct != NULL) && (ImageStruct->PdbStringOffset != 0)) {\r
607 Print(L" <Pdb>%a</Pdb>\n", (UINT8 *)ImageStruct + ImageStruct->PdbStringOffset);\r
608 }\r
609 Print(L" </Module>\n");\r
610 Print(L" <Handler Address=\"0x%x\">\n", SmiHandlerStruct->Handler);\r
611 if (ImageStruct != NULL) {\r
612 Print(L" <RVA>0x%x</RVA>\n", SmiHandlerStruct->Handler - ImageStruct->ImageBase);\r
613 }\r
614 Print(L" </Handler>\n", SmiHandlerStruct->Handler);\r
615 Print(L" <Caller Address=\"0x%x\">\n", SmiHandlerStruct->CallerAddr);\r
616 if (ImageStruct != NULL) {\r
617 Print(L" <RVA>0x%x</RVA>\n", SmiHandlerStruct->CallerAddr - ImageStruct->ImageBase);\r
618 }\r
619 Print(L" </Caller>\n", SmiHandlerStruct->Handler);\r
620 SmiHandlerStruct = (VOID *)((UINTN)SmiHandlerStruct + SmiHandlerStruct->Length);\r
621 Print(L" </SmiHandler>\n");\r
622 }\r
623 Print(L" </SmiEntry>\n");\r
624 }\r
625 SmiStruct = (VOID *)((UINTN)SmiStruct + SmiStruct->Header.Length);\r
626 }\r
627\r
628 return;\r
629}\r
630\r
631/**\r
632 The Entry Point for SMI handler profile info application.\r
633\r
634 @param ImageHandle The firmware allocated handle for the EFI image.\r
635 @param SystemTable A pointer to the EFI System Table.\r
636\r
637 @retval EFI_SUCCESS The entry point is executed successfully.\r
638 @retval Other Some error occurred when executing this entry point.\r
639**/\r
640EFI_STATUS\r
641EFIAPI\r
642SmiHandlerProfileInfoEntrypoint (\r
643 IN EFI_HANDLE ImageHandle,\r
644 IN EFI_SYSTEM_TABLE *SystemTable\r
645 )\r
646{\r
647 GetSmiHandlerProfileDatabase();\r
648\r
649 if (mSmiHandlerProfileDatabase == NULL) {\r
650 return EFI_SUCCESS;\r
651 }\r
652\r
653 //\r
654 // Dump all image\r
655 //\r
656 Print(L"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");\r
657 Print(L"<SmiHandlerProfile>\n");\r
658 Print(L"<ImageDatabase>\n");\r
659 Print(L" <!-- SMM image loaded -->\n");\r
660 DumpSmmLoadedImage();\r
661 Print(L"</ImageDatabase>\n\n");\r
662\r
663 //\r
664 // Dump SMI Handler\r
665 //\r
666 Print(L"<SmiHandlerDatabase>\n");\r
667 Print(L" <!-- SMI Handler registered -->\n\n");\r
668 Print(L" <SmiHandlerCategory Name=\"RootSmi\">\n");\r
669 Print(L" <!-- The root SMI Handler registered by SmmCore -->\n");\r
670 DumpSmiHandler(SmmCoreSmiHandlerCategoryRootHandler);\r
671 Print(L" </SmiHandlerCategory>\n\n");\r
672\r
673 Print(L" <SmiHandlerCategory Name=\"GuidSmi\">\n");\r
674 Print(L" <!-- The GUID SMI Handler registered by SmmCore -->\n");\r
675 DumpSmiHandler(SmmCoreSmiHandlerCategoryGuidHandler);\r
676 Print(L" </SmiHandlerCategory>\n\n");\r
677\r
678 Print(L" <SmiHandlerCategory Name=\"HardwareSmi\">\n");\r
679 Print(L" <!-- The hardware SMI Handler registered by SmmChildDispatcher -->\n");\r
680 DumpSmiHandler(SmmCoreSmiHandlerCategoryHardwareHandler);\r
681 Print(L" </SmiHandlerCategory>\n\n");\r
682\r
683 Print(L"</SmiHandlerDatabase>\n");\r
684 Print(L"</SmiHandlerProfile>\n");\r
685\r
686 if (mSmiHandlerProfileDatabase != NULL) {\r
687 FreePool(mSmiHandlerProfileDatabase);\r
688 }\r
689\r
690 return EFI_SUCCESS;\r
691}\r