Commit | Line | Data |
---|---|---|
216b942d JY |
1 | /** @file\r |
2 | Shell application to dump SMI handler profile information.\r | |
3 | \r | |
4 | Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>\r | |
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/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 | |
33 | CHAR8 mNameString[PROFILE_NAME_STRING_LENGTH + 1];\r | |
34 | \r | |
35 | VOID *mSmiHandlerProfileDatabase;\r | |
36 | UINTN 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 | |
44 | VOID\r | |
45 | InternalDumpData (\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 | |
62 | VOID\r | |
63 | GetSmiHandlerProfileDatabase(\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 | |
201 | VOID\r | |
202 | GetShortPdbFileName (\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 | |
253 | CHAR8 *\r | |
254 | GetDriverNameString (\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 | |
314 | SMM_CORE_IMAGE_DATABASE_STRUCTURE *\r | |
315 | GetImageFromRef (\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 | |
337 | VOID\r | |
338 | DumpSmmLoadedImage(\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 | |
369 | CHAR8 *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 | |
385 | CHAR8 *\r | |
386 | SxTypeToString (\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 | |
398 | CHAR8 *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 | |
410 | CHAR8 *\r | |
411 | SxPhaseToString (\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 | |
423 | CHAR8 *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 | |
435 | CHAR8 *\r | |
436 | PowerButtonPhaseToString (\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 | |
448 | CHAR8 *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 | |
460 | CHAR8 *\r | |
461 | StandbyButtonPhaseToString (\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 | |
473 | CHAR8 *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 | |
486 | CHAR8 *\r | |
487 | IoTrapTypeToString (\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 | |
499 | CHAR8 *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 | |
511 | CHAR8 *\r | |
512 | UsbTypeToString (\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 | |
531 | VOID\r | |
532 | DumpSmiChildContext (\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 | |
577 | VOID\r | |
578 | DumpSmiHandler(\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 | |
640 | EFI_STATUS\r | |
641 | EFIAPI\r | |
642 | SmiHandlerProfileInfoEntrypoint (\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 |