REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the MdeModulePkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
		
			
				
	
	
		
			706 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			706 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   Shell application to dump SMI handler profile information.
 | |
| 
 | |
| Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
 | |
| SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| 
 | |
| **/
 | |
| 
 | |
| #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/DxeServicesLib.h>
 | |
| #include <Protocol/SmmCommunication.h>
 | |
| #include <Guid/PiSmmCommunicationRegionTable.h>
 | |
| 
 | |
| #include <Guid/SmiHandlerProfile.h>
 | |
| 
 | |
| #define PROFILE_NAME_STRING_LENGTH  64
 | |
| CHAR8  mNameString[PROFILE_NAME_STRING_LENGTH + 1];
 | |
| 
 | |
| VOID   *mSmiHandlerProfileDatabase;
 | |
| UINTN  mSmiHandlerProfileDatabaseSize;
 | |
| 
 | |
| /**
 | |
|   This function dump raw data.
 | |
| 
 | |
|   @param  Data  raw data
 | |
|   @param  Size  raw data size
 | |
| **/
 | |
| VOID
 | |
| InternalDumpData (
 | |
|   IN UINT8  *Data,
 | |
|   IN UINTN  Size
 | |
|   )
 | |
| {
 | |
|   UINTN  Index;
 | |
| 
 | |
|   for (Index = 0; Index < Size; Index++) {
 | |
|     Print (L"%02x", (UINTN)Data[Index]);
 | |
|     if ((Index + 1) != Size) {
 | |
|       Print (L" ");
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Get SMI handler profile database.
 | |
| **/
 | |
| VOID
 | |
| GetSmiHandlerProfileDatabase (
 | |
|   VOID
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                                        Status;
 | |
|   UINTN                                             CommSize;
 | |
|   UINT8                                             *CommBuffer;
 | |
|   EFI_SMM_COMMUNICATE_HEADER                        *CommHeader;
 | |
|   SMI_HANDLER_PROFILE_PARAMETER_GET_INFO            *CommGetInfo;
 | |
|   SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET  *CommGetData;
 | |
|   EFI_SMM_COMMUNICATION_PROTOCOL                    *SmmCommunication;
 | |
|   UINTN                                             MinimalSizeNeeded;
 | |
|   EDKII_PI_SMM_COMMUNICATION_REGION_TABLE           *PiSmmCommunicationRegionTable;
 | |
|   UINT32                                            Index;
 | |
|   EFI_MEMORY_DESCRIPTOR                             *Entry;
 | |
|   VOID                                              *Buffer;
 | |
|   UINTN                                             Size;
 | |
|   UINTN                                             Offset;
 | |
| 
 | |
|   Status = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **)&SmmCommunication);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     Print (L"SmiHandlerProfile: Locate SmmCommunication protocol - %r\n", Status);
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   MinimalSizeNeeded = EFI_PAGE_SIZE;
 | |
| 
 | |
|   Status = EfiGetSystemConfigurationTable (
 | |
|              &gEdkiiPiSmmCommunicationRegionTableGuid,
 | |
|              (VOID **)&PiSmmCommunicationRegionTable
 | |
|              );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     Print (L"SmiHandlerProfile: Get PiSmmCommunicationRegionTable - %r\n", Status);
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   ASSERT (PiSmmCommunicationRegionTable != NULL);
 | |
|   Entry = (EFI_MEMORY_DESCRIPTOR *)(PiSmmCommunicationRegionTable + 1);
 | |
|   Size  = 0;
 | |
|   for (Index = 0; Index < PiSmmCommunicationRegionTable->NumberOfEntries; Index++) {
 | |
|     if (Entry->Type == EfiConventionalMemory) {
 | |
|       Size = EFI_PAGES_TO_SIZE ((UINTN)Entry->NumberOfPages);
 | |
|       if (Size >= MinimalSizeNeeded) {
 | |
|         break;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     Entry = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)Entry + PiSmmCommunicationRegionTable->DescriptorSize);
 | |
|   }
 | |
| 
 | |
|   ASSERT (Index < PiSmmCommunicationRegionTable->NumberOfEntries);
 | |
|   CommBuffer = (UINT8 *)(UINTN)Entry->PhysicalStart;
 | |
| 
 | |
|   //
 | |
|   // Get Size
 | |
|   //
 | |
|   CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0];
 | |
|   CopyMem (&CommHeader->HeaderGuid, &gSmiHandlerProfileGuid, sizeof (gSmiHandlerProfileGuid));
 | |
|   CommHeader->MessageLength = sizeof (SMI_HANDLER_PROFILE_PARAMETER_GET_INFO);
 | |
| 
 | |
|   CommGetInfo                      = (SMI_HANDLER_PROFILE_PARAMETER_GET_INFO *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)];
 | |
|   CommGetInfo->Header.Command      = SMI_HANDLER_PROFILE_COMMAND_GET_INFO;
 | |
|   CommGetInfo->Header.DataLength   = sizeof (*CommGetInfo);
 | |
|   CommGetInfo->Header.ReturnStatus = (UINT64)-1;
 | |
|   CommGetInfo->DataSize            = 0;
 | |
| 
 | |
|   CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + CommHeader->MessageLength;
 | |
|   Status   = SmmCommunication->Communicate (SmmCommunication, CommBuffer, &CommSize);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     Print (L"SmiHandlerProfile: SmmCommunication - %r\n", Status);
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   if (CommGetInfo->Header.ReturnStatus != 0) {
 | |
|     Print (L"SmiHandlerProfile: GetInfo - 0x%0x\n", CommGetInfo->Header.ReturnStatus);
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   mSmiHandlerProfileDatabaseSize = (UINTN)CommGetInfo->DataSize;
 | |
| 
 | |
|   //
 | |
|   // Get Data
 | |
|   //
 | |
|   mSmiHandlerProfileDatabase = AllocateZeroPool (mSmiHandlerProfileDatabaseSize);
 | |
|   if (mSmiHandlerProfileDatabase == NULL) {
 | |
|     Status = EFI_OUT_OF_RESOURCES;
 | |
|     Print (L"SmiHandlerProfile: AllocateZeroPool (0x%x) for dump buffer - %r\n", mSmiHandlerProfileDatabaseSize, Status);
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0];
 | |
|   CopyMem (&CommHeader->HeaderGuid, &gSmiHandlerProfileGuid, sizeof (gSmiHandlerProfileGuid));
 | |
|   CommHeader->MessageLength = sizeof (SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET);
 | |
| 
 | |
|   CommGetData                      = (SMI_HANDLER_PROFILE_PARAMETER_GET_DATA_BY_OFFSET *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)];
 | |
|   CommGetData->Header.Command      = SMI_HANDLER_PROFILE_COMMAND_GET_DATA_BY_OFFSET;
 | |
|   CommGetData->Header.DataLength   = sizeof (*CommGetData);
 | |
|   CommGetData->Header.ReturnStatus = (UINT64)-1;
 | |
| 
 | |
|   CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + CommHeader->MessageLength;
 | |
|   Buffer   = (UINT8 *)CommHeader + CommSize;
 | |
|   Size    -= CommSize;
 | |
| 
 | |
|   CommGetData->DataBuffer = (PHYSICAL_ADDRESS)(UINTN)Buffer;
 | |
|   CommGetData->DataOffset = 0;
 | |
|   while (CommGetData->DataOffset < mSmiHandlerProfileDatabaseSize) {
 | |
|     Offset = (UINTN)CommGetData->DataOffset;
 | |
|     if (Size <= (mSmiHandlerProfileDatabaseSize - CommGetData->DataOffset)) {
 | |
|       CommGetData->DataSize = (UINT64)Size;
 | |
|     } else {
 | |
|       CommGetData->DataSize = (UINT64)(mSmiHandlerProfileDatabaseSize - CommGetData->DataOffset);
 | |
|     }
 | |
| 
 | |
|     Status = SmmCommunication->Communicate (SmmCommunication, CommBuffer, &CommSize);
 | |
|     ASSERT_EFI_ERROR (Status);
 | |
| 
 | |
|     if (CommGetData->Header.ReturnStatus != 0) {
 | |
|       FreePool (mSmiHandlerProfileDatabase);
 | |
|       mSmiHandlerProfileDatabase = NULL;
 | |
|       Print (L"SmiHandlerProfile: GetData - 0x%x\n", CommGetData->Header.ReturnStatus);
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     CopyMem ((UINT8 *)mSmiHandlerProfileDatabase + Offset, (VOID *)(UINTN)CommGetData->DataBuffer, (UINTN)CommGetData->DataSize);
 | |
|   }
 | |
| 
 | |
|   DEBUG ((DEBUG_INFO, "SmiHandlerProfileSize - 0x%x\n", mSmiHandlerProfileDatabaseSize));
 | |
| 
 | |
|   return;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Get the file name portion of the Pdb File Name.
 | |
| 
 | |
|   The portion of the Pdb File Name between the last backslash and
 | |
|   either a following period or the end of the string is copied into
 | |
|   AsciiBuffer.  The name is truncated, if necessary, to ensure that
 | |
|   AsciiBuffer is not overrun.
 | |
| 
 | |
|   @param[in]  PdbFileName     Pdb file name.
 | |
|   @param[out] AsciiBuffer     The resultant Ascii File Name.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| GetShortPdbFileName (
 | |
|   IN  CHAR8  *PdbFileName,
 | |
|   OUT CHAR8  *AsciiBuffer
 | |
|   )
 | |
| {
 | |
|   UINTN  IndexPdb;    // Current work location within a Pdb string.
 | |
|   UINTN  IndexBuffer; // Current work location within a Buffer string.
 | |
|   UINTN  StartIndex;
 | |
|   UINTN  EndIndex;
 | |
| 
 | |
|   ZeroMem (AsciiBuffer, PROFILE_NAME_STRING_LENGTH + 1);
 | |
| 
 | |
|   if (PdbFileName == NULL) {
 | |
|     AsciiStrnCpyS (AsciiBuffer, PROFILE_NAME_STRING_LENGTH + 1, " ", 1);
 | |
|   } else {
 | |
|     StartIndex = 0;
 | |
|     for (EndIndex = 0; PdbFileName[EndIndex] != 0; EndIndex++) {
 | |
|     }
 | |
| 
 | |
|     for (IndexPdb = 0; PdbFileName[IndexPdb] != 0; IndexPdb++) {
 | |
|       if ((PdbFileName[IndexPdb] == '\\') || (PdbFileName[IndexPdb] == '/')) {
 | |
|         StartIndex = IndexPdb + 1;
 | |
|       }
 | |
| 
 | |
|       if (PdbFileName[IndexPdb] == '.') {
 | |
|         EndIndex = IndexPdb;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     IndexBuffer = 0;
 | |
|     for (IndexPdb = StartIndex; IndexPdb < EndIndex; IndexPdb++) {
 | |
|       AsciiBuffer[IndexBuffer] = PdbFileName[IndexPdb];
 | |
|       IndexBuffer++;
 | |
|       if (IndexBuffer >= PROFILE_NAME_STRING_LENGTH) {
 | |
|         AsciiBuffer[PROFILE_NAME_STRING_LENGTH] = 0;
 | |
|         break;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Get a human readable name for an image.
 | |
|   The following methods will be tried orderly:
 | |
|     1. Image PDB
 | |
|     2. FFS UI section
 | |
|     3. Image GUID
 | |
| 
 | |
|   @param[in] ImageStruct  Point to the image structure.
 | |
| 
 | |
|   @return The resulting Ascii name string is stored in the mNameString global array.
 | |
| 
 | |
| **/
 | |
| CHAR8 *
 | |
| GetDriverNameString (
 | |
|   IN SMM_CORE_IMAGE_DATABASE_STRUCTURE  *ImageStruct
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
|   CHAR16      *NameString;
 | |
|   UINTN       StringSize;
 | |
| 
 | |
|   if (ImageStruct == NULL) {
 | |
|     return "???";
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Method 1: Get the name string from image PDB
 | |
|   //
 | |
|   if (ImageStruct->PdbStringOffset != 0) {
 | |
|     GetShortPdbFileName ((CHAR8 *)((UINTN)ImageStruct + ImageStruct->PdbStringOffset), 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%lx\" Size=\"0x%lx\"", ImageStruct->ImageBase, ImageStruct->ImageSize);
 | |
|       if (ImageStruct->EntryPoint != 0) {
 | |
|         Print (L" EntryPoint=\"0x%lx\"", ImageStruct->EntryPoint);
 | |
|       }
 | |
| 
 | |
|       Print (L" FvFile=\"%g\"", &ImageStruct->FileGuid);
 | |
|       Print (L" RefId=\"0x%x\"", ImageStruct->ImageRef);
 | |
|       Print (L">\n");
 | |
|       if (ImageStruct->PdbStringOffset != 0) {
 | |
|         PdbString = (CHAR8 *)((UINTN)ImageStruct + ImageStruct->PdbStringOffset);
 | |
|         Print (L"    <Pdb>%a</Pdb>\n", PdbString);
 | |
|       }
 | |
| 
 | |
|       Print (L"  </Image>\n");
 | |
|     }
 | |
| 
 | |
|     ImageStruct = (VOID *)((UINTN)ImageStruct + ImageStruct->Header.Length);
 | |
|   }
 | |
| 
 | |
|   return;
 | |
| }
 | |
| 
 | |
| CHAR8  *mSxTypeString[] = {
 | |
|   "SxS0",
 | |
|   "SxS1",
 | |
|   "SxS2",
 | |
|   "SxS3",
 | |
|   "SxS4",
 | |
|   "SxS5",
 | |
| };
 | |
| 
 | |
| /**
 | |
|   Convert SxType to a string.
 | |
| 
 | |
|   @param Type SxType
 | |
| 
 | |
|   @return SxType string
 | |
| **/
 | |
| CHAR8 *
 | |
| SxTypeToString (
 | |
|   IN EFI_SLEEP_TYPE  Type
 | |
|   )
 | |
| {
 | |
|   if ((Type >= 0) && (Type < ARRAY_SIZE (mSxTypeString))) {
 | |
|     return mSxTypeString[Type];
 | |
|   } else {
 | |
|     AsciiSPrint (mNameString, sizeof (mNameString), "0x%x", Type);
 | |
|     return mNameString;
 | |
|   }
 | |
| }
 | |
| 
 | |
| CHAR8  *mSxPhaseString[] = {
 | |
|   "SxEntry",
 | |
|   "SxExit",
 | |
| };
 | |
| 
 | |
| /**
 | |
|   Convert SxPhase to a string.
 | |
| 
 | |
|   @param Phase SxPhase
 | |
| 
 | |
|   @return SxPhase string
 | |
| **/
 | |
| CHAR8 *
 | |
| SxPhaseToString (
 | |
|   IN EFI_SLEEP_PHASE  Phase
 | |
|   )
 | |
| {
 | |
|   if ((Phase >= 0) && (Phase < ARRAY_SIZE (mSxPhaseString))) {
 | |
|     return mSxPhaseString[Phase];
 | |
|   } else {
 | |
|     AsciiSPrint (mNameString, sizeof (mNameString), "0x%x", Phase);
 | |
|     return mNameString;
 | |
|   }
 | |
| }
 | |
| 
 | |
| CHAR8  *mPowerButtonPhaseString[] = {
 | |
|   "PowerButtonEntry",
 | |
|   "PowerButtonExit",
 | |
| };
 | |
| 
 | |
| /**
 | |
|   Convert PowerButtonPhase to a string.
 | |
| 
 | |
|   @param Phase PowerButtonPhase
 | |
| 
 | |
|   @return PowerButtonPhase string
 | |
| **/
 | |
| CHAR8 *
 | |
| PowerButtonPhaseToString (
 | |
|   IN EFI_POWER_BUTTON_PHASE  Phase
 | |
|   )
 | |
| {
 | |
|   if ((Phase >= 0) && (Phase < ARRAY_SIZE (mPowerButtonPhaseString))) {
 | |
|     return mPowerButtonPhaseString[Phase];
 | |
|   } else {
 | |
|     AsciiSPrint (mNameString, sizeof (mNameString), "0x%x", Phase);
 | |
|     return mNameString;
 | |
|   }
 | |
| }
 | |
| 
 | |
| CHAR8  *mStandbyButtonPhaseString[] = {
 | |
|   "StandbyButtonEntry",
 | |
|   "StandbyButtonExit",
 | |
| };
 | |
| 
 | |
| /**
 | |
|   Convert StandbyButtonPhase to a string.
 | |
| 
 | |
|   @param Phase StandbyButtonPhase
 | |
| 
 | |
|   @return StandbyButtonPhase string
 | |
| **/
 | |
| CHAR8 *
 | |
| StandbyButtonPhaseToString (
 | |
|   IN EFI_STANDBY_BUTTON_PHASE  Phase
 | |
|   )
 | |
| {
 | |
|   if ((Phase >= 0) && (Phase < ARRAY_SIZE (mStandbyButtonPhaseString))) {
 | |
|     return mStandbyButtonPhaseString[Phase];
 | |
|   } else {
 | |
|     AsciiSPrint (mNameString, sizeof (mNameString), "0x%x", Phase);
 | |
|     return mNameString;
 | |
|   }
 | |
| }
 | |
| 
 | |
| CHAR8  *mIoTrapTypeString[] = {
 | |
|   "WriteTrap",
 | |
|   "ReadTrap",
 | |
|   "ReadWriteTrap",
 | |
| };
 | |
| 
 | |
| /**
 | |
|   Convert IoTrapType to a string.
 | |
| 
 | |
|   @param Type IoTrapType
 | |
| 
 | |
|   @return IoTrapType string
 | |
| **/
 | |
| CHAR8 *
 | |
| IoTrapTypeToString (
 | |
|   IN EFI_SMM_IO_TRAP_DISPATCH_TYPE  Type
 | |
|   )
 | |
| {
 | |
|   if ((Type >= 0) && (Type < ARRAY_SIZE (mIoTrapTypeString))) {
 | |
|     return mIoTrapTypeString[Type];
 | |
|   } else {
 | |
|     AsciiSPrint (mNameString, sizeof (mNameString), "0x%x", Type);
 | |
|     return mNameString;
 | |
|   }
 | |
| }
 | |
| 
 | |
| CHAR8  *mUsbTypeString[] = {
 | |
|   "UsbLegacy",
 | |
|   "UsbWake",
 | |
| };
 | |
| 
 | |
| /**
 | |
|   Convert UsbType to a string.
 | |
| 
 | |
|   @param Type UsbType
 | |
| 
 | |
|   @return UsbType string
 | |
| **/
 | |
| CHAR8 *
 | |
| UsbTypeToString (
 | |
|   IN EFI_USB_SMI_TYPE  Type
 | |
|   )
 | |
| {
 | |
|   if ((Type >= 0) && (Type < ARRAY_SIZE (mUsbTypeString))) {
 | |
|     return mUsbTypeString[Type];
 | |
|   } else {
 | |
|     AsciiSPrint (mNameString, sizeof (mNameString), "0x%x", Type);
 | |
|     return mNameString;
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Dump SMI child context.
 | |
| 
 | |
|   @param HandlerType  the handler type
 | |
|   @param Context      the handler context
 | |
|   @param ContextSize  the handler context size
 | |
| **/
 | |
| VOID
 | |
| DumpSmiChildContext (
 | |
|   IN EFI_GUID  *HandlerType,
 | |
|   IN VOID      *Context,
 | |
|   IN UINTN     ContextSize
 | |
|   )
 | |
| {
 | |
|   CHAR16  *Str;
 | |
| 
 | |
|   if (CompareGuid (HandlerType, &gEfiSmmSwDispatch2ProtocolGuid)) {
 | |
|     Print (L" SwSmi=\"0x%lx\"", ((SMI_HANDLER_PROFILE_SW_REGISTER_CONTEXT *)Context)->SwSmiInputValue);
 | |
|   } else if (CompareGuid (HandlerType, &gEfiSmmSxDispatch2ProtocolGuid)) {
 | |
|     Print (L" SxType=\"%a\"", SxTypeToString (((EFI_SMM_SX_REGISTER_CONTEXT *)Context)->Type));
 | |
|     Print (L" SxPhase=\"%a\"", SxPhaseToString (((EFI_SMM_SX_REGISTER_CONTEXT *)Context)->Phase));
 | |
|   } else if (CompareGuid (HandlerType, &gEfiSmmPowerButtonDispatch2ProtocolGuid)) {
 | |
|     Print (L" PowerButtonPhase=\"%a\"", PowerButtonPhaseToString (((EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT *)Context)->Phase));
 | |
|   } else if (CompareGuid (HandlerType, &gEfiSmmStandbyButtonDispatch2ProtocolGuid)) {
 | |
|     Print (L" StandbyButtonPhase=\"%a\"", StandbyButtonPhaseToString (((EFI_SMM_STANDBY_BUTTON_REGISTER_CONTEXT *)Context)->Phase));
 | |
|   } else if (CompareGuid (HandlerType, &gEfiSmmPeriodicTimerDispatch2ProtocolGuid)) {
 | |
|     Print (L" PeriodicTimerPeriod=\"%ld\"", ((EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT *)Context)->Period);
 | |
|     Print (L" PeriodicTimerSmiTickInterval=\"%ld\"", ((EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT *)Context)->SmiTickInterval);
 | |
|   } else if (CompareGuid (HandlerType, &gEfiSmmGpiDispatch2ProtocolGuid)) {
 | |
|     Print (L" GpiNum=\"0x%lx\"", ((EFI_SMM_GPI_REGISTER_CONTEXT *)Context)->GpiNum);
 | |
|   } else if (CompareGuid (HandlerType, &gEfiSmmIoTrapDispatch2ProtocolGuid)) {
 | |
|     Print (L" IoTrapAddress=\"0x%x\"", ((EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Context)->Address);
 | |
|     Print (L" IoTrapLength=\"0x%x\"", ((EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Context)->Length);
 | |
|     Print (L" IoTrapType=\"%a\"", IoTrapTypeToString (((EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Context)->Type));
 | |
|   } else if (CompareGuid (HandlerType, &gEfiSmmUsbDispatch2ProtocolGuid)) {
 | |
|     Print (L" UsbType=\"0x%x\"", UsbTypeToString (((SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT *)Context)->Type));
 | |
|     Str = ConvertDevicePathToText ((EFI_DEVICE_PATH_PROTOCOL *)(((SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT *)Context) + 1), TRUE, TRUE);
 | |
|     Print (L" UsbDevicePath=\"%s\"", Str);
 | |
|     if (Str != NULL) {
 | |
|       FreePool (Str);
 | |
|     }
 | |
|   } else {
 | |
|     Print (L" Context=\"");
 | |
|     InternalDumpData (Context, ContextSize);
 | |
|     Print (L"\"");
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Dump SMI handler in HandlerCategory.
 | |
| 
 | |
|   @param HandlerCategory  SMI handler category
 | |
| **/
 | |
| VOID
 | |
| DumpSmiHandler (
 | |
|   IN UINT32  HandlerCategory
 | |
|   )
 | |
| {
 | |
|   SMM_CORE_SMI_DATABASE_STRUCTURE    *SmiStruct;
 | |
|   SMM_CORE_SMI_HANDLER_STRUCTURE     *SmiHandlerStruct;
 | |
|   UINTN                              Index;
 | |
|   SMM_CORE_IMAGE_DATABASE_STRUCTURE  *ImageStruct;
 | |
|   CHAR8                              *NameString;
 | |
| 
 | |
|   SmiStruct = (VOID *)mSmiHandlerProfileDatabase;
 | |
|   while ((UINTN)SmiStruct < (UINTN)mSmiHandlerProfileDatabase + mSmiHandlerProfileDatabaseSize) {
 | |
|     if ((SmiStruct->Header.Signature == SMM_CORE_SMI_DATABASE_SIGNATURE) && (SmiStruct->HandlerCategory == HandlerCategory)) {
 | |
|       SmiHandlerStruct = (VOID *)(SmiStruct + 1);
 | |
|       Print (L"  <SmiEntry");
 | |
|       if (!IsZeroGuid (&SmiStruct->HandlerType)) {
 | |
|         Print (L" HandlerType=\"%g\"", &SmiStruct->HandlerType);
 | |
|       }
 | |
| 
 | |
|       Print (L">\n");
 | |
|       for (Index = 0; Index < SmiStruct->HandlerCount; Index++) {
 | |
|         Print (L"    <SmiHandler");
 | |
|         if (SmiHandlerStruct->ContextBufferSize != 0) {
 | |
|           DumpSmiChildContext (&SmiStruct->HandlerType, (UINT8 *)SmiHandlerStruct + SmiHandlerStruct->ContextBufferOffset, SmiHandlerStruct->ContextBufferSize);
 | |
|         }
 | |
| 
 | |
|         Print (L">\n");
 | |
|         ImageStruct = GetImageFromRef ((UINTN)SmiHandlerStruct->ImageRef);
 | |
|         NameString  = GetDriverNameString (ImageStruct);
 | |
|         Print (L"      <Module RefId=\"0x%x\" Name=\"%a\">\n", SmiHandlerStruct->ImageRef, NameString);
 | |
|         if ((ImageStruct != NULL) && (ImageStruct->PdbStringOffset != 0)) {
 | |
|           Print (L"      <Pdb>%a</Pdb>\n", (UINT8 *)ImageStruct + ImageStruct->PdbStringOffset);
 | |
|         }
 | |
| 
 | |
|         Print (L"      </Module>\n");
 | |
|         Print (L"      <Handler Address=\"0x%lx\">\n", SmiHandlerStruct->Handler);
 | |
|         if (ImageStruct != NULL) {
 | |
|           Print (L"         <RVA>0x%x</RVA>\n", (UINTN)(SmiHandlerStruct->Handler - ImageStruct->ImageBase));
 | |
|         }
 | |
| 
 | |
|         Print (L"      </Handler>\n", SmiHandlerStruct->Handler);
 | |
|         Print (L"      <Caller Address=\"0x%lx\">\n", SmiHandlerStruct->CallerAddr);
 | |
|         if (ImageStruct != NULL) {
 | |
|           Print (L"         <RVA>0x%x</RVA>\n", (UINTN)(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;
 | |
| }
 |