]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfo.c
MdeModulePkg SmiHandlerProfile: Use fixed data type in data structure
[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
8ced192d
SZ
269 if (ImageStruct->PdbStringOffset != 0) {\r
270 GetShortPdbFileName ((CHAR8 *) ((UINTN) ImageStruct + ImageStruct->PdbStringOffset), mNameString);\r
216b942d
JY
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
f2485395 351 Print(L" Base=\"0x%lx\" Size=\"0x%lx\"", ImageStruct->ImageBase, ImageStruct->ImageSize);\r
216b942d 352 if (ImageStruct->EntryPoint != 0) {\r
f2485395 353 Print(L" EntryPoint=\"0x%lx\"", ImageStruct->EntryPoint);\r
216b942d
JY
354 }\r
355 Print(L" FvFile=\"%g\"", &ImageStruct->FileGuid);\r
356 Print(L" RefId=\"0x%x\"", ImageStruct->ImageRef);\r
357 Print(L">\n");\r
8ced192d
SZ
358 if (ImageStruct->PdbStringOffset != 0) {\r
359 PdbString = (CHAR8 *)((UINTN)ImageStruct + ImageStruct->PdbStringOffset);\r
360 Print(L" <Pdb>%a</Pdb>\n", PdbString);\r
361 }\r
216b942d
JY
362 Print(L" </Image>\n");\r
363 }\r
364\r
365 ImageStruct = (VOID *)((UINTN)ImageStruct + ImageStruct->Header.Length);\r
366 }\r
367\r
368 return;\r
369}\r
370\r
371CHAR8 *mSxTypeString[] = {\r
372 "SxS0",\r
373 "SxS1",\r
374 "SxS2",\r
375 "SxS3",\r
376 "SxS4",\r
377 "SxS5",\r
378};\r
379\r
380/**\r
381 Convert SxType to a string.\r
382\r
383 @param Type SxType\r
384\r
385 @return SxType string\r
386**/\r
387CHAR8 *\r
388SxTypeToString (\r
389 IN EFI_SLEEP_TYPE Type\r
390 )\r
391{\r
392 if (Type >= 0 && Type <= ARRAY_SIZE(mSxTypeString)) {\r
393 return mSxTypeString[Type];\r
394 } else {\r
395 AsciiSPrint (mNameString, sizeof(mNameString), "0x%x", Type);\r
396 return mNameString;\r
397 }\r
398}\r
399\r
400CHAR8 *mSxPhaseString[] = {\r
401 "SxEntry",\r
402 "SxExit",\r
403};\r
404\r
405/**\r
406 Convert SxPhase to a string.\r
407\r
408 @param Phase SxPhase\r
409\r
410 @return SxPhase string\r
411**/\r
412CHAR8 *\r
413SxPhaseToString (\r
414 IN EFI_SLEEP_PHASE Phase\r
415 )\r
416{\r
417 if (Phase >= 0 && Phase <= ARRAY_SIZE(mSxPhaseString)) {\r
418 return mSxPhaseString[Phase];\r
419 } else {\r
420 AsciiSPrint (mNameString, sizeof(mNameString), "0x%x", Phase);\r
421 return mNameString;\r
422 }\r
423}\r
424\r
425CHAR8 *mPowerButtonPhaseString[] = {\r
426 "PowerButtonEntry",\r
427 "PowerButtonExit",\r
428};\r
429\r
430/**\r
431 Convert PowerButtonPhase to a string.\r
432\r
433 @param Phase PowerButtonPhase\r
434\r
435 @return PowerButtonPhase string\r
436**/\r
437CHAR8 *\r
438PowerButtonPhaseToString (\r
439 IN EFI_POWER_BUTTON_PHASE Phase\r
440 )\r
441{\r
442 if (Phase >= 0 && Phase <= ARRAY_SIZE(mPowerButtonPhaseString)) {\r
443 return mPowerButtonPhaseString[Phase];\r
444 } else {\r
445 AsciiSPrint (mNameString, sizeof(mNameString), "0x%x", Phase);\r
446 return mNameString;\r
447 }\r
448}\r
449\r
450CHAR8 *mStandbyButtonPhaseString[] = {\r
451 "StandbyButtonEntry",\r
452 "StandbyButtonExit",\r
453};\r
454\r
455/**\r
456 Convert StandbyButtonPhase to a string.\r
457\r
458 @param Phase StandbyButtonPhase\r
459\r
460 @return StandbyButtonPhase string\r
461**/\r
462CHAR8 *\r
463StandbyButtonPhaseToString (\r
464 IN EFI_STANDBY_BUTTON_PHASE Phase\r
465 )\r
466{\r
467 if (Phase >= 0 && Phase <= ARRAY_SIZE(mStandbyButtonPhaseString)) {\r
468 return mStandbyButtonPhaseString[Phase];\r
469 } else {\r
470 AsciiSPrint (mNameString, sizeof(mNameString), "0x%x", Phase);\r
471 return mNameString;\r
472 }\r
473}\r
474\r
475CHAR8 *mIoTrapTypeString[] = {\r
476 "WriteTrap",\r
477 "ReadTrap",\r
478 "ReadWriteTrap",\r
479};\r
480\r
481/**\r
482 Convert IoTrapType to a string.\r
483\r
484 @param Type IoTrapType\r
485\r
486 @return IoTrapType string\r
487**/\r
488CHAR8 *\r
489IoTrapTypeToString (\r
490 IN EFI_SMM_IO_TRAP_DISPATCH_TYPE Type\r
491 )\r
492{\r
493 if (Type >= 0 && Type <= ARRAY_SIZE(mIoTrapTypeString)) {\r
494 return mIoTrapTypeString[Type];\r
495 } else {\r
496 AsciiSPrint (mNameString, sizeof(mNameString), "0x%x", Type);\r
497 return mNameString;\r
498 }\r
499}\r
500\r
501CHAR8 *mUsbTypeString[] = {\r
502 "UsbLegacy",\r
503 "UsbWake",\r
504};\r
505\r
506/**\r
507 Convert UsbType to a string.\r
508\r
509 @param Type UsbType\r
510\r
511 @return UsbType string\r
512**/\r
513CHAR8 *\r
514UsbTypeToString (\r
515 IN EFI_USB_SMI_TYPE Type\r
516 )\r
517{\r
518 if (Type >= 0 && Type <= ARRAY_SIZE(mUsbTypeString)) {\r
519 return mUsbTypeString[Type];\r
520 } else {\r
521 AsciiSPrint (mNameString, sizeof(mNameString), "0x%x", Type);\r
522 return mNameString;\r
523 }\r
524}\r
525\r
526/**\r
527 Dump SMI child context.\r
528\r
529 @param HandlerType the handler type\r
530 @param Context the handler context\r
531 @param ContextSize the handler context size\r
532**/\r
533VOID\r
534DumpSmiChildContext (\r
535 IN EFI_GUID *HandlerType,\r
536 IN VOID *Context,\r
537 IN UINTN ContextSize\r
538 )\r
539{\r
fb1c81a1
SZ
540 CHAR16 *Str;\r
541\r
216b942d 542 if (CompareGuid (HandlerType, &gEfiSmmSwDispatch2ProtocolGuid)) {\r
f2485395 543 Print(L" SwSmi=\"0x%lx\"", ((SMI_HANDLER_PROFILE_SW_REGISTER_CONTEXT *)Context)->SwSmiInputValue);\r
216b942d
JY
544 } else if (CompareGuid (HandlerType, &gEfiSmmSxDispatch2ProtocolGuid)) {\r
545 Print(L" SxType=\"%a\"", SxTypeToString(((EFI_SMM_SX_REGISTER_CONTEXT *)Context)->Type));\r
546 Print(L" SxPhase=\"%a\"", SxPhaseToString(((EFI_SMM_SX_REGISTER_CONTEXT *)Context)->Phase));\r
547 } else if (CompareGuid (HandlerType, &gEfiSmmPowerButtonDispatch2ProtocolGuid)) {\r
548 Print(L" PowerButtonPhase=\"%a\"", PowerButtonPhaseToString(((EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT *)Context)->Phase));\r
549 } else if (CompareGuid (HandlerType, &gEfiSmmStandbyButtonDispatch2ProtocolGuid)) {\r
550 Print(L" StandbyButtonPhase=\"%a\"", StandbyButtonPhaseToString(((EFI_SMM_STANDBY_BUTTON_REGISTER_CONTEXT *)Context)->Phase));\r
551 } else if (CompareGuid (HandlerType, &gEfiSmmPeriodicTimerDispatch2ProtocolGuid)) {\r
552 Print(L" PeriodicTimerPeriod=\"%ld\"", ((EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT *)Context)->Period);\r
553 Print(L" PeriodicTimerSmiTickInterval=\"%ld\"", ((EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT *)Context)->SmiTickInterval);\r
554 } else if (CompareGuid (HandlerType, &gEfiSmmGpiDispatch2ProtocolGuid)) {\r
555 Print(L" GpiNum=\"0x%lx\"", ((EFI_SMM_GPI_REGISTER_CONTEXT *)Context)->GpiNum);\r
556 } else if (CompareGuid (HandlerType, &gEfiSmmIoTrapDispatch2ProtocolGuid)) {\r
557 Print(L" IoTrapAddress=\"0x%x\"", ((EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Context)->Address);\r
558 Print(L" IoTrapLength=\"0x%x\"", ((EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Context)->Length);\r
559 Print(L" IoTrapType=\"%a\"", IoTrapTypeToString(((EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Context)->Type));\r
560 } else if (CompareGuid (HandlerType, &gEfiSmmUsbDispatch2ProtocolGuid)) {\r
561 Print(L" UsbType=\"0x%x\"", UsbTypeToString(((SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT *)Context)->Type));\r
fb1c81a1
SZ
562 Str = ConvertDevicePathToText((EFI_DEVICE_PATH_PROTOCOL *)(((SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT *)Context) + 1), TRUE, TRUE);\r
563 Print(L" UsbDevicePath=\"%s\"", Str);\r
564 if (Str != NULL) {\r
565 FreePool (Str);\r
566 }\r
216b942d
JY
567 } else {\r
568 Print(L" Context=\"");\r
569 InternalDumpData (Context, ContextSize);\r
570 Print(L"\"");\r
571 }\r
572}\r
573\r
574/**\r
575 Dump SMI handler in HandlerCategory.\r
576\r
577 @param HandlerCategory SMI handler category\r
578**/\r
579VOID\r
580DumpSmiHandler(\r
581 IN UINT32 HandlerCategory\r
582 )\r
583{\r
584 SMM_CORE_SMI_DATABASE_STRUCTURE *SmiStruct;\r
585 SMM_CORE_SMI_HANDLER_STRUCTURE *SmiHandlerStruct;\r
586 UINTN Index;\r
587 SMM_CORE_IMAGE_DATABASE_STRUCTURE *ImageStruct;\r
588 CHAR8 *NameString;\r
589\r
590 SmiStruct = (VOID *)mSmiHandlerProfileDatabase;\r
591 while ((UINTN)SmiStruct < (UINTN)mSmiHandlerProfileDatabase + mSmiHandlerProfileDatabaseSize) {\r
592 if ((SmiStruct->Header.Signature == SMM_CORE_SMI_DATABASE_SIGNATURE) && (SmiStruct->HandlerCategory == HandlerCategory)) {\r
593 SmiHandlerStruct = (VOID *)(SmiStruct + 1);\r
594 Print(L" <SmiEntry");\r
595 if (!IsZeroGuid (&SmiStruct->HandlerType)) {\r
596 Print(L" HandlerType=\"%g\"", &SmiStruct->HandlerType);\r
597 }\r
598 Print(L">\n");\r
599 for (Index = 0; Index < SmiStruct->HandlerCount; Index++) {\r
600 Print(L" <SmiHandler");\r
601 if (SmiHandlerStruct->ContextBufferSize != 0) {\r
602 DumpSmiChildContext (&SmiStruct->HandlerType, (UINT8 *)SmiHandlerStruct + SmiHandlerStruct->ContextBufferOffset, SmiHandlerStruct->ContextBufferSize);\r
603 }\r
604 Print(L">\n");\r
605 ImageStruct = GetImageFromRef((UINTN)SmiHandlerStruct->ImageRef);\r
606 NameString = GetDriverNameString (ImageStruct);\r
607 Print(L" <Module RefId=\"0x%x\" Name=\"%a\">\n", SmiHandlerStruct->ImageRef, NameString);\r
608 if ((ImageStruct != NULL) && (ImageStruct->PdbStringOffset != 0)) {\r
609 Print(L" <Pdb>%a</Pdb>\n", (UINT8 *)ImageStruct + ImageStruct->PdbStringOffset);\r
610 }\r
611 Print(L" </Module>\n");\r
f2485395 612 Print(L" <Handler Address=\"0x%lx\">\n", SmiHandlerStruct->Handler);\r
216b942d 613 if (ImageStruct != NULL) {\r
f2485395 614 Print(L" <RVA>0x%x</RVA>\n", (UINTN) (SmiHandlerStruct->Handler - ImageStruct->ImageBase));\r
216b942d
JY
615 }\r
616 Print(L" </Handler>\n", SmiHandlerStruct->Handler);\r
f2485395 617 Print(L" <Caller Address=\"0x%lx\">\n", SmiHandlerStruct->CallerAddr);\r
216b942d 618 if (ImageStruct != NULL) {\r
f2485395 619 Print(L" <RVA>0x%x</RVA>\n", (UINTN) (SmiHandlerStruct->CallerAddr - ImageStruct->ImageBase));\r
216b942d
JY
620 }\r
621 Print(L" </Caller>\n", SmiHandlerStruct->Handler);\r
622 SmiHandlerStruct = (VOID *)((UINTN)SmiHandlerStruct + SmiHandlerStruct->Length);\r
623 Print(L" </SmiHandler>\n");\r
624 }\r
625 Print(L" </SmiEntry>\n");\r
626 }\r
627 SmiStruct = (VOID *)((UINTN)SmiStruct + SmiStruct->Header.Length);\r
628 }\r
629\r
630 return;\r
631}\r
632\r
633/**\r
634 The Entry Point for SMI handler profile info application.\r
635\r
636 @param ImageHandle The firmware allocated handle for the EFI image.\r
637 @param SystemTable A pointer to the EFI System Table.\r
638\r
639 @retval EFI_SUCCESS The entry point is executed successfully.\r
640 @retval Other Some error occurred when executing this entry point.\r
641**/\r
642EFI_STATUS\r
643EFIAPI\r
644SmiHandlerProfileInfoEntrypoint (\r
645 IN EFI_HANDLE ImageHandle,\r
646 IN EFI_SYSTEM_TABLE *SystemTable\r
647 )\r
648{\r
649 GetSmiHandlerProfileDatabase();\r
650\r
651 if (mSmiHandlerProfileDatabase == NULL) {\r
652 return EFI_SUCCESS;\r
653 }\r
654\r
655 //\r
656 // Dump all image\r
657 //\r
658 Print(L"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");\r
659 Print(L"<SmiHandlerProfile>\n");\r
660 Print(L"<ImageDatabase>\n");\r
661 Print(L" <!-- SMM image loaded -->\n");\r
662 DumpSmmLoadedImage();\r
663 Print(L"</ImageDatabase>\n\n");\r
664\r
665 //\r
666 // Dump SMI Handler\r
667 //\r
668 Print(L"<SmiHandlerDatabase>\n");\r
669 Print(L" <!-- SMI Handler registered -->\n\n");\r
670 Print(L" <SmiHandlerCategory Name=\"RootSmi\">\n");\r
671 Print(L" <!-- The root SMI Handler registered by SmmCore -->\n");\r
672 DumpSmiHandler(SmmCoreSmiHandlerCategoryRootHandler);\r
673 Print(L" </SmiHandlerCategory>\n\n");\r
674\r
675 Print(L" <SmiHandlerCategory Name=\"GuidSmi\">\n");\r
676 Print(L" <!-- The GUID SMI Handler registered by SmmCore -->\n");\r
677 DumpSmiHandler(SmmCoreSmiHandlerCategoryGuidHandler);\r
678 Print(L" </SmiHandlerCategory>\n\n");\r
679\r
680 Print(L" <SmiHandlerCategory Name=\"HardwareSmi\">\n");\r
681 Print(L" <!-- The hardware SMI Handler registered by SmmChildDispatcher -->\n");\r
682 DumpSmiHandler(SmmCoreSmiHandlerCategoryHardwareHandler);\r
683 Print(L" </SmiHandlerCategory>\n\n");\r
684\r
685 Print(L"</SmiHandlerDatabase>\n");\r
686 Print(L"</SmiHandlerProfile>\n");\r
687\r
688 if (mSmiHandlerProfileDatabase != NULL) {\r
689 FreePool(mSmiHandlerProfileDatabase);\r
690 }\r
691\r
692 return EFI_SUCCESS;\r
693}\r