]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfo.c
MdeModulePkg/BMMUiLib: Replace same logic with API in UefiBootManagerLib
[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
248 @param[in] DriverInfo Pointer to memory profile driver info.\r
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
538 if (CompareGuid (HandlerType, &gEfiSmmSwDispatch2ProtocolGuid)) {\r
539 Print(L" SwSmi=\"0x%x\"", ((EFI_SMM_SW_REGISTER_CONTEXT *)Context)->SwSmiInputValue);\r
540 } else if (CompareGuid (HandlerType, &gEfiSmmSxDispatch2ProtocolGuid)) {\r
541 Print(L" SxType=\"%a\"", SxTypeToString(((EFI_SMM_SX_REGISTER_CONTEXT *)Context)->Type));\r
542 Print(L" SxPhase=\"%a\"", SxPhaseToString(((EFI_SMM_SX_REGISTER_CONTEXT *)Context)->Phase));\r
543 } else if (CompareGuid (HandlerType, &gEfiSmmPowerButtonDispatch2ProtocolGuid)) {\r
544 Print(L" PowerButtonPhase=\"%a\"", PowerButtonPhaseToString(((EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT *)Context)->Phase));\r
545 } else if (CompareGuid (HandlerType, &gEfiSmmStandbyButtonDispatch2ProtocolGuid)) {\r
546 Print(L" StandbyButtonPhase=\"%a\"", StandbyButtonPhaseToString(((EFI_SMM_STANDBY_BUTTON_REGISTER_CONTEXT *)Context)->Phase));\r
547 } else if (CompareGuid (HandlerType, &gEfiSmmPeriodicTimerDispatch2ProtocolGuid)) {\r
548 Print(L" PeriodicTimerPeriod=\"%ld\"", ((EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT *)Context)->Period);\r
549 Print(L" PeriodicTimerSmiTickInterval=\"%ld\"", ((EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT *)Context)->SmiTickInterval);\r
550 } else if (CompareGuid (HandlerType, &gEfiSmmGpiDispatch2ProtocolGuid)) {\r
551 Print(L" GpiNum=\"0x%lx\"", ((EFI_SMM_GPI_REGISTER_CONTEXT *)Context)->GpiNum);\r
552 } else if (CompareGuid (HandlerType, &gEfiSmmIoTrapDispatch2ProtocolGuid)) {\r
553 Print(L" IoTrapAddress=\"0x%x\"", ((EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Context)->Address);\r
554 Print(L" IoTrapLength=\"0x%x\"", ((EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Context)->Length);\r
555 Print(L" IoTrapType=\"%a\"", IoTrapTypeToString(((EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Context)->Type));\r
556 } else if (CompareGuid (HandlerType, &gEfiSmmUsbDispatch2ProtocolGuid)) {\r
557 Print(L" UsbType=\"0x%x\"", UsbTypeToString(((SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT *)Context)->Type));\r
558 Print(L" UsbDevicePath=\"%s\"", ConvertDevicePathToText((EFI_DEVICE_PATH_PROTOCOL *)(((SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT *)Context) + 1), TRUE, TRUE));\r
559 } else {\r
560 Print(L" Context=\"");\r
561 InternalDumpData (Context, ContextSize);\r
562 Print(L"\"");\r
563 }\r
564}\r
565\r
566/**\r
567 Dump SMI handler in HandlerCategory.\r
568\r
569 @param HandlerCategory SMI handler category\r
570**/\r
571VOID\r
572DumpSmiHandler(\r
573 IN UINT32 HandlerCategory\r
574 )\r
575{\r
576 SMM_CORE_SMI_DATABASE_STRUCTURE *SmiStruct;\r
577 SMM_CORE_SMI_HANDLER_STRUCTURE *SmiHandlerStruct;\r
578 UINTN Index;\r
579 SMM_CORE_IMAGE_DATABASE_STRUCTURE *ImageStruct;\r
580 CHAR8 *NameString;\r
581\r
582 SmiStruct = (VOID *)mSmiHandlerProfileDatabase;\r
583 while ((UINTN)SmiStruct < (UINTN)mSmiHandlerProfileDatabase + mSmiHandlerProfileDatabaseSize) {\r
584 if ((SmiStruct->Header.Signature == SMM_CORE_SMI_DATABASE_SIGNATURE) && (SmiStruct->HandlerCategory == HandlerCategory)) {\r
585 SmiHandlerStruct = (VOID *)(SmiStruct + 1);\r
586 Print(L" <SmiEntry");\r
587 if (!IsZeroGuid (&SmiStruct->HandlerType)) {\r
588 Print(L" HandlerType=\"%g\"", &SmiStruct->HandlerType);\r
589 }\r
590 Print(L">\n");\r
591 for (Index = 0; Index < SmiStruct->HandlerCount; Index++) {\r
592 Print(L" <SmiHandler");\r
593 if (SmiHandlerStruct->ContextBufferSize != 0) {\r
594 DumpSmiChildContext (&SmiStruct->HandlerType, (UINT8 *)SmiHandlerStruct + SmiHandlerStruct->ContextBufferOffset, SmiHandlerStruct->ContextBufferSize);\r
595 }\r
596 Print(L">\n");\r
597 ImageStruct = GetImageFromRef((UINTN)SmiHandlerStruct->ImageRef);\r
598 NameString = GetDriverNameString (ImageStruct);\r
599 Print(L" <Module RefId=\"0x%x\" Name=\"%a\">\n", SmiHandlerStruct->ImageRef, NameString);\r
600 if ((ImageStruct != NULL) && (ImageStruct->PdbStringOffset != 0)) {\r
601 Print(L" <Pdb>%a</Pdb>\n", (UINT8 *)ImageStruct + ImageStruct->PdbStringOffset);\r
602 }\r
603 Print(L" </Module>\n");\r
604 Print(L" <Handler Address=\"0x%x\">\n", SmiHandlerStruct->Handler);\r
605 if (ImageStruct != NULL) {\r
606 Print(L" <RVA>0x%x</RVA>\n", SmiHandlerStruct->Handler - ImageStruct->ImageBase);\r
607 }\r
608 Print(L" </Handler>\n", SmiHandlerStruct->Handler);\r
609 Print(L" <Caller Address=\"0x%x\">\n", SmiHandlerStruct->CallerAddr);\r
610 if (ImageStruct != NULL) {\r
611 Print(L" <RVA>0x%x</RVA>\n", SmiHandlerStruct->CallerAddr - ImageStruct->ImageBase);\r
612 }\r
613 Print(L" </Caller>\n", SmiHandlerStruct->Handler);\r
614 SmiHandlerStruct = (VOID *)((UINTN)SmiHandlerStruct + SmiHandlerStruct->Length);\r
615 Print(L" </SmiHandler>\n");\r
616 }\r
617 Print(L" </SmiEntry>\n");\r
618 }\r
619 SmiStruct = (VOID *)((UINTN)SmiStruct + SmiStruct->Header.Length);\r
620 }\r
621\r
622 return;\r
623}\r
624\r
625/**\r
626 The Entry Point for SMI handler profile info application.\r
627\r
628 @param ImageHandle The firmware allocated handle for the EFI image.\r
629 @param SystemTable A pointer to the EFI System Table.\r
630\r
631 @retval EFI_SUCCESS The entry point is executed successfully.\r
632 @retval Other Some error occurred when executing this entry point.\r
633**/\r
634EFI_STATUS\r
635EFIAPI\r
636SmiHandlerProfileInfoEntrypoint (\r
637 IN EFI_HANDLE ImageHandle,\r
638 IN EFI_SYSTEM_TABLE *SystemTable\r
639 )\r
640{\r
641 GetSmiHandlerProfileDatabase();\r
642\r
643 if (mSmiHandlerProfileDatabase == NULL) {\r
644 return EFI_SUCCESS;\r
645 }\r
646\r
647 //\r
648 // Dump all image\r
649 //\r
650 Print(L"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");\r
651 Print(L"<SmiHandlerProfile>\n");\r
652 Print(L"<ImageDatabase>\n");\r
653 Print(L" <!-- SMM image loaded -->\n");\r
654 DumpSmmLoadedImage();\r
655 Print(L"</ImageDatabase>\n\n");\r
656\r
657 //\r
658 // Dump SMI Handler\r
659 //\r
660 Print(L"<SmiHandlerDatabase>\n");\r
661 Print(L" <!-- SMI Handler registered -->\n\n");\r
662 Print(L" <SmiHandlerCategory Name=\"RootSmi\">\n");\r
663 Print(L" <!-- The root SMI Handler registered by SmmCore -->\n");\r
664 DumpSmiHandler(SmmCoreSmiHandlerCategoryRootHandler);\r
665 Print(L" </SmiHandlerCategory>\n\n");\r
666\r
667 Print(L" <SmiHandlerCategory Name=\"GuidSmi\">\n");\r
668 Print(L" <!-- The GUID SMI Handler registered by SmmCore -->\n");\r
669 DumpSmiHandler(SmmCoreSmiHandlerCategoryGuidHandler);\r
670 Print(L" </SmiHandlerCategory>\n\n");\r
671\r
672 Print(L" <SmiHandlerCategory Name=\"HardwareSmi\">\n");\r
673 Print(L" <!-- The hardware SMI Handler registered by SmmChildDispatcher -->\n");\r
674 DumpSmiHandler(SmmCoreSmiHandlerCategoryHardwareHandler);\r
675 Print(L" </SmiHandlerCategory>\n\n");\r
676\r
677 Print(L"</SmiHandlerDatabase>\n");\r
678 Print(L"</SmiHandlerProfile>\n");\r
679\r
680 if (mSmiHandlerProfileDatabase != NULL) {\r
681 FreePool(mSmiHandlerProfileDatabase);\r
682 }\r
683\r
684 return EFI_SUCCESS;\r
685}\r