mirror of https://github.com/acidanthera/audk.git
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:
parent
ca41f3f43f
commit
216b942d4d
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
|
|
@ -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."
|
||||
|
|
@ -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"
|
||||
|
||||
|
Loading…
Reference in New Issue