mirror of
				https://github.com/acidanthera/audk.git
				synced 2025-10-31 11:13:53 +01:00 
			
		
		
		
	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>
		
			
				
	
	
		
			1414 lines
		
	
	
		
			51 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1414 lines
		
	
	
		
			51 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
| 
 | |
|   Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.<BR>
 | |
|   SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| 
 | |
| **/
 | |
| 
 | |
| #include <Uefi.h>
 | |
| #include <PiDxe.h>
 | |
| #include <Library/BaseLib.h>
 | |
| #include <Library/BaseMemoryLib.h>
 | |
| #include <Library/MemoryAllocationLib.h>
 | |
| #include <Library/UefiLib.h>
 | |
| #include <Library/UefiApplicationEntryPoint.h>
 | |
| #include <Library/UefiBootServicesTableLib.h>
 | |
| #include <Library/UefiRuntimeServicesTableLib.h>
 | |
| #include <Library/DebugLib.h>
 | |
| #include <Library/DxeServicesLib.h>
 | |
| #include <Library/PrintLib.h>
 | |
| 
 | |
| #include <Protocol/SmmCommunication.h>
 | |
| #include <Protocol/SmmAccess2.h>
 | |
| 
 | |
| #include <Guid/MemoryProfile.h>
 | |
| #include <Guid/PiSmmCommunicationRegionTable.h>
 | |
| 
 | |
| CHAR8  *mActionString[] = {
 | |
|   "Unknown",
 | |
|   "gBS->AllocatePages",
 | |
|   "gBS->FreePages",
 | |
|   "gBS->AllocatePool",
 | |
|   "gBS->FreePool",
 | |
| };
 | |
| 
 | |
| CHAR8  *mSmmActionString[] = {
 | |
|   "SmmUnknown",
 | |
|   "gSmst->SmmAllocatePages",
 | |
|   "gSmst->SmmFreePages",
 | |
|   "gSmst->SmmAllocatePool",
 | |
|   "gSmst->SmmFreePool",
 | |
| };
 | |
| 
 | |
| typedef struct {
 | |
|   MEMORY_PROFILE_ACTION    Action;
 | |
|   CHAR8                    *String;
 | |
| } ACTION_STRING;
 | |
| 
 | |
| ACTION_STRING  mExtActionString[] = {
 | |
|   { MEMORY_PROFILE_ACTION_LIB_ALLOCATE_PAGES,                  "Lib:AllocatePages"                },
 | |
|   { MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_PAGES,          "Lib:AllocateRuntimePages"         },
 | |
|   { MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_PAGES,         "Lib:AllocateReservedPages"        },
 | |
|   { MEMORY_PROFILE_ACTION_LIB_FREE_PAGES,                      "Lib:FreePages"                    },
 | |
|   { MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_PAGES,          "Lib:AllocateAlignedPages"         },
 | |
|   { MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RUNTIME_PAGES,  "Lib:AllocateAlignedRuntimePages"  },
 | |
|   { MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RESERVED_PAGES, "Lib:AllocateAlignedReservedPages" },
 | |
|   { MEMORY_PROFILE_ACTION_LIB_FREE_ALIGNED_PAGES,              "Lib:FreeAlignedPages"             },
 | |
|   { MEMORY_PROFILE_ACTION_LIB_ALLOCATE_POOL,                   "Lib:AllocatePool"                 },
 | |
|   { MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_POOL,           "Lib:AllocateRuntimePool"          },
 | |
|   { MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_POOL,          "Lib:AllocateReservedPool"         },
 | |
|   { MEMORY_PROFILE_ACTION_LIB_FREE_POOL,                       "Lib:FreePool"                     },
 | |
|   { MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ZERO_POOL,              "Lib:AllocateZeroPool"             },
 | |
|   { MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_ZERO_POOL,      "Lib:AllocateRuntimeZeroPool"      },
 | |
|   { MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_ZERO_POOL,     "Lib:AllocateReservedZeroPool"     },
 | |
|   { MEMORY_PROFILE_ACTION_LIB_ALLOCATE_COPY_POOL,              "Lib:AllocateCopyPool"             },
 | |
|   { MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_COPY_POOL,      "Lib:AllocateRuntimeCopyPool"      },
 | |
|   { MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_COPY_POOL,     "Lib:AllocateReservedCopyPool"     },
 | |
|   { MEMORY_PROFILE_ACTION_LIB_REALLOCATE_POOL,                 "Lib:ReallocatePool"               },
 | |
|   { MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RUNTIME_POOL,         "Lib:ReallocateRuntimePool"        },
 | |
|   { MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RESERVED_POOL,        "Lib:ReallocateReservedPool"       },
 | |
| };
 | |
| 
 | |
| CHAR8  mUserDefinedActionString[] = { "UserDefined-0x80000000" };
 | |
| 
 | |
| CHAR8  *mMemoryTypeString[] = {
 | |
|   "EfiReservedMemoryType",
 | |
|   "EfiLoaderCode",
 | |
|   "EfiLoaderData",
 | |
|   "EfiBootServicesCode",
 | |
|   "EfiBootServicesData",
 | |
|   "EfiRuntimeServicesCode",
 | |
|   "EfiRuntimeServicesData",
 | |
|   "EfiConventionalMemory",
 | |
|   "EfiUnusableMemory",
 | |
|   "EfiACPIReclaimMemory",
 | |
|   "EfiACPIMemoryNVS",
 | |
|   "EfiMemoryMappedIO",
 | |
|   "EfiMemoryMappedIOPortSpace",
 | |
|   "EfiPalCode",
 | |
|   "EfiPersistentMemory",
 | |
|   "EfiOSReserved",
 | |
|   "EfiOemReserved",
 | |
| };
 | |
| 
 | |
| CHAR8  *mSubsystemString[] = {
 | |
|   "Unknown",
 | |
|   "NATIVE",
 | |
|   "WINDOWS_GUI",
 | |
|   "WINDOWS_CUI",
 | |
|   "Unknown",
 | |
|   "Unknown",
 | |
|   "Unknown",
 | |
|   "POSIX_CUI",
 | |
|   "Unknown",
 | |
|   "WINDOWS_CE_GUI",
 | |
|   "EFI_APPLICATION",
 | |
|   "EFI_BOOT_SERVICE_DRIVER",
 | |
|   "EFI_RUNTIME_DRIVER",
 | |
|   "EFI_ROM",
 | |
|   "XBOX",
 | |
|   "Unknown",
 | |
| };
 | |
| 
 | |
| CHAR8  *mFileTypeString[] = {
 | |
|   "Unknown",
 | |
|   "RAW",
 | |
|   "FREEFORM",
 | |
|   "SECURITY_CORE",
 | |
|   "PEI_CORE",
 | |
|   "DXE_CORE",
 | |
|   "PEIM",
 | |
|   "DRIVER",
 | |
|   "COMBINED_PEIM_DRIVER",
 | |
|   "APPLICATION",
 | |
|   "SMM",
 | |
|   "FIRMWARE_VOLUME_IMAGE",
 | |
|   "COMBINED_SMM_DXE",
 | |
|   "SMM_CORE",
 | |
| };
 | |
| 
 | |
| #define PROFILE_NAME_STRING_LENGTH  64
 | |
| CHAR8  mNameString[PROFILE_NAME_STRING_LENGTH + 1];
 | |
| 
 | |
| //
 | |
| // Profile summary information
 | |
| //
 | |
| #define MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE  SIGNATURE_32 ('M','P','A','S')
 | |
| #define MEMORY_PROFILE_ALLOC_SUMMARY_INFO_REVISION   0x0001
 | |
| 
 | |
| typedef struct {
 | |
|   MEMORY_PROFILE_COMMON_HEADER    Header;
 | |
|   PHYSICAL_ADDRESS                CallerAddress;
 | |
|   MEMORY_PROFILE_ACTION           Action;
 | |
|   CHAR8                           *ActionString;
 | |
|   UINT32                          AllocateCount;
 | |
|   UINT64                          TotalSize;
 | |
| } MEMORY_PROFILE_ALLOC_SUMMARY_INFO;
 | |
| 
 | |
| typedef struct {
 | |
|   UINT32                               Signature;
 | |
|   MEMORY_PROFILE_ALLOC_SUMMARY_INFO    AllocSummaryInfo;
 | |
|   LIST_ENTRY                           Link;
 | |
| } MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA;
 | |
| 
 | |
| typedef struct {
 | |
|   UINT32                        Signature;
 | |
|   MEMORY_PROFILE_DRIVER_INFO    *DriverInfo;
 | |
|   LIST_ENTRY                    *AllocSummaryInfoList;
 | |
|   LIST_ENTRY                    Link;
 | |
| } MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA;
 | |
| 
 | |
| typedef struct {
 | |
|   UINT32                    Signature;
 | |
|   MEMORY_PROFILE_CONTEXT    *Context;
 | |
|   LIST_ENTRY                *DriverSummaryInfoList;
 | |
| } MEMORY_PROFILE_CONTEXT_SUMMARY_DATA;
 | |
| 
 | |
| LIST_ENTRY                           mImageSummaryQueue = INITIALIZE_LIST_HEAD_VARIABLE (mImageSummaryQueue);
 | |
| MEMORY_PROFILE_CONTEXT_SUMMARY_DATA  mMemoryProfileContextSummary;
 | |
| 
 | |
| /**
 | |
|   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 MEMORY_PROFILE_DRIVER_INFO  *DriverInfo
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
|   CHAR16      *NameString;
 | |
|   UINTN       StringSize;
 | |
| 
 | |
|   //
 | |
|   // Method 1: Get the name string from image PDB
 | |
|   //
 | |
|   if (DriverInfo->PdbStringOffset != 0) {
 | |
|     GetShortPdbFileName ((CHAR8 *)((UINTN)DriverInfo + DriverInfo->PdbStringOffset), mNameString);
 | |
|     return mNameString;
 | |
|   }
 | |
| 
 | |
|   if (!IsZeroGuid (&DriverInfo->FileName)) {
 | |
|     //
 | |
|     // Try to get the image's FFS UI section by image GUID
 | |
|     //
 | |
|     NameString = NULL;
 | |
|     StringSize = 0;
 | |
|     Status     = GetSectionFromAnyFv (
 | |
|                    &DriverInfo->FileName,
 | |
|                    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", &DriverInfo->FileName);
 | |
|   return mNameString;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Memory type to string.
 | |
| 
 | |
|   @param[in] MemoryType Memory type.
 | |
| 
 | |
|   @return Pointer to string.
 | |
| 
 | |
| **/
 | |
| CHAR8 *
 | |
| ProfileMemoryTypeToStr (
 | |
|   IN EFI_MEMORY_TYPE  MemoryType
 | |
|   )
 | |
| {
 | |
|   UINTN  Index;
 | |
| 
 | |
|   if ((UINT32)MemoryType >= 0x80000000) {
 | |
|     //
 | |
|     // OS reserved memory type.
 | |
|     //
 | |
|     Index = EfiMaxMemoryType;
 | |
|   } else if ((UINT32)MemoryType >= 0x70000000) {
 | |
|     //
 | |
|     // OEM reserved memory type.
 | |
|     //
 | |
|     Index = EfiMaxMemoryType + 1;
 | |
|   } else {
 | |
|     Index = MemoryType;
 | |
|   }
 | |
| 
 | |
|   return mMemoryTypeString[Index];
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Action to string.
 | |
| 
 | |
|   @param[in] Action                     Profile action.
 | |
|   @param[in] UserDefinedActionString    Pointer to user defined action string.
 | |
|   @param[in] IsForSmm                   TRUE  - SMRAM profile.
 | |
|                                         FALSE - UEFI memory profile.
 | |
| 
 | |
|   @return Pointer to string.
 | |
| 
 | |
| **/
 | |
| CHAR8 *
 | |
| ProfileActionToStr (
 | |
|   IN MEMORY_PROFILE_ACTION  Action,
 | |
|   IN CHAR8                  *UserDefinedActionString,
 | |
|   IN BOOLEAN                IsForSmm
 | |
|   )
 | |
| {
 | |
|   UINTN  Index;
 | |
|   UINTN  ActionStringCount;
 | |
|   CHAR8  **ActionString;
 | |
| 
 | |
|   if (IsForSmm) {
 | |
|     ActionString      = mSmmActionString;
 | |
|     ActionStringCount = ARRAY_SIZE (mSmmActionString);
 | |
|   } else {
 | |
|     ActionString      = mActionString;
 | |
|     ActionStringCount = ARRAY_SIZE (mActionString);
 | |
|   }
 | |
| 
 | |
|   if ((UINTN)(UINT32)Action < ActionStringCount) {
 | |
|     return ActionString[Action];
 | |
|   }
 | |
| 
 | |
|   for (Index = 0; Index < ARRAY_SIZE (mExtActionString); Index++) {
 | |
|     if (mExtActionString[Index].Action == Action) {
 | |
|       return mExtActionString[Index].String;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if ((Action & MEMORY_PROFILE_ACTION_USER_DEFINED_MASK) != 0) {
 | |
|     if (UserDefinedActionString != NULL) {
 | |
|       return UserDefinedActionString;
 | |
|     }
 | |
| 
 | |
|     AsciiSPrint (mUserDefinedActionString, sizeof (mUserDefinedActionString), "UserDefined-0x%08x", Action);
 | |
|     return mUserDefinedActionString;
 | |
|   }
 | |
| 
 | |
|   return ActionString[0];
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Dump memory profile allocate information.
 | |
| 
 | |
|   @param[in] DriverInfo         Pointer to memory profile driver info.
 | |
|   @param[in] AllocIndex         Memory profile alloc info index.
 | |
|   @param[in] AllocInfo          Pointer to memory profile alloc info.
 | |
|   @param[in] IsForSmm           TRUE  - SMRAM profile.
 | |
|                                 FALSE - UEFI memory profile.
 | |
| 
 | |
|   @return Pointer to next memory profile alloc info.
 | |
| 
 | |
| **/
 | |
| MEMORY_PROFILE_ALLOC_INFO *
 | |
| DumpMemoryProfileAllocInfo (
 | |
|   IN MEMORY_PROFILE_DRIVER_INFO  *DriverInfo,
 | |
|   IN UINTN                       AllocIndex,
 | |
|   IN MEMORY_PROFILE_ALLOC_INFO   *AllocInfo,
 | |
|   IN BOOLEAN                     IsForSmm
 | |
|   )
 | |
| {
 | |
|   CHAR8  *ActionString;
 | |
| 
 | |
|   if (AllocInfo->Header.Signature != MEMORY_PROFILE_ALLOC_INFO_SIGNATURE) {
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   if (AllocInfo->ActionStringOffset != 0) {
 | |
|     ActionString = (CHAR8 *)((UINTN)AllocInfo + AllocInfo->ActionStringOffset);
 | |
|   } else {
 | |
|     ActionString = NULL;
 | |
|   }
 | |
| 
 | |
|   Print (L"    MEMORY_PROFILE_ALLOC_INFO (0x%x)\n", AllocIndex);
 | |
|   Print (L"      Signature     - 0x%08x\n", AllocInfo->Header.Signature);
 | |
|   Print (L"      Length        - 0x%04x\n", AllocInfo->Header.Length);
 | |
|   Print (L"      Revision      - 0x%04x\n", AllocInfo->Header.Revision);
 | |
|   Print (L"      CallerAddress - 0x%016lx (Offset: 0x%08x)\n", AllocInfo->CallerAddress, (UINTN)(AllocInfo->CallerAddress - DriverInfo->ImageBase));
 | |
|   Print (L"      SequenceId    - 0x%08x\n", AllocInfo->SequenceId);
 | |
|   Print (L"      Action        - 0x%08x (%a)\n", AllocInfo->Action, ProfileActionToStr (AllocInfo->Action, ActionString, IsForSmm));
 | |
|   Print (L"      MemoryType    - 0x%08x (%a)\n", AllocInfo->MemoryType, ProfileMemoryTypeToStr (AllocInfo->MemoryType));
 | |
|   Print (L"      Buffer        - 0x%016lx\n", AllocInfo->Buffer);
 | |
|   Print (L"      Size          - 0x%016lx\n", AllocInfo->Size);
 | |
| 
 | |
|   return (MEMORY_PROFILE_ALLOC_INFO *)((UINTN)AllocInfo + AllocInfo->Header.Length);
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Dump memory profile driver information.
 | |
| 
 | |
|   @param[in] DriverIndex        Memory profile driver info index.
 | |
|   @param[in] DriverInfo         Pointer to memory profile driver info.
 | |
|   @param[in] IsForSmm           TRUE  - SMRAM profile.
 | |
|                                 FALSE - UEFI memory profile.
 | |
| 
 | |
|   @return Pointer to next memory profile driver info.
 | |
| 
 | |
| **/
 | |
| MEMORY_PROFILE_DRIVER_INFO *
 | |
| DumpMemoryProfileDriverInfo (
 | |
|   IN UINTN                       DriverIndex,
 | |
|   IN MEMORY_PROFILE_DRIVER_INFO  *DriverInfo,
 | |
|   IN BOOLEAN                     IsForSmm
 | |
|   )
 | |
| {
 | |
|   UINTN                      TypeIndex;
 | |
|   MEMORY_PROFILE_ALLOC_INFO  *AllocInfo;
 | |
|   UINTN                      AllocIndex;
 | |
|   CHAR8                      *NameString;
 | |
| 
 | |
|   if (DriverInfo->Header.Signature != MEMORY_PROFILE_DRIVER_INFO_SIGNATURE) {
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   Print (L"  MEMORY_PROFILE_DRIVER_INFO (0x%x)\n", DriverIndex);
 | |
|   Print (L"    Signature               - 0x%08x\n", DriverInfo->Header.Signature);
 | |
|   Print (L"    Length                  - 0x%04x\n", DriverInfo->Header.Length);
 | |
|   Print (L"    Revision                - 0x%04x\n", DriverInfo->Header.Revision);
 | |
|   NameString = GetDriverNameString (DriverInfo);
 | |
|   Print (L"    FileName                - %a\n", NameString);
 | |
|   if (DriverInfo->PdbStringOffset != 0) {
 | |
|     Print (L"    Pdb                     - %a\n", (CHAR8 *)((UINTN)DriverInfo + DriverInfo->PdbStringOffset));
 | |
|   }
 | |
| 
 | |
|   Print (L"    ImageBase               - 0x%016lx\n", DriverInfo->ImageBase);
 | |
|   Print (L"    ImageSize               - 0x%016lx\n", DriverInfo->ImageSize);
 | |
|   Print (L"    EntryPoint              - 0x%016lx\n", DriverInfo->EntryPoint);
 | |
|   Print (L"    ImageSubsystem          - 0x%04x (%a)\n", DriverInfo->ImageSubsystem, mSubsystemString[(DriverInfo->ImageSubsystem < sizeof (mSubsystemString)/sizeof (mSubsystemString[0])) ? DriverInfo->ImageSubsystem : 0]);
 | |
|   Print (L"    FileType                - 0x%02x (%a)\n", DriverInfo->FileType, mFileTypeString[(DriverInfo->FileType < sizeof (mFileTypeString)/sizeof (mFileTypeString[0])) ? DriverInfo->FileType : 0]);
 | |
|   Print (L"    CurrentUsage            - 0x%016lx\n", DriverInfo->CurrentUsage);
 | |
|   Print (L"    PeakUsage               - 0x%016lx\n", DriverInfo->PeakUsage);
 | |
|   for (TypeIndex = 0; TypeIndex < sizeof (DriverInfo->CurrentUsageByType) / sizeof (DriverInfo->CurrentUsageByType[0]); TypeIndex++) {
 | |
|     if ((DriverInfo->CurrentUsageByType[TypeIndex] != 0) ||
 | |
|         (DriverInfo->PeakUsageByType[TypeIndex] != 0))
 | |
|     {
 | |
|       Print (L"    CurrentUsage[0x%02x]      - 0x%016lx (%a)\n", TypeIndex, DriverInfo->CurrentUsageByType[TypeIndex], mMemoryTypeString[TypeIndex]);
 | |
|       Print (L"    PeakUsage[0x%02x]         - 0x%016lx (%a)\n", TypeIndex, DriverInfo->PeakUsageByType[TypeIndex], mMemoryTypeString[TypeIndex]);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   Print (L"    AllocRecordCount        - 0x%08x\n", DriverInfo->AllocRecordCount);
 | |
| 
 | |
|   AllocInfo = (MEMORY_PROFILE_ALLOC_INFO *)((UINTN)DriverInfo + DriverInfo->Header.Length);
 | |
|   for (AllocIndex = 0; AllocIndex < DriverInfo->AllocRecordCount; AllocIndex++) {
 | |
|     AllocInfo = DumpMemoryProfileAllocInfo (DriverInfo, AllocIndex, AllocInfo, IsForSmm);
 | |
|     if (AllocInfo == NULL) {
 | |
|       return NULL;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return (MEMORY_PROFILE_DRIVER_INFO *)AllocInfo;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Dump memory profile context information.
 | |
| 
 | |
|   @param[in] Context            Pointer to memory profile context.
 | |
|   @param[in] IsForSmm           TRUE  - SMRAM profile.
 | |
|                                 FALSE - UEFI memory profile.
 | |
| 
 | |
|   @return Pointer to the end of memory profile context buffer.
 | |
| 
 | |
| **/
 | |
| VOID *
 | |
| DumpMemoryProfileContext (
 | |
|   IN MEMORY_PROFILE_CONTEXT  *Context,
 | |
|   IN BOOLEAN                 IsForSmm
 | |
|   )
 | |
| {
 | |
|   UINTN                       TypeIndex;
 | |
|   MEMORY_PROFILE_DRIVER_INFO  *DriverInfo;
 | |
|   UINTN                       DriverIndex;
 | |
| 
 | |
|   if (Context->Header.Signature != MEMORY_PROFILE_CONTEXT_SIGNATURE) {
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   Print (L"MEMORY_PROFILE_CONTEXT\n");
 | |
|   Print (L"  Signature                     - 0x%08x\n", Context->Header.Signature);
 | |
|   Print (L"  Length                        - 0x%04x\n", Context->Header.Length);
 | |
|   Print (L"  Revision                      - 0x%04x\n", Context->Header.Revision);
 | |
|   Print (L"  CurrentTotalUsage             - 0x%016lx\n", Context->CurrentTotalUsage);
 | |
|   Print (L"  PeakTotalUsage                - 0x%016lx\n", Context->PeakTotalUsage);
 | |
|   for (TypeIndex = 0; TypeIndex < sizeof (Context->CurrentTotalUsageByType) / sizeof (Context->CurrentTotalUsageByType[0]); TypeIndex++) {
 | |
|     if ((Context->CurrentTotalUsageByType[TypeIndex] != 0) ||
 | |
|         (Context->PeakTotalUsageByType[TypeIndex] != 0))
 | |
|     {
 | |
|       Print (L"  CurrentTotalUsage[0x%02x]       - 0x%016lx (%a)\n", TypeIndex, Context->CurrentTotalUsageByType[TypeIndex], mMemoryTypeString[TypeIndex]);
 | |
|       Print (L"  PeakTotalUsage[0x%02x]          - 0x%016lx (%a)\n", TypeIndex, Context->PeakTotalUsageByType[TypeIndex], mMemoryTypeString[TypeIndex]);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   Print (L"  TotalImageSize                - 0x%016lx\n", Context->TotalImageSize);
 | |
|   Print (L"  ImageCount                    - 0x%08x\n", Context->ImageCount);
 | |
|   Print (L"  SequenceCount                 - 0x%08x\n", Context->SequenceCount);
 | |
| 
 | |
|   DriverInfo = (MEMORY_PROFILE_DRIVER_INFO *)((UINTN)Context + Context->Header.Length);
 | |
|   for (DriverIndex = 0; DriverIndex < Context->ImageCount; DriverIndex++) {
 | |
|     DriverInfo = DumpMemoryProfileDriverInfo (DriverIndex, DriverInfo, IsForSmm);
 | |
|     if (DriverInfo == NULL) {
 | |
|       return NULL;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return (VOID *)DriverInfo;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Dump memory profile descriptor information.
 | |
| 
 | |
|   @param[in] DescriptorIndex    Memory profile descriptor index.
 | |
|   @param[in] Descriptor         Pointer to memory profile descriptor.
 | |
| 
 | |
|   @return Pointer to next memory profile descriptor.
 | |
| 
 | |
| **/
 | |
| MEMORY_PROFILE_DESCRIPTOR *
 | |
| DumpMemoryProfileDescriptor (
 | |
|   IN UINTN                      DescriptorIndex,
 | |
|   IN MEMORY_PROFILE_DESCRIPTOR  *Descriptor
 | |
|   )
 | |
| {
 | |
|   if (Descriptor->Header.Signature != MEMORY_PROFILE_DESCRIPTOR_SIGNATURE) {
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   Print (L"  MEMORY_PROFILE_DESCRIPTOR (0x%x)\n", DescriptorIndex);
 | |
|   Print (L"    Signature               - 0x%08x\n", Descriptor->Header.Signature);
 | |
|   Print (L"    Length                  - 0x%04x\n", Descriptor->Header.Length);
 | |
|   Print (L"    Revision                - 0x%04x\n", Descriptor->Header.Revision);
 | |
|   Print (L"    Address                 - 0x%016lx\n", Descriptor->Address);
 | |
|   Print (L"    Size                    - 0x%016lx\n", Descriptor->Size);
 | |
| 
 | |
|   return (MEMORY_PROFILE_DESCRIPTOR *)((UINTN)Descriptor + Descriptor->Header.Length);
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Dump memory profile free memory information.
 | |
| 
 | |
|   @param[in] FreeMemory         Pointer to memory profile free memory.
 | |
| 
 | |
|   @return Pointer to the end of memory profile free memory buffer.
 | |
| 
 | |
| **/
 | |
| VOID *
 | |
| DumpMemoryProfileFreeMemory (
 | |
|   IN MEMORY_PROFILE_FREE_MEMORY  *FreeMemory
 | |
|   )
 | |
| {
 | |
|   MEMORY_PROFILE_DESCRIPTOR  *Descriptor;
 | |
|   UINTN                      DescriptorIndex;
 | |
| 
 | |
|   if (FreeMemory->Header.Signature != MEMORY_PROFILE_FREE_MEMORY_SIGNATURE) {
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   Print (L"MEMORY_PROFILE_FREE_MEMORY\n");
 | |
|   Print (L"  Signature                     - 0x%08x\n", FreeMemory->Header.Signature);
 | |
|   Print (L"  Length                        - 0x%04x\n", FreeMemory->Header.Length);
 | |
|   Print (L"  Revision                      - 0x%04x\n", FreeMemory->Header.Revision);
 | |
|   Print (L"  TotalFreeMemoryPages          - 0x%016lx\n", FreeMemory->TotalFreeMemoryPages);
 | |
|   Print (L"  FreeMemoryEntryCount          - 0x%08x\n", FreeMemory->FreeMemoryEntryCount);
 | |
| 
 | |
|   Descriptor = (MEMORY_PROFILE_DESCRIPTOR *)((UINTN)FreeMemory + FreeMemory->Header.Length);
 | |
|   for (DescriptorIndex = 0; DescriptorIndex < FreeMemory->FreeMemoryEntryCount; DescriptorIndex++) {
 | |
|     Descriptor = DumpMemoryProfileDescriptor (DescriptorIndex, Descriptor);
 | |
|     if (Descriptor == NULL) {
 | |
|       return NULL;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return (VOID *)Descriptor;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Dump memory profile memory range information.
 | |
| 
 | |
|   @param[in] MemoryRange        Pointer to memory profile memory range.
 | |
| 
 | |
|   @return Pointer to the end of memory profile memory range buffer.
 | |
| 
 | |
| **/
 | |
| VOID *
 | |
| DumpMemoryProfileMemoryRange (
 | |
|   IN MEMORY_PROFILE_MEMORY_RANGE  *MemoryRange
 | |
|   )
 | |
| {
 | |
|   MEMORY_PROFILE_DESCRIPTOR  *Descriptor;
 | |
|   UINTN                      DescriptorIndex;
 | |
| 
 | |
|   if (MemoryRange->Header.Signature != MEMORY_PROFILE_MEMORY_RANGE_SIGNATURE) {
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   Print (L"MEMORY_PROFILE_MEMORY_RANGE\n");
 | |
|   Print (L"  Signature                     - 0x%08x\n", MemoryRange->Header.Signature);
 | |
|   Print (L"  Length                        - 0x%04x\n", MemoryRange->Header.Length);
 | |
|   Print (L"  Revision                      - 0x%04x\n", MemoryRange->Header.Revision);
 | |
|   Print (L"  MemoryRangeCount              - 0x%08x\n", MemoryRange->MemoryRangeCount);
 | |
| 
 | |
|   Descriptor = (MEMORY_PROFILE_DESCRIPTOR *)((UINTN)MemoryRange + MemoryRange->Header.Length);
 | |
|   for (DescriptorIndex = 0; DescriptorIndex < MemoryRange->MemoryRangeCount; DescriptorIndex++) {
 | |
|     Descriptor = DumpMemoryProfileDescriptor (DescriptorIndex, Descriptor);
 | |
|     if (Descriptor == NULL) {
 | |
|       return NULL;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return (VOID *)Descriptor;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Scan memory profile by Signature.
 | |
| 
 | |
|   @param[in] ProfileBuffer      Memory profile base address.
 | |
|   @param[in] ProfileSize        Memory profile size.
 | |
|   @param[in] Signature          Signature.
 | |
| 
 | |
|   @return Pointer to the structure with the signature.
 | |
| 
 | |
| **/
 | |
| VOID *
 | |
| ScanMemoryProfileBySignature (
 | |
|   IN PHYSICAL_ADDRESS  ProfileBuffer,
 | |
|   IN UINT64            ProfileSize,
 | |
|   IN UINT32            Signature
 | |
|   )
 | |
| {
 | |
|   MEMORY_PROFILE_COMMON_HEADER  *CommonHeader;
 | |
|   UINTN                         ProfileEnd;
 | |
| 
 | |
|   ProfileEnd   = (UINTN)(ProfileBuffer + ProfileSize);
 | |
|   CommonHeader = (MEMORY_PROFILE_COMMON_HEADER *)(UINTN)ProfileBuffer;
 | |
|   while ((UINTN)CommonHeader < ProfileEnd) {
 | |
|     if (CommonHeader->Signature == Signature) {
 | |
|       //
 | |
|       // Found it.
 | |
|       //
 | |
|       return (VOID *)CommonHeader;
 | |
|     }
 | |
| 
 | |
|     if (CommonHeader->Length == 0) {
 | |
|       ASSERT (FALSE);
 | |
|       return NULL;
 | |
|     }
 | |
| 
 | |
|     CommonHeader = (MEMORY_PROFILE_COMMON_HEADER *)((UINTN)CommonHeader + CommonHeader->Length);
 | |
|   }
 | |
| 
 | |
|   return NULL;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Dump memory profile information.
 | |
| 
 | |
|   @param[in] ProfileBuffer      Memory profile base address.
 | |
|   @param[in] ProfileSize        Memory profile size.
 | |
|   @param[in] IsForSmm           TRUE  - SMRAM profile.
 | |
|                                 FALSE - UEFI memory profile.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| DumpMemoryProfile (
 | |
|   IN PHYSICAL_ADDRESS  ProfileBuffer,
 | |
|   IN UINT64            ProfileSize,
 | |
|   IN BOOLEAN           IsForSmm
 | |
|   )
 | |
| {
 | |
|   MEMORY_PROFILE_CONTEXT       *Context;
 | |
|   MEMORY_PROFILE_FREE_MEMORY   *FreeMemory;
 | |
|   MEMORY_PROFILE_MEMORY_RANGE  *MemoryRange;
 | |
| 
 | |
|   Context = (MEMORY_PROFILE_CONTEXT *)ScanMemoryProfileBySignature (ProfileBuffer, ProfileSize, MEMORY_PROFILE_CONTEXT_SIGNATURE);
 | |
|   if (Context != NULL) {
 | |
|     DumpMemoryProfileContext (Context, IsForSmm);
 | |
|   }
 | |
| 
 | |
|   FreeMemory = (MEMORY_PROFILE_FREE_MEMORY *)ScanMemoryProfileBySignature (ProfileBuffer, ProfileSize, MEMORY_PROFILE_FREE_MEMORY_SIGNATURE);
 | |
|   if (FreeMemory != NULL) {
 | |
|     DumpMemoryProfileFreeMemory (FreeMemory);
 | |
|   }
 | |
| 
 | |
|   MemoryRange = (MEMORY_PROFILE_MEMORY_RANGE *)ScanMemoryProfileBySignature (ProfileBuffer, ProfileSize, MEMORY_PROFILE_MEMORY_RANGE_SIGNATURE);
 | |
|   if (MemoryRange != NULL) {
 | |
|     DumpMemoryProfileMemoryRange (MemoryRange);
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Get Allocate summary information structure by caller address.
 | |
| 
 | |
|   @param[in] CallerAddress          Caller address.
 | |
|   @param[in] DriverSummaryInfoData  Driver summary information data structure.
 | |
| 
 | |
|   @return Allocate summary information structure by caller address.
 | |
| 
 | |
| **/
 | |
| MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA *
 | |
| GetAllocSummaryInfoByCallerAddress (
 | |
|   IN PHYSICAL_ADDRESS                         CallerAddress,
 | |
|   IN MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA  *DriverSummaryInfoData
 | |
|   )
 | |
| {
 | |
|   LIST_ENTRY                              *AllocSummaryInfoList;
 | |
|   LIST_ENTRY                              *AllocSummaryLink;
 | |
|   MEMORY_PROFILE_ALLOC_SUMMARY_INFO       *AllocSummaryInfo;
 | |
|   MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA  *AllocSummaryInfoData;
 | |
| 
 | |
|   AllocSummaryInfoList = DriverSummaryInfoData->AllocSummaryInfoList;
 | |
| 
 | |
|   for (AllocSummaryLink = AllocSummaryInfoList->ForwardLink;
 | |
|        AllocSummaryLink != AllocSummaryInfoList;
 | |
|        AllocSummaryLink = AllocSummaryLink->ForwardLink)
 | |
|   {
 | |
|     AllocSummaryInfoData = CR (
 | |
|                              AllocSummaryLink,
 | |
|                              MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA,
 | |
|                              Link,
 | |
|                              MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE
 | |
|                              );
 | |
|     AllocSummaryInfo = &AllocSummaryInfoData->AllocSummaryInfo;
 | |
|     if (AllocSummaryInfo->CallerAddress == CallerAddress) {
 | |
|       return AllocSummaryInfoData;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return NULL;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Create Allocate summary information structure and
 | |
|   link to Driver summary information data structure.
 | |
| 
 | |
|   @param[in, out] DriverSummaryInfoData Driver summary information data structure.
 | |
|   @param[in]      AllocInfo             Pointer to memory profile alloc info.
 | |
| 
 | |
|   @return Pointer to next memory profile alloc info.
 | |
| 
 | |
| **/
 | |
| MEMORY_PROFILE_ALLOC_INFO *
 | |
| CreateAllocSummaryInfo (
 | |
|   IN OUT MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA  *DriverSummaryInfoData,
 | |
|   IN MEMORY_PROFILE_ALLOC_INFO                    *AllocInfo
 | |
|   )
 | |
| {
 | |
|   MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA  *AllocSummaryInfoData;
 | |
|   MEMORY_PROFILE_ALLOC_SUMMARY_INFO       *AllocSummaryInfo;
 | |
| 
 | |
|   if (AllocInfo->Header.Signature != MEMORY_PROFILE_ALLOC_INFO_SIGNATURE) {
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   AllocSummaryInfoData = GetAllocSummaryInfoByCallerAddress (AllocInfo->CallerAddress, DriverSummaryInfoData);
 | |
|   if (AllocSummaryInfoData == NULL) {
 | |
|     AllocSummaryInfoData = AllocatePool (sizeof (*AllocSummaryInfoData));
 | |
|     if (AllocSummaryInfoData == NULL) {
 | |
|       return NULL;
 | |
|     }
 | |
| 
 | |
|     AllocSummaryInfoData->Signature    = MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE;
 | |
|     AllocSummaryInfo                   = &AllocSummaryInfoData->AllocSummaryInfo;
 | |
|     AllocSummaryInfo->Header.Signature = MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE;
 | |
|     AllocSummaryInfo->Header.Length    = sizeof (*AllocSummaryInfo);
 | |
|     AllocSummaryInfo->Header.Revision  = MEMORY_PROFILE_ALLOC_SUMMARY_INFO_REVISION;
 | |
|     AllocSummaryInfo->CallerAddress    = AllocInfo->CallerAddress;
 | |
|     AllocSummaryInfo->Action           = AllocInfo->Action;
 | |
|     if (AllocInfo->ActionStringOffset != 0) {
 | |
|       AllocSummaryInfo->ActionString = (CHAR8 *)((UINTN)AllocInfo + AllocInfo->ActionStringOffset);
 | |
|     } else {
 | |
|       AllocSummaryInfo->ActionString = NULL;
 | |
|     }
 | |
| 
 | |
|     AllocSummaryInfo->AllocateCount = 0;
 | |
|     AllocSummaryInfo->TotalSize     = 0;
 | |
|     InsertTailList (DriverSummaryInfoData->AllocSummaryInfoList, &AllocSummaryInfoData->Link);
 | |
|   }
 | |
| 
 | |
|   AllocSummaryInfo = &AllocSummaryInfoData->AllocSummaryInfo;
 | |
|   AllocSummaryInfo->AllocateCount++;
 | |
|   AllocSummaryInfo->TotalSize += AllocInfo->Size;
 | |
| 
 | |
|   return (MEMORY_PROFILE_ALLOC_INFO *)((UINTN)AllocInfo + AllocInfo->Header.Length);
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Create Driver summary information structure and
 | |
|   link to Context summary information data structure.
 | |
| 
 | |
|   @param[in, out] ContextSummaryData    Context summary information data structure.
 | |
|   @param[in]      DriverInfo            Pointer to memory profile driver info.
 | |
| 
 | |
|   @return Pointer to next memory profile driver info.
 | |
| 
 | |
| **/
 | |
| MEMORY_PROFILE_DRIVER_INFO *
 | |
| CreateDriverSummaryInfo (
 | |
|   IN OUT MEMORY_PROFILE_CONTEXT_SUMMARY_DATA  *ContextSummaryData,
 | |
|   IN MEMORY_PROFILE_DRIVER_INFO               *DriverInfo
 | |
|   )
 | |
| {
 | |
|   MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA  *DriverSummaryInfoData;
 | |
|   MEMORY_PROFILE_ALLOC_INFO                *AllocInfo;
 | |
|   UINTN                                    AllocIndex;
 | |
| 
 | |
|   if (DriverInfo->Header.Signature != MEMORY_PROFILE_DRIVER_INFO_SIGNATURE) {
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   DriverSummaryInfoData = AllocatePool (sizeof (*DriverSummaryInfoData) + sizeof (LIST_ENTRY));
 | |
|   if (DriverSummaryInfoData == NULL) {
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   DriverSummaryInfoData->Signature            = MEMORY_PROFILE_DRIVER_INFO_SIGNATURE;
 | |
|   DriverSummaryInfoData->DriverInfo           = DriverInfo;
 | |
|   DriverSummaryInfoData->AllocSummaryInfoList = (LIST_ENTRY *)(DriverSummaryInfoData + 1);
 | |
|   InitializeListHead (DriverSummaryInfoData->AllocSummaryInfoList);
 | |
|   InsertTailList (ContextSummaryData->DriverSummaryInfoList, &DriverSummaryInfoData->Link);
 | |
| 
 | |
|   AllocInfo = (MEMORY_PROFILE_ALLOC_INFO *)((UINTN)DriverInfo + DriverInfo->Header.Length);
 | |
|   for (AllocIndex = 0; AllocIndex < DriverInfo->AllocRecordCount; AllocIndex++) {
 | |
|     AllocInfo = CreateAllocSummaryInfo (DriverSummaryInfoData, AllocInfo);
 | |
|     if (AllocInfo == NULL) {
 | |
|       return NULL;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return (MEMORY_PROFILE_DRIVER_INFO *)AllocInfo;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Create Context summary information structure.
 | |
| 
 | |
|   @param[in] ProfileBuffer      Memory profile base address.
 | |
|   @param[in] ProfileSize        Memory profile size.
 | |
| 
 | |
|   @return Context summary information structure.
 | |
| 
 | |
| **/
 | |
| MEMORY_PROFILE_CONTEXT_SUMMARY_DATA *
 | |
| CreateContextSummaryData (
 | |
|   IN PHYSICAL_ADDRESS  ProfileBuffer,
 | |
|   IN UINT64            ProfileSize
 | |
|   )
 | |
| {
 | |
|   MEMORY_PROFILE_CONTEXT      *Context;
 | |
|   MEMORY_PROFILE_DRIVER_INFO  *DriverInfo;
 | |
|   UINTN                       DriverIndex;
 | |
| 
 | |
|   Context = (MEMORY_PROFILE_CONTEXT *)ScanMemoryProfileBySignature (ProfileBuffer, ProfileSize, MEMORY_PROFILE_CONTEXT_SIGNATURE);
 | |
|   if (Context == NULL) {
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   mMemoryProfileContextSummary.Signature             = MEMORY_PROFILE_CONTEXT_SIGNATURE;
 | |
|   mMemoryProfileContextSummary.Context               = Context;
 | |
|   mMemoryProfileContextSummary.DriverSummaryInfoList = &mImageSummaryQueue;
 | |
| 
 | |
|   DriverInfo = (MEMORY_PROFILE_DRIVER_INFO *)((UINTN)Context + Context->Header.Length);
 | |
|   for (DriverIndex = 0; DriverIndex < Context->ImageCount; DriverIndex++) {
 | |
|     DriverInfo = CreateDriverSummaryInfo (&mMemoryProfileContextSummary, DriverInfo);
 | |
|     if (DriverInfo == NULL) {
 | |
|       return NULL;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return &mMemoryProfileContextSummary;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Dump Context summary information.
 | |
| 
 | |
|   @param[in] ContextSummaryData Context summary information data.
 | |
|   @param[in] IsForSmm           TRUE  - SMRAM profile.
 | |
|                                 FALSE - UEFI memory profile.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| DumpContextSummaryData (
 | |
|   IN MEMORY_PROFILE_CONTEXT_SUMMARY_DATA  *ContextSummaryData,
 | |
|   IN BOOLEAN                              IsForSmm
 | |
|   )
 | |
| {
 | |
|   MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA  *DriverSummaryInfoData;
 | |
|   MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA   *AllocSummaryInfoData;
 | |
|   LIST_ENTRY                               *DriverSummaryInfoList;
 | |
|   LIST_ENTRY                               *DriverSummaryLink;
 | |
|   LIST_ENTRY                               *AllocSummaryInfoList;
 | |
|   LIST_ENTRY                               *AllocSummaryLink;
 | |
|   MEMORY_PROFILE_DRIVER_INFO               *DriverInfo;
 | |
|   MEMORY_PROFILE_ALLOC_SUMMARY_INFO        *AllocSummaryInfo;
 | |
|   CHAR8                                    *NameString;
 | |
| 
 | |
|   if (ContextSummaryData == NULL) {
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   Print (L"\nSummary Data:\n");
 | |
| 
 | |
|   DriverSummaryInfoList = ContextSummaryData->DriverSummaryInfoList;
 | |
|   for (DriverSummaryLink = DriverSummaryInfoList->ForwardLink;
 | |
|        DriverSummaryLink != DriverSummaryInfoList;
 | |
|        DriverSummaryLink = DriverSummaryLink->ForwardLink)
 | |
|   {
 | |
|     DriverSummaryInfoData = CR (
 | |
|                               DriverSummaryLink,
 | |
|                               MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA,
 | |
|                               Link,
 | |
|                               MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
 | |
|                               );
 | |
|     DriverInfo = DriverSummaryInfoData->DriverInfo;
 | |
| 
 | |
|     NameString = GetDriverNameString (DriverInfo);
 | |
|     Print (L"\nDriver - %a (Usage - 0x%08x)", NameString, DriverInfo->CurrentUsage);
 | |
|     if (DriverInfo->CurrentUsage == 0) {
 | |
|       Print (L"\n");
 | |
|       continue;
 | |
|     }
 | |
| 
 | |
|     if (DriverInfo->PdbStringOffset != 0) {
 | |
|       Print (L" (Pdb - %a)\n", (CHAR8 *)((UINTN)DriverInfo + DriverInfo->PdbStringOffset));
 | |
|     } else {
 | |
|       Print (L"\n");
 | |
|     }
 | |
| 
 | |
|     Print (L"Caller List:\n");
 | |
|     Print (L"  Count            Size                   RVA              Action\n");
 | |
|     Print (L"==========  ==================     ================== (================================)\n");
 | |
|     AllocSummaryInfoList = DriverSummaryInfoData->AllocSummaryInfoList;
 | |
|     for (AllocSummaryLink = AllocSummaryInfoList->ForwardLink;
 | |
|          AllocSummaryLink != AllocSummaryInfoList;
 | |
|          AllocSummaryLink = AllocSummaryLink->ForwardLink)
 | |
|     {
 | |
|       AllocSummaryInfoData = CR (
 | |
|                                AllocSummaryLink,
 | |
|                                MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA,
 | |
|                                Link,
 | |
|                                MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE
 | |
|                                );
 | |
|       AllocSummaryInfo = &AllocSummaryInfoData->AllocSummaryInfo;
 | |
| 
 | |
|       Print (
 | |
|         L"0x%08x  0x%016lx <== 0x%016lx",
 | |
|         AllocSummaryInfo->AllocateCount,
 | |
|         AllocSummaryInfo->TotalSize,
 | |
|         AllocSummaryInfo->CallerAddress - DriverInfo->ImageBase
 | |
|         );
 | |
|       Print (L" (%a)\n", ProfileActionToStr (AllocSummaryInfo->Action, AllocSummaryInfo->ActionString, IsForSmm));
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Destroy Context summary information.
 | |
| 
 | |
|   @param[in, out] ContextSummaryData    Context summary information data.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| DestroyContextSummaryData (
 | |
|   IN OUT MEMORY_PROFILE_CONTEXT_SUMMARY_DATA  *ContextSummaryData
 | |
|   )
 | |
| {
 | |
|   MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA  *DriverSummaryInfoData;
 | |
|   MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA   *AllocSummaryInfoData;
 | |
|   LIST_ENTRY                               *DriverSummaryInfoList;
 | |
|   LIST_ENTRY                               *DriverSummaryLink;
 | |
|   LIST_ENTRY                               *AllocSummaryInfoList;
 | |
|   LIST_ENTRY                               *AllocSummaryLink;
 | |
| 
 | |
|   if (ContextSummaryData == NULL) {
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   DriverSummaryInfoList = ContextSummaryData->DriverSummaryInfoList;
 | |
|   for (DriverSummaryLink = DriverSummaryInfoList->ForwardLink;
 | |
|        DriverSummaryLink != DriverSummaryInfoList;
 | |
|        )
 | |
|   {
 | |
|     DriverSummaryInfoData = CR (
 | |
|                               DriverSummaryLink,
 | |
|                               MEMORY_PROFILE_DRIVER_SUMMARY_INFO_DATA,
 | |
|                               Link,
 | |
|                               MEMORY_PROFILE_DRIVER_INFO_SIGNATURE
 | |
|                               );
 | |
|     DriverSummaryLink = DriverSummaryLink->ForwardLink;
 | |
| 
 | |
|     AllocSummaryInfoList = DriverSummaryInfoData->AllocSummaryInfoList;
 | |
|     for (AllocSummaryLink = AllocSummaryInfoList->ForwardLink;
 | |
|          AllocSummaryLink != AllocSummaryInfoList;
 | |
|          )
 | |
|     {
 | |
|       AllocSummaryInfoData = CR (
 | |
|                                AllocSummaryLink,
 | |
|                                MEMORY_PROFILE_ALLOC_SUMMARY_INFO_DATA,
 | |
|                                Link,
 | |
|                                MEMORY_PROFILE_ALLOC_SUMMARY_INFO_SIGNATURE
 | |
|                                );
 | |
|       AllocSummaryLink = AllocSummaryLink->ForwardLink;
 | |
| 
 | |
|       RemoveEntryList (&AllocSummaryInfoData->Link);
 | |
|       FreePool (AllocSummaryInfoData);
 | |
|     }
 | |
| 
 | |
|     RemoveEntryList (&DriverSummaryInfoData->Link);
 | |
|     FreePool (DriverSummaryInfoData);
 | |
|   }
 | |
| 
 | |
|   return;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Get and dump UEFI memory profile data.
 | |
| 
 | |
|   @return EFI_SUCCESS   Get the memory profile data successfully.
 | |
|   @return other         Fail to get the memory profile data.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| GetUefiMemoryProfileData (
 | |
|   VOID
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                           Status;
 | |
|   EDKII_MEMORY_PROFILE_PROTOCOL        *ProfileProtocol;
 | |
|   VOID                                 *Data;
 | |
|   UINT64                               Size;
 | |
|   MEMORY_PROFILE_CONTEXT_SUMMARY_DATA  *MemoryProfileContextSummaryData;
 | |
|   BOOLEAN                              RecordingState;
 | |
| 
 | |
|   Status = gBS->LocateProtocol (&gEdkiiMemoryProfileGuid, NULL, (VOID **)&ProfileProtocol);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     DEBUG ((DEBUG_ERROR, "UefiMemoryProfile: Locate MemoryProfile protocol - %r\n", Status));
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Set recording state if needed.
 | |
|   //
 | |
|   RecordingState = MEMORY_PROFILE_RECORDING_DISABLE;
 | |
|   Status         = ProfileProtocol->GetRecordingState (ProfileProtocol, &RecordingState);
 | |
|   if (RecordingState == MEMORY_PROFILE_RECORDING_ENABLE) {
 | |
|     ProfileProtocol->SetRecordingState (ProfileProtocol, MEMORY_PROFILE_RECORDING_DISABLE);
 | |
|   }
 | |
| 
 | |
|   Size   = 0;
 | |
|   Data   = NULL;
 | |
|   Status = ProfileProtocol->GetData (
 | |
|                               ProfileProtocol,
 | |
|                               &Size,
 | |
|                               Data
 | |
|                               );
 | |
|   if (Status != EFI_BUFFER_TOO_SMALL) {
 | |
|     Print (L"UefiMemoryProfile: GetData - %r\n", Status);
 | |
|     goto Done;
 | |
|   }
 | |
| 
 | |
|   Data = AllocateZeroPool ((UINTN)Size);
 | |
|   if (Data == NULL) {
 | |
|     Status = EFI_OUT_OF_RESOURCES;
 | |
|     Print (L"UefiMemoryProfile: AllocateZeroPool (0x%x) - %r\n", Size, Status);
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   Status = ProfileProtocol->GetData (
 | |
|                               ProfileProtocol,
 | |
|                               &Size,
 | |
|                               Data
 | |
|                               );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     Print (L"UefiMemoryProfile: GetData - %r\n", Status);
 | |
|     goto Done;
 | |
|   }
 | |
| 
 | |
|   Print (L"UefiMemoryProfileSize - 0x%x\n", Size);
 | |
|   Print (L"======= UefiMemoryProfile begin =======\n");
 | |
|   DumpMemoryProfile ((PHYSICAL_ADDRESS)(UINTN)Data, Size, FALSE);
 | |
| 
 | |
|   //
 | |
|   // Dump summary information
 | |
|   //
 | |
|   MemoryProfileContextSummaryData = CreateContextSummaryData ((PHYSICAL_ADDRESS)(UINTN)Data, Size);
 | |
|   if (MemoryProfileContextSummaryData != NULL) {
 | |
|     DumpContextSummaryData (MemoryProfileContextSummaryData, FALSE);
 | |
|     DestroyContextSummaryData (MemoryProfileContextSummaryData);
 | |
|   }
 | |
| 
 | |
|   Print (L"======= UefiMemoryProfile end =======\n\n\n");
 | |
| 
 | |
| Done:
 | |
|   if (Data != NULL) {
 | |
|     FreePool (Data);
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Restore recording state if needed.
 | |
|   //
 | |
|   if (RecordingState == MEMORY_PROFILE_RECORDING_ENABLE) {
 | |
|     ProfileProtocol->SetRecordingState (ProfileProtocol, MEMORY_PROFILE_RECORDING_ENABLE);
 | |
|   }
 | |
| 
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Get and dump SMRAM profile data.
 | |
| 
 | |
|   @return EFI_SUCCESS   Get the SMRAM profile data successfully.
 | |
|   @return other         Fail to get the SMRAM profile data.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| GetSmramProfileData (
 | |
|   VOID
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                                          Status;
 | |
|   UINTN                                               CommSize;
 | |
|   UINT8                                               *CommBuffer;
 | |
|   EFI_SMM_COMMUNICATE_HEADER                          *CommHeader;
 | |
|   SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO            *CommGetProfileInfo;
 | |
|   SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET  *CommGetProfileData;
 | |
|   SMRAM_PROFILE_PARAMETER_RECORDING_STATE             *CommRecordingState;
 | |
|   UINTN                                               ProfileSize;
 | |
|   VOID                                                *ProfileBuffer;
 | |
|   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;
 | |
|   MEMORY_PROFILE_CONTEXT_SUMMARY_DATA                 *MemoryProfileContextSummaryData;
 | |
|   BOOLEAN                                             RecordingState;
 | |
| 
 | |
|   ProfileBuffer = NULL;
 | |
| 
 | |
|   Status = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **)&SmmCommunication);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     DEBUG ((DEBUG_ERROR, "SmramProfile: Locate SmmCommunication protocol - %r\n", Status));
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   MinimalSizeNeeded = sizeof (EFI_GUID) +
 | |
|                       sizeof (UINTN) +
 | |
|                       MAX (
 | |
|                         sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO),
 | |
|                         MAX (
 | |
|                           sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET),
 | |
|                           sizeof (SMRAM_PROFILE_PARAMETER_RECORDING_STATE)
 | |
|                           )
 | |
|                         );
 | |
|   MinimalSizeNeeded += MAX (
 | |
|                          sizeof (MEMORY_PROFILE_CONTEXT),
 | |
|                          MAX (
 | |
|                            sizeof (MEMORY_PROFILE_DRIVER_INFO),
 | |
|                            MAX (
 | |
|                              sizeof (MEMORY_PROFILE_ALLOC_INFO),
 | |
|                              MAX (
 | |
|                                sizeof (MEMORY_PROFILE_DESCRIPTOR),
 | |
|                                MAX (
 | |
|                                  sizeof (MEMORY_PROFILE_FREE_MEMORY),
 | |
|                                  sizeof (MEMORY_PROFILE_MEMORY_RANGE)
 | |
|                                  )
 | |
|                                )
 | |
|                              )
 | |
|                            )
 | |
|                          );
 | |
| 
 | |
|   Status = EfiGetSystemConfigurationTable (
 | |
|              &gEdkiiPiSmmCommunicationRegionTableGuid,
 | |
|              (VOID **)&PiSmmCommunicationRegionTable
 | |
|              );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     DEBUG ((DEBUG_ERROR, "SmramProfile: Get PiSmmCommunicationRegionTable - %r\n", Status));
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   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;
 | |
| 
 | |
|   //
 | |
|   // Set recording state if needed.
 | |
|   //
 | |
|   RecordingState = MEMORY_PROFILE_RECORDING_DISABLE;
 | |
| 
 | |
|   CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0];
 | |
|   CopyMem (&CommHeader->HeaderGuid, &gEdkiiMemoryProfileGuid, sizeof (gEdkiiMemoryProfileGuid));
 | |
|   CommHeader->MessageLength = sizeof (SMRAM_PROFILE_PARAMETER_RECORDING_STATE);
 | |
| 
 | |
|   CommRecordingState                      = (SMRAM_PROFILE_PARAMETER_RECORDING_STATE *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)];
 | |
|   CommRecordingState->Header.Command      = SMRAM_PROFILE_COMMAND_GET_RECORDING_STATE;
 | |
|   CommRecordingState->Header.DataLength   = sizeof (*CommRecordingState);
 | |
|   CommRecordingState->Header.ReturnStatus = (UINT64)-1;
 | |
|   CommRecordingState->RecordingState      = MEMORY_PROFILE_RECORDING_DISABLE;
 | |
| 
 | |
|   CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + CommHeader->MessageLength;
 | |
|   Status   = SmmCommunication->Communicate (SmmCommunication, CommBuffer, &CommSize);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     DEBUG ((DEBUG_ERROR, "SmramProfile: SmmCommunication - %r\n", Status));
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   if (CommRecordingState->Header.ReturnStatus != 0) {
 | |
|     Print (L"SmramProfile: GetRecordingState - 0x%0x\n", CommRecordingState->Header.ReturnStatus);
 | |
|     return EFI_SUCCESS;
 | |
|   }
 | |
| 
 | |
|   RecordingState = CommRecordingState->RecordingState;
 | |
|   if (RecordingState == MEMORY_PROFILE_RECORDING_ENABLE) {
 | |
|     CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0];
 | |
|     CopyMem (&CommHeader->HeaderGuid, &gEdkiiMemoryProfileGuid, sizeof (gEdkiiMemoryProfileGuid));
 | |
|     CommHeader->MessageLength = sizeof (SMRAM_PROFILE_PARAMETER_RECORDING_STATE);
 | |
| 
 | |
|     CommRecordingState                      = (SMRAM_PROFILE_PARAMETER_RECORDING_STATE *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)];
 | |
|     CommRecordingState->Header.Command      = SMRAM_PROFILE_COMMAND_SET_RECORDING_STATE;
 | |
|     CommRecordingState->Header.DataLength   = sizeof (*CommRecordingState);
 | |
|     CommRecordingState->Header.ReturnStatus = (UINT64)-1;
 | |
|     CommRecordingState->RecordingState      = MEMORY_PROFILE_RECORDING_DISABLE;
 | |
| 
 | |
|     CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + CommHeader->MessageLength;
 | |
|     SmmCommunication->Communicate (SmmCommunication, CommBuffer, &CommSize);
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Get Size
 | |
|   //
 | |
|   CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0];
 | |
|   CopyMem (&CommHeader->HeaderGuid, &gEdkiiMemoryProfileGuid, sizeof (gEdkiiMemoryProfileGuid));
 | |
|   CommHeader->MessageLength = sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO);
 | |
| 
 | |
|   CommGetProfileInfo                      = (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)];
 | |
|   CommGetProfileInfo->Header.Command      = SMRAM_PROFILE_COMMAND_GET_PROFILE_INFO;
 | |
|   CommGetProfileInfo->Header.DataLength   = sizeof (*CommGetProfileInfo);
 | |
|   CommGetProfileInfo->Header.ReturnStatus = (UINT64)-1;
 | |
|   CommGetProfileInfo->ProfileSize         = 0;
 | |
| 
 | |
|   CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + CommHeader->MessageLength;
 | |
|   Status   = SmmCommunication->Communicate (SmmCommunication, CommBuffer, &CommSize);
 | |
|   ASSERT_EFI_ERROR (Status);
 | |
| 
 | |
|   if (CommGetProfileInfo->Header.ReturnStatus != 0) {
 | |
|     Status = EFI_SUCCESS;
 | |
|     Print (L"SmramProfile: GetProfileInfo - 0x%0x\n", CommGetProfileInfo->Header.ReturnStatus);
 | |
|     goto Done;
 | |
|   }
 | |
| 
 | |
|   ProfileSize = (UINTN)CommGetProfileInfo->ProfileSize;
 | |
| 
 | |
|   //
 | |
|   // Get Data
 | |
|   //
 | |
|   ProfileBuffer = AllocateZeroPool (ProfileSize);
 | |
|   if (ProfileBuffer == NULL) {
 | |
|     Status = EFI_OUT_OF_RESOURCES;
 | |
|     Print (L"SmramProfile: AllocateZeroPool (0x%x) for profile buffer - %r\n", ProfileSize, Status);
 | |
|     goto Done;
 | |
|   }
 | |
| 
 | |
|   CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0];
 | |
|   CopyMem (&CommHeader->HeaderGuid, &gEdkiiMemoryProfileGuid, sizeof (gEdkiiMemoryProfileGuid));
 | |
|   CommHeader->MessageLength = sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET);
 | |
| 
 | |
|   CommGetProfileData                      = (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)];
 | |
|   CommGetProfileData->Header.Command      = SMRAM_PROFILE_COMMAND_GET_PROFILE_DATA_BY_OFFSET;
 | |
|   CommGetProfileData->Header.DataLength   = sizeof (*CommGetProfileData);
 | |
|   CommGetProfileData->Header.ReturnStatus = (UINT64)-1;
 | |
| 
 | |
|   CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + CommHeader->MessageLength;
 | |
|   Buffer   = (UINT8 *)CommHeader + CommSize;
 | |
|   Size    -= CommSize;
 | |
| 
 | |
|   CommGetProfileData->ProfileBuffer = (PHYSICAL_ADDRESS)(UINTN)Buffer;
 | |
|   CommGetProfileData->ProfileOffset = 0;
 | |
|   while (CommGetProfileData->ProfileOffset < ProfileSize) {
 | |
|     Offset = (UINTN)CommGetProfileData->ProfileOffset;
 | |
|     if (Size <= (ProfileSize - CommGetProfileData->ProfileOffset)) {
 | |
|       CommGetProfileData->ProfileSize = (UINT64)Size;
 | |
|     } else {
 | |
|       CommGetProfileData->ProfileSize = (UINT64)(ProfileSize - CommGetProfileData->ProfileOffset);
 | |
|     }
 | |
| 
 | |
|     Status = SmmCommunication->Communicate (SmmCommunication, CommBuffer, &CommSize);
 | |
|     ASSERT_EFI_ERROR (Status);
 | |
| 
 | |
|     if (CommGetProfileData->Header.ReturnStatus != 0) {
 | |
|       Status = EFI_SUCCESS;
 | |
|       Print (L"GetProfileData - 0x%x\n", CommGetProfileData->Header.ReturnStatus);
 | |
|       goto Done;
 | |
|     }
 | |
| 
 | |
|     CopyMem ((UINT8 *)ProfileBuffer + Offset, (VOID *)(UINTN)CommGetProfileData->ProfileBuffer, (UINTN)CommGetProfileData->ProfileSize);
 | |
|   }
 | |
| 
 | |
|   Print (L"SmramProfileSize - 0x%x\n", ProfileSize);
 | |
|   Print (L"======= SmramProfile begin =======\n");
 | |
|   DumpMemoryProfile ((PHYSICAL_ADDRESS)(UINTN)ProfileBuffer, ProfileSize, TRUE);
 | |
| 
 | |
|   //
 | |
|   // Dump summary information
 | |
|   //
 | |
|   MemoryProfileContextSummaryData = CreateContextSummaryData ((PHYSICAL_ADDRESS)(UINTN)ProfileBuffer, ProfileSize);
 | |
|   if (MemoryProfileContextSummaryData != NULL) {
 | |
|     DumpContextSummaryData (MemoryProfileContextSummaryData, TRUE);
 | |
|     DestroyContextSummaryData (MemoryProfileContextSummaryData);
 | |
|   }
 | |
| 
 | |
|   Print (L"======= SmramProfile end =======\n\n\n");
 | |
| 
 | |
| Done:
 | |
|   if (ProfileBuffer != NULL) {
 | |
|     FreePool (ProfileBuffer);
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Restore recording state if needed.
 | |
|   //
 | |
|   if (RecordingState == MEMORY_PROFILE_RECORDING_ENABLE) {
 | |
|     CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0];
 | |
|     CopyMem (&CommHeader->HeaderGuid, &gEdkiiMemoryProfileGuid, sizeof (gEdkiiMemoryProfileGuid));
 | |
|     CommHeader->MessageLength = sizeof (SMRAM_PROFILE_PARAMETER_RECORDING_STATE);
 | |
| 
 | |
|     CommRecordingState                      = (SMRAM_PROFILE_PARAMETER_RECORDING_STATE *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)];
 | |
|     CommRecordingState->Header.Command      = SMRAM_PROFILE_COMMAND_SET_RECORDING_STATE;
 | |
|     CommRecordingState->Header.DataLength   = sizeof (*CommRecordingState);
 | |
|     CommRecordingState->Header.ReturnStatus = (UINT64)-1;
 | |
|     CommRecordingState->RecordingState      = MEMORY_PROFILE_RECORDING_ENABLE;
 | |
| 
 | |
|     CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + CommHeader->MessageLength;
 | |
|     SmmCommunication->Communicate (SmmCommunication, CommBuffer, &CommSize);
 | |
|   }
 | |
| 
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   The user Entry Point for Application. The user code starts with this function
 | |
|   as the real entry point for the image goes into a library that calls this function.
 | |
| 
 | |
|   @param[in] ImageHandle    The firmware allocated handle for the EFI image.
 | |
|   @param[in] SystemTable    A pointer to the EFI System Table.
 | |
| 
 | |
|   @retval EFI_SUCCESS       The entry point is executed successfully.
 | |
|   @retval other             Some error occurs when executing this entry point.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| UefiMain (
 | |
|   IN EFI_HANDLE        ImageHandle,
 | |
|   IN EFI_SYSTEM_TABLE  *SystemTable
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
| 
 | |
|   Status = GetUefiMemoryProfileData ();
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     DEBUG ((DEBUG_ERROR, "GetUefiMemoryProfileData - %r\n", Status));
 | |
|   }
 | |
| 
 | |
|   Status = GetSmramProfileData ();
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     DEBUG ((DEBUG_ERROR, "GetSmramProfileData - %r\n", Status));
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 |