]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Library/DxeSmmPerformanceLib/DxeSmmPerformanceLib.c
MdeModulePkg: Clean up source files
[mirror_edk2.git] / MdeModulePkg / Library / DxeSmmPerformanceLib / DxeSmmPerformanceLib.c
index 3c69ceeb7d6a0297a2a5fff7d8f60bd5c2f91902..353174724e4b65479658d24d03a862c0f9662cdc 100644 (file)
@@ -5,7 +5,7 @@
   StartPerformanceMeasurement(), EndPerformanceMeasurement(), StartPerformanceMeasurementEx()\r
   and EndPerformanceMeasurementEx() are not implemented.\r
 \r
-  Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2011 - 2018, 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
@@ -32,15 +32,21 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 #include <Protocol/SmmCommunication.h>\r
 \r
+#include <Guid/PiSmmCommunicationRegionTable.h>\r
+#include <Library/UefiLib.h>\r
+\r
 #define SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE (OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)  + sizeof (SMM_PERF_COMMUNICATE))\r
 \r
 EFI_SMM_COMMUNICATION_PROTOCOL  *mSmmCommunication = NULL;\r
-UINT8                           mSmmPerformanceBuffer[SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE];\r
+UINT8                           *mSmmPerformanceBuffer;\r
 GAUGE_DATA_ENTRY                *mGaugeData = NULL;\r
 UINTN                           mGaugeNumberOfEntries = 0;\r
 GAUGE_DATA_ENTRY_EX             *mGaugeDataEx = NULL;\r
 UINTN                           mGaugeNumberOfEntriesEx = 0;\r
 \r
+BOOLEAN                         mNoSmmPerfHandler = FALSE;\r
+BOOLEAN                         mNoSmmPerfExHandler = FALSE;\r
+\r
 //\r
 // The cached Performance Protocol and PerformanceEx Protocol interface.\r
 //\r
@@ -163,7 +169,7 @@ StartPerformanceMeasurementEx (
 /**\r
   Fills in the end time of a performance measurement.\r
 \r
-  Looks up the record that matches Handle, Token, Module and Identifier.\r
+  Looks up the record that matches Handle, Token and Module.\r
   If the record can not be found then return RETURN_NOT_FOUND.\r
   If the record is found and TimeStamp is not zero,\r
   then TimeStamp is added to the record as the end time.\r
@@ -307,7 +313,7 @@ EndPerformanceMeasurement (
 UINTN\r
 EFIAPI\r
 GetByPerformanceProtocol (\r
-  IN  UINTN       LogEntryKey, \r
+  IN  UINTN       LogEntryKey,\r
   OUT CONST VOID  **Handle,\r
   OUT CONST CHAR8 **Token,\r
   OUT CONST CHAR8 **Module,\r
@@ -372,7 +378,7 @@ GetByPerformanceProtocol (
                                   On exit, the key of the next performance log entry.\r
 \r
   @retval !NULL           Get all gauge data success.\r
-  @retval NULL            Get all guage data failed.\r
+  @retval NULL            Get all gauge data failed.\r
 **/\r
 GAUGE_DATA_ENTRY *\r
 EFIAPI\r
@@ -380,11 +386,26 @@ GetAllSmmGaugeData (
   IN UINTN      LogEntryKey\r
   )\r
 {\r
-  EFI_STATUS                  Status;\r
-  EFI_SMM_COMMUNICATE_HEADER  *SmmCommBufferHeader;\r
-  SMM_PERF_COMMUNICATE        *SmmPerfCommData;\r
-  UINTN                       CommSize;\r
-  UINTN                       DataSize;\r
+  EFI_STATUS                                Status;\r
+  EFI_SMM_COMMUNICATE_HEADER                *SmmCommBufferHeader;\r
+  SMM_PERF_COMMUNICATE                      *SmmPerfCommData;\r
+  UINTN                                     CommSize;\r
+  UINTN                                     DataSize;\r
+  EDKII_PI_SMM_COMMUNICATION_REGION_TABLE   *PiSmmCommunicationRegionTable;\r
+  UINT32                                    Index;\r
+  EFI_MEMORY_DESCRIPTOR                     *Entry;\r
+  UINT8                                     *Buffer;\r
+  UINTN                                     Size;\r
+  UINTN                                     NumberOfEntries;\r
+  UINTN                                     EntriesGot;\r
+\r
+  if (mNoSmmPerfHandler) {\r
+    //\r
+    // Not try to get the SMM gauge data again\r
+    // if no SMM Performance handler found.\r
+    //\r
+    return NULL;\r
+  }\r
 \r
   if (LogEntryKey != 0) {\r
     if (mGaugeData != NULL) {\r
@@ -392,7 +413,7 @@ GetAllSmmGaugeData (
     }\r
   } else {\r
     //\r
-    // Reget the SMM guage data at the first entry get.\r
+    // Reget the SMM gauge data at the first entry get.\r
     //\r
     if (mGaugeData != NULL) {\r
       FreePool (mGaugeData);\r
@@ -406,45 +427,83 @@ GetAllSmmGaugeData (
     return NULL;\r
   }\r
 \r
+  Status = EfiGetSystemConfigurationTable (\r
+             &gEdkiiPiSmmCommunicationRegionTableGuid,\r
+             (VOID **) &PiSmmCommunicationRegionTable\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return NULL;\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 >= (SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE + sizeof (GAUGE_DATA_ENTRY))) {\r
+        break;\r
+      }\r
+    }\r
+    Entry = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) Entry + PiSmmCommunicationRegionTable->DescriptorSize);\r
+  }\r
+  ASSERT (Index < PiSmmCommunicationRegionTable->NumberOfEntries);\r
+  mSmmPerformanceBuffer = (UINT8 *) (UINTN) Entry->PhysicalStart;\r
+\r
   //\r
-  // Initialize communicate buffer \r
+  // Initialize communicate buffer\r
   //\r
   SmmCommBufferHeader = (EFI_SMM_COMMUNICATE_HEADER *)mSmmPerformanceBuffer;\r
   SmmPerfCommData = (SMM_PERF_COMMUNICATE *)SmmCommBufferHeader->Data;\r
   ZeroMem((UINT8*)SmmPerfCommData, sizeof(SMM_PERF_COMMUNICATE));\r
-    \r
+\r
   CopyGuid (&SmmCommBufferHeader->HeaderGuid, &gSmmPerformanceProtocolGuid);\r
   SmmCommBufferHeader->MessageLength = sizeof(SMM_PERF_COMMUNICATE);\r
   CommSize = SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE;\r
 \r
   //\r
-  // Get totol number of SMM gauge entries\r
+  // Get total number of SMM gauge entries\r
   //\r
   SmmPerfCommData->Function = SMM_PERF_FUNCTION_GET_GAUGE_ENTRY_NUMBER;\r
   Status = mSmmCommunication->Communicate (mSmmCommunication, mSmmPerformanceBuffer, &CommSize);\r
+  if (Status == EFI_NOT_FOUND) {\r
+    mNoSmmPerfHandler = TRUE;\r
+  }\r
   if (EFI_ERROR (Status) || EFI_ERROR (SmmPerfCommData->ReturnStatus) || SmmPerfCommData->NumberOfEntries == 0) {\r
     return NULL;\r
   }\r
 \r
   mGaugeNumberOfEntries = SmmPerfCommData->NumberOfEntries;\r
-  \r
+\r
+  Buffer = mSmmPerformanceBuffer + SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE;\r
+  NumberOfEntries = (Size - SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE) / sizeof (GAUGE_DATA_ENTRY);\r
   DataSize = mGaugeNumberOfEntries * sizeof(GAUGE_DATA_ENTRY);\r
   mGaugeData = AllocateZeroPool(DataSize);\r
   ASSERT (mGaugeData != NULL);\r
-  \r
+\r
   //\r
   // Get all SMM gauge data\r
-  //  \r
+  //\r
   SmmPerfCommData->Function = SMM_PERF_FUNCTION_GET_GAUGE_DATA;\r
-  SmmPerfCommData->LogEntryKey = 0;\r
-  SmmPerfCommData->NumberOfEntries = mGaugeNumberOfEntries;\r
-  SmmPerfCommData->GaugeData = mGaugeData;\r
-  Status = mSmmCommunication->Communicate (mSmmCommunication, mSmmPerformanceBuffer, &CommSize);\r
-  if (EFI_ERROR (Status) || EFI_ERROR (SmmPerfCommData->ReturnStatus)) {\r
-    FreePool (mGaugeData);\r
-    mGaugeData = NULL;\r
-    mGaugeNumberOfEntries = 0;\r
-  }\r
+  SmmPerfCommData->GaugeData = (GAUGE_DATA_ENTRY *) Buffer;\r
+  EntriesGot = 0;\r
+  do {\r
+    SmmPerfCommData->LogEntryKey = EntriesGot;\r
+    if ((mGaugeNumberOfEntries - EntriesGot) >= NumberOfEntries) {\r
+      SmmPerfCommData->NumberOfEntries = NumberOfEntries;\r
+    } else {\r
+      SmmPerfCommData->NumberOfEntries = mGaugeNumberOfEntries - EntriesGot;\r
+    }\r
+    Status = mSmmCommunication->Communicate (mSmmCommunication, mSmmPerformanceBuffer, &CommSize);\r
+    if (EFI_ERROR (Status) || EFI_ERROR (SmmPerfCommData->ReturnStatus)) {\r
+      FreePool (mGaugeData);\r
+      mGaugeData = NULL;\r
+      mGaugeNumberOfEntries = 0;\r
+      return NULL;\r
+    } else {\r
+      CopyMem (&mGaugeData[EntriesGot], Buffer, SmmPerfCommData->NumberOfEntries * sizeof (GAUGE_DATA_ENTRY));\r
+    }\r
+    EntriesGot += SmmPerfCommData->NumberOfEntries;\r
+  } while (EntriesGot < mGaugeNumberOfEntries);\r
 \r
   return mGaugeData;\r
 }\r
@@ -459,7 +518,7 @@ GetAllSmmGaugeData (
                                   On exit, the key of the next performance log entry.\r
 \r
   @retval !NULL           Get all gauge data success.\r
-  @retval NULL            Get all guage data failed.\r
+  @retval NULL            Get all gauge data failed.\r
 **/\r
 GAUGE_DATA_ENTRY_EX *\r
 EFIAPI\r
@@ -467,11 +526,26 @@ GetAllSmmGaugeDataEx (
   IN UINTN      LogEntryKey\r
   )\r
 {\r
-  EFI_STATUS                  Status;\r
-  EFI_SMM_COMMUNICATE_HEADER  *SmmCommBufferHeader;\r
-  SMM_PERF_COMMUNICATE_EX     *SmmPerfCommData;\r
-  UINTN                       CommSize;\r
-  UINTN                       DataSize;\r
+  EFI_STATUS                                Status;\r
+  EFI_SMM_COMMUNICATE_HEADER                *SmmCommBufferHeader;\r
+  SMM_PERF_COMMUNICATE_EX                   *SmmPerfCommData;\r
+  UINTN                                     CommSize;\r
+  UINTN                                     DataSize;\r
+  EDKII_PI_SMM_COMMUNICATION_REGION_TABLE   *PiSmmCommunicationRegionTable;\r
+  UINT32                                    Index;\r
+  EFI_MEMORY_DESCRIPTOR                     *Entry;\r
+  UINT8                                     *Buffer;\r
+  UINTN                                     Size;\r
+  UINTN                                     NumberOfEntries;\r
+  UINTN                                     EntriesGot;\r
+\r
+  if (mNoSmmPerfExHandler) {\r
+    //\r
+    // Not try to get the SMM gauge data again\r
+    // if no SMM PerformanceEx handler found.\r
+    //\r
+    return NULL;\r
+  }\r
 \r
   if (LogEntryKey != 0) {\r
     if (mGaugeDataEx != NULL) {\r
@@ -479,7 +553,7 @@ GetAllSmmGaugeDataEx (
     }\r
   } else {\r
     //\r
-    // Reget the SMM guage data at the first entry get.\r
+    // Reget the SMM gauge data at the first entry get.\r
     //\r
     if (mGaugeDataEx != NULL) {\r
       FreePool (mGaugeDataEx);\r
@@ -493,46 +567,83 @@ GetAllSmmGaugeDataEx (
     return NULL;\r
   }\r
 \r
+  Status = EfiGetSystemConfigurationTable (\r
+             &gEdkiiPiSmmCommunicationRegionTableGuid,\r
+             (VOID **) &PiSmmCommunicationRegionTable\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    return NULL;\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 >= (SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE + sizeof (GAUGE_DATA_ENTRY_EX))) {\r
+        break;\r
+      }\r
+    }\r
+    Entry = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) Entry + PiSmmCommunicationRegionTable->DescriptorSize);\r
+  }\r
+  ASSERT (Index < PiSmmCommunicationRegionTable->NumberOfEntries);\r
+  mSmmPerformanceBuffer = (UINT8 *) (UINTN) Entry->PhysicalStart;\r
   //\r
-  // Initialize communicate buffer \r
+  // Initialize communicate buffer\r
   //\r
   SmmCommBufferHeader = (EFI_SMM_COMMUNICATE_HEADER *)mSmmPerformanceBuffer;\r
   SmmPerfCommData = (SMM_PERF_COMMUNICATE_EX *)SmmCommBufferHeader->Data;\r
   ZeroMem((UINT8*)SmmPerfCommData, sizeof(SMM_PERF_COMMUNICATE_EX));\r
-    \r
+\r
   CopyGuid (&SmmCommBufferHeader->HeaderGuid, &gSmmPerformanceExProtocolGuid);\r
   SmmCommBufferHeader->MessageLength = sizeof(SMM_PERF_COMMUNICATE_EX);\r
   CommSize = SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE;\r
 \r
   //\r
-  // Get totol number of SMM gauge entries\r
+  // Get total number of SMM gauge entries\r
   //\r
   SmmPerfCommData->Function = SMM_PERF_FUNCTION_GET_GAUGE_ENTRY_NUMBER;\r
   Status = mSmmCommunication->Communicate (mSmmCommunication, mSmmPerformanceBuffer, &CommSize);\r
+  if (Status == EFI_NOT_FOUND) {\r
+    mNoSmmPerfExHandler = TRUE;\r
+  }\r
   if (EFI_ERROR (Status) || EFI_ERROR (SmmPerfCommData->ReturnStatus) || SmmPerfCommData->NumberOfEntries == 0) {\r
     return NULL;\r
   }\r
 \r
   mGaugeNumberOfEntriesEx = SmmPerfCommData->NumberOfEntries;\r
-  \r
+\r
+  Buffer = mSmmPerformanceBuffer + SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE;\r
+  NumberOfEntries = (Size - SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE) / sizeof (GAUGE_DATA_ENTRY_EX);\r
   DataSize = mGaugeNumberOfEntriesEx * sizeof(GAUGE_DATA_ENTRY_EX);\r
   mGaugeDataEx = AllocateZeroPool(DataSize);\r
   ASSERT (mGaugeDataEx != NULL);\r
-  \r
+\r
   //\r
   // Get all SMM gauge data\r
-  //  \r
+  //\r
   SmmPerfCommData->Function = SMM_PERF_FUNCTION_GET_GAUGE_DATA;\r
-  SmmPerfCommData->LogEntryKey = 0;\r
-  SmmPerfCommData->NumberOfEntries = mGaugeNumberOfEntriesEx;\r
-  SmmPerfCommData->GaugeDataEx = mGaugeDataEx;\r
-  Status = mSmmCommunication->Communicate (mSmmCommunication, mSmmPerformanceBuffer, &CommSize);\r
-  if (EFI_ERROR (Status) || EFI_ERROR (SmmPerfCommData->ReturnStatus)) {\r
-    FreePool (mGaugeDataEx);\r
-    mGaugeDataEx = NULL;\r
-    mGaugeNumberOfEntriesEx = 0;\r
-  }\r
\r
+  SmmPerfCommData->GaugeDataEx = (GAUGE_DATA_ENTRY_EX *) Buffer;\r
+  EntriesGot = 0;\r
+  do {\r
+    SmmPerfCommData->LogEntryKey = EntriesGot;\r
+    if ((mGaugeNumberOfEntriesEx - EntriesGot) >= NumberOfEntries) {\r
+      SmmPerfCommData->NumberOfEntries = NumberOfEntries;\r
+    } else {\r
+      SmmPerfCommData->NumberOfEntries = mGaugeNumberOfEntriesEx - EntriesGot;\r
+    }\r
+    Status = mSmmCommunication->Communicate (mSmmCommunication, mSmmPerformanceBuffer, &CommSize);\r
+    if (EFI_ERROR (Status) || EFI_ERROR (SmmPerfCommData->ReturnStatus)) {\r
+      FreePool (mGaugeDataEx);\r
+      mGaugeDataEx = NULL;\r
+      mGaugeNumberOfEntriesEx = 0;\r
+      return NULL;\r
+    } else {\r
+      CopyMem (&mGaugeDataEx[EntriesGot], Buffer, SmmPerfCommData->NumberOfEntries * sizeof (GAUGE_DATA_ENTRY_EX));\r
+    }\r
+    EntriesGot += SmmPerfCommData->NumberOfEntries;\r
+  } while (EntriesGot < mGaugeNumberOfEntriesEx);\r
+\r
   return mGaugeDataEx;\r
 }\r
 \r
@@ -580,7 +691,7 @@ GetAllSmmGaugeDataEx (
 UINTN\r
 EFIAPI\r
 GetPerformanceMeasurementEx (\r
-  IN  UINTN       LogEntryKey, \r
+  IN  UINTN       LogEntryKey,\r
   OUT CONST VOID  **Handle,\r
   OUT CONST CHAR8 **Token,\r
   OUT CONST CHAR8 **Module,\r
@@ -658,7 +769,15 @@ GetPerformanceMeasurementEx (
       GaugeData = (GAUGE_DATA_ENTRY_EX *) &mGaugeData[LogEntryKey++];\r
       *Identifier = 0;\r
     } else {\r
-      return 0;\r
+      return GetByPerformanceProtocol (\r
+               LogEntryKey,\r
+               Handle,\r
+               Token,\r
+               Module,\r
+               StartTimeStamp,\r
+               EndTimeStamp,\r
+               Identifier\r
+               );\r
     }\r
   }\r
 \r