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