From 216b942d4d4795f5d919d43276d4f446190e5d35 Mon Sep 17 00:00:00 2001 From: Jiewen Yao Date: Fri, 20 Jan 2017 06:14:59 -0800 Subject: [PATCH] MdeModulePkg/App: Add SmiHandlerProfile dump app. This app uses SMM communication to get SMI handler profile from SMM core. Cc: Feng Tian Cc: Star Zeng Cc: Michael D Kinney Cc: Laszlo Ersek Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jiewen Yao Reviewed-by: Star Zeng --- .../SmiHandlerProfileInfo.c | 685 ++++++++++++++++++ .../SmiHandlerProfileInfo.inf | 65 ++ .../SmiHandlerProfileInfo.uni | 22 + .../SmiHandlerProfileInfoExtra.uni | 19 + 4 files changed, 791 insertions(+) create mode 100644 MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfo.c create mode 100644 MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfo.inf create mode 100644 MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfo.uni create mode 100644 MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfoExtra.uni diff --git a/MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfo.c b/MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfo.c new file mode 100644 index 0000000000..00cab0cd8e --- /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.
+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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#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" 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" %a\n", PdbString); + Print(L" \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" HandlerType)) { + Print(L" HandlerType=\"%g\"", &SmiStruct->HandlerType); + } + Print(L">\n"); + for (Index = 0; Index < SmiStruct->HandlerCount; Index++) { + Print(L" ContextBufferSize != 0) { + DumpSmiChildContext (&SmiStruct->HandlerType, (UINT8 *)SmiHandlerStruct + SmiHandlerStruct->ContextBufferOffset, SmiHandlerStruct->ContextBufferSize); + } + Print(L">\n"); + ImageStruct = GetImageFromRef((UINTN)SmiHandlerStruct->ImageRef); + NameString = GetDriverNameString (ImageStruct); + Print(L" \n", SmiHandlerStruct->ImageRef, NameString); + if ((ImageStruct != NULL) && (ImageStruct->PdbStringOffset != 0)) { + Print(L" %a\n", (UINT8 *)ImageStruct + ImageStruct->PdbStringOffset); + } + Print(L" \n"); + Print(L" \n", SmiHandlerStruct->Handler); + if (ImageStruct != NULL) { + Print(L" 0x%x\n", SmiHandlerStruct->Handler - ImageStruct->ImageBase); + } + Print(L" \n", SmiHandlerStruct->Handler); + Print(L" \n", SmiHandlerStruct->CallerAddr); + if (ImageStruct != NULL) { + Print(L" 0x%x\n", SmiHandlerStruct->CallerAddr - ImageStruct->ImageBase); + } + Print(L" \n", SmiHandlerStruct->Handler); + SmiHandlerStruct = (VOID *)((UINTN)SmiHandlerStruct + SmiHandlerStruct->Length); + Print(L" \n"); + } + Print(L" \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"\n"); + Print(L"\n"); + Print(L"\n"); + Print(L" \n"); + DumpSmmLoadedImage(); + Print(L"\n\n"); + + // + // Dump SMI Handler + // + Print(L"\n"); + Print(L" \n\n"); + Print(L" \n"); + Print(L" \n"); + DumpSmiHandler(SmmCoreSmiHandlerCategoryRootHandler); + Print(L" \n\n"); + + Print(L" \n"); + Print(L" \n"); + DumpSmiHandler(SmmCoreSmiHandlerCategoryGuidHandler); + Print(L" \n\n"); + + Print(L" \n"); + Print(L" \n"); + DumpSmiHandler(SmmCoreSmiHandlerCategoryHardwareHandler); + Print(L" \n\n"); + + Print(L"\n"); + Print(L"\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 0000000000..73cc052cc3 --- /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.
+# 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 0000000000..d73a1a0bf0 --- /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.
+// +// 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 0000000000..b10c71a7ab --- /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.
+// +// 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.39.2