]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Application/MemoryProfileInfo/MemoryProfileInfo.c
MdeModulePkg-MemoryProfile(3): Use SMRAM_PROFILE_COMMAND_GET_PROFILE_DATA_BY_OFFSET...
[mirror_edk2.git] / MdeModulePkg / Application / MemoryProfileInfo / MemoryProfileInfo.c
index f69a3e77486a82368f127e42b5280fb2c3608865..ea2a00bd8340a42315720111468dd6b52b844f73 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
   \r
-  Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials                          \r
   are licensed and made available under the terms and conditions of the BSD License         \r
   which accompanies this distribution.  The full text of the license may be found at        \r
@@ -11,6 +11,7 @@
 \r
 **/\r
 \r
+#include <Base.h>\r
 #include <Uefi.h>\r
 #include <PiDxe.h>\r
 #include <Library/BaseLib.h>\r
@@ -30,6 +31,7 @@
 \r
 #include <Guid/ZeroGuid.h>\r
 #include <Guid/MemoryProfile.h>\r
+#include <Guid/PiSmmCommunicationRegionTable.h>\r
 \r
 CHAR16 *mActionString[] = {\r
   L"Unknown",\r
@@ -635,10 +637,17 @@ GetSmramProfileData (
   UINT8                                         *CommBuffer;\r
   EFI_SMM_COMMUNICATE_HEADER                    *CommHeader;\r
   SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO      *CommGetProfileInfo;\r
-  SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA      *CommGetProfileData;\r
-  UINT64                                        ProfileSize;\r
-  PHYSICAL_ADDRESS                              ProfileBuffer;\r
+  SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET *CommGetProfileData;\r
+  UINT                                        ProfileSize;\r
+  VOID                                          *ProfileBuffer;\r
   EFI_SMM_COMMUNICATION_PROTOCOL                *SmmCommunication;\r
+  UINTN                                         MinimalSizeNeeded;\r
+  EDKII_PI_SMM_COMMUNICATION_REGION_TABLE       *PiSmmCommunicationRegionTable;\r
+  UINT32                                        Index;\r
+  EFI_MEMORY_DESCRIPTOR                         *Entry;\r
+  VOID                                          *Buffer;\r
+  UINTN                                         Size;\r
+  UINTN                                         Offset;\r
 \r
   Status = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &SmmCommunication);\r
   if (EFI_ERROR (Status)) {\r
@@ -646,13 +655,39 @@ GetSmramProfileData (
     return Status;\r
   }\r
 \r
-  CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA);\r
-  CommBuffer = AllocateZeroPool (CommSize);\r
-  if (CommBuffer == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    Print (L"SmramProfile: AllocateZeroPool (0x%x) for comm buffer - %r\n", CommSize, Status);\r
+  MinimalSizeNeeded = sizeof (EFI_GUID) +\r
+                      sizeof (UINTN) +\r
+                      MAX (sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_INFO),\r
+                           sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET));\r
+  MinimalSizeNeeded += MAX (sizeof (MEMORY_PROFILE_CONTEXT),\r
+                            MAX (sizeof (MEMORY_PROFILE_DRIVER_INFO),\r
+                                 MAX (sizeof (MEMORY_PROFILE_ALLOC_INFO),\r
+                                      MAX (sizeof (MEMORY_PROFILE_DESCRIPTOR),\r
+                                           MAX (sizeof (MEMORY_PROFILE_FREE_MEMORY),\r
+                                                sizeof (MEMORY_PROFILE_MEMORY_RANGE))))));\r
+\r
+  Status = EfiGetSystemConfigurationTable (\r
+             &gEdkiiPiSmmCommunicationRegionTableGuid,\r
+             (VOID **) &PiSmmCommunicationRegionTable\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_ERROR, "SmramProfile: Get PiSmmCommunicationRegionTable - %r\n", Status));\r
     return Status;\r
   }\r
+  ASSERT (PiSmmCommunicationRegionTable != NULL);\r
+  Entry = (EFI_MEMORY_DESCRIPTOR *) (PiSmmCommunicationRegionTable + 1);\r
+  Size = 0;\r
+  for (Index = 0; Index < PiSmmCommunicationRegionTable->NumberOfEntries; Index++) {\r
+    if (Entry->Type == EfiConventionalMemory) {\r
+      Size = EFI_PAGES_TO_SIZE ((UINTN) Entry->NumberOfPages);\r
+      if (Size >= MinimalSizeNeeded) {\r
+        break;\r
+      }\r
+    }\r
+    Entry = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) Entry + PiSmmCommunicationRegionTable->DescriptorSize);\r
+  }\r
+  ASSERT (Index < PiSmmCommunicationRegionTable->NumberOfEntries);\r
+  CommBuffer = (UINT8 *) (UINTN) Entry->PhysicalStart;\r
 \r
   //\r
   // Get Size\r
@@ -670,7 +705,6 @@ GetSmramProfileData (
   CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + CommHeader->MessageLength;\r
   Status = SmmCommunication->Communicate (SmmCommunication, CommBuffer, &CommSize);\r
   if (EFI_ERROR (Status)) {\r
-    FreePool (CommBuffer);\r
     DEBUG ((EFI_D_ERROR, "SmramProfile: SmmCommunication - %r\n", Status));\r
     return Status;\r
   }\r
@@ -680,49 +714,58 @@ GetSmramProfileData (
     return EFI_SUCCESS;\r
   }\r
 \r
-  ProfileSize = CommGetProfileInfo->ProfileSize;\r
+  ProfileSize = (UINTN) CommGetProfileInfo->ProfileSize;\r
 \r
   //\r
   // Get Data\r
   //\r
-  ProfileBuffer = (PHYSICAL_ADDRESS) (UINTN) AllocateZeroPool ((UINTN) ProfileSize);\r
+  ProfileBuffer = AllocateZeroPool (ProfileSize);\r
   if (ProfileBuffer == 0) {\r
-    FreePool (CommBuffer);\r
     Status = EFI_OUT_OF_RESOURCES;\r
-    Print (L"SmramProfile: AllocateZeroPool (0x%x) for profile buffer - %r\n", (UINTN) ProfileSize, Status);\r
+    Print (L"SmramProfile: AllocateZeroPool (0x%x) for profile buffer - %r\n", ProfileSize, Status);\r
     return Status;\r
   }\r
 \r
   CommHeader = (EFI_SMM_COMMUNICATE_HEADER *) &CommBuffer[0];\r
   CopyMem (&CommHeader->HeaderGuid, &gEdkiiMemoryProfileGuid, sizeof(gEdkiiMemoryProfileGuid));\r
-  CommHeader->MessageLength = sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA);\r
+  CommHeader->MessageLength = sizeof (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET);\r
 \r
-  CommGetProfileData = (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA *) &CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)];\r
-  CommGetProfileData->Header.Command      = SMRAM_PROFILE_COMMAND_GET_PROFILE_DATA;\r
+  CommGetProfileData = (SMRAM_PROFILE_PARAMETER_GET_PROFILE_DATA_BY_OFFSET *) &CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)];\r
+  CommGetProfileData->Header.Command      = SMRAM_PROFILE_COMMAND_GET_PROFILE_DATA_BY_OFFSET;\r
   CommGetProfileData->Header.DataLength   = sizeof (*CommGetProfileData);\r
   CommGetProfileData->Header.ReturnStatus = (UINT64)-1;\r
-  CommGetProfileData->ProfileSize         = ProfileSize;\r
-  CommGetProfileData->ProfileBuffer       = ProfileBuffer;\r
 \r
   CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + CommHeader->MessageLength;\r
-  Status = SmmCommunication->Communicate (SmmCommunication, CommBuffer, &CommSize);\r
-  ASSERT_EFI_ERROR (Status);\r
+  Buffer = (UINT8 *) CommHeader + CommSize;\r
+  Size -= CommSize;\r
+\r
+  CommGetProfileData->ProfileBuffer       = (PHYSICAL_ADDRESS) (UINTN) Buffer;\r
+  CommGetProfileData->ProfileOffset       = 0;\r
+  while (CommGetProfileData->ProfileOffset < ProfileSize) {\r
+    Offset = (UINTN) CommGetProfileData->ProfileOffset;\r
+    if (Size <= (ProfileSize - CommGetProfileData->ProfileOffset)) {\r
+      CommGetProfileData->ProfileSize = (UINT64) Size;\r
+    } else {\r
+      CommGetProfileData->ProfileSize = (UINT64) (ProfileSize - CommGetProfileData->ProfileOffset);\r
+    }\r
+    Status = SmmCommunication->Communicate (SmmCommunication, CommBuffer, &CommSize);\r
+    ASSERT_EFI_ERROR (Status);\r
 \r
-  if (CommGetProfileData->Header.ReturnStatus != 0) {\r
-    FreePool ((VOID *) (UINTN) CommGetProfileData->ProfileBuffer);\r
-    FreePool (CommBuffer);\r
-    Print (L"GetProfileData - 0x%x\n", CommGetProfileData->Header.ReturnStatus);\r
-    return EFI_SUCCESS;\r
+    if (CommGetProfileData->Header.ReturnStatus != 0) {\r
+      FreePool (ProfileBuffer);\r
+      Print (L"GetProfileData - 0x%x\n", CommGetProfileData->Header.ReturnStatus);\r
+      return EFI_SUCCESS;\r
+    }\r
+    CopyMem ((UINT8 *) ProfileBuffer + Offset, (VOID *) (UINTN) CommGetProfileData->ProfileBuffer, (UINTN) CommGetProfileData->ProfileSize);\r
   }\r
 \r
 \r
-  Print (L"SmramProfileSize - 0x%x\n", CommGetProfileData->ProfileSize);\r
+  Print (L"SmramProfileSize - 0x%x\n", ProfileSize);\r
   Print (L"======= SmramProfile begin =======\n");\r
-  DumpMemoryProfile (CommGetProfileData->ProfileBuffer, CommGetProfileData->ProfileSize);\r
+  DumpMemoryProfile ((PHYSICAL_ADDRESS) (UINTN) ProfileBuffer, ProfileSize);\r
   Print (L"======= SmramProfile end =======\n\n\n");\r
 \r
-  FreePool ((VOID *) (UINTN) CommGetProfileData->ProfileBuffer);\r
-  FreePool (CommBuffer);\r
+  FreePool (ProfileBuffer);\r
 \r
   return EFI_SUCCESS;\r
 }\r