2 Shell application to dump SMI handler profile information.
4 Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include <Library/BaseLib.h>
17 #include <Library/BaseMemoryLib.h>
18 #include <Library/MemoryAllocationLib.h>
19 #include <Library/UefiBootServicesTableLib.h>
20 #include <Library/UefiRuntimeServicesTableLib.h>
21 #include <Library/DebugLib.h>
22 #include <Library/PrintLib.h>
23 #include <Library/UefiLib.h>
24 #include <Library/DevicePathLib.h>
25 #include <Library/DxeServicesLib.h>
26 #include <Protocol/SmmCommunication.h>
27 #include <Guid/PiSmmCommunicationRegionTable.h>
29 #include <Guid/SmiHandlerProfile.h>
31 #define PROFILE_NAME_STRING_LENGTH 64
32 CHAR8 mNameString
[PROFILE_NAME_STRING_LENGTH
+ 1];
34 VOID
*mSmiHandlerProfileDatabase
;
35 UINTN mSmiHandlerProfileDatabaseSize
;
38 This function dump raw data.
41 @param Size raw data size
50 for (Index
= 0; Index
< Size
; Index
++) {
51 Print (L
"%02x", (UINTN
)Data
[Index
]);
52 if ((Index
+ 1) != Size
) {
59 Get SMI handler profile database.
62 GetSmiHandlerProfileDatabase(
69 EFI_SMM_COMMUNICATE_HEADER
*CommHeader
;
70 SMI_HANDLER_PROFILE_PARAMETER_GET_INFO
*CommGetInfo
;
71 SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET
*CommGetData
;
72 EFI_SMM_COMMUNICATION_PROTOCOL
*SmmCommunication
;
73 UINTN MinimalSizeNeeded
;
74 EDKII_PI_SMM_COMMUNICATION_REGION_TABLE
*PiSmmCommunicationRegionTable
;
76 EFI_MEMORY_DESCRIPTOR
*Entry
;
81 Status
= gBS
->LocateProtocol(&gEfiSmmCommunicationProtocolGuid
, NULL
, (VOID
**)&SmmCommunication
);
82 if (EFI_ERROR(Status
)) {
83 Print(L
"SmiHandlerProfile: Locate SmmCommunication protocol - %r\n", Status
);
87 MinimalSizeNeeded
= EFI_PAGE_SIZE
;
89 Status
= EfiGetSystemConfigurationTable(
90 &gEdkiiPiSmmCommunicationRegionTableGuid
,
91 (VOID
**)&PiSmmCommunicationRegionTable
93 if (EFI_ERROR(Status
)) {
94 Print(L
"SmiHandlerProfile: Get PiSmmCommunicationRegionTable - %r\n", Status
);
97 ASSERT(PiSmmCommunicationRegionTable
!= NULL
);
98 Entry
= (EFI_MEMORY_DESCRIPTOR
*)(PiSmmCommunicationRegionTable
+ 1);
100 for (Index
= 0; Index
< PiSmmCommunicationRegionTable
->NumberOfEntries
; Index
++) {
101 if (Entry
->Type
== EfiConventionalMemory
) {
102 Size
= EFI_PAGES_TO_SIZE((UINTN
)Entry
->NumberOfPages
);
103 if (Size
>= MinimalSizeNeeded
) {
107 Entry
= (EFI_MEMORY_DESCRIPTOR
*)((UINT8
*)Entry
+ PiSmmCommunicationRegionTable
->DescriptorSize
);
109 ASSERT(Index
< PiSmmCommunicationRegionTable
->NumberOfEntries
);
110 CommBuffer
= (UINT8
*)(UINTN
)Entry
->PhysicalStart
;
115 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*)&CommBuffer
[0];
116 CopyMem(&CommHeader
->HeaderGuid
, &gSmiHandlerProfileGuid
, sizeof(gSmiHandlerProfileGuid
));
117 CommHeader
->MessageLength
= sizeof(SMI_HANDLER_PROFILE_PARAMETER_GET_INFO
);
119 CommGetInfo
= (SMI_HANDLER_PROFILE_PARAMETER_GET_INFO
*)&CommBuffer
[OFFSET_OF(EFI_SMM_COMMUNICATE_HEADER
, Data
)];
120 CommGetInfo
->Header
.Command
= SMI_HANDLER_PROFILE_COMMAND_GET_INFO
;
121 CommGetInfo
->Header
.DataLength
= sizeof(*CommGetInfo
);
122 CommGetInfo
->Header
.ReturnStatus
= (UINT64
)-1;
123 CommGetInfo
->DataSize
= 0;
125 CommSize
= sizeof(EFI_GUID
) + sizeof(UINTN
) + CommHeader
->MessageLength
;
126 Status
= SmmCommunication
->Communicate(SmmCommunication
, CommBuffer
, &CommSize
);
127 if (EFI_ERROR(Status
)) {
128 Print(L
"SmiHandlerProfile: SmmCommunication - %r\n", Status
);
132 if (CommGetInfo
->Header
.ReturnStatus
!= 0) {
133 Print(L
"SmiHandlerProfile: GetInfo - 0x%0x\n", CommGetInfo
->Header
.ReturnStatus
);
137 mSmiHandlerProfileDatabaseSize
= (UINTN
)CommGetInfo
->DataSize
;
142 mSmiHandlerProfileDatabase
= AllocateZeroPool(mSmiHandlerProfileDatabaseSize
);
143 if (mSmiHandlerProfileDatabase
== NULL
) {
144 Status
= EFI_OUT_OF_RESOURCES
;
145 Print(L
"SmiHandlerProfile: AllocateZeroPool (0x%x) for dump buffer - %r\n", mSmiHandlerProfileDatabaseSize
, Status
);
149 CommHeader
= (EFI_SMM_COMMUNICATE_HEADER
*)&CommBuffer
[0];
150 CopyMem(&CommHeader
->HeaderGuid
, &gSmiHandlerProfileGuid
, sizeof(gSmiHandlerProfileGuid
));
151 CommHeader
->MessageLength
= sizeof(SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET
);
153 CommGetData
= (SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET
*)&CommBuffer
[OFFSET_OF(EFI_SMM_COMMUNICATE_HEADER
, Data
)];
154 CommGetData
->Header
.Command
= SMI_HANDLER_PROFILE_COMMAND_GET_DATA_BY_OFFSET
;
155 CommGetData
->Header
.DataLength
= sizeof(*CommGetData
);
156 CommGetData
->Header
.ReturnStatus
= (UINT64
)-1;
158 CommSize
= sizeof(EFI_GUID
) + sizeof(UINTN
) + CommHeader
->MessageLength
;
159 Buffer
= (UINT8
*)CommHeader
+ CommSize
;
162 CommGetData
->DataBuffer
= (PHYSICAL_ADDRESS
)(UINTN
)Buffer
;
163 CommGetData
->DataOffset
= 0;
164 while (CommGetData
->DataOffset
< mSmiHandlerProfileDatabaseSize
) {
165 Offset
= (UINTN
)CommGetData
->DataOffset
;
166 if (Size
<= (mSmiHandlerProfileDatabaseSize
- CommGetData
->DataOffset
)) {
167 CommGetData
->DataSize
= (UINT64
)Size
;
169 CommGetData
->DataSize
= (UINT64
)(mSmiHandlerProfileDatabaseSize
- CommGetData
->DataOffset
);
171 Status
= SmmCommunication
->Communicate(SmmCommunication
, CommBuffer
, &CommSize
);
172 ASSERT_EFI_ERROR(Status
);
174 if (CommGetData
->Header
.ReturnStatus
!= 0) {
175 FreePool(mSmiHandlerProfileDatabase
);
176 mSmiHandlerProfileDatabase
= NULL
;
177 Print(L
"SmiHandlerProfile: GetData - 0x%x\n", CommGetData
->Header
.ReturnStatus
);
180 CopyMem((UINT8
*)mSmiHandlerProfileDatabase
+ Offset
, (VOID
*)(UINTN
)CommGetData
->DataBuffer
, (UINTN
)CommGetData
->DataSize
);
183 DEBUG ((DEBUG_INFO
, "SmiHandlerProfileSize - 0x%x\n", mSmiHandlerProfileDatabaseSize
));
189 Get the file name portion of the Pdb File Name.
191 The portion of the Pdb File Name between the last backslash and
192 either a following period or the end of the string is copied into
193 AsciiBuffer. The name is truncated, if necessary, to ensure that
194 AsciiBuffer is not overrun.
196 @param[in] PdbFileName Pdb file name.
197 @param[out] AsciiBuffer The resultant Ascii File Name.
201 GetShortPdbFileName (
202 IN CHAR8
*PdbFileName
,
203 OUT CHAR8
*AsciiBuffer
206 UINTN IndexPdb
; // Current work location within a Pdb string.
207 UINTN IndexBuffer
; // Current work location within a Buffer string.
211 ZeroMem (AsciiBuffer
, PROFILE_NAME_STRING_LENGTH
+ 1);
213 if (PdbFileName
== NULL
) {
214 AsciiStrnCpyS (AsciiBuffer
, PROFILE_NAME_STRING_LENGTH
+ 1, " ", 1);
217 for (EndIndex
= 0; PdbFileName
[EndIndex
] != 0; EndIndex
++);
218 for (IndexPdb
= 0; PdbFileName
[IndexPdb
] != 0; IndexPdb
++) {
219 if ((PdbFileName
[IndexPdb
] == '\\') || (PdbFileName
[IndexPdb
] == '/')) {
220 StartIndex
= IndexPdb
+ 1;
223 if (PdbFileName
[IndexPdb
] == '.') {
229 for (IndexPdb
= StartIndex
; IndexPdb
< EndIndex
; IndexPdb
++) {
230 AsciiBuffer
[IndexBuffer
] = PdbFileName
[IndexPdb
];
232 if (IndexBuffer
>= PROFILE_NAME_STRING_LENGTH
) {
233 AsciiBuffer
[PROFILE_NAME_STRING_LENGTH
] = 0;
241 Get a human readable name for an image.
242 The following methods will be tried orderly:
247 @param[in] ImageStruct Point to the image structure.
249 @return The resulting Ascii name string is stored in the mNameString global array.
253 GetDriverNameString (
254 IN SMM_CORE_IMAGE_DATABASE_STRUCTURE
*ImageStruct
261 if (ImageStruct
== NULL
) {
266 // Method 1: Get the name string from image PDB
268 if (ImageStruct
->PdbStringOffset
!= 0) {
269 GetShortPdbFileName ((CHAR8
*) ((UINTN
) ImageStruct
+ ImageStruct
->PdbStringOffset
), mNameString
);
273 if (!IsZeroGuid (&ImageStruct
->FileGuid
)) {
275 // Try to get the image's FFS UI section by image GUID
279 Status
= GetSectionFromAnyFv (
280 &ImageStruct
->FileGuid
,
281 EFI_SECTION_USER_INTERFACE
,
283 (VOID
**) &NameString
,
286 if (!EFI_ERROR (Status
)) {
288 // Method 2: Get the name string from FFS UI section
290 if (StrLen (NameString
) > PROFILE_NAME_STRING_LENGTH
) {
291 NameString
[PROFILE_NAME_STRING_LENGTH
] = 0;
293 UnicodeStrToAsciiStrS (NameString
, mNameString
, sizeof (mNameString
));
294 FreePool (NameString
);
300 // Method 3: Get the name string from image GUID
302 AsciiSPrint (mNameString
, sizeof (mNameString
), "%g", &ImageStruct
->FileGuid
);
307 Get image structure from reference index.
309 @param ImageRef the image reference index
311 @return image structure
313 SMM_CORE_IMAGE_DATABASE_STRUCTURE
*
318 SMM_CORE_IMAGE_DATABASE_STRUCTURE
*ImageStruct
;
320 ImageStruct
= (VOID
*)mSmiHandlerProfileDatabase
;
321 while ((UINTN
)ImageStruct
< (UINTN
)mSmiHandlerProfileDatabase
+ mSmiHandlerProfileDatabaseSize
) {
322 if (ImageStruct
->Header
.Signature
== SMM_CORE_IMAGE_DATABASE_SIGNATURE
) {
323 if (ImageStruct
->ImageRef
== ImageRef
) {
327 ImageStruct
= (VOID
*)((UINTN
)ImageStruct
+ ImageStruct
->Header
.Length
);
334 Dump SMM loaded image information.
341 SMM_CORE_IMAGE_DATABASE_STRUCTURE
*ImageStruct
;
345 ImageStruct
= (VOID
*)mSmiHandlerProfileDatabase
;
346 while ((UINTN
)ImageStruct
< (UINTN
)mSmiHandlerProfileDatabase
+ mSmiHandlerProfileDatabaseSize
) {
347 if (ImageStruct
->Header
.Signature
== SMM_CORE_IMAGE_DATABASE_SIGNATURE
) {
348 NameString
= GetDriverNameString (ImageStruct
);
349 Print(L
" <Image Name=\"%a\"", NameString
);
350 Print(L
" Base=\"0x%lx\" Size=\"0x%lx\"", ImageStruct
->ImageBase
, ImageStruct
->ImageSize
);
351 if (ImageStruct
->EntryPoint
!= 0) {
352 Print(L
" EntryPoint=\"0x%lx\"", ImageStruct
->EntryPoint
);
354 Print(L
" FvFile=\"%g\"", &ImageStruct
->FileGuid
);
355 Print(L
" RefId=\"0x%x\"", ImageStruct
->ImageRef
);
357 if (ImageStruct
->PdbStringOffset
!= 0) {
358 PdbString
= (CHAR8
*)((UINTN
)ImageStruct
+ ImageStruct
->PdbStringOffset
);
359 Print(L
" <Pdb>%a</Pdb>\n", PdbString
);
361 Print(L
" </Image>\n");
364 ImageStruct
= (VOID
*)((UINTN
)ImageStruct
+ ImageStruct
->Header
.Length
);
370 CHAR8
*mSxTypeString
[] = {
380 Convert SxType to a string.
384 @return SxType string
388 IN EFI_SLEEP_TYPE Type
391 if (Type
>= 0 && Type
<= ARRAY_SIZE(mSxTypeString
)) {
392 return mSxTypeString
[Type
];
394 AsciiSPrint (mNameString
, sizeof(mNameString
), "0x%x", Type
);
399 CHAR8
*mSxPhaseString
[] = {
405 Convert SxPhase to a string.
409 @return SxPhase string
413 IN EFI_SLEEP_PHASE Phase
416 if (Phase
>= 0 && Phase
<= ARRAY_SIZE(mSxPhaseString
)) {
417 return mSxPhaseString
[Phase
];
419 AsciiSPrint (mNameString
, sizeof(mNameString
), "0x%x", Phase
);
424 CHAR8
*mPowerButtonPhaseString
[] = {
430 Convert PowerButtonPhase to a string.
432 @param Phase PowerButtonPhase
434 @return PowerButtonPhase string
437 PowerButtonPhaseToString (
438 IN EFI_POWER_BUTTON_PHASE Phase
441 if (Phase
>= 0 && Phase
<= ARRAY_SIZE(mPowerButtonPhaseString
)) {
442 return mPowerButtonPhaseString
[Phase
];
444 AsciiSPrint (mNameString
, sizeof(mNameString
), "0x%x", Phase
);
449 CHAR8
*mStandbyButtonPhaseString
[] = {
450 "StandbyButtonEntry",
455 Convert StandbyButtonPhase to a string.
457 @param Phase StandbyButtonPhase
459 @return StandbyButtonPhase string
462 StandbyButtonPhaseToString (
463 IN EFI_STANDBY_BUTTON_PHASE Phase
466 if (Phase
>= 0 && Phase
<= ARRAY_SIZE(mStandbyButtonPhaseString
)) {
467 return mStandbyButtonPhaseString
[Phase
];
469 AsciiSPrint (mNameString
, sizeof(mNameString
), "0x%x", Phase
);
474 CHAR8
*mIoTrapTypeString
[] = {
481 Convert IoTrapType to a string.
483 @param Type IoTrapType
485 @return IoTrapType string
489 IN EFI_SMM_IO_TRAP_DISPATCH_TYPE Type
492 if (Type
>= 0 && Type
<= ARRAY_SIZE(mIoTrapTypeString
)) {
493 return mIoTrapTypeString
[Type
];
495 AsciiSPrint (mNameString
, sizeof(mNameString
), "0x%x", Type
);
500 CHAR8
*mUsbTypeString
[] = {
506 Convert UsbType to a string.
510 @return UsbType string
514 IN EFI_USB_SMI_TYPE Type
517 if (Type
>= 0 && Type
<= ARRAY_SIZE(mUsbTypeString
)) {
518 return mUsbTypeString
[Type
];
520 AsciiSPrint (mNameString
, sizeof(mNameString
), "0x%x", Type
);
526 Dump SMI child context.
528 @param HandlerType the handler type
529 @param Context the handler context
530 @param ContextSize the handler context size
533 DumpSmiChildContext (
534 IN EFI_GUID
*HandlerType
,
541 if (CompareGuid (HandlerType
, &gEfiSmmSwDispatch2ProtocolGuid
)) {
542 Print(L
" SwSmi=\"0x%lx\"", ((SMI_HANDLER_PROFILE_SW_REGISTER_CONTEXT
*)Context
)->SwSmiInputValue
);
543 } else if (CompareGuid (HandlerType
, &gEfiSmmSxDispatch2ProtocolGuid
)) {
544 Print(L
" SxType=\"%a\"", SxTypeToString(((EFI_SMM_SX_REGISTER_CONTEXT
*)Context
)->Type
));
545 Print(L
" SxPhase=\"%a\"", SxPhaseToString(((EFI_SMM_SX_REGISTER_CONTEXT
*)Context
)->Phase
));
546 } else if (CompareGuid (HandlerType
, &gEfiSmmPowerButtonDispatch2ProtocolGuid
)) {
547 Print(L
" PowerButtonPhase=\"%a\"", PowerButtonPhaseToString(((EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT
*)Context
)->Phase
));
548 } else if (CompareGuid (HandlerType
, &gEfiSmmStandbyButtonDispatch2ProtocolGuid
)) {
549 Print(L
" StandbyButtonPhase=\"%a\"", StandbyButtonPhaseToString(((EFI_SMM_STANDBY_BUTTON_REGISTER_CONTEXT
*)Context
)->Phase
));
550 } else if (CompareGuid (HandlerType
, &gEfiSmmPeriodicTimerDispatch2ProtocolGuid
)) {
551 Print(L
" PeriodicTimerPeriod=\"%ld\"", ((EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT
*)Context
)->Period
);
552 Print(L
" PeriodicTimerSmiTickInterval=\"%ld\"", ((EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT
*)Context
)->SmiTickInterval
);
553 } else if (CompareGuid (HandlerType
, &gEfiSmmGpiDispatch2ProtocolGuid
)) {
554 Print(L
" GpiNum=\"0x%lx\"", ((EFI_SMM_GPI_REGISTER_CONTEXT
*)Context
)->GpiNum
);
555 } else if (CompareGuid (HandlerType
, &gEfiSmmIoTrapDispatch2ProtocolGuid
)) {
556 Print(L
" IoTrapAddress=\"0x%x\"", ((EFI_SMM_IO_TRAP_REGISTER_CONTEXT
*)Context
)->Address
);
557 Print(L
" IoTrapLength=\"0x%x\"", ((EFI_SMM_IO_TRAP_REGISTER_CONTEXT
*)Context
)->Length
);
558 Print(L
" IoTrapType=\"%a\"", IoTrapTypeToString(((EFI_SMM_IO_TRAP_REGISTER_CONTEXT
*)Context
)->Type
));
559 } else if (CompareGuid (HandlerType
, &gEfiSmmUsbDispatch2ProtocolGuid
)) {
560 Print(L
" UsbType=\"0x%x\"", UsbTypeToString(((SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT
*)Context
)->Type
));
561 Str
= ConvertDevicePathToText((EFI_DEVICE_PATH_PROTOCOL
*)(((SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT
*)Context
) + 1), TRUE
, TRUE
);
562 Print(L
" UsbDevicePath=\"%s\"", Str
);
567 Print(L
" Context=\"");
568 InternalDumpData (Context
, ContextSize
);
574 Dump SMI handler in HandlerCategory.
576 @param HandlerCategory SMI handler category
580 IN UINT32 HandlerCategory
583 SMM_CORE_SMI_DATABASE_STRUCTURE
*SmiStruct
;
584 SMM_CORE_SMI_HANDLER_STRUCTURE
*SmiHandlerStruct
;
586 SMM_CORE_IMAGE_DATABASE_STRUCTURE
*ImageStruct
;
589 SmiStruct
= (VOID
*)mSmiHandlerProfileDatabase
;
590 while ((UINTN
)SmiStruct
< (UINTN
)mSmiHandlerProfileDatabase
+ mSmiHandlerProfileDatabaseSize
) {
591 if ((SmiStruct
->Header
.Signature
== SMM_CORE_SMI_DATABASE_SIGNATURE
) && (SmiStruct
->HandlerCategory
== HandlerCategory
)) {
592 SmiHandlerStruct
= (VOID
*)(SmiStruct
+ 1);
593 Print(L
" <SmiEntry");
594 if (!IsZeroGuid (&SmiStruct
->HandlerType
)) {
595 Print(L
" HandlerType=\"%g\"", &SmiStruct
->HandlerType
);
598 for (Index
= 0; Index
< SmiStruct
->HandlerCount
; Index
++) {
599 Print(L
" <SmiHandler");
600 if (SmiHandlerStruct
->ContextBufferSize
!= 0) {
601 DumpSmiChildContext (&SmiStruct
->HandlerType
, (UINT8
*)SmiHandlerStruct
+ SmiHandlerStruct
->ContextBufferOffset
, SmiHandlerStruct
->ContextBufferSize
);
604 ImageStruct
= GetImageFromRef((UINTN
)SmiHandlerStruct
->ImageRef
);
605 NameString
= GetDriverNameString (ImageStruct
);
606 Print(L
" <Module RefId=\"0x%x\" Name=\"%a\">\n", SmiHandlerStruct
->ImageRef
, NameString
);
607 if ((ImageStruct
!= NULL
) && (ImageStruct
->PdbStringOffset
!= 0)) {
608 Print(L
" <Pdb>%a</Pdb>\n", (UINT8
*)ImageStruct
+ ImageStruct
->PdbStringOffset
);
610 Print(L
" </Module>\n");
611 Print(L
" <Handler Address=\"0x%lx\">\n", SmiHandlerStruct
->Handler
);
612 if (ImageStruct
!= NULL
) {
613 Print(L
" <RVA>0x%x</RVA>\n", (UINTN
) (SmiHandlerStruct
->Handler
- ImageStruct
->ImageBase
));
615 Print(L
" </Handler>\n", SmiHandlerStruct
->Handler
);
616 Print(L
" <Caller Address=\"0x%lx\">\n", SmiHandlerStruct
->CallerAddr
);
617 if (ImageStruct
!= NULL
) {
618 Print(L
" <RVA>0x%x</RVA>\n", (UINTN
) (SmiHandlerStruct
->CallerAddr
- ImageStruct
->ImageBase
));
620 Print(L
" </Caller>\n", SmiHandlerStruct
->Handler
);
621 SmiHandlerStruct
= (VOID
*)((UINTN
)SmiHandlerStruct
+ SmiHandlerStruct
->Length
);
622 Print(L
" </SmiHandler>\n");
624 Print(L
" </SmiEntry>\n");
626 SmiStruct
= (VOID
*)((UINTN
)SmiStruct
+ SmiStruct
->Header
.Length
);
633 The Entry Point for SMI handler profile info application.
635 @param ImageHandle The firmware allocated handle for the EFI image.
636 @param SystemTable A pointer to the EFI System Table.
638 @retval EFI_SUCCESS The entry point is executed successfully.
639 @retval Other Some error occurred when executing this entry point.
643 SmiHandlerProfileInfoEntrypoint (
644 IN EFI_HANDLE ImageHandle
,
645 IN EFI_SYSTEM_TABLE
*SystemTable
648 GetSmiHandlerProfileDatabase();
650 if (mSmiHandlerProfileDatabase
== NULL
) {
657 Print(L
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
658 Print(L
"<SmiHandlerProfile>\n");
659 Print(L
"<ImageDatabase>\n");
660 Print(L
" <!-- SMM image loaded -->\n");
661 DumpSmmLoadedImage();
662 Print(L
"</ImageDatabase>\n\n");
667 Print(L
"<SmiHandlerDatabase>\n");
668 Print(L
" <!-- SMI Handler registered -->\n\n");
669 Print(L
" <SmiHandlerCategory Name=\"RootSmi\">\n");
670 Print(L
" <!-- The root SMI Handler registered by SmmCore -->\n");
671 DumpSmiHandler(SmmCoreSmiHandlerCategoryRootHandler
);
672 Print(L
" </SmiHandlerCategory>\n\n");
674 Print(L
" <SmiHandlerCategory Name=\"GuidSmi\">\n");
675 Print(L
" <!-- The GUID SMI Handler registered by SmmCore -->\n");
676 DumpSmiHandler(SmmCoreSmiHandlerCategoryGuidHandler
);
677 Print(L
" </SmiHandlerCategory>\n\n");
679 Print(L
" <SmiHandlerCategory Name=\"HardwareSmi\">\n");
680 Print(L
" <!-- The hardware SMI Handler registered by SmmChildDispatcher -->\n");
681 DumpSmiHandler(SmmCoreSmiHandlerCategoryHardwareHandler
);
682 Print(L
" </SmiHandlerCategory>\n\n");
684 Print(L
"</SmiHandlerDatabase>\n");
685 Print(L
"</SmiHandlerProfile>\n");
687 if (mSmiHandlerProfileDatabase
!= NULL
) {
688 FreePool(mSmiHandlerProfileDatabase
);