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