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>
---
MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfo.c | 685 ++++++++++++++++++++
MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfo.inf | 65 ++
MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfo.uni | 22 +
MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfoExtra.uni | 19 +
4 files changed, 791 insertions(+)
diff --git a/MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfo.c b/MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfo.c
new file mode 100644
index 0000000..00cab0c
--- /dev/null
+++ b/MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfo.c
@@ -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;
+}
diff --git a/MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfo.inf b/MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfo.inf
new file mode 100644
index 0000000..73cc052
--- /dev/null
+++ b/MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfo.inf
@@ -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
+
diff --git a/MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfo.uni b/MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfo.uni
new file mode 100644
index 0000000..d73a1a0
--- /dev/null
+++ b/MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfo.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."
+
diff --git a/MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfoExtra.uni b/MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfoExtra.uni
new file mode 100644
index 0000000..b10c71a
--- /dev/null
+++ b/MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfoExtra.uni
@@ -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"
+
+
--
2.7.4.windows.1
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
© 2016 - 2024 Red Hat, Inc.