Cc: Jiewen Yao <jiewen....@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Star Zeng <star.z...@intel.com>
Reviewed-by: Jiewen Yao <jiewen....@intel.com>
---
 .../MemoryProfileInfo/MemoryProfileInfo.c          | 884 +++++++++++++++++----
 .../MemoryProfileInfo/MemoryProfileInfo.inf        |   3 +-
 2 files changed, 725 insertions(+), 162 deletions(-)

diff --git a/MdeModulePkg/Application/MemoryProfileInfo/MemoryProfileInfo.c 
b/MdeModulePkg/Application/MemoryProfileInfo/MemoryProfileInfo.c
index ea2a00bd8340..48d8f4657ba6 100644
--- a/MdeModulePkg/Application/MemoryProfileInfo/MemoryProfileInfo.c
+++ b/MdeModulePkg/Application/MemoryProfileInfo/MemoryProfileInfo.c
@@ -1,17 +1,16 @@
 /** @file
-  
+
   Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>
-  This program and the accompanying materials                          
-  are licensed and made available under the terms and conditions of the BSD 
License         
-  which accompanies this distribution.  The full text of the license may be 
found at        
-  http://opensource.org/licenses/bsd-license.php                               
             
+  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.             
+  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 <Base.h>
 #include <Uefi.h>
 #include <PiDxe.h>
 #include <Library/BaseLib.h>
@@ -23,7 +22,6 @@
 #include <Library/UefiRuntimeServicesTableLib.h>
 #include <Library/DebugLib.h>
 #include <Library/DxeServicesLib.h>
-#include <Library/PeCoffGetEntryPointLib.h>
 #include <Library/PrintLib.h>
 
 #include <Protocol/SmmCommunication.h>
@@ -33,126 +31,202 @@
 #include <Guid/MemoryProfile.h>
 #include <Guid/PiSmmCommunicationRegionTable.h>
 
-CHAR16 *mActionString[] = {
-  L"Unknown",
-  L"AllocatePages",
-  L"FreePages",
-  L"AllocatePool",
-  L"FreePool",
+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"},
 };
 
-CHAR16 *mMemoryTypeString[] = {
-  L"EfiReservedMemoryType",
-  L"EfiLoaderCode",
-  L"EfiLoaderData",
-  L"EfiBootServicesCode",
-  L"EfiBootServicesData",
-  L"EfiRuntimeServicesCode",
-  L"EfiRuntimeServicesData",
-  L"EfiConventionalMemory",
-  L"EfiUnusableMemory",
-  L"EfiACPIReclaimMemory",
-  L"EfiACPIMemoryNVS",
-  L"EfiMemoryMappedIO",
-  L"EfiMemoryMappedIOPortSpace",
-  L"EfiPalCode",
-  L"EfiPersistentMemory",
-  L"EfiOSReserved",
-  L"EfiOemReserved",
+CHAR8 mUserDefinedActionString[] = {"UserDefined-0x80000000"};
+
+CHAR8 *mMemoryTypeString[] = {
+  "EfiReservedMemoryType",
+  "EfiLoaderCode",
+  "EfiLoaderData",
+  "EfiBootServicesCode",
+  "EfiBootServicesData",
+  "EfiRuntimeServicesCode",
+  "EfiRuntimeServicesData",
+  "EfiConventionalMemory",
+  "EfiUnusableMemory",
+  "EfiACPIReclaimMemory",
+  "EfiACPIMemoryNVS",
+  "EfiMemoryMappedIO",
+  "EfiMemoryMappedIOPortSpace",
+  "EfiPalCode",
+  "EfiPersistentMemory",
+  "EfiOSReserved",
+  "EfiOemReserved",
 };
 
-CHAR16 *mSubsystemString[] = {
-  L"Unknown",
-  L"NATIVE",
-  L"WINDOWS_GUI",
-  L"WINDOWS_CUI",
-  L"Unknown",
-  L"Unknown",
-  L"Unknown",
-  L"POSIX_CUI",
-  L"Unknown",
-  L"WINDOWS_CE_GUI",
-  L"EFI_APPLICATION",
-  L"EFI_BOOT_SERVICE_DRIVER",
-  L"EFI_RUNTIME_DRIVER",
-  L"EFI_ROM",
-  L"XBOX",
-  L"Unknown",
+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",
 };
 
-CHAR16 *mFileTypeString[] = {
-  L"Unknown",
-  L"RAW",
-  L"FREEFORM",
-  L"SECURITY_CORE",
-  L"PEI_CORE",
-  L"DXE_CORE",
-  L"PEIM",
-  L"DRIVER",
-  L"COMBINED_PEIM_DRIVER",
-  L"APPLICATION",
-  L"SMM",
-  L"FIRMWARE_VOLUME_IMAGE",
-  L"COMBINED_SMM_DXE",
-  L"SMM_CORE",
+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  36
-CHAR16 mNameString[PROFILE_NAME_STRING_LENGTH + 1];
+#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 converted
-  to Unicode and copied into UnicodeBuffer.  The name is truncated,
-  if necessary, to ensure that UnicodeBuffer is not overrun.
-  
+  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] UnicodeBuffer   The resultant Unicode File Name.
-  
+  @param[out] AsciiBuffer     The resultant Ascii File Name.
+
 **/
 VOID
 GetShortPdbFileName (
   IN  CHAR8     *PdbFileName,
-  OUT CHAR16    *UnicodeBuffer
+  OUT CHAR8     *AsciiBuffer
   )
 {
-  UINTN IndexA;     // Current work location within an ASCII string.
-  UINTN IndexU;     // Current work location within a Unicode string.
+  UINTN IndexPdb;     // Current work location within a Pdb string.
+  UINTN IndexBuffer;  // Current work location within a Buffer string.
   UINTN StartIndex;
   UINTN EndIndex;
 
-  ZeroMem (UnicodeBuffer, (PROFILE_NAME_STRING_LENGTH + 1) * sizeof (CHAR16));
+  ZeroMem (AsciiBuffer, PROFILE_NAME_STRING_LENGTH + 1);
 
   if (PdbFileName == NULL) {
-    StrnCpyS (UnicodeBuffer, PROFILE_NAME_STRING_LENGTH + 1, L" ", 1);
+    AsciiStrnCpyS (AsciiBuffer, PROFILE_NAME_STRING_LENGTH + 1, " ", 1);
   } else {
     StartIndex = 0;
     for (EndIndex = 0; PdbFileName[EndIndex] != 0; EndIndex++);
-    for (IndexA = 0; PdbFileName[IndexA] != 0; IndexA++) {
-      if (PdbFileName[IndexA] == '\\') {
-        StartIndex = IndexA + 1;
+    for (IndexPdb = 0; PdbFileName[IndexPdb] != 0; IndexPdb++) {
+      if (PdbFileName[IndexPdb] == '\\') {
+        StartIndex = IndexPdb + 1;
       }
 
-      if (PdbFileName[IndexA] == '.') {
-        EndIndex = IndexA;
+      if (PdbFileName[IndexPdb] == '.') {
+        EndIndex = IndexPdb;
       }
     }
 
-    IndexU = 0;
-    for (IndexA = StartIndex; IndexA < EndIndex; IndexA++) {
-      UnicodeBuffer[IndexU] = (CHAR16) PdbFileName[IndexA];
-      IndexU++;
-      if (IndexU >= PROFILE_NAME_STRING_LENGTH) {
-        UnicodeBuffer[PROFILE_NAME_STRING_LENGTH] = 0;
+    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
@@ -161,29 +235,24 @@ GetShortPdbFileName (
 
   @param[in] DriverInfo Pointer to memory profile driver info.
 
-  @post The resulting Unicode name string is stored in the mNameString global 
array.
+  @return The resulting Ascii name string is stored in the mNameString global 
array.
 
 **/
-VOID
+CHAR8 *
 GetDriverNameString (
  IN MEMORY_PROFILE_DRIVER_INFO  *DriverInfo
  )
 {
   EFI_STATUS                  Status;
-  CHAR8                       *PdbFileName;
   CHAR16                      *NameString;
   UINTN                       StringSize;
 
   //
   // Method 1: Get the name string from image PDB
   //
-  if ((DriverInfo->ImageBase != 0) && (DriverInfo->FileType != 
EFI_FV_FILETYPE_SMM) && (DriverInfo->FileType != EFI_FV_FILETYPE_SMM_CORE)) {
-    PdbFileName = PeCoffLoaderGetPdbPointer ((VOID *) (UINTN) 
DriverInfo->ImageBase);
-
-    if (PdbFileName != NULL) {
-      GetShortPdbFileName (PdbFileName, mNameString);
-      return;
-    }
+  if (DriverInfo->Header.Length > sizeof (MEMORY_PROFILE_DRIVER_INFO)) {
+    GetShortPdbFileName ((CHAR8 *) (DriverInfo + 1), mNameString);
+    return mNameString;
   }
 
   if (!CompareGuid (&DriverInfo->FileName, &gZeroGuid)) {
@@ -203,17 +272,20 @@ GetDriverNameString (
       //
       // Method 2: Get the name string from FFS UI section
       //
-      StrnCpyS (mNameString, PROFILE_NAME_STRING_LENGTH + 1, NameString, 
PROFILE_NAME_STRING_LENGTH);
-      mNameString[PROFILE_NAME_STRING_LENGTH] = 0;
+      if (StrLen (NameString) > PROFILE_NAME_STRING_LENGTH) {
+        NameString[PROFILE_NAME_STRING_LENGTH] = 0;
+      }
+      UnicodeStrToAsciiStrS (NameString, mNameString, sizeof (mNameString));
       FreePool (NameString);
-      return;
+      return mNameString;
     }
   }
 
   //
   // Method 3: Get the name string from image GUID
   //
-  UnicodeSPrint (mNameString, sizeof (mNameString), L"%g", 
&DriverInfo->FileName);
+  AsciiSPrint (mNameString, sizeof (mNameString), "%g", &DriverInfo->FileName);
+  return mNameString;
 }
 
 /**
@@ -224,7 +296,7 @@ GetDriverNameString (
   @return Pointer to string.
 
 **/
-CHAR16 *
+CHAR8 *
 ProfileMemoryTypeToStr (
   IN EFI_MEMORY_TYPE    MemoryType
   )
@@ -249,11 +321,62 @@ ProfileMemoryTypeToStr (
 }
 
 /**
+  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 = sizeof (mSmmActionString) / sizeof 
(mSmmActionString[0]);
+  } else {
+    ActionString = mActionString;
+    ActionStringCount = sizeof (mActionString) / sizeof (mActionString[0]);
+  }
+
+  if ((UINTN) (UINT32) Action < ActionStringCount) {
+    return ActionString[Action];
+  }
+  for (Index = 0; Index < sizeof (mExtActionString) / sizeof 
(mExtActionString[0]); 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.
 
@@ -262,20 +385,30 @@ MEMORY_PROFILE_ALLOC_INFO *
 DumpMemoryProfileAllocInfo (
   IN MEMORY_PROFILE_DRIVER_INFO *DriverInfo,
   IN UINTN                      AllocIndex,
-  IN MEMORY_PROFILE_ALLOC_INFO  *AllocInfo
+  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"      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 (%s)\n", AllocInfo->Action, 
mActionString[(AllocInfo->Action < 
sizeof(mActionString)/sizeof(mActionString[0])) ? AllocInfo->Action : 0]);
-  Print (L"      MemoryType    - 0x%08x (%s)\n", AllocInfo->MemoryType, 
ProfileMemoryTypeToStr (AllocInfo->MemoryType));
+  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);
 
@@ -287,6 +420,8 @@ DumpMemoryProfileAllocInfo (
 
   @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.
 
@@ -294,12 +429,14 @@ DumpMemoryProfileAllocInfo (
 MEMORY_PROFILE_DRIVER_INFO *
 DumpMemoryProfileDriverInfo (
   IN UINTN                      DriverIndex,
-  IN MEMORY_PROFILE_DRIVER_INFO *DriverInfo
+  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;
@@ -307,28 +444,31 @@ DumpMemoryProfileDriverInfo (
   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);  
-  GetDriverNameString (DriverInfo);
-  Print (L"    FileName                - %s\n", &mNameString);
+  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 (%s)\n", 
DriverInfo->ImageSubsystem, mSubsystemString[(DriverInfo->ImageSubsystem < 
sizeof(mSubsystemString)/sizeof(mSubsystemString[0])) ? 
DriverInfo->ImageSubsystem : 0]);
-  Print (L"    FileType                - 0x%02x (%s)\n", DriverInfo->FileType, 
mFileTypeString[(DriverInfo->FileType < 
sizeof(mFileTypeString)/sizeof(mFileTypeString[0])) ? DriverInfo->FileType : 
0]);
+  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 (%s)\n", TypeIndex, 
DriverInfo->CurrentUsageByType[TypeIndex], mMemoryTypeString[TypeIndex]);
-      Print (L"    PeakUsage[0x%02x]         - 0x%016lx (%s)\n", TypeIndex, 
DriverInfo->PeakUsageByType[TypeIndex], mMemoryTypeString[TypeIndex]);
+      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);
+    AllocInfo = DumpMemoryProfileAllocInfo (DriverInfo, AllocIndex, AllocInfo, 
IsForSmm);
     if (AllocInfo == NULL) {
       return NULL;
     }
@@ -340,13 +480,16 @@ DumpMemoryProfileDriverInfo (
   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 MEMORY_PROFILE_CONTEXT     *Context,
+  IN BOOLEAN                    IsForSmm
   )
 {
   UINTN                         TypeIndex;
@@ -359,14 +502,14 @@ DumpMemoryProfileContext (
   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"  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 (%s)\n", 
TypeIndex, Context->CurrentTotalUsageByType[TypeIndex], 
mMemoryTypeString[TypeIndex]);
-      Print (L"  PeakTotalUsage[0x%02x]          - 0x%016lx (%s)\n", 
TypeIndex, Context->PeakTotalUsageByType[TypeIndex], 
mMemoryTypeString[TypeIndex]);
+      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);
@@ -375,7 +518,7 @@ DumpMemoryProfileContext (
 
   DriverInfo = (MEMORY_PROFILE_DRIVER_INFO *) ((UINTN) Context + 
Context->Header.Length);
   for (DriverIndex = 0; DriverIndex < Context->ImageCount; DriverIndex++) {
-    DriverInfo = DumpMemoryProfileDriverInfo (DriverIndex, DriverInfo);
+    DriverInfo = DumpMemoryProfileDriverInfo (DriverIndex, DriverInfo, 
IsForSmm);
     if (DriverInfo == NULL) {
       return NULL;
     }
@@ -404,7 +547,7 @@ DumpMemoryProfileDescriptor (
   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"    Revision                - 0x%04x\n", 
Descriptor->Header.Revision);
   Print (L"    Address                 - 0x%016lx\n", Descriptor->Address);
   Print (L"    Size                    - 0x%016lx\n", Descriptor->Size);
 
@@ -433,7 +576,7 @@ DumpMemoryProfileFreeMemory (
   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"  Revision                      - 0x%04x\n", 
FreeMemory->Header.Revision);
   Print (L"  TotalFreeMemoryPages          - 0x%016lx\n", 
FreeMemory->TotalFreeMemoryPages);
   Print (L"  FreeMemoryEntryCount          - 0x%08x\n", 
FreeMemory->FreeMemoryEntryCount);
 
@@ -470,7 +613,7 @@ DumpMemoryProfileMemoryRange (
   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"  Revision                      - 0x%04x\n", 
MemoryRange->Header.Revision);
   Print (L"  MemoryRangeCount              - 0x%08x\n", 
MemoryRange->MemoryRangeCount);
 
   Descriptor = (MEMORY_PROFILE_DESCRIPTOR *) ((UINTN) MemoryRange + 
MemoryRange->Header.Length);
@@ -513,6 +656,10 @@ ScanMemoryProfileBySignature (
       //
       return (VOID *) CommonHeader;
     }
+    if (CommonHeader->Length == 0) {
+      ASSERT (FALSE);
+      return NULL;
+    }
     CommonHeader = (MEMORY_PROFILE_COMMON_HEADER *) ((UINTN) CommonHeader + 
CommonHeader->Length);
   }
 
@@ -524,12 +671,15 @@ ScanMemoryProfileBySignature (
 
   @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 UINT64                     ProfileSize,
+  IN BOOLEAN                    IsForSmm
   )
 {
   MEMORY_PROFILE_CONTEXT        *Context;
@@ -538,7 +688,7 @@ DumpMemoryProfile (
 
   Context = (MEMORY_PROFILE_CONTEXT *) ScanMemoryProfileBySignature 
(ProfileBuffer, ProfileSize, MEMORY_PROFILE_CONTEXT_SIGNATURE);
   if (Context != NULL) {
-    DumpMemoryProfileContext (Context);
+    DumpMemoryProfileContext (Context, IsForSmm);
   }
 
   FreeMemory = (MEMORY_PROFILE_FREE_MEMORY *) ScanMemoryProfileBySignature 
(ProfileBuffer, ProfileSize, MEMORY_PROFILE_FREE_MEMORY_SIGNATURE);
@@ -553,6 +703,317 @@ DumpMemoryProfile (
 }
 
 /**
+  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.
@@ -564,10 +1025,12 @@ GetUefiMemoryProfileData (
   VOID
   )
 {
-  EFI_STATUS                    Status;
-  EDKII_MEMORY_PROFILE_PROTOCOL *ProfileProtocol;
-  VOID                          *Data;
-  UINT64                        Size;
+  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)) {
@@ -575,6 +1038,15 @@ GetUefiMemoryProfileData (
     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 (
@@ -584,13 +1056,9 @@ GetUefiMemoryProfileData (
                               );
   if (Status != EFI_BUFFER_TOO_SMALL) {
     Print (L"UefiMemoryProfile: GetData - %r\n", Status);
-    return Status;
+    goto Done;
   }
 
-  //
-  // Add one sizeof (MEMORY_PROFILE_ALLOC_INFO) to Size for this AllocatePool 
action.
-  //
-  Size = Size + sizeof (MEMORY_PROFILE_ALLOC_INFO);
   Data = AllocateZeroPool ((UINTN) Size);
   if (Data == NULL) {
     Status = EFI_OUT_OF_RESOURCES;
@@ -604,20 +1072,39 @@ GetUefiMemoryProfileData (
                               Data
                               );
   if (EFI_ERROR (Status)) {
-    FreePool (Data);
     Print (L"UefiMemoryProfile: GetData - %r\n", Status);
-    return Status;
+    goto Done;
   }
 
 
   Print (L"UefiMemoryProfileSize - 0x%x\n", Size);
   Print (L"======= UefiMemoryProfile begin =======\n");
-  DumpMemoryProfile ((PHYSICAL_ADDRESS) (UINTN) Data, Size);
+  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");
 
-  FreePool (Data);
+Done:
+  if (Data != NULL) {
+    FreePool (Data);
+  }
 
-  return EFI_SUCCESS;
+  //
+  // Restore recording state if needed.
+  //
+  if (RecordingState == MEMORY_PROFILE_RECORDING_ENABLE) {
+    ProfileProtocol->SetRecordingState (ProfileProtocol, 
MEMORY_PROFILE_RECORDING_ENABLE);
+  }
+
+  return Status;
 }
 
 /**
@@ -638,6 +1125,7 @@ GetSmramProfileData (
   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;
@@ -648,6 +1136,10 @@ GetSmramProfileData (
   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)) {
@@ -658,7 +1150,8 @@ GetSmramProfileData (
   MinimalSizeNeeded = sizeof (EFI_GUID) +
                       sizeof (UINTN) +
                       MAX (sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO),
-                           sizeof 
(SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET));
+                           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),
@@ -690,6 +1183,48 @@ GetSmramProfileData (
   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 ((EFI_D_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];
@@ -704,14 +1239,12 @@ GetSmramProfileData (
 
   CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + CommHeader->MessageLength;
   Status = SmmCommunication->Communicate (SmmCommunication, CommBuffer, 
&CommSize);
-  if (EFI_ERROR (Status)) {
-    DEBUG ((EFI_D_ERROR, "SmramProfile: SmmCommunication - %r\n", Status));
-    return Status;
-  }
+  ASSERT_EFI_ERROR (Status);
 
   if (CommGetProfileInfo->Header.ReturnStatus != 0) {
+    Status = EFI_SUCCESS;
     Print (L"SmramProfile: GetProfileInfo - 0x%0x\n", 
CommGetProfileInfo->Header.ReturnStatus);
-    return EFI_SUCCESS;
+    goto Done;
   }
 
   ProfileSize = (UINTN) CommGetProfileInfo->ProfileSize;
@@ -720,10 +1253,10 @@ GetSmramProfileData (
   // Get Data
   //
   ProfileBuffer = AllocateZeroPool (ProfileSize);
-  if (ProfileBuffer == 0) {
+  if (ProfileBuffer == NULL) {
     Status = EFI_OUT_OF_RESOURCES;
     Print (L"SmramProfile: AllocateZeroPool (0x%x) for profile buffer - %r\n", 
ProfileSize, Status);
-    return Status;
+    goto Done;
   }
 
   CommHeader = (EFI_SMM_COMMUNICATE_HEADER *) &CommBuffer[0];
@@ -752,9 +1285,9 @@ GetSmramProfileData (
     ASSERT_EFI_ERROR (Status);
 
     if (CommGetProfileData->Header.ReturnStatus != 0) {
-      FreePool (ProfileBuffer);
+      Status = EFI_SUCCESS;
       Print (L"GetProfileData - 0x%x\n", 
CommGetProfileData->Header.ReturnStatus);
-      return EFI_SUCCESS;
+      goto Done;
     }
     CopyMem ((UINT8 *) ProfileBuffer + Offset, (VOID *) (UINTN) 
CommGetProfileData->ProfileBuffer, (UINTN) CommGetProfileData->ProfileSize);
   }
@@ -762,21 +1295,52 @@ GetSmramProfileData (
 
   Print (L"SmramProfileSize - 0x%x\n", ProfileSize);
   Print (L"======= SmramProfile begin =======\n");
-  DumpMemoryProfile ((PHYSICAL_ADDRESS) (UINTN) ProfileBuffer, ProfileSize);
+  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");
 
-  FreePool (ProfileBuffer);
+Done:
+  if (ProfileBuffer != NULL) {
+    FreePool (ProfileBuffer);
+  }
 
-  return EFI_SUCCESS;
+  //
+  // 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] 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.
 
@@ -788,7 +1352,7 @@ UefiMain (
   IN EFI_SYSTEM_TABLE   *SystemTable
   )
 {
-  EFI_STATUS                    Status;
+  EFI_STATUS                     Status;
 
   Status = GetUefiMemoryProfileData ();
   if (EFI_ERROR (Status)) {
diff --git a/MdeModulePkg/Application/MemoryProfileInfo/MemoryProfileInfo.inf 
b/MdeModulePkg/Application/MemoryProfileInfo/MemoryProfileInfo.inf
index a1bc6752f02c..c512a3f65133 100644
--- a/MdeModulePkg/Application/MemoryProfileInfo/MemoryProfileInfo.inf
+++ b/MdeModulePkg/Application/MemoryProfileInfo/MemoryProfileInfo.inf
@@ -46,9 +46,8 @@ [LibraryClasses]
   UefiLib
   MemoryAllocationLib
   DxeServicesLib
-  PeCoffGetEntryPointLib
   PrintLib
-  
+
 [Guids]
   ## SOMETIMES_CONSUMES   ## GUID # Locate protocol
   ## SOMETIMES_CONSUMES   ## GUID # SmiHandlerRegister
-- 
2.7.0.windows.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to