MdeModulePkg/App: Add SmiHandlerProfile dump app.

This app uses SMM communication to get SMI handler profile
from SMM core.

Cc: Feng Tian <feng.tian@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Star Zeng <star.zeng@intel.com>
This commit is contained in:
Jiewen Yao 2017-01-20 06:14:59 -08:00
parent ca41f3f43f
commit 216b942d4d
4 changed files with 791 additions and 0 deletions

View File

@ -0,0 +1,685 @@
/** @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] DriverInfo Pointer to memory profile driver info.
@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
)
{
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));
Print(L" UsbDevicePath=\"%s\"", ConvertDevicePathToText((EFI_DEVICE_PATH_PROTOCOL *)(((SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT *)Context) + 1), TRUE, TRUE));
} 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;
}

View File

@ -0,0 +1,65 @@
## @file
# Shell application to dump SMI handler profile information.
#
# Note that if the feature is not enabled by setting PcdSmiHandlerProfilePropertyMask,
# the application will not display 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 that 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.
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = SmiHandlerProfileInfo
MODULE_UNI_FILE = SmiHandlerProfileInfo.uni
FILE_GUID = 611EA796-8DF8-4BB6-91FE-6540ED70DC66
MODULE_TYPE = UEFI_APPLICATION
VERSION_STRING = 1.0
ENTRY_POINT = SmiHandlerProfileInfoEntrypoint
[Sources]
SmiHandlerProfileInfo.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
[LibraryClasses]
UefiApplicationEntryPoint
BaseLib
BaseMemoryLib
MemoryAllocationLib
DebugLib
UefiBootServicesTableLib
UefiRuntimeServicesTableLib
UefiLib
PrintLib
DevicePathLib
PeCoffGetEntryPointLib
DxeServicesLib
[Protocols]
gEfiSmmCommunicationProtocolGuid ## CONSUMES
gEfiSmmSwDispatch2ProtocolGuid ## SOMETIMES_CONSUMES
gEfiSmmSxDispatch2ProtocolGuid ## SOMETIMES_CONSUMES
gEfiSmmPowerButtonDispatch2ProtocolGuid ## SOMETIMES_CONSUMES
gEfiSmmStandbyButtonDispatch2ProtocolGuid ## SOMETIMES_CONSUMES
gEfiSmmPeriodicTimerDispatch2ProtocolGuid ## SOMETIMES_CONSUMES
gEfiSmmGpiDispatch2ProtocolGuid ## SOMETIMES_CONSUMES
gEfiSmmIoTrapDispatch2ProtocolGuid ## SOMETIMES_CONSUMES
gEfiSmmUsbDispatch2ProtocolGuid ## SOMETIMES_CONSUMES
[Guids]
gEdkiiPiSmmCommunicationRegionTableGuid ## CONSUMES ## SystemTable
gSmiHandlerProfileGuid ## SOMETIMES_CONSUMES ## GUID # SmiHandlerRegister
[UserExtensions.TianoCore."ExtraFiles"]
SmiHandlerProfileInfoExtra.uni

View File

@ -0,0 +1,22 @@
// /** @file
// Shell application to dump SMI handler profile information.
//
// Note that if the feature is not enabled by setting PcdSmiHandlerProfilePropertyMask,
// the application will not display 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.
//
// **/
#string STR_MODULE_ABSTRACT #language en-US "Shell application to dump SMI handler profile information."
#string STR_MODULE_DESCRIPTION #language en-US "Note that if the feature is not enabled by setting PcdSmiHandlerProfilePropertyMask, the application will not display SMI handler profile information."

View File

@ -0,0 +1,19 @@
// /** @file
// SmiHandlerProfileInfo Localized Strings and Content
//
// 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.
//
// **/
#string STR_PROPERTIES_MODULE_NAME
#language en-US
"SMI Handler Profile Information Application"