This patch enhance performance data SMM communication by using fixed
SMM communication buffer.

Update PerformanceLib to use fixed SMM communication buffer to get
performance data by SMM_FPDT_FUNCTION_GET_BOOT_RECORD_DATA_BY_OFFSET API.

This is designed to meet Microsoft WSMT table definition on FIXED_COMM_BUFFERS
requirement.

Cc: "Gao, Liming" <[email protected]>
Cc: "Tian, Feng" <[email protected]>
Cc: "Laszlo Ersek" <[email protected]>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: "Gao, Liming" <[email protected]>
Reviewed-by: "Tian, Feng" <[email protected]>
---
 .../DxeSmmPerformanceLib/DxeSmmPerformanceLib.c    | 154 ++++++++++++++++-----
 .../DxeSmmPerformanceLib/DxeSmmPerformanceLib.inf  |   3 +-
 2 files changed, 122 insertions(+), 35 deletions(-)

diff --git a/MdeModulePkg/Library/DxeSmmPerformanceLib/DxeSmmPerformanceLib.c 
b/MdeModulePkg/Library/DxeSmmPerformanceLib/DxeSmmPerformanceLib.c
index 218cf8b..d8d0684 100644
--- a/MdeModulePkg/Library/DxeSmmPerformanceLib/DxeSmmPerformanceLib.c
+++ b/MdeModulePkg/Library/DxeSmmPerformanceLib/DxeSmmPerformanceLib.c
@@ -32,10 +32,13 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER 
EXPRESS OR IMPLIED.
 
 #include <Protocol/SmmCommunication.h>
 
+#include <Guid/PiSmmCommunicationRegionTable.h>
+#include <Library/UefiLib.h>
+
 #define SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE (OFFSET_OF 
(EFI_SMM_COMMUNICATE_HEADER, Data)  + sizeof (SMM_PERF_COMMUNICATE))
 
 EFI_SMM_COMMUNICATION_PROTOCOL  *mSmmCommunication = NULL;
-UINT8                           
mSmmPerformanceBuffer[SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE];
+UINT8                           *mSmmPerformanceBuffer;
 GAUGE_DATA_ENTRY                *mGaugeData = NULL;
 UINTN                           mGaugeNumberOfEntries = 0;
 GAUGE_DATA_ENTRY_EX             *mGaugeDataEx = NULL;
@@ -383,11 +386,18 @@ GetAllSmmGaugeData (
   IN UINTN      LogEntryKey
   )
 {
-  EFI_STATUS                  Status;
-  EFI_SMM_COMMUNICATE_HEADER  *SmmCommBufferHeader;
-  SMM_PERF_COMMUNICATE        *SmmPerfCommData;
-  UINTN                       CommSize;
-  UINTN                       DataSize;
+  EFI_STATUS                                Status;
+  EFI_SMM_COMMUNICATE_HEADER                *SmmCommBufferHeader;
+  SMM_PERF_COMMUNICATE                      *SmmPerfCommData;
+  UINTN                                     CommSize;
+  UINTN                                     DataSize;
+  EDKII_PI_SMM_COMMUNICATION_REGION_TABLE   *PiSmmCommunicationRegionTable;
+  UINT32                                    Index;
+  EFI_MEMORY_DESCRIPTOR                     *Entry;
+  UINT8                                     *Buffer;
+  UINTN                                     Size;
+  UINTN                                     NumberOfEntries;
+  UINTN                                     EntriesGot;
 
   if (mNoSmmPerfHandler) {
     //
@@ -417,6 +427,28 @@ GetAllSmmGaugeData (
     return NULL;
   }
 
+  Status = EfiGetSystemConfigurationTable (
+             &gEdkiiPiSmmCommunicationRegionTableGuid,
+             (VOID **) &PiSmmCommunicationRegionTable
+             );
+  if (EFI_ERROR (Status)) {
+    return NULL;
+  }
+  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 >= (SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE + sizeof 
(GAUGE_DATA_ENTRY))) {
+        break;
+      }
+    }
+    Entry = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) Entry + 
PiSmmCommunicationRegionTable->DescriptorSize);
+  }
+  ASSERT (Index < PiSmmCommunicationRegionTable->NumberOfEntries);
+  mSmmPerformanceBuffer = (UINT8 *) (UINTN) Entry->PhysicalStart;
+
   //
   // Initialize communicate buffer 
   //
@@ -441,24 +473,37 @@ GetAllSmmGaugeData (
   }
 
   mGaugeNumberOfEntries = SmmPerfCommData->NumberOfEntries;
-  
+
+  Buffer = mSmmPerformanceBuffer + SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE;
+  NumberOfEntries = (Size - SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE) / 
sizeof (GAUGE_DATA_ENTRY);
   DataSize = mGaugeNumberOfEntries * sizeof(GAUGE_DATA_ENTRY);
   mGaugeData = AllocateZeroPool(DataSize);
   ASSERT (mGaugeData != NULL);
-  
+
   //
   // Get all SMM gauge data
   //  
   SmmPerfCommData->Function = SMM_PERF_FUNCTION_GET_GAUGE_DATA;
-  SmmPerfCommData->LogEntryKey = 0;
-  SmmPerfCommData->NumberOfEntries = mGaugeNumberOfEntries;
-  SmmPerfCommData->GaugeData = mGaugeData;
-  Status = mSmmCommunication->Communicate (mSmmCommunication, 
mSmmPerformanceBuffer, &CommSize);
-  if (EFI_ERROR (Status) || EFI_ERROR (SmmPerfCommData->ReturnStatus)) {
-    FreePool (mGaugeData);
-    mGaugeData = NULL;
-    mGaugeNumberOfEntries = 0;
-  }
+  SmmPerfCommData->GaugeData = (GAUGE_DATA_ENTRY *) Buffer;
+  EntriesGot = 0;
+  do {
+    SmmPerfCommData->LogEntryKey = EntriesGot;
+    if ((mGaugeNumberOfEntries - EntriesGot) >= NumberOfEntries) {
+      SmmPerfCommData->NumberOfEntries = NumberOfEntries;
+    } else {
+      SmmPerfCommData->NumberOfEntries = mGaugeNumberOfEntries - EntriesGot;
+    }
+    Status = mSmmCommunication->Communicate (mSmmCommunication, 
mSmmPerformanceBuffer, &CommSize);
+    if (EFI_ERROR (Status) || EFI_ERROR (SmmPerfCommData->ReturnStatus)) {
+      FreePool (mGaugeData);
+      mGaugeData = NULL;
+      mGaugeNumberOfEntries = 0;
+      return NULL;
+    } else {
+      CopyMem (&mGaugeData[EntriesGot], Buffer, 
SmmPerfCommData->NumberOfEntries * sizeof (GAUGE_DATA_ENTRY));
+    }
+    EntriesGot += SmmPerfCommData->NumberOfEntries;
+  } while (EntriesGot < mGaugeNumberOfEntries);
 
   return mGaugeData;
 }
@@ -481,11 +526,18 @@ GetAllSmmGaugeDataEx (
   IN UINTN      LogEntryKey
   )
 {
-  EFI_STATUS                  Status;
-  EFI_SMM_COMMUNICATE_HEADER  *SmmCommBufferHeader;
-  SMM_PERF_COMMUNICATE_EX     *SmmPerfCommData;
-  UINTN                       CommSize;
-  UINTN                       DataSize;
+  EFI_STATUS                                Status;
+  EFI_SMM_COMMUNICATE_HEADER                *SmmCommBufferHeader;
+  SMM_PERF_COMMUNICATE_EX                   *SmmPerfCommData;
+  UINTN                                     CommSize;
+  UINTN                                     DataSize;
+  EDKII_PI_SMM_COMMUNICATION_REGION_TABLE   *PiSmmCommunicationRegionTable;
+  UINT32                                    Index;
+  EFI_MEMORY_DESCRIPTOR                     *Entry;
+  UINT8                                     *Buffer;
+  UINTN                                     Size;
+  UINTN                                     NumberOfEntries;
+  UINTN                                     EntriesGot;
 
   if (mNoSmmPerfExHandler) {
     //
@@ -515,6 +567,27 @@ GetAllSmmGaugeDataEx (
     return NULL;
   }
 
+  Status = EfiGetSystemConfigurationTable (
+             &gEdkiiPiSmmCommunicationRegionTableGuid,
+             (VOID **) &PiSmmCommunicationRegionTable
+             );
+  if (EFI_ERROR (Status)) {
+    return NULL;
+  }
+  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 >= (SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE + sizeof 
(GAUGE_DATA_ENTRY_EX))) {
+        break;
+      }
+    }
+    Entry = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) Entry + 
PiSmmCommunicationRegionTable->DescriptorSize);
+  }
+  ASSERT (Index < PiSmmCommunicationRegionTable->NumberOfEntries);
+  mSmmPerformanceBuffer = (UINT8 *) (UINTN) Entry->PhysicalStart;
   //
   // Initialize communicate buffer 
   //
@@ -539,25 +612,38 @@ GetAllSmmGaugeDataEx (
   }
 
   mGaugeNumberOfEntriesEx = SmmPerfCommData->NumberOfEntries;
-  
+
+  Buffer = mSmmPerformanceBuffer + SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE;
+  NumberOfEntries = (Size - SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE) / 
sizeof (GAUGE_DATA_ENTRY_EX);
   DataSize = mGaugeNumberOfEntriesEx * sizeof(GAUGE_DATA_ENTRY_EX);
   mGaugeDataEx = AllocateZeroPool(DataSize);
   ASSERT (mGaugeDataEx != NULL);
-  
+
   //
   // Get all SMM gauge data
   //  
   SmmPerfCommData->Function = SMM_PERF_FUNCTION_GET_GAUGE_DATA;
-  SmmPerfCommData->LogEntryKey = 0;
-  SmmPerfCommData->NumberOfEntries = mGaugeNumberOfEntriesEx;
-  SmmPerfCommData->GaugeDataEx = mGaugeDataEx;
-  Status = mSmmCommunication->Communicate (mSmmCommunication, 
mSmmPerformanceBuffer, &CommSize);
-  if (EFI_ERROR (Status) || EFI_ERROR (SmmPerfCommData->ReturnStatus)) {
-    FreePool (mGaugeDataEx);
-    mGaugeDataEx = NULL;
-    mGaugeNumberOfEntriesEx = 0;
-  }
- 
+  SmmPerfCommData->GaugeDataEx = (GAUGE_DATA_ENTRY_EX *) Buffer;
+  EntriesGot = 0;
+  do {
+    SmmPerfCommData->LogEntryKey = EntriesGot;
+    if ((mGaugeNumberOfEntriesEx - EntriesGot) >= NumberOfEntries) {
+      SmmPerfCommData->NumberOfEntries = NumberOfEntries;
+    } else {
+      SmmPerfCommData->NumberOfEntries = mGaugeNumberOfEntriesEx - EntriesGot;
+    }
+    Status = mSmmCommunication->Communicate (mSmmCommunication, 
mSmmPerformanceBuffer, &CommSize);
+    if (EFI_ERROR (Status) || EFI_ERROR (SmmPerfCommData->ReturnStatus)) {
+      FreePool (mGaugeDataEx);
+      mGaugeDataEx = NULL;
+      mGaugeNumberOfEntriesEx = 0;
+      return NULL;
+    } else {
+      CopyMem (&mGaugeDataEx[EntriesGot], Buffer, 
SmmPerfCommData->NumberOfEntries * sizeof (GAUGE_DATA_ENTRY_EX));
+    }
+    EntriesGot += SmmPerfCommData->NumberOfEntries;
+  } while (EntriesGot < mGaugeNumberOfEntriesEx);
+
   return mGaugeDataEx;
 }
 
diff --git a/MdeModulePkg/Library/DxeSmmPerformanceLib/DxeSmmPerformanceLib.inf 
b/MdeModulePkg/Library/DxeSmmPerformanceLib/DxeSmmPerformanceLib.inf
index a661328..2dbaa7c 100644
--- a/MdeModulePkg/Library/DxeSmmPerformanceLib/DxeSmmPerformanceLib.inf
+++ b/MdeModulePkg/Library/DxeSmmPerformanceLib/DxeSmmPerformanceLib.inf
@@ -5,7 +5,7 @@
 #  StartPerformanceMeasurement(), EndPerformanceMeasurement(), 
StartPerformanceMeasurementEx()
 #  and EndPerformanceMeasurementEx() are not implemented.
 #  
-#  Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2011 - 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
@@ -54,6 +54,7 @@
   gPerformanceExProtocolGuid            ## SOMETIMES_CONSUMES   ## UNDEFINED # 
Locate protocol
   gSmmPerformanceProtocolGuid           ## SOMETIMES_PRODUCES   ## UNDEFINED # 
Used to do smm communication
   gSmmPerformanceExProtocolGuid         ## SOMETIMES_PRODUCES   ## UNDEFINED # 
Used to do smm communication
+  gEdkiiPiSmmCommunicationRegionTableGuid    ## CONSUMES ## SystemTable
 
 [Protocols]
   gEfiSmmCommunicationProtocolGuid      ## CONSUMES
-- 
2.7.4.windows.1

_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to