audk/MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfo.c

692 lines
22 KiB
C
Raw Normal View History

/** @file
Shell application to dump SMI handler profile information.
Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include <PiDxe.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/DebugLib.h>
#include <Library/PrintLib.h>
#include <Library/UefiLib.h>
#include <Library/DevicePathLib.h>
#include <Library/PeCoffGetEntryPointLib.h>
#include <Library/DxeServicesLib.h>
#include <Protocol/SmmCommunication.h>
#include <Guid/PiSmmCommunicationRegionTable.h>
#include <Guid/SmiHandlerProfile.h>
#define PROFILE_NAME_STRING_LENGTH 64
CHAR8 mNameString[PROFILE_NAME_STRING_LENGTH + 1];
VOID *mSmiHandlerProfileDatabase;
UINTN mSmiHandlerProfileDatabaseSize;
/**
This function dump raw data.
@param Data raw data
@param Size raw data size
**/
VOID
InternalDumpData (
IN UINT8 *Data,
IN UINTN Size
)
{
UINTN Index;
for (Index = 0; Index < Size; Index++) {
Print (L"%02x", (UINTN)Data[Index]);
if ((Index + 1) != Size) {
Print (L" ");
}
}
}
/**
Get SMI handler profile database.
**/
VOID
GetSmiHandlerProfileDatabase(
VOID
)
{
EFI_STATUS Status;
UINTN CommSize;
UINT8 *CommBuffer;
EFI_SMM_COMMUNICATE_HEADER *CommHeader;
SMI_HANDLER_PROFILE_PARAMETER_GET_INFO *CommGetInfo;
SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET *CommGetData;
EFI_SMM_COMMUNICATION_PROTOCOL *SmmCommunication;
UINTN MinimalSizeNeeded;
EDKII_PI_SMM_COMMUNICATION_REGION_TABLE *PiSmmCommunicationRegionTable;
UINT32 Index;
EFI_MEMORY_DESCRIPTOR *Entry;
VOID *Buffer;
UINTN Size;
UINTN Offset;
Status = gBS->LocateProtocol(&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **)&SmmCommunication);
if (EFI_ERROR(Status)) {
Print(L"SmiHandlerProfile: Locate SmmCommunication protocol - %r\n", Status);
return ;
}
MinimalSizeNeeded = EFI_PAGE_SIZE;
Status = EfiGetSystemConfigurationTable(
&gEdkiiPiSmmCommunicationRegionTableGuid,
(VOID **)&PiSmmCommunicationRegionTable
);
if (EFI_ERROR(Status)) {
Print(L"SmiHandlerProfile: Get PiSmmCommunicationRegionTable - %r\n", Status);
return ;
}
ASSERT(PiSmmCommunicationRegionTable != NULL);
Entry = (EFI_MEMORY_DESCRIPTOR *)(PiSmmCommunicationRegionTable + 1);
Size = 0;
for (Index = 0; Index < PiSmmCommunicationRegionTable->NumberOfEntries; Index++) {
if (Entry->Type == EfiConventionalMemory) {
Size = EFI_PAGES_TO_SIZE((UINTN)Entry->NumberOfPages);
if (Size >= MinimalSizeNeeded) {
break;
}
}
Entry = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)Entry + PiSmmCommunicationRegionTable->DescriptorSize);
}
ASSERT(Index < PiSmmCommunicationRegionTable->NumberOfEntries);
CommBuffer = (UINT8 *)(UINTN)Entry->PhysicalStart;
//
// Get Size
//
CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0];
CopyMem(&CommHeader->HeaderGuid, &gSmiHandlerProfileGuid, sizeof(gSmiHandlerProfileGuid));
CommHeader->MessageLength = sizeof(SMI_HANDLER_PROFILE_PARAMETER_GET_INFO);
CommGetInfo = (SMI_HANDLER_PROFILE_PARAMETER_GET_INFO *)&CommBuffer[OFFSET_OF(EFI_SMM_COMMUNICATE_HEADER, Data)];
CommGetInfo->Header.Command = SMI_HANDLER_PROFILE_COMMAND_GET_INFO;
CommGetInfo->Header.DataLength = sizeof(*CommGetInfo);
CommGetInfo->Header.ReturnStatus = (UINT64)-1;
CommGetInfo->DataSize = 0;
CommSize = sizeof(EFI_GUID) + sizeof(UINTN) + CommHeader->MessageLength;
Status = SmmCommunication->Communicate(SmmCommunication, CommBuffer, &CommSize);
if (EFI_ERROR(Status)) {
Print(L"SmiHandlerProfile: SmmCommunication - %r\n", Status);
return ;
}
if (CommGetInfo->Header.ReturnStatus != 0) {
Print(L"SmiHandlerProfile: GetInfo - 0x%0x\n", CommGetInfo->Header.ReturnStatus);
return ;
}
mSmiHandlerProfileDatabaseSize = (UINTN)CommGetInfo->DataSize;
//
// Get Data
//
mSmiHandlerProfileDatabase = AllocateZeroPool(mSmiHandlerProfileDatabaseSize);
if (mSmiHandlerProfileDatabase == NULL) {
Status = EFI_OUT_OF_RESOURCES;
Print(L"SmiHandlerProfile: AllocateZeroPool (0x%x) for dump buffer - %r\n", mSmiHandlerProfileDatabaseSize, Status);
return ;
}
CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0];
CopyMem(&CommHeader->HeaderGuid, &gSmiHandlerProfileGuid, sizeof(gSmiHandlerProfileGuid));
CommHeader->MessageLength = sizeof(SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET);
CommGetData = (SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET *)&CommBuffer[OFFSET_OF(EFI_SMM_COMMUNICATE_HEADER, Data)];
CommGetData->Header.Command = SMI_HANDLER_PROFILE_COMMAND_GET_DATA_BY_OFFSET;
CommGetData->Header.DataLength = sizeof(*CommGetData);
CommGetData->Header.ReturnStatus = (UINT64)-1;
CommSize = sizeof(EFI_GUID) + sizeof(UINTN) + CommHeader->MessageLength;
Buffer = (UINT8 *)CommHeader + CommSize;
Size -= CommSize;
CommGetData->DataBuffer = (PHYSICAL_ADDRESS)(UINTN)Buffer;
CommGetData->DataOffset = 0;
while (CommGetData->DataOffset < mSmiHandlerProfileDatabaseSize) {
Offset = (UINTN)CommGetData->DataOffset;
if (Size <= (mSmiHandlerProfileDatabaseSize - CommGetData->DataOffset)) {
CommGetData->DataSize = (UINT64)Size;
} else {
CommGetData->DataSize = (UINT64)(mSmiHandlerProfileDatabaseSize - CommGetData->DataOffset);
}
Status = SmmCommunication->Communicate(SmmCommunication, CommBuffer, &CommSize);
ASSERT_EFI_ERROR(Status);
if (CommGetData->Header.ReturnStatus != 0) {
FreePool(mSmiHandlerProfileDatabase);
mSmiHandlerProfileDatabase = NULL;
Print(L"SmiHandlerProfile: GetData - 0x%x\n", CommGetData->Header.ReturnStatus);
return ;
}
CopyMem((UINT8 *)mSmiHandlerProfileDatabase + Offset, (VOID *)(UINTN)CommGetData->DataBuffer, (UINTN)CommGetData->DataSize);
}
DEBUG ((DEBUG_INFO, "SmiHandlerProfileSize - 0x%x\n", mSmiHandlerProfileDatabaseSize));
return ;
}
/**
Get the file name portion of the Pdb File Name.
The portion of the Pdb File Name between the last backslash and
either a following period or the end of the string is copied into
AsciiBuffer. The name is truncated, if necessary, to ensure that
AsciiBuffer is not overrun.
@param[in] PdbFileName Pdb file name.
@param[out] AsciiBuffer The resultant Ascii File Name.
**/
VOID
GetShortPdbFileName (
IN CHAR8 *PdbFileName,
OUT CHAR8 *AsciiBuffer
)
{
UINTN IndexPdb; // Current work location within a Pdb string.
UINTN IndexBuffer; // Current work location within a Buffer string.
UINTN StartIndex;
UINTN EndIndex;
ZeroMem (AsciiBuffer, PROFILE_NAME_STRING_LENGTH + 1);
if (PdbFileName == NULL) {
AsciiStrnCpyS (AsciiBuffer, PROFILE_NAME_STRING_LENGTH + 1, " ", 1);
} else {
StartIndex = 0;
for (EndIndex = 0; PdbFileName[EndIndex] != 0; EndIndex++);
for (IndexPdb = 0; PdbFileName[IndexPdb] != 0; IndexPdb++) {
if ((PdbFileName[IndexPdb] == '\\') || (PdbFileName[IndexPdb] == '/')) {
StartIndex = IndexPdb + 1;
}
if (PdbFileName[IndexPdb] == '.') {
EndIndex = IndexPdb;
}
}
IndexBuffer = 0;
for (IndexPdb = StartIndex; IndexPdb < EndIndex; IndexPdb++) {
AsciiBuffer[IndexBuffer] = PdbFileName[IndexPdb];
IndexBuffer++;
if (IndexBuffer >= PROFILE_NAME_STRING_LENGTH) {
AsciiBuffer[PROFILE_NAME_STRING_LENGTH] = 0;
break;
}
}
}
}
/**
Get a human readable name for an image.
The following methods will be tried orderly:
1. Image PDB
2. FFS UI section
3. Image GUID
@param[in] ImageStruct Point to the image structure.
@return The resulting Ascii name string is stored in the mNameString global array.
**/
CHAR8 *
GetDriverNameString (
IN SMM_CORE_IMAGE_DATABASE_STRUCTURE *ImageStruct
)
{
EFI_STATUS Status;
CHAR16 *NameString;
UINTN StringSize;
if (ImageStruct == NULL) {
return "???";
}
//
// Method 1: Get the name string from image PDB
//
if (ImageStruct->Header.Length > sizeof (SMM_CORE_IMAGE_DATABASE_STRUCTURE)) {
GetShortPdbFileName ((CHAR8 *) (ImageStruct + 1), mNameString);
return mNameString;
}
if (!IsZeroGuid (&ImageStruct->FileGuid)) {
//
// Try to get the image's FFS UI section by image GUID
//
NameString = NULL;
StringSize = 0;
Status = GetSectionFromAnyFv (
&ImageStruct->FileGuid,
EFI_SECTION_USER_INTERFACE,
0,
(VOID **) &NameString,
&StringSize
);
if (!EFI_ERROR (Status)) {
//
// Method 2: Get the name string from FFS UI section
//
if (StrLen (NameString) > PROFILE_NAME_STRING_LENGTH) {
NameString[PROFILE_NAME_STRING_LENGTH] = 0;
}
UnicodeStrToAsciiStrS (NameString, mNameString, sizeof (mNameString));
FreePool (NameString);
return mNameString;
}
}
//
// Method 3: Get the name string from image GUID
//
AsciiSPrint (mNameString, sizeof (mNameString), "%g", &ImageStruct->FileGuid);
return mNameString;
}
/**
Get image structure from reference index.
@param ImageRef the image reference index
@return image structure
**/
SMM_CORE_IMAGE_DATABASE_STRUCTURE *
GetImageFromRef (
IN UINTN ImageRef
)
{
SMM_CORE_IMAGE_DATABASE_STRUCTURE *ImageStruct;
ImageStruct = (VOID *)mSmiHandlerProfileDatabase;
while ((UINTN)ImageStruct < (UINTN)mSmiHandlerProfileDatabase + mSmiHandlerProfileDatabaseSize) {
if (ImageStruct->Header.Signature == SMM_CORE_IMAGE_DATABASE_SIGNATURE) {
if (ImageStruct->ImageRef == ImageRef) {
return ImageStruct;
}
}
ImageStruct = (VOID *)((UINTN)ImageStruct + ImageStruct->Header.Length);
}
return NULL;
}
/**
Dump SMM loaded image information.
**/
VOID
DumpSmmLoadedImage(
VOID
)
{
SMM_CORE_IMAGE_DATABASE_STRUCTURE *ImageStruct;
CHAR8 *PdbString;
CHAR8 *NameString;
ImageStruct = (VOID *)mSmiHandlerProfileDatabase;
while ((UINTN)ImageStruct < (UINTN)mSmiHandlerProfileDatabase + mSmiHandlerProfileDatabaseSize) {
if (ImageStruct->Header.Signature == SMM_CORE_IMAGE_DATABASE_SIGNATURE) {
NameString = GetDriverNameString (ImageStruct);
Print(L" <Image Name=\"%a\"", NameString);
Print(L" Base=\"0x%x\" Size=\"0x%x\"", ImageStruct->ImageBase, ImageStruct->ImageSize);
if (ImageStruct->EntryPoint != 0) {
Print(L" EntryPoint=\"0x%x\"", ImageStruct->EntryPoint);
}
Print(L" FvFile=\"%g\"", &ImageStruct->FileGuid);
Print(L" RefId=\"0x%x\"", ImageStruct->ImageRef);
Print(L">\n");
PdbString = (CHAR8 *)((UINTN)ImageStruct + ImageStruct->PdbStringOffset);
Print(L" <Pdb>%a</Pdb>\n", PdbString);
Print(L" </Image>\n");
}
ImageStruct = (VOID *)((UINTN)ImageStruct + ImageStruct->Header.Length);
}
return;
}
CHAR8 *mSxTypeString[] = {
"SxS0",
"SxS1",
"SxS2",
"SxS3",
"SxS4",
"SxS5",
};
/**
Convert SxType to a string.
@param Type SxType
@return SxType string
**/
CHAR8 *
SxTypeToString (
IN EFI_SLEEP_TYPE Type
)
{
if (Type >= 0 && Type <= ARRAY_SIZE(mSxTypeString)) {
return mSxTypeString[Type];
} else {
AsciiSPrint (mNameString, sizeof(mNameString), "0x%x", Type);
return mNameString;
}
}
CHAR8 *mSxPhaseString[] = {
"SxEntry",
"SxExit",
};
/**
Convert SxPhase to a string.
@param Phase SxPhase
@return SxPhase string
**/
CHAR8 *
SxPhaseToString (
IN EFI_SLEEP_PHASE Phase
)
{
if (Phase >= 0 && Phase <= ARRAY_SIZE(mSxPhaseString)) {
return mSxPhaseString[Phase];
} else {
AsciiSPrint (mNameString, sizeof(mNameString), "0x%x", Phase);
return mNameString;
}
}
CHAR8 *mPowerButtonPhaseString[] = {
"PowerButtonEntry",
"PowerButtonExit",
};
/**
Convert PowerButtonPhase to a string.
@param Phase PowerButtonPhase
@return PowerButtonPhase string
**/
CHAR8 *
PowerButtonPhaseToString (
IN EFI_POWER_BUTTON_PHASE Phase
)
{
if (Phase >= 0 && Phase <= ARRAY_SIZE(mPowerButtonPhaseString)) {
return mPowerButtonPhaseString[Phase];
} else {
AsciiSPrint (mNameString, sizeof(mNameString), "0x%x", Phase);
return mNameString;
}
}
CHAR8 *mStandbyButtonPhaseString[] = {
"StandbyButtonEntry",
"StandbyButtonExit",
};
/**
Convert StandbyButtonPhase to a string.
@param Phase StandbyButtonPhase
@return StandbyButtonPhase string
**/
CHAR8 *
StandbyButtonPhaseToString (
IN EFI_STANDBY_BUTTON_PHASE Phase
)
{
if (Phase >= 0 && Phase <= ARRAY_SIZE(mStandbyButtonPhaseString)) {
return mStandbyButtonPhaseString[Phase];
} else {
AsciiSPrint (mNameString, sizeof(mNameString), "0x%x", Phase);
return mNameString;
}
}
CHAR8 *mIoTrapTypeString[] = {
"WriteTrap",
"ReadTrap",
"ReadWriteTrap",
};
/**
Convert IoTrapType to a string.
@param Type IoTrapType
@return IoTrapType string
**/
CHAR8 *
IoTrapTypeToString (
IN EFI_SMM_IO_TRAP_DISPATCH_TYPE Type
)
{
if (Type >= 0 && Type <= ARRAY_SIZE(mIoTrapTypeString)) {
return mIoTrapTypeString[Type];
} else {
AsciiSPrint (mNameString, sizeof(mNameString), "0x%x", Type);
return mNameString;
}
}
CHAR8 *mUsbTypeString[] = {
"UsbLegacy",
"UsbWake",
};
/**
Convert UsbType to a string.
@param Type UsbType
@return UsbType string
**/
CHAR8 *
UsbTypeToString (
IN EFI_USB_SMI_TYPE Type
)
{
if (Type >= 0 && Type <= ARRAY_SIZE(mUsbTypeString)) {
return mUsbTypeString[Type];
} else {
AsciiSPrint (mNameString, sizeof(mNameString), "0x%x", Type);
return mNameString;
}
}
/**
Dump SMI child context.
@param HandlerType the handler type
@param Context the handler context
@param ContextSize the handler context size
**/
VOID
DumpSmiChildContext (
IN EFI_GUID *HandlerType,
IN VOID *Context,
IN UINTN ContextSize
)
{
CHAR16 *Str;
if (CompareGuid (HandlerType, &gEfiSmmSwDispatch2ProtocolGuid)) {
Print(L" SwSmi=\"0x%x\"", ((EFI_SMM_SW_REGISTER_CONTEXT *)Context)->SwSmiInputValue);
} else if (CompareGuid (HandlerType, &gEfiSmmSxDispatch2ProtocolGuid)) {
Print(L" SxType=\"%a\"", SxTypeToString(((EFI_SMM_SX_REGISTER_CONTEXT *)Context)->Type));
Print(L" SxPhase=\"%a\"", SxPhaseToString(((EFI_SMM_SX_REGISTER_CONTEXT *)Context)->Phase));
} else if (CompareGuid (HandlerType, &gEfiSmmPowerButtonDispatch2ProtocolGuid)) {
Print(L" PowerButtonPhase=\"%a\"", PowerButtonPhaseToString(((EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT *)Context)->Phase));
} else if (CompareGuid (HandlerType, &gEfiSmmStandbyButtonDispatch2ProtocolGuid)) {
Print(L" StandbyButtonPhase=\"%a\"", StandbyButtonPhaseToString(((EFI_SMM_STANDBY_BUTTON_REGISTER_CONTEXT *)Context)->Phase));
} else if (CompareGuid (HandlerType, &gEfiSmmPeriodicTimerDispatch2ProtocolGuid)) {
Print(L" PeriodicTimerPeriod=\"%ld\"", ((EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT *)Context)->Period);
Print(L" PeriodicTimerSmiTickInterval=\"%ld\"", ((EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT *)Context)->SmiTickInterval);
} else if (CompareGuid (HandlerType, &gEfiSmmGpiDispatch2ProtocolGuid)) {
Print(L" GpiNum=\"0x%lx\"", ((EFI_SMM_GPI_REGISTER_CONTEXT *)Context)->GpiNum);
} else if (CompareGuid (HandlerType, &gEfiSmmIoTrapDispatch2ProtocolGuid)) {
Print(L" IoTrapAddress=\"0x%x\"", ((EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Context)->Address);
Print(L" IoTrapLength=\"0x%x\"", ((EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Context)->Length);
Print(L" IoTrapType=\"%a\"", IoTrapTypeToString(((EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Context)->Type));
} else if (CompareGuid (HandlerType, &gEfiSmmUsbDispatch2ProtocolGuid)) {
Print(L" UsbType=\"0x%x\"", UsbTypeToString(((SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT *)Context)->Type));
Str = ConvertDevicePathToText((EFI_DEVICE_PATH_PROTOCOL *)(((SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT *)Context) + 1), TRUE, TRUE);
Print(L" UsbDevicePath=\"%s\"", Str);
if (Str != NULL) {
FreePool (Str);
}
} else {
Print(L" Context=\"");
InternalDumpData (Context, ContextSize);
Print(L"\"");
}
}
/**
Dump SMI handler in HandlerCategory.
@param HandlerCategory SMI handler category
**/
VOID
DumpSmiHandler(
IN UINT32 HandlerCategory
)
{
SMM_CORE_SMI_DATABASE_STRUCTURE *SmiStruct;
SMM_CORE_SMI_HANDLER_STRUCTURE *SmiHandlerStruct;
UINTN Index;
SMM_CORE_IMAGE_DATABASE_STRUCTURE *ImageStruct;
CHAR8 *NameString;
SmiStruct = (VOID *)mSmiHandlerProfileDatabase;
while ((UINTN)SmiStruct < (UINTN)mSmiHandlerProfileDatabase + mSmiHandlerProfileDatabaseSize) {
if ((SmiStruct->Header.Signature == SMM_CORE_SMI_DATABASE_SIGNATURE) && (SmiStruct->HandlerCategory == HandlerCategory)) {
SmiHandlerStruct = (VOID *)(SmiStruct + 1);
Print(L" <SmiEntry");
if (!IsZeroGuid (&SmiStruct->HandlerType)) {
Print(L" HandlerType=\"%g\"", &SmiStruct->HandlerType);
}
Print(L">\n");
for (Index = 0; Index < SmiStruct->HandlerCount; Index++) {
Print(L" <SmiHandler");
if (SmiHandlerStruct->ContextBufferSize != 0) {
DumpSmiChildContext (&SmiStruct->HandlerType, (UINT8 *)SmiHandlerStruct + SmiHandlerStruct->ContextBufferOffset, SmiHandlerStruct->ContextBufferSize);
}
Print(L">\n");
ImageStruct = GetImageFromRef((UINTN)SmiHandlerStruct->ImageRef);
NameString = GetDriverNameString (ImageStruct);
Print(L" <Module RefId=\"0x%x\" Name=\"%a\">\n", SmiHandlerStruct->ImageRef, NameString);
if ((ImageStruct != NULL) && (ImageStruct->PdbStringOffset != 0)) {
Print(L" <Pdb>%a</Pdb>\n", (UINT8 *)ImageStruct + ImageStruct->PdbStringOffset);
}
Print(L" </Module>\n");
Print(L" <Handler Address=\"0x%x\">\n", SmiHandlerStruct->Handler);
if (ImageStruct != NULL) {
Print(L" <RVA>0x%x</RVA>\n", SmiHandlerStruct->Handler - ImageStruct->ImageBase);
}
Print(L" </Handler>\n", SmiHandlerStruct->Handler);
Print(L" <Caller Address=\"0x%x\">\n", SmiHandlerStruct->CallerAddr);
if (ImageStruct != NULL) {
Print(L" <RVA>0x%x</RVA>\n", SmiHandlerStruct->CallerAddr - ImageStruct->ImageBase);
}
Print(L" </Caller>\n", SmiHandlerStruct->Handler);
SmiHandlerStruct = (VOID *)((UINTN)SmiHandlerStruct + SmiHandlerStruct->Length);
Print(L" </SmiHandler>\n");
}
Print(L" </SmiEntry>\n");
}
SmiStruct = (VOID *)((UINTN)SmiStruct + SmiStruct->Header.Length);
}
return;
}
/**
The Entry Point for SMI handler profile info application.
@param ImageHandle The firmware allocated handle for the EFI image.
@param SystemTable A pointer to the EFI System Table.
@retval EFI_SUCCESS The entry point is executed successfully.
@retval Other Some error occurred when executing this entry point.
**/
EFI_STATUS
EFIAPI
SmiHandlerProfileInfoEntrypoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
GetSmiHandlerProfileDatabase();
if (mSmiHandlerProfileDatabase == NULL) {
return EFI_SUCCESS;
}
//
// Dump all image
//
Print(L"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
Print(L"<SmiHandlerProfile>\n");
Print(L"<ImageDatabase>\n");
Print(L" <!-- SMM image loaded -->\n");
DumpSmmLoadedImage();
Print(L"</ImageDatabase>\n\n");
//
// Dump SMI Handler
//
Print(L"<SmiHandlerDatabase>\n");
Print(L" <!-- SMI Handler registered -->\n\n");
Print(L" <SmiHandlerCategory Name=\"RootSmi\">\n");
Print(L" <!-- The root SMI Handler registered by SmmCore -->\n");
DumpSmiHandler(SmmCoreSmiHandlerCategoryRootHandler);
Print(L" </SmiHandlerCategory>\n\n");
Print(L" <SmiHandlerCategory Name=\"GuidSmi\">\n");
Print(L" <!-- The GUID SMI Handler registered by SmmCore -->\n");
DumpSmiHandler(SmmCoreSmiHandlerCategoryGuidHandler);
Print(L" </SmiHandlerCategory>\n\n");
Print(L" <SmiHandlerCategory Name=\"HardwareSmi\">\n");
Print(L" <!-- The hardware SMI Handler registered by SmmChildDispatcher -->\n");
DumpSmiHandler(SmmCoreSmiHandlerCategoryHardwareHandler);
Print(L" </SmiHandlerCategory>\n\n");
Print(L"</SmiHandlerDatabase>\n");
Print(L"</SmiHandlerProfile>\n");
if (mSmiHandlerProfileDatabase != NULL) {
FreePool(mSmiHandlerProfileDatabase);
}
return EFI_SUCCESS;
}