]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Add new extension PerformanceLib APIs to store ID info.
authorlzeng14 <lzeng14@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 24 Apr 2012 09:12:36 +0000 (09:12 +0000)
committerlzeng14 <lzeng14@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 24 Apr 2012 09:12:36 +0000 (09:12 +0000)
Signed-off-by: Star Zeng <star.zeng@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13215 6f19259b-4bc3-4df7-8a09-765794883524

16 files changed:
MdeModulePkg/Include/Guid/Performance.h
MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.c
MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf
MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLibInternal.h
MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.c
MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
MdeModulePkg/Library/DxeSmmPerformanceLib/DxeSmmPerformanceLib.c
MdeModulePkg/Library/DxeSmmPerformanceLib/DxeSmmPerformanceLib.inf
MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.c
MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.c
MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.inf
MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLibInternal.h
MdeModulePkg/Library/SmmPerformanceLib/SmmPerformanceLib.c
MdeModulePkg/Library/SmmPerformanceLib/SmmPerformanceLib.inf
MdeModulePkg/MdeModulePkg.dec

index 3659ccc3280d1443d549d1bf7313352648761864..d7768e1fc12669eade32e1f788ca548f45bb941b 100644 (file)
@@ -4,7 +4,7 @@
   * performance protocol interfaces.\r
   * performance variables.  \r
 \r
-Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials are licensed and made available under \r
 the terms and conditions of the BSD License that accompanies this distribution.  \r
 The full text of the license may be found at\r
@@ -66,12 +66,16 @@ typedef struct {
 } PERF_HEADER;\r
 \r
 #define PERFORMANCE_PROTOCOL_GUID \\r
-  { 0x76b6bdfa, 0x2acd, 0x4462, {0x9E, 0x3F, 0xcb, 0x58, 0xC9, 0x69, 0xd9, 0x37 } }\r
+  { 0x76b6bdfa, 0x2acd, 0x4462, { 0x9E, 0x3F, 0xcb, 0x58, 0xC9, 0x69, 0xd9, 0x37 } }\r
+\r
+#define PERFORMANCE_EX_PROTOCOL_GUID \\r
+  { 0x1ea81bec, 0xf01a, 0x4d98, { 0xa2, 0x1,  0x4a, 0x61, 0xce, 0x2f, 0xc0, 0x22 } }\r
 \r
 //\r
 // Forward reference for pure ANSI compatibility\r
 //\r
 typedef struct _PERFORMANCE_PROTOCOL PERFORMANCE_PROTOCOL;\r
+typedef struct _PERFORMANCE_EX_PROTOCOL PERFORMANCE_EX_PROTOCOL;\r
 \r
 //\r
 // DXE_PERFORMANCE_STRING_SIZE must be a multiple of 8.\r
@@ -92,6 +96,15 @@ typedef struct {
   UINT64                EndTimeStamp;                        ///< End time point.\r
 } GAUGE_DATA_ENTRY;\r
 \r
+typedef struct {\r
+  EFI_PHYSICAL_ADDRESS  Handle;\r
+  CHAR8                 Token[DXE_PERFORMANCE_STRING_SIZE];  ///< Measured token string name. \r
+  CHAR8                 Module[DXE_PERFORMANCE_STRING_SIZE]; ///< Module string name.\r
+  UINT64                StartTimeStamp;                      ///< Start time point.\r
+  UINT64                EndTimeStamp;                        ///< End time point.\r
+  UINT32                Identifier;                          ///< Identifier.\r
+} GAUGE_DATA_ENTRY_EX;\r
+\r
 //\r
 // The header must be aligned at 8 bytes\r
 //\r
@@ -105,7 +118,10 @@ typedef struct {
 //\r
 \r
 #define SMM_PERFORMANCE_PROTOCOL_GUID \\r
-  { 0xf866226a, 0xeaa5, 0x4f5a, { 0xa9, 0xa, 0x6c, 0xfb, 0xa5, 0x7c, 0x58, 0x8e } }\r
+  { 0xf866226a, 0xeaa5, 0x4f5a, { 0xa9, 0xa,  0x6c, 0xfb, 0xa5, 0x7c, 0x58, 0x8e } }\r
+\r
+#define SMM_PERFORMANCE_EX_PROTOCOL_GUID \\r
+  { 0x931fc048, 0xc71d, 0x4455, { 0x89, 0x30, 0x47, 0x6,  0x30, 0xe3, 0xe,  0xe5 } }\r
 \r
 //\r
 // SMM_PERFORMANCE_STRING_SIZE.\r
@@ -126,6 +142,14 @@ typedef struct {
   GAUGE_DATA_ENTRY  *GaugeData;\r
 } SMM_PERF_COMMUNICATE;\r
 \r
+typedef struct {\r
+  UINTN                Function;\r
+  EFI_STATUS           ReturnStatus;\r
+  UINTN                NumberOfEntries;\r
+  UINTN                LogEntryKey;\r
+  GAUGE_DATA_ENTRY_EX  *GaugeDataEx;\r
+} SMM_PERF_COMMUNICATE_EX;\r
+\r
 #define SMM_PERF_FUNCTION_GET_GAUGE_ENTRY_NUMBER          1\r
 #define SMM_PERF_FUNCTION_GET_GAUGE_DATA                  2\r
 \r
@@ -195,6 +219,8 @@ EFI_STATUS
 \r
 /**\r
   Retrieves a previously logged performance measurement.\r
+  It can also retrieve the log created by StartGaugeEx and EndGaugeEx of PERFORMANCE_EX_PROTOCOL,\r
+  and then eliminate the Identifier.\r
 \r
   Retrieves the performance log entry from the performance log specified by LogEntryKey.\r
   If it stands for a valid entry, then EFI_SUCCESS is returned and\r
@@ -216,13 +242,116 @@ EFI_STATUS
   OUT GAUGE_DATA_ENTRY    **GaugeDataEntry\r
   );\r
 \r
+/**\r
+  Adds a record at the end of the performance measurement log\r
+  that records the start time of a performance measurement.\r
+\r
+  The added record contains the Handle, Token, Module and Identifier.\r
+  The end time of the new record is not recorded, so it is set to zero.\r
+  If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.\r
+  If TimeStamp is zero, the start time in the record is filled in with the value\r
+  read from the current time stamp.\r
+\r
+  @param  Handle                  The pointer to environment specific context used\r
+                                  to identify the component being measured.\r
+  @param  Token                   The pointer to a Null-terminated ASCII string\r
+                                  that identifies the component being measured.\r
+  @param  Module                  The pointer to a Null-terminated ASCII string\r
+                                  that identifies the module being measured.\r
+  @param  TimeStamp               The 64-bit time stamp.\r
+  @param  Identifier              32-bit identifier. If the value is 0, the created record\r
+                                  is same as the one created by StartGauge of PERFORMANCE_PROTOCOL.\r
+\r
+  @retval EFI_SUCCESS             The data was read correctly from the device.\r
+  @retval EFI_OUT_OF_RESOURCES    There are not enough resources to record the measurement.\r
+\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI * PERFORMANCE_START_GAUGE_EX)(\r
+  IN CONST VOID   *Handle,  OPTIONAL\r
+  IN CONST CHAR8  *Token,   OPTIONAL\r
+  IN CONST CHAR8  *Module,  OPTIONAL\r
+  IN UINT64       TimeStamp,\r
+  IN UINT32       Identifier\r
+  );\r
+\r
+/**\r
+  Searches the performance measurement log from the beginning of the log\r
+  for the first matching record that contains a zero end time and fills in a valid end time.\r
+\r
+  Searches the performance measurement log from the beginning of the log\r
+  for the first record that matches Handle, Token, Module and Identifier, and has an end time value of zero.\r
+  If the record can not be found then return EFI_NOT_FOUND.\r
+  If the record is found and TimeStamp is not zero,\r
+  then the end time in the record is filled in with the value specified by TimeStamp.\r
+  If the record is found and TimeStamp is zero, then the end time in the matching record\r
+  is filled in with the current time stamp value.\r
+\r
+  @param  Handle                  The pointer to environment specific context used\r
+                                  to identify the component being measured.\r
+  @param  Token                   The pointer to a Null-terminated ASCII string\r
+                                  that identifies the component being measured.\r
+  @param  Module                  The pointer to a Null-terminated ASCII string\r
+                                  that identifies the module being measured.\r
+  @param  TimeStamp               The 64-bit time stamp.\r
+  @param  Identifier              32-bit identifier. If the value is 0, the found record\r
+                                  is same as the one found by EndGauge of PERFORMANCE_PROTOCOL.\r
+\r
+  @retval EFI_SUCCESS             The end of  the measurement was recorded.\r
+  @retval EFI_NOT_FOUND           The specified measurement record could not be found.\r
+\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI * PERFORMANCE_END_GAUGE_EX)(\r
+  IN CONST VOID   *Handle,  OPTIONAL\r
+  IN CONST CHAR8  *Token,   OPTIONAL\r
+  IN CONST CHAR8  *Module,  OPTIONAL\r
+  IN UINT64       TimeStamp,\r
+  IN UINT32       Identifier\r
+  );\r
+\r
+/**\r
+  Retrieves a previously logged performance measurement.\r
+  It can also retrieve the log created by StartGauge and EndGauge of PERFORMANCE_PROTOCOL,\r
+  and then assign the Identifier with 0.\r
+\r
+  Retrieves the performance log entry from the performance log specified by LogEntryKey.\r
+  If it stands for a valid entry, then EFI_SUCCESS is returned and\r
+  GaugeDataEntryEx stores the pointer to that entry.\r
+\r
+  @param  LogEntryKey             The key for the previous performance measurement log entry.\r
+                                  If 0, then the first performance measurement log entry is retrieved.\r
+  @param  GaugeDataEntryEx        Out parameter for the indirect pointer to the extented gauge data entry specified by LogEntryKey.\r
+                                  \r
+  @retval EFI_SUCCESS             The GuageDataEntryEx is successfully found based on LogEntryKey.\r
+  @retval EFI_NOT_FOUND           There is no entry after the measurement referred to by LogEntryKey.\r
+  @retval EFI_INVALID_PARAMETER   The LogEntryKey is not a valid entry, or GaugeDataEntryEx is NULL.\r
+\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI * PERFORMANCE_GET_GAUGE_EX)(\r
+  IN  UINTN                 LogEntryKey,\r
+  OUT GAUGE_DATA_ENTRY_EX   **GaugeDataEntryEx\r
+  );\r
+\r
 struct _PERFORMANCE_PROTOCOL {\r
   PERFORMANCE_START_GAUGE             StartGauge;\r
   PERFORMANCE_END_GAUGE               EndGauge;\r
   PERFORMANCE_GET_GAUGE               GetGauge;\r
 };\r
 \r
+struct _PERFORMANCE_EX_PROTOCOL {\r
+  PERFORMANCE_START_GAUGE_EX          StartGaugeEx;\r
+  PERFORMANCE_END_GAUGE_EX            EndGaugeEx;\r
+  PERFORMANCE_GET_GAUGE_EX            GetGaugeEx;\r
+};\r
+\r
 extern EFI_GUID gPerformanceProtocolGuid;\r
 extern EFI_GUID gSmmPerformanceProtocolGuid;\r
+extern EFI_GUID gPerformanceExProtocolGuid;\r
+extern EFI_GUID gSmmPerformanceExProtocolGuid;\r
 \r
 #endif\r
index e459513e1508e6d0143481469c398261706509fd..08d295ca5a6b956588638a4159305fb3036a09c5 100644 (file)
@@ -4,13 +4,13 @@
   This library provides the performance measurement interfaces and initializes performance\r
   logging for DXE phase. It first initializes its private global data structure for\r
   performance logging and saves the performance GUIDed HOB passed from PEI phase. \r
-  It initializes DXE phase performance logging by publishing the Performance Protocol,\r
-  which is consumed by DxePerformanceLib to logging performance data in DXE phase.\r
+  It initializes DXE phase performance logging by publishing the Performance and PerformanceEx Protocol,\r
+  which are consumed by DxePerformanceLib to logging performance data in DXE phase.\r
 \r
   This library is mainly used by DxeCore to start performance logging to ensure that\r
   Performance Protocol is installed at the very beginning of DXE phase.\r
 \r
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2012, 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
@@ -43,7 +43,7 @@ UINT32               mMaxGaugeRecords;
 EFI_HANDLE           mHandle = NULL;\r
 \r
 //\r
-// Interfaces for performance protocol.\r
+// Interfaces for Performance Protocol.\r
 //\r
 PERFORMANCE_PROTOCOL mPerformanceInterface = {\r
   StartGauge,\r
@@ -51,11 +51,20 @@ PERFORMANCE_PROTOCOL mPerformanceInterface = {
   GetGauge\r
   };\r
 \r
+//\r
+// Interfaces for PerformanceEx Protocol.\r
+//\r
+PERFORMANCE_EX_PROTOCOL mPerformanceExInterface = {\r
+  StartGaugeEx,\r
+  EndGaugeEx,\r
+  GetGaugeEx\r
+  };\r
+\r
 /**\r
-  Searches in the gauge array with keyword Handle, Token and Module.\r
+  Searches in the gauge array with keyword Handle, Token, Module and Identifier.\r
 \r
   This internal function searches for the gauge entry in the gauge array.\r
-  If there is an entry that exactly matches the given key word triple\r
+  If there is an entry that exactly matches the given keywords\r
   and its end time stamp is zero, then the index of that gauge entry is returned;\r
   otherwise, the the number of gauge entries in the array is returned.\r
 \r
@@ -65,6 +74,7 @@ PERFORMANCE_PROTOCOL mPerformanceInterface = {
                                   that identifies the component being measured.\r
   @param  Module                  Pointer to a Null-terminated ASCII string\r
                                   that identifies the module being measured.\r
+  @param  Identifier              32-bit identifier.\r
 \r
   @retval The index of gauge entry in the array.\r
 \r
@@ -73,12 +83,13 @@ UINT32
 InternalSearchForGaugeEntry (\r
   IN CONST VOID                 *Handle,  OPTIONAL\r
   IN CONST CHAR8                *Token,   OPTIONAL\r
-  IN CONST CHAR8                *Module   OPTIONAL\r
+  IN CONST CHAR8                *Module,   OPTIONAL\r
+  IN UINT32                     Identifier\r
   )\r
 {\r
   UINT32                    Index;\r
   UINT32                    NumberOfEntries;\r
-  GAUGE_DATA_ENTRY          *GaugeEntryArray;\r
+  GAUGE_DATA_ENTRY_EX       *GaugeEntryExArray;\r
 \r
   if (Token == NULL) {\r
     Token = "";\r
@@ -88,13 +99,14 @@ InternalSearchForGaugeEntry (
   }\r
 \r
   NumberOfEntries = mGaugeData->NumberOfEntries;\r
-  GaugeEntryArray = (GAUGE_DATA_ENTRY *) (mGaugeData + 1);\r
+  GaugeEntryExArray = (GAUGE_DATA_ENTRY_EX *) (mGaugeData + 1);\r
 \r
   for (Index = 0; Index < NumberOfEntries; Index++) {\r
-    if ((GaugeEntryArray[Index].Handle == (EFI_PHYSICAL_ADDRESS) (UINTN) Handle) &&\r
-         AsciiStrnCmp (GaugeEntryArray[Index].Token, Token, DXE_PERFORMANCE_STRING_LENGTH) == 0 &&\r
-         AsciiStrnCmp (GaugeEntryArray[Index].Module, Module, DXE_PERFORMANCE_STRING_LENGTH) == 0 &&\r
-         GaugeEntryArray[Index].EndTimeStamp == 0\r
+    if ((GaugeEntryExArray[Index].Handle == (EFI_PHYSICAL_ADDRESS) (UINTN) Handle) &&\r
+         AsciiStrnCmp (GaugeEntryExArray[Index].Token, Token, DXE_PERFORMANCE_STRING_LENGTH) == 0 &&\r
+         AsciiStrnCmp (GaugeEntryExArray[Index].Module, Module, DXE_PERFORMANCE_STRING_LENGTH) == 0 &&\r
+         (GaugeEntryExArray[Index].Identifier == Identifier) &&\r
+         GaugeEntryExArray[Index].EndTimeStamp == 0\r
        ) {\r
       break;\r
     }\r
@@ -108,7 +120,7 @@ InternalSearchForGaugeEntry (
   that records the start time of a performance measurement.\r
 \r
   Adds a record to the end of the performance measurement log\r
-  that contains the Handle, Token, and Module.\r
+  that contains the Handle, Token, Module and Identifier.\r
   The end time of the new record must be set to zero.\r
   If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.\r
   If TimeStamp is zero, the start time in the record is filled in with the value\r
@@ -121,6 +133,8 @@ InternalSearchForGaugeEntry (
   @param  Module                  Pointer to a Null-terminated ASCII string\r
                                   that identifies the module being measured.\r
   @param  TimeStamp               64-bit time stamp.\r
+  @param  Identifier              32-bit identifier. If the value is 0, the created record\r
+                                  is same as the one created by StartGauge of PERFORMANCE_PROTOCOL.\r
 \r
   @retval EFI_SUCCESS             The data was read correctly from the device.\r
   @retval EFI_OUT_OF_RESOURCES    There are not enough resources to record the measurement.\r
@@ -128,15 +142,17 @@ InternalSearchForGaugeEntry (
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-StartGauge (\r
+StartGaugeEx (\r
   IN CONST VOID   *Handle,  OPTIONAL\r
   IN CONST CHAR8  *Token,   OPTIONAL\r
   IN CONST CHAR8  *Module,  OPTIONAL\r
-  IN UINT64       TimeStamp\r
+  IN UINT64       TimeStamp,\r
+  IN UINT32       Identifier\r
   )\r
 {\r
-  GAUGE_DATA_ENTRY          *GaugeEntryArray;\r
+  GAUGE_DATA_ENTRY_EX       *GaugeEntryExArray;\r
   UINTN                     GaugeDataSize;\r
+  GAUGE_DATA_HEADER         *NewGaugeData;\r
   UINTN                     OldGaugeDataSize;\r
   GAUGE_DATA_HEADER         *OldGaugeData;\r
   UINT32                    Index;\r
@@ -147,15 +163,18 @@ StartGauge (
     // Try to enlarge the scale of gauge array.\r
     //\r
     OldGaugeData      = mGaugeData;\r
-    OldGaugeDataSize  = sizeof (GAUGE_DATA_HEADER) + sizeof (GAUGE_DATA_ENTRY) * mMaxGaugeRecords;\r
+    OldGaugeDataSize  = sizeof (GAUGE_DATA_HEADER) + sizeof (GAUGE_DATA_ENTRY_EX) * mMaxGaugeRecords;\r
 \r
-    mMaxGaugeRecords *= 2;\r
-    GaugeDataSize     = sizeof (GAUGE_DATA_HEADER) + sizeof (GAUGE_DATA_ENTRY) * mMaxGaugeRecords;\r
+    GaugeDataSize     = sizeof (GAUGE_DATA_HEADER) + sizeof (GAUGE_DATA_ENTRY_EX) * mMaxGaugeRecords * 2;\r
 \r
-    mGaugeData = AllocateZeroPool (GaugeDataSize);\r
-    if (mGaugeData == NULL) {\r
+    NewGaugeData = AllocateZeroPool (GaugeDataSize);\r
+    if (NewGaugeData == NULL) {\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
+\r
+    mGaugeData = NewGaugeData;\r
+    mMaxGaugeRecords *= 2;\r
+\r
     //\r
     // Initialize new data array and migrate old data one.\r
     //\r
@@ -164,20 +183,23 @@ StartGauge (
     FreePool (OldGaugeData);\r
   }\r
 \r
-  GaugeEntryArray               = (GAUGE_DATA_ENTRY *) (mGaugeData + 1);\r
-  GaugeEntryArray[Index].Handle = (EFI_PHYSICAL_ADDRESS) (UINTN) Handle;\r
+  GaugeEntryExArray               = (GAUGE_DATA_ENTRY_EX *) (mGaugeData + 1);\r
+  GaugeEntryExArray[Index].Handle = (EFI_PHYSICAL_ADDRESS) (UINTN) Handle;\r
 \r
   if (Token != NULL) {\r
-    AsciiStrnCpy (GaugeEntryArray[Index].Token, Token, DXE_PERFORMANCE_STRING_LENGTH);\r
+    AsciiStrnCpy (GaugeEntryExArray[Index].Token, Token, DXE_PERFORMANCE_STRING_LENGTH);\r
   }\r
   if (Module != NULL) {\r
-    AsciiStrnCpy (GaugeEntryArray[Index].Module, Module, DXE_PERFORMANCE_STRING_LENGTH);\r
+    AsciiStrnCpy (GaugeEntryExArray[Index].Module, Module, DXE_PERFORMANCE_STRING_LENGTH);\r
   }\r
 \r
+  GaugeEntryExArray[Index].EndTimeStamp = 0;\r
+  GaugeEntryExArray[Index].Identifier = Identifier;\r
+\r
   if (TimeStamp == 0) {\r
     TimeStamp = GetPerformanceCounter ();\r
   }\r
-  GaugeEntryArray[Index].StartTimeStamp = TimeStamp;\r
+  GaugeEntryExArray[Index].StartTimeStamp = TimeStamp;\r
 \r
   mGaugeData->NumberOfEntries++;\r
 \r
@@ -189,7 +211,7 @@ StartGauge (
   for the first matching record that contains a zero end time and fills in a valid end time.\r
 \r
   Searches the performance measurement log from the beginning of the log\r
-  for the first record that matches Handle, Token, and Module and has an end time value of zero.\r
+  for the first record that matches Handle, Token, Module and Identifier and has an end time value of zero.\r
   If the record can not be found then return EFI_NOT_FOUND.\r
   If the record is found and TimeStamp is not zero,\r
   then the end time in the record is filled in with the value specified by TimeStamp.\r
@@ -203,6 +225,8 @@ StartGauge (
   @param  Module                  Pointer to a Null-terminated ASCII string\r
                                   that identifies the module being measured.\r
   @param  TimeStamp               64-bit time stamp.\r
+  @param  Identifier              32-bit identifier. If the value is 0, the found record\r
+                                  is same as the one found by EndGauge of PERFORMANCE_PROTOCOL.\r
 \r
   @retval EFI_SUCCESS             The end of  the measurement was recorded.\r
   @retval EFI_NOT_FOUND           The specified measurement record could not be found.\r
@@ -210,57 +234,60 @@ StartGauge (
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-EndGauge (\r
+EndGaugeEx (\r
   IN CONST VOID   *Handle,  OPTIONAL\r
   IN CONST CHAR8  *Token,   OPTIONAL\r
   IN CONST CHAR8  *Module,  OPTIONAL\r
-  IN UINT64       TimeStamp\r
+  IN UINT64       TimeStamp,\r
+  IN UINT32       Identifier\r
   )\r
 {\r
-  GAUGE_DATA_ENTRY  *GaugeEntryArray;\r
-  UINT32            Index;\r
+  GAUGE_DATA_ENTRY_EX *GaugeEntryExArray;\r
+  UINT32              Index;\r
 \r
   if (TimeStamp == 0) {\r
     TimeStamp = GetPerformanceCounter ();\r
   }\r
 \r
-  Index = InternalSearchForGaugeEntry (Handle, Token, Module);\r
+  Index = InternalSearchForGaugeEntry (Handle, Token, Module, Identifier);\r
   if (Index >= mGaugeData->NumberOfEntries) {\r
     return EFI_NOT_FOUND;\r
   }\r
-  GaugeEntryArray = (GAUGE_DATA_ENTRY  *) (mGaugeData + 1);\r
-  GaugeEntryArray[Index].EndTimeStamp = TimeStamp;\r
+  GaugeEntryExArray = (GAUGE_DATA_ENTRY_EX *) (mGaugeData + 1);\r
+  GaugeEntryExArray[Index].EndTimeStamp = TimeStamp;\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
   Retrieves a previously logged performance measurement.\r
+  It can also retrieve the log created by StartGauge and EndGauge of PERFORMANCE_PROTOCOL,\r
+  and then assign the Identifier with 0.\r
 \r
   Retrieves the performance log entry from the performance log specified by LogEntryKey.\r
   If it stands for a valid entry, then EFI_SUCCESS is returned and\r
-  GaugeDataEntry stores the pointer to that entry.\r
+  GaugeDataEntryEx stores the pointer to that entry.\r
 \r
   @param  LogEntryKey             The key for the previous performance measurement log entry.\r
                                   If 0, then the first performance measurement log entry is retrieved.\r
-  @param  GaugeDataEntry          The indirect pointer to the gauge data entry specified by LogEntryKey\r
+  @param  GaugeDataEntryEx        The indirect pointer to the extended gauge data entry specified by LogEntryKey\r
                                   if the retrieval is successful.\r
 \r
-  @retval EFI_SUCCESS             The GuageDataEntry is successfully found based on LogEntryKey.\r
+  @retval EFI_SUCCESS             The GuageDataEntryEx is successfully found based on LogEntryKey.\r
   @retval EFI_NOT_FOUND           The LogEntryKey is the last entry (equals to the total entry number).\r
   @retval EFI_INVALIDE_PARAMETER  The LogEntryKey is not a valid entry (greater than the total entry number).\r
-  @retval EFI_INVALIDE_PARAMETER  GaugeDataEntry is NULL.\r
+  @retval EFI_INVALIDE_PARAMETER  GaugeDataEntryEx is NULL.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-GetGauge (\r
-  IN  UINTN               LogEntryKey,\r
-  OUT GAUGE_DATA_ENTRY    **GaugeDataEntry\r
+GetGaugeEx (\r
+  IN  UINTN                 LogEntryKey,\r
+  OUT GAUGE_DATA_ENTRY_EX   **GaugeDataEntryEx\r
   )\r
 {\r
   UINTN               NumberOfEntries;\r
-  GAUGE_DATA_ENTRY    *LogEntryArray;\r
+  GAUGE_DATA_ENTRY_EX *GaugeEntryExArray;\r
 \r
   NumberOfEntries = (UINTN) (mGaugeData->NumberOfEntries);\r
   if (LogEntryKey > NumberOfEntries) {\r
@@ -270,12 +297,127 @@ GetGauge (
     return EFI_NOT_FOUND;\r
   }\r
 \r
-  LogEntryArray   = (GAUGE_DATA_ENTRY *) (mGaugeData + 1);\r
+  GaugeEntryExArray = (GAUGE_DATA_ENTRY_EX *) (mGaugeData + 1);\r
+\r
+  if (GaugeDataEntryEx == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  *GaugeDataEntryEx = &GaugeEntryExArray[LogEntryKey];\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Adds a record at the end of the performance measurement log\r
+  that records the start time of a performance measurement.\r
+\r
+  Adds a record to the end of the performance measurement log\r
+  that contains the Handle, Token, and Module.\r
+  The end time of the new record must be set to zero.\r
+  If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.\r
+  If TimeStamp is zero, the start time in the record is filled in with the value\r
+  read from the current time stamp.\r
+\r
+  @param  Handle                  Pointer to environment specific context used\r
+                                  to identify the component being measured.\r
+  @param  Token                   Pointer to a Null-terminated ASCII string\r
+                                  that identifies the component being measured.\r
+  @param  Module                  Pointer to a Null-terminated ASCII string\r
+                                  that identifies the module being measured.\r
+  @param  TimeStamp               64-bit time stamp.\r
+\r
+  @retval EFI_SUCCESS             The data was read correctly from the device.\r
+  @retval EFI_OUT_OF_RESOURCES    There are not enough resources to record the measurement.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+StartGauge (\r
+  IN CONST VOID   *Handle,  OPTIONAL\r
+  IN CONST CHAR8  *Token,   OPTIONAL\r
+  IN CONST CHAR8  *Module,  OPTIONAL\r
+  IN UINT64       TimeStamp\r
+  )\r
+{\r
+  return StartGaugeEx (Handle, Token, Module, TimeStamp, 0);\r
+}\r
+\r
+/**\r
+  Searches the performance measurement log from the beginning of the log\r
+  for the first matching record that contains a zero end time and fills in a valid end time.\r
+\r
+  Searches the performance measurement log from the beginning of the log\r
+  for the first record that matches Handle, Token, and Module and has an end time value of zero.\r
+  If the record can not be found then return EFI_NOT_FOUND.\r
+  If the record is found and TimeStamp is not zero,\r
+  then the end time in the record is filled in with the value specified by TimeStamp.\r
+  If the record is found and TimeStamp is zero, then the end time in the matching record\r
+  is filled in with the current time stamp value.\r
+\r
+  @param  Handle                  Pointer to environment specific context used\r
+                                  to identify the component being measured.\r
+  @param  Token                   Pointer to a Null-terminated ASCII string\r
+                                  that identifies the component being measured.\r
+  @param  Module                  Pointer to a Null-terminated ASCII string\r
+                                  that identifies the module being measured.\r
+  @param  TimeStamp               64-bit time stamp.\r
+\r
+  @retval EFI_SUCCESS             The end of  the measurement was recorded.\r
+  @retval EFI_NOT_FOUND           The specified measurement record could not be found.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EndGauge (\r
+  IN CONST VOID   *Handle,  OPTIONAL\r
+  IN CONST CHAR8  *Token,   OPTIONAL\r
+  IN CONST CHAR8  *Module,  OPTIONAL\r
+  IN UINT64       TimeStamp\r
+  )\r
+{\r
+  return EndGaugeEx (Handle, Token, Module, TimeStamp, 0);\r
+}\r
+\r
+/**\r
+  Retrieves a previously logged performance measurement.\r
+  It can also retrieve the log created by StartGaugeEx and EndGaugeEx of PERFORMANCE_EX_PROTOCOL,\r
+  and then eliminate the Identifier.\r
+\r
+  Retrieves the performance log entry from the performance log specified by LogEntryKey.\r
+  If it stands for a valid entry, then EFI_SUCCESS is returned and\r
+  GaugeDataEntry stores the pointer to that entry.\r
+\r
+  @param  LogEntryKey             The key for the previous performance measurement log entry.\r
+                                  If 0, then the first performance measurement log entry is retrieved.\r
+  @param  GaugeDataEntry          The indirect pointer to the gauge data entry specified by LogEntryKey\r
+                                  if the retrieval is successful.\r
+\r
+  @retval EFI_SUCCESS             The GuageDataEntry is successfully found based on LogEntryKey.\r
+  @retval EFI_NOT_FOUND           The LogEntryKey is the last entry (equals to the total entry number).\r
+  @retval EFI_INVALIDE_PARAMETER  The LogEntryKey is not a valid entry (greater than the total entry number).\r
+  @retval EFI_INVALIDE_PARAMETER  GaugeDataEntry is NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetGauge (\r
+  IN  UINTN               LogEntryKey,\r
+  OUT GAUGE_DATA_ENTRY    **GaugeDataEntry\r
+  )\r
+{\r
+  EFI_STATUS          Status;\r
+  GAUGE_DATA_ENTRY_EX *GaugeEntryEx;\r
+\r
+  Status = GetGaugeEx (LogEntryKey, &GaugeEntryEx);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
 \r
   if (GaugeDataEntry == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  *GaugeDataEntry = &LogEntryArray[LogEntryKey];\r
+\r
+  *GaugeDataEntry = (GAUGE_DATA_ENTRY *) GaugeEntryEx;\r
 \r
   return EFI_SUCCESS;\r
 }\r
@@ -296,12 +438,13 @@ InternalGetPeiPerformance (
   EFI_HOB_GUID_TYPE                 *GuidHob;\r
   PEI_PERFORMANCE_LOG_HEADER        *LogHob;\r
   PEI_PERFORMANCE_LOG_ENTRY         *LogEntryArray;\r
-  GAUGE_DATA_ENTRY                  *GaugeEntryArray;\r
+  UINT32                            *LogIdArray;\r
+  GAUGE_DATA_ENTRY_EX               *GaugeEntryExArray;\r
   UINT32                            Index;\r
   UINT32                            NumberOfEntries;\r
 \r
   NumberOfEntries = 0;\r
-  GaugeEntryArray = (GAUGE_DATA_ENTRY *) (mGaugeData + 1);\r
+  GaugeEntryExArray = (GAUGE_DATA_ENTRY_EX *) (mGaugeData + 1);\r
 \r
   //\r
   // Dump PEI Log Entries to DXE Guage Data structure.\r
@@ -310,15 +453,23 @@ InternalGetPeiPerformance (
   if (GuidHob != NULL) {\r
     LogHob          = GET_GUID_HOB_DATA (GuidHob);\r
     LogEntryArray   = (PEI_PERFORMANCE_LOG_ENTRY *) (LogHob + 1);\r
-    GaugeEntryArray = (GAUGE_DATA_ENTRY *) (mGaugeData + 1);\r
 \r
     NumberOfEntries = LogHob->NumberOfEntries;\r
     for (Index = 0; Index < NumberOfEntries; Index++) {\r
-      GaugeEntryArray[Index].Handle         = LogEntryArray[Index].Handle;\r
-      AsciiStrnCpy (GaugeEntryArray[Index].Token,  LogEntryArray[Index].Token,  DXE_PERFORMANCE_STRING_LENGTH);\r
-      AsciiStrnCpy (GaugeEntryArray[Index].Module, LogEntryArray[Index].Module, DXE_PERFORMANCE_STRING_LENGTH);\r
-      GaugeEntryArray[Index].StartTimeStamp = LogEntryArray[Index].StartTimeStamp;\r
-      GaugeEntryArray[Index].EndTimeStamp   = LogEntryArray[Index].EndTimeStamp;\r
+      GaugeEntryExArray[Index].Handle         = LogEntryArray[Index].Handle;\r
+      AsciiStrnCpy (GaugeEntryExArray[Index].Token,  LogEntryArray[Index].Token,  DXE_PERFORMANCE_STRING_LENGTH);\r
+      AsciiStrnCpy (GaugeEntryExArray[Index].Module, LogEntryArray[Index].Module, DXE_PERFORMANCE_STRING_LENGTH);\r
+      GaugeEntryExArray[Index].StartTimeStamp = LogEntryArray[Index].StartTimeStamp;\r
+      GaugeEntryExArray[Index].EndTimeStamp   = LogEntryArray[Index].EndTimeStamp;\r
+      GaugeEntryExArray[Index].Identifier     = 0;\r
+    }\r
+\r
+    GuidHob = GetFirstGuidHob (&gPerformanceExProtocolGuid);\r
+    if (GuidHob != NULL) {\r
+      LogIdArray    = GET_GUID_HOB_DATA (GuidHob);\r
+      for (Index = 0; Index < NumberOfEntries; Index++) {\r
+        GaugeEntryExArray[Index].Identifier   = LogIdArray[Index];\r
+      }\r
     }\r
   }\r
   mGaugeData->NumberOfEntries = NumberOfEntries;\r
@@ -327,7 +478,7 @@ InternalGetPeiPerformance (
 /**\r
   The constructor function initializes Performance infrastructure for DXE phase.\r
 \r
-  The constructor function publishes Performance protocol, allocates memory to log DXE performance\r
+  The constructor function publishes Performance and PerformanceEx protocol, allocates memory to log DXE performance\r
   and merges PEI performance data to DXE performance log.\r
   It will ASSERT() if one of these operations fails and it will always return EFI_SUCCESS.\r
 \r
@@ -355,17 +506,19 @@ DxeCorePerformanceLibConstructor (
   //\r
   // Install the protocol interfaces.\r
   //\r
-  Status = gBS->InstallProtocolInterface (\r
+  Status = gBS->InstallMultipleProtocolInterfaces (\r
                   &mHandle,\r
                   &gPerformanceProtocolGuid,\r
-                  EFI_NATIVE_INTERFACE,\r
-                  &mPerformanceInterface\r
+                  &mPerformanceInterface,\r
+                  &gPerformanceExProtocolGuid,\r
+                  &mPerformanceExInterface,\r
+                  NULL\r
                   );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
   mMaxGaugeRecords = INIT_DXE_GAUGE_DATA_ENTRIES + PcdGet8 (PcdMaxPeiPerformanceLogEntries);\r
 \r
-  mGaugeData = AllocateZeroPool (sizeof (GAUGE_DATA_HEADER) + (sizeof (GAUGE_DATA_ENTRY) * mMaxGaugeRecords));\r
+  mGaugeData = AllocateZeroPool (sizeof (GAUGE_DATA_HEADER) + (sizeof (GAUGE_DATA_ENTRY_EX) * mMaxGaugeRecords));\r
   ASSERT (mGaugeData != NULL);\r
 \r
   InternalGetPeiPerformance ();\r
@@ -378,7 +531,7 @@ DxeCorePerformanceLibConstructor (
   that records the start time of a performance measurement.\r
 \r
   Adds a record to the end of the performance measurement log\r
-  that contains the Handle, Token, and Module.\r
+  that contains the Handle, Token, Module and Identifier.\r
   The end time of the new record must be set to zero.\r
   If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.\r
   If TimeStamp is zero, the start time in the record is filled in with the value\r
@@ -391,6 +544,8 @@ DxeCorePerformanceLibConstructor (
   @param  Module                  Pointer to a Null-terminated ASCII string\r
                                   that identifies the module being measured.\r
   @param  TimeStamp               64-bit time stamp.\r
+  @param  Identifier              32-bit identifier. If the value is 0, the created record\r
+                                  is same as the one created by StartPerformanceMeasurement.\r
 \r
   @retval RETURN_SUCCESS          The start of the measurement was recorded.\r
   @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.\r
@@ -398,17 +553,15 @@ DxeCorePerformanceLibConstructor (
 **/\r
 RETURN_STATUS\r
 EFIAPI\r
-StartPerformanceMeasurement (\r
+StartPerformanceMeasurementEx (\r
   IN CONST VOID   *Handle,  OPTIONAL\r
   IN CONST CHAR8  *Token,   OPTIONAL\r
   IN CONST CHAR8  *Module,  OPTIONAL\r
-  IN UINT64       TimeStamp\r
+  IN UINT64       TimeStamp,\r
+  IN UINT32       Identifier\r
   )\r
 {\r
-  EFI_STATUS  Status;\r
-\r
-  Status = StartGauge (Handle, Token, Module, TimeStamp);\r
-  return (RETURN_STATUS) Status;\r
+  return (RETURN_STATUS) StartGaugeEx (Handle, Token, Module, TimeStamp, Identifier);\r
 }\r
 \r
 /**\r
@@ -416,7 +569,7 @@ StartPerformanceMeasurement (
   for the first matching record that contains a zero end time and fills in a valid end time.\r
 \r
   Searches the performance measurement log from the beginning of the log\r
-  for the first record that matches Handle, Token, and Module and has an end time value of zero.\r
+  for the first record that matches Handle, Token, Module and Identifier and has an end time value of zero.\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 the end time in the record is filled in with the value specified by TimeStamp.\r
@@ -430,6 +583,8 @@ StartPerformanceMeasurement (
   @param  Module                  Pointer to a Null-terminated ASCII string\r
                                   that identifies the module being measured.\r
   @param  TimeStamp               64-bit time stamp.\r
+  @param  Identifier              32-bit identifier. If the value is 0, the found record\r
+                                  is same as the one found by EndPerformanceMeasurement.\r
 \r
   @retval RETURN_SUCCESS          The end of  the measurement was recorded.\r
   @retval RETURN_NOT_FOUND        The specified measurement record could not be found.\r
@@ -437,21 +592,21 @@ StartPerformanceMeasurement (
 **/\r
 RETURN_STATUS\r
 EFIAPI\r
-EndPerformanceMeasurement (\r
+EndPerformanceMeasurementEx (\r
   IN CONST VOID   *Handle,  OPTIONAL\r
   IN CONST CHAR8  *Token,   OPTIONAL\r
   IN CONST CHAR8  *Module,  OPTIONAL\r
-  IN UINT64       TimeStamp\r
+  IN UINT64       TimeStamp,\r
+  IN UINT32       Identifier\r
   )\r
 {\r
-  EFI_STATUS  Status;\r
-\r
-  Status = EndGauge (Handle, Token, Module, TimeStamp);\r
-  return (RETURN_STATUS) Status;\r
+  return (RETURN_STATUS) EndGaugeEx (Handle, Token, Module, TimeStamp, Identifier);\r
 }\r
 \r
 /**\r
   Attempts to retrieve a performance measurement log entry from the performance measurement log.\r
+  It can also retrieve the log created by StartPerformanceMeasurement and EndPerformanceMeasurement,\r
+  and then assign the Identifier with 0.\r
 \r
   Attempts to retrieve the performance log entry specified by LogEntryKey.  If LogEntryKey is\r
   zero on entry, then an attempt is made to retrieve the first entry from the performance log,\r
@@ -462,13 +617,14 @@ EndPerformanceMeasurement (
   retrieved and an implementation specific non-zero key value that specifies the end of the performance\r
   log is returned.  If LogEntryKey is equal this implementation specific non-zero key value, then no entry\r
   is retrieved and zero is returned.  In the cases where a performance log entry can be returned,\r
-  the log entry is returned in Handle, Token, Module, StartTimeStamp, and EndTimeStamp.\r
+  the log entry is returned in Handle, Token, Module, StartTimeStamp, EndTimeStamp and Identifier.\r
   If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().\r
   If Handle is NULL, then ASSERT().\r
   If Token is NULL, then ASSERT().\r
   If Module is NULL, then ASSERT().\r
   If StartTimeStamp is NULL, then ASSERT().\r
   If EndTimeStamp is NULL, then ASSERT().\r
+  If Identifier is NULL, then ASSERT().\r
 \r
   @param  LogEntryKey             On entry, the key of the performance measurement log entry to retrieve.\r
                                   0, then the first performance measurement log entry is retrieved.\r
@@ -483,23 +639,25 @@ EndPerformanceMeasurement (
                                   was started.\r
   @param  EndTimeStamp            Pointer to the 64-bit time stamp that was recorded when the measurement\r
                                   was ended.\r
+  @param  Identifier              Pointer to the 32-bit identifier that was recorded.\r
 \r
   @return The key for the next performance log entry (in general case).\r
 \r
 **/\r
 UINTN\r
 EFIAPI\r
-GetPerformanceMeasurement (\r
-  IN  UINTN       LogEntryKey,\r
+GetPerformanceMeasurementEx (\r
+  IN  UINTN       LogEntryKey, \r
   OUT CONST VOID  **Handle,\r
   OUT CONST CHAR8 **Token,\r
   OUT CONST CHAR8 **Module,\r
   OUT UINT64      *StartTimeStamp,\r
-  OUT UINT64      *EndTimeStamp\r
+  OUT UINT64      *EndTimeStamp,\r
+  OUT UINT32      *Identifier\r
   )\r
 {\r
-  EFI_STATUS        Status;\r
-  GAUGE_DATA_ENTRY  *GaugeData;\r
+  EFI_STATUS           Status;\r
+  GAUGE_DATA_ENTRY_EX  *GaugeData;\r
 \r
   GaugeData = NULL;\r
   \r
@@ -508,8 +666,9 @@ GetPerformanceMeasurement (
   ASSERT (Module != NULL);\r
   ASSERT (StartTimeStamp != NULL);\r
   ASSERT (EndTimeStamp != NULL);\r
+  ASSERT (Identifier != NULL);\r
 \r
-  Status = GetGauge (LogEntryKey++, &GaugeData);\r
+  Status = GetGaugeEx (LogEntryKey++, &GaugeData);\r
 \r
   //\r
   // Make sure that LogEntryKey is a valid log entry key,\r
@@ -530,10 +689,136 @@ GetPerformanceMeasurement (
   *Module         = GaugeData->Module;\r
   *StartTimeStamp = GaugeData->StartTimeStamp;\r
   *EndTimeStamp   = GaugeData->EndTimeStamp;\r
+  *Identifier     = GaugeData->Identifier;\r
 \r
   return LogEntryKey;\r
 }\r
 \r
+/**\r
+  Adds a record at the end of the performance measurement log\r
+  that records the start time of a performance measurement.\r
+\r
+  Adds a record to the end of the performance measurement log\r
+  that contains the Handle, Token, and Module.\r
+  The end time of the new record must be set to zero.\r
+  If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.\r
+  If TimeStamp is zero, the start time in the record is filled in with the value\r
+  read from the current time stamp.\r
+\r
+  @param  Handle                  Pointer to environment specific context used\r
+                                  to identify the component being measured.\r
+  @param  Token                   Pointer to a Null-terminated ASCII string\r
+                                  that identifies the component being measured.\r
+  @param  Module                  Pointer to a Null-terminated ASCII string\r
+                                  that identifies the module being measured.\r
+  @param  TimeStamp               64-bit time stamp.\r
+\r
+  @retval RETURN_SUCCESS          The start of the measurement was recorded.\r
+  @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+StartPerformanceMeasurement (\r
+  IN CONST VOID   *Handle,  OPTIONAL\r
+  IN CONST CHAR8  *Token,   OPTIONAL\r
+  IN CONST CHAR8  *Module,  OPTIONAL\r
+  IN UINT64       TimeStamp\r
+  )\r
+{\r
+  return StartPerformanceMeasurementEx (Handle, Token, Module, TimeStamp, 0);\r
+}\r
+\r
+/**\r
+  Searches the performance measurement log from the beginning of the log\r
+  for the first matching record that contains a zero end time and fills in a valid end time.\r
+\r
+  Searches the performance measurement log from the beginning of the log\r
+  for the first record that matches Handle, Token, and Module and has an end time value of zero.\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 the end time in the record is filled in with the value specified by TimeStamp.\r
+  If the record is found and TimeStamp is zero, then the end time in the matching record\r
+  is filled in with the current time stamp value.\r
+\r
+  @param  Handle                  Pointer to environment specific context used\r
+                                  to identify the component being measured.\r
+  @param  Token                   Pointer to a Null-terminated ASCII string\r
+                                  that identifies the component being measured.\r
+  @param  Module                  Pointer to a Null-terminated ASCII string\r
+                                  that identifies the module being measured.\r
+  @param  TimeStamp               64-bit time stamp.\r
+\r
+  @retval RETURN_SUCCESS          The end of  the measurement was recorded.\r
+  @retval RETURN_NOT_FOUND        The specified measurement record could not be found.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+EndPerformanceMeasurement (\r
+  IN CONST VOID   *Handle,  OPTIONAL\r
+  IN CONST CHAR8  *Token,   OPTIONAL\r
+  IN CONST CHAR8  *Module,  OPTIONAL\r
+  IN UINT64       TimeStamp\r
+  )\r
+{\r
+  return EndPerformanceMeasurementEx (Handle, Token, Module, TimeStamp, 0);\r
+}\r
+\r
+/**\r
+  Attempts to retrieve a performance measurement log entry from the performance measurement log.\r
+  It can also retrieve the log created by StartPerformanceMeasurementEx and EndPerformanceMeasurementEx,\r
+  and then eliminate the Identifier.\r
+\r
+  Attempts to retrieve the performance log entry specified by LogEntryKey.  If LogEntryKey is\r
+  zero on entry, then an attempt is made to retrieve the first entry from the performance log,\r
+  and the key for the second entry in the log is returned.  If the performance log is empty,\r
+  then no entry is retrieved and zero is returned.  If LogEntryKey is not zero, then the performance\r
+  log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is\r
+  returned.  If LogEntryKey is the key for the last entry in the log, then the last log entry is\r
+  retrieved and an implementation specific non-zero key value that specifies the end of the performance\r
+  log is returned.  If LogEntryKey is equal this implementation specific non-zero key value, then no entry\r
+  is retrieved and zero is returned.  In the cases where a performance log entry can be returned,\r
+  the log entry is returned in Handle, Token, Module, StartTimeStamp, and EndTimeStamp.\r
+  If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().\r
+  If Handle is NULL, then ASSERT().\r
+  If Token is NULL, then ASSERT().\r
+  If Module is NULL, then ASSERT().\r
+  If StartTimeStamp is NULL, then ASSERT().\r
+  If EndTimeStamp is NULL, then ASSERT().\r
+\r
+  @param  LogEntryKey             On entry, the key of the performance measurement log entry to retrieve.\r
+                                  0, then the first performance measurement log entry is retrieved.\r
+                                  On exit, the key of the next performance log entry.\r
+  @param  Handle                  Pointer to environment specific context used to identify the component\r
+                                  being measured.\r
+  @param  Token                   Pointer to a Null-terminated ASCII string that identifies the component\r
+                                  being measured.\r
+  @param  Module                  Pointer to a Null-terminated ASCII string that identifies the module\r
+                                  being measured.\r
+  @param  StartTimeStamp          Pointer to the 64-bit time stamp that was recorded when the measurement\r
+                                  was started.\r
+  @param  EndTimeStamp            Pointer to the 64-bit time stamp that was recorded when the measurement\r
+                                  was ended.\r
+\r
+  @return The key for the next performance log entry (in general case).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+GetPerformanceMeasurement (\r
+  IN  UINTN       LogEntryKey,\r
+  OUT CONST VOID  **Handle,\r
+  OUT CONST CHAR8 **Token,\r
+  OUT CONST CHAR8 **Module,\r
+  OUT UINT64      *StartTimeStamp,\r
+  OUT UINT64      *EndTimeStamp\r
+  )\r
+{\r
+  UINT32 Identifier;\r
+  return GetPerformanceMeasurementEx (LogEntryKey, Handle, Token, Module, StartTimeStamp, EndTimeStamp, &Identifier);\r
+}\r
+\r
 /**\r
   Returns TRUE if the performance measurement macros are enabled.\r
 \r
index 6ab725309c4dfc42696777dd11c0fb9a340e1831..64d7e3db4ae20934090d7c1587b8390dbbd5a927 100644 (file)
@@ -4,12 +4,12 @@
 #  This library provides the performance measurement interfaces and initializes performance\r
 #  logging for DXE phase. It first initializes its private global data structure for\r
 #  performance logging and saves the performance GUIDed HOB passed from PEI phase. \r
-#  It initializes DXE phase performance logging by publishing the Performance Protocol,\r
+#  It initializes DXE phase performance logging by publishing the Performance and PerformanceEx Protocol,\r
 #  which is consumed by DxePerformanceLib to logging performance data in DXE phase.\r
 #  This library is mainly used by DxeCore to start performance logging to ensure that\r
-#  Performance Protocol is installed at the very beginning of DXE phase.\r
+#  Performance and PerformanceEx Protocol are installed at the very beginning of DXE phase.\r
 #  \r
-#  Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
+#  Copyright (c) 2006 - 2012, 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
@@ -59,6 +59,8 @@
 [Guids]\r
   gPerformanceProtocolGuid                        ## CONSUMES ## HOB\r
   gPerformanceProtocolGuid                        ## PRODUCES ## PROTOCOL\r
+  gPerformanceExProtocolGuid                      ## CONSUMES ## HOB\r
+  gPerformanceExProtocolGuid                      ## PRODUCES ## PROTOCOL\r
 \r
 [Pcd]\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdMaxPeiPerformanceLogEntries\r
index 2005e174e843cbe985a035c57fdc00dbc19938e1..2b9ccd2fee0c1895fb5044965302f5023e791f4a 100644 (file)
@@ -1,10 +1,10 @@
 /** @file\r
   Master header files for DxeCorePerformanceLib instance.\r
 \r
-  This header file holds the prototypes of the Performance Protocol published by this\r
+  This header file holds the prototypes of the Performance and PerformanceEx Protocol published by this\r
   library instance at its constructor.\r
 \r
-Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2012, 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
@@ -33,6 +33,107 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/UefiBootServicesTableLib.h>\r
 #include <Library/MemoryAllocationLib.h>\r
 \r
+//\r
+// Interface declarations for PerformanceEx Protocol.\r
+//\r
+/**\r
+  Adds a record at the end of the performance measurement log\r
+  that records the start time of a performance measurement.\r
+\r
+  Adds a record to the end of the performance measurement log\r
+  that contains the Handle, Token, Module and Identifier.\r
+  The end time of the new record must be set to zero.\r
+  If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.\r
+  If TimeStamp is zero, the start time in the record is filled in with the value\r
+  read from the current time stamp.\r
+\r
+  @param  Handle                  Pointer to environment specific context used\r
+                                  to identify the component being measured.\r
+  @param  Token                   Pointer to a Null-terminated ASCII string\r
+                                  that identifies the component being measured.\r
+  @param  Module                  Pointer to a Null-terminated ASCII string\r
+                                  that identifies the module being measured.\r
+  @param  TimeStamp               64-bit time stamp.\r
+  @param  Identifier              32-bit identifier. If the value is 0, the created record\r
+                                  is same as the one created by StartGauge of PERFORMANCE_PROTOCOL.\r
+\r
+  @retval EFI_SUCCESS             The data was read correctly from the device.\r
+  @retval EFI_OUT_OF_RESOURCES    There are not enough resources to record the measurement.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+StartGaugeEx (\r
+  IN CONST VOID   *Handle,  OPTIONAL\r
+  IN CONST CHAR8  *Token,   OPTIONAL\r
+  IN CONST CHAR8  *Module,  OPTIONAL\r
+  IN UINT64       TimeStamp,\r
+  IN UINT32       Identifier\r
+  );\r
+\r
+/**\r
+  Searches the performance measurement log from the beginning of the log\r
+  for the first matching record that contains a zero end time and fills in a valid end time.\r
+\r
+  Searches the performance measurement log from the beginning of the log\r
+  for the first record that matches Handle, Token, Module and Identifier and has an end time value of zero.\r
+  If the record can not be found then return EFI_NOT_FOUND.\r
+  If the record is found and TimeStamp is not zero,\r
+  then the end time in the record is filled in with the value specified by TimeStamp.\r
+  If the record is found and TimeStamp is zero, then the end time in the matching record\r
+  is filled in with the current time stamp value.\r
+\r
+  @param  Handle                  Pointer to environment specific context used\r
+                                  to identify the component being measured.\r
+  @param  Token                   Pointer to a Null-terminated ASCII string\r
+                                  that identifies the component being measured.\r
+  @param  Module                  Pointer to a Null-terminated ASCII string\r
+                                  that identifies the module being measured.\r
+  @param  TimeStamp               64-bit time stamp.\r
+  @param  Identifier              32-bit identifier. If the value is 0, the found record\r
+                                  is same as the one found by EndGauge of PERFORMANCE_PROTOCOL.\r
+\r
+  @retval EFI_SUCCESS             The end of  the measurement was recorded.\r
+  @retval EFI_NOT_FOUND           The specified measurement record could not be found.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EndGaugeEx (\r
+  IN CONST VOID   *Handle,  OPTIONAL\r
+  IN CONST CHAR8  *Token,   OPTIONAL\r
+  IN CONST CHAR8  *Module,  OPTIONAL\r
+  IN UINT64       TimeStamp,\r
+  IN UINT32       Identifier\r
+  );\r
+\r
+/**\r
+  Retrieves a previously logged performance measurement.\r
+  It can also retrieve the log created by StartGauge and EndGauge of PERFORMANCE_PROTOCOL,\r
+  and then assign the Identifier with 0.\r
+\r
+  Retrieves the performance log entry from the performance log specified by LogEntryKey.\r
+  If it stands for a valid entry, then EFI_SUCCESS is returned and\r
+  GaugeDataEntryEx stores the pointer to that entry.\r
+\r
+  @param  LogEntryKey             The key for the previous performance measurement log entry.\r
+                                  If 0, then the first performance measurement log entry is retrieved.\r
+  @param  GaugeDataEntryEx        The indirect pointer to the extended gauge data entry specified by LogEntryKey\r
+                                  if the retrieval is successful.\r
+\r
+  @retval EFI_SUCCESS             The GuageDataEntryEx is successfully found based on LogEntryKey.\r
+  @retval EFI_NOT_FOUND           The LogEntryKey is the last entry (equals to the total entry number).\r
+  @retval EFI_INVALIDE_PARAMETER  The LogEntryKey is not a valid entry (greater than the total entry number).\r
+  @retval EFI_INVALIDE_PARAMETER  GaugeDataEntryEx is NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetGaugeEx (\r
+  IN  UINTN                 LogEntryKey,\r
+  OUT GAUGE_DATA_ENTRY_EX   **GaugeDataEntryEx\r
+  );\r
+\r
 //\r
 // Interface declarations for Performance Protocol.\r
 //\r
@@ -103,6 +204,8 @@ EndGauge (
 \r
 /**\r
   Retrieves a previously logged performance measurement.\r
+  It can also retrieve the log created by StartGaugeEx and EndGaugeEx of PERFORMANCE_EX_PROTOCOL,\r
+  and then eliminate the Identifier.\r
 \r
   Retrieves the performance log entry from the performance log specified by LogEntryKey.\r
   If it stands for a valid entry, then EFI_SUCCESS is returned and\r
index 5fb3ff226442c0e86706440fed53e4ea19575d06..2ddd983126ecdf4dba6f52eca3c10b932f63025f 100644 (file)
@@ -2,8 +2,8 @@
   Performance Library\r
 \r
   This library instance provides infrastructure for DXE phase drivers to log performance\r
-  data. It consumes Performance Protocol published by DxeCorePerformanceLib\r
-  to log performance data. If Performance Protocol is not available, it does not log any\r
+  data. It consumes PerformanceEx or Performance Protocol published by DxeCorePerformanceLib\r
+  to log performance data. If both PerformanceEx and Performance Protocol is not available, it does not log any\r
   performance information.\r
 \r
   Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
@@ -28,18 +28,18 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/PcdLib.h>\r
 \r
 //\r
-// The cached performance protocol interface.\r
+// The cached Performance Protocol and PerformanceEx Protocol interface.\r
 //\r
-PERFORMANCE_PROTOCOL    *mPerformance = NULL;\r
+PERFORMANCE_PROTOCOL        *mPerformance = NULL;\r
+PERFORMANCE_EX_PROTOCOL     *mPerformanceEx = NULL;\r
 \r
 /**\r
-  The constructor function caches the pointer to Performance protocol.\r
+  The function caches the pointers to PerformanceEx protocol and Performance Protocol.\r
 \r
-  The constructor function locates Performance protocol from protocol database.\r
-  It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.\r
+  The function locates PerformanceEx protocol and Performance Protocol from protocol database.\r
 \r
-  @retval EFI_SUCCESS     Performance protocol is successfully located.\r
-  @retval Other           Performance protocol is not located to log performance.\r
+  @retval EFI_SUCCESS     PerformanceEx protocol or Performance Protocol is successfully located.\r
+  @retval EFI_NOT_FOUND   Both PerformanceEx protocol and Performance Protocol are not located to log performance.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -47,10 +47,21 @@ GetPerformanceProtocol (
   VOID\r
   )\r
 {\r
-  EFI_STATUS            Status;\r
-  PERFORMANCE_PROTOCOL  *Performance;\r
+  EFI_STATUS                Status;\r
+  PERFORMANCE_PROTOCOL      *Performance;\r
+  PERFORMANCE_EX_PROTOCOL   *PerformanceEx;\r
 \r
-  if (mPerformance != NULL) {\r
+  if (mPerformanceEx != NULL || mPerformance != NULL) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  Status = gBS->LocateProtocol (&gPerformanceExProtocolGuid, NULL, (VOID **) &PerformanceEx);\r
+  if (!EFI_ERROR (Status)) {\r
+    ASSERT (PerformanceEx != NULL);\r
+    //\r
+    // Cache PerformanceEx Protocol.\r
+    //\r
+    mPerformanceEx = PerformanceEx;\r
     return EFI_SUCCESS;\r
   }\r
 \r
@@ -61,15 +72,16 @@ GetPerformanceProtocol (
     // Cache performance protocol.\r
     //\r
     mPerformance = Performance;\r
+    return EFI_SUCCESS;\r
   }\r
 \r
-  return Status;\r
+  return EFI_NOT_FOUND;\r
 }\r
 \r
 /**\r
   Creates a record for the beginning of a performance measurement.\r
 \r
-  Creates a record that contains the Handle, Token, and Module.\r
+  Creates a record that contains the Handle, Token, Module and Identifier.\r
   If TimeStamp is not zero, then TimeStamp is added to the record as the start time.\r
   If TimeStamp is zero, then this function reads the current time stamp\r
   and adds that time stamp value to the record as the start time.\r
@@ -81,6 +93,8 @@ GetPerformanceProtocol (
   @param  Module                  Pointer to a Null-terminated ASCII string\r
                                   that identifies the module being measured.\r
   @param  TimeStamp               64-bit time stamp.\r
+  @param  Identifier              32-bit identifier. If the value is 0, the created record\r
+                                  is same as the one created by StartPerformanceMeasurement.\r
 \r
   @retval RETURN_SUCCESS          The start of the measurement was recorded.\r
   @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.\r
@@ -88,11 +102,12 @@ GetPerformanceProtocol (
 **/\r
 RETURN_STATUS\r
 EFIAPI\r
-StartPerformanceMeasurement (\r
+StartPerformanceMeasurementEx (\r
   IN CONST VOID   *Handle,  OPTIONAL\r
   IN CONST CHAR8  *Token,   OPTIONAL\r
   IN CONST CHAR8  *Module,  OPTIONAL\r
-  IN UINT64       TimeStamp\r
+  IN UINT64       TimeStamp,\r
+  IN UINT32       Identifier\r
   )\r
 {\r
   EFI_STATUS  Status;\r
@@ -102,7 +117,13 @@ StartPerformanceMeasurement (
     return RETURN_OUT_OF_RESOURCES;\r
   }\r
 \r
-  Status = mPerformance->StartGauge (Handle, Token, Module, TimeStamp);\r
+  if (mPerformanceEx != NULL) {\r
+    Status = mPerformanceEx->StartGaugeEx (Handle, Token, Module, TimeStamp, Identifier);\r
+  } else if (mPerformance != NULL) {\r
+    Status = mPerformance->StartGauge (Handle, Token, Module, TimeStamp);\r
+  } else {\r
+    ASSERT (FALSE);\r
+  }\r
 \r
   return (RETURN_STATUS) Status;\r
 }\r
@@ -110,7 +131,7 @@ StartPerformanceMeasurement (
 /**\r
   Fills in the end time of a performance measurement.\r
 \r
-  Looks up the record that matches Handle, Token, and Module.\r
+  Looks up the record that matches Handle, Token, Module and Identifier.\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
@@ -124,6 +145,8 @@ StartPerformanceMeasurement (
   @param  Module                  Pointer to a Null-terminated ASCII string\r
                                   that identifies the module being measured.\r
   @param  TimeStamp               64-bit time stamp.\r
+  @param  Identifier              32-bit identifier. If the value is 0, the found record\r
+                                  is same as the one found by EndPerformanceMeasurement.\r
 \r
   @retval RETURN_SUCCESS          The end of  the measurement was recorded.\r
   @retval RETURN_NOT_FOUND        The specified measurement record could not be found.\r
@@ -131,11 +154,12 @@ StartPerformanceMeasurement (
 **/\r
 RETURN_STATUS\r
 EFIAPI\r
-EndPerformanceMeasurement (\r
+EndPerformanceMeasurementEx (\r
   IN CONST VOID   *Handle,  OPTIONAL\r
   IN CONST CHAR8  *Token,   OPTIONAL\r
   IN CONST CHAR8  *Module,  OPTIONAL\r
-  IN UINT64       TimeStamp\r
+  IN UINT64       TimeStamp,\r
+  IN UINT32       Identifier\r
   )\r
 {\r
   EFI_STATUS  Status;\r
@@ -145,13 +169,21 @@ EndPerformanceMeasurement (
     return RETURN_NOT_FOUND;\r
   }\r
 \r
-  Status = mPerformance->EndGauge (Handle, Token, Module, TimeStamp);\r
+  if (mPerformanceEx != NULL) {\r
+    Status = mPerformanceEx->EndGaugeEx (Handle, Token, Module, TimeStamp, Identifier);\r
+  } else if (mPerformance != NULL) {\r
+    Status = mPerformance->EndGauge (Handle, Token, Module, TimeStamp);\r
+  } else {\r
+    ASSERT (FALSE);\r
+  }\r
 \r
   return (RETURN_STATUS) Status;\r
 }\r
 \r
 /**\r
   Attempts to retrieve a performance measurement log entry from the performance measurement log.\r
+  It can also retrieve the log created by StartPerformanceMeasurement and EndPerformanceMeasurement,\r
+  and then assign the Identifier with 0.\r
 \r
   Attempts to retrieve the performance log entry specified by LogEntryKey.  If LogEntryKey is\r
   zero on entry, then an attempt is made to retrieve the first entry from the performance log,\r
@@ -162,13 +194,14 @@ EndPerformanceMeasurement (
   retrieved and an implementation specific non-zero key value that specifies the end of the performance\r
   log is returned.  If LogEntryKey is equal this implementation specific non-zero key value, then no entry\r
   is retrieved and zero is returned.  In the cases where a performance log entry can be returned,\r
-  the log entry is returned in Handle, Token, Module, StartTimeStamp, and EndTimeStamp.\r
+  the log entry is returned in Handle, Token, Module, StartTimeStamp, EndTimeStamp and Identifier.\r
   If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().\r
   If Handle is NULL, then ASSERT().\r
   If Token is NULL, then ASSERT().\r
   If Module is NULL, then ASSERT().\r
   If StartTimeStamp is NULL, then ASSERT().\r
   If EndTimeStamp is NULL, then ASSERT().\r
+  If Identifier is NULL, then ASSERT().\r
 \r
   @param  LogEntryKey             On entry, the key of the performance measurement log entry to retrieve.\r
                                   0, then the first performance measurement log entry is retrieved.\r
@@ -183,36 +216,48 @@ EndPerformanceMeasurement (
                                   was started.\r
   @param  EndTimeStamp            Pointer to the 64-bit time stamp that was recorded when the measurement\r
                                   was ended.\r
+  @param  Identifier              Pointer to the 32-bit identifier that was recorded.\r
 \r
   @return The key for the next performance log entry (in general case).\r
 \r
 **/\r
 UINTN\r
 EFIAPI\r
-GetPerformanceMeasurement (\r
-  IN  UINTN       LogEntryKey,\r
+GetPerformanceMeasurementEx (\r
+  IN  UINTN       LogEntryKey, \r
   OUT CONST VOID  **Handle,\r
   OUT CONST CHAR8 **Token,\r
   OUT CONST CHAR8 **Module,\r
   OUT UINT64      *StartTimeStamp,\r
-  OUT UINT64      *EndTimeStamp\r
+  OUT UINT64      *EndTimeStamp,\r
+  OUT UINT32      *Identifier\r
   )\r
 {\r
-  EFI_STATUS        Status;\r
-  GAUGE_DATA_ENTRY  *GaugeData;\r
+  EFI_STATUS            Status;\r
+  GAUGE_DATA_ENTRY_EX   *GaugeData;\r
+\r
+  GaugeData = NULL;\r
 \r
   ASSERT (Handle != NULL);\r
   ASSERT (Token != NULL);\r
   ASSERT (Module != NULL);\r
   ASSERT (StartTimeStamp != NULL);\r
   ASSERT (EndTimeStamp != NULL);\r
+  ASSERT (Identifier != NULL);\r
 \r
   Status = GetPerformanceProtocol ();\r
   if (EFI_ERROR (Status)) {\r
     return 0;\r
   }\r
 \r
-  Status = mPerformance->GetGauge (LogEntryKey++, &GaugeData);\r
+  if (mPerformanceEx != NULL) {\r
+    Status = mPerformanceEx->GetGaugeEx (LogEntryKey++, &GaugeData);\r
+  } else if (mPerformance != NULL) {\r
+    Status = mPerformance->GetGauge (LogEntryKey++, (GAUGE_DATA_ENTRY **) &GaugeData);\r
+  } else {\r
+    ASSERT (FALSE);\r
+    return 0;\r
+  }\r
 \r
   //\r
   // Make sure that LogEntryKey is a valid log entry key,\r
@@ -233,10 +278,135 @@ GetPerformanceMeasurement (
   *Module         = GaugeData->Module;\r
   *StartTimeStamp = GaugeData->StartTimeStamp;\r
   *EndTimeStamp   = GaugeData->EndTimeStamp;\r
+  if (mPerformanceEx != NULL) {\r
+    *Identifier   = GaugeData->Identifier;\r
+  } else {\r
+    *Identifier   = 0;\r
+  }\r
 \r
   return LogEntryKey;\r
 }\r
 \r
+/**\r
+  Creates a record for the beginning of a performance measurement.\r
+\r
+  Creates a record that contains the Handle, Token, and Module.\r
+  If TimeStamp is not zero, then TimeStamp is added to the record as the start time.\r
+  If TimeStamp is zero, then this function reads the current time stamp\r
+  and adds that time stamp value to the record as the start time.\r
+\r
+  @param  Handle                  Pointer to environment specific context used\r
+                                  to identify the component being measured.\r
+  @param  Token                   Pointer to a Null-terminated ASCII string\r
+                                  that identifies the component being measured.\r
+  @param  Module                  Pointer to a Null-terminated ASCII string\r
+                                  that identifies the module being measured.\r
+  @param  TimeStamp               64-bit time stamp.\r
+\r
+  @retval RETURN_SUCCESS          The start of the measurement was recorded.\r
+  @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+StartPerformanceMeasurement (\r
+  IN CONST VOID   *Handle,  OPTIONAL\r
+  IN CONST CHAR8  *Token,   OPTIONAL\r
+  IN CONST CHAR8  *Module,  OPTIONAL\r
+  IN UINT64       TimeStamp\r
+  )\r
+{\r
+  return StartPerformanceMeasurementEx (Handle, Token, Module, TimeStamp, 0);\r
+}\r
+\r
+/**\r
+  Fills in the end time of a performance measurement.\r
+\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
+  If the record is found and TimeStamp is zero, then this function reads\r
+  the current time stamp and adds that time stamp value to the record as the end time.\r
+\r
+  @param  Handle                  Pointer to environment specific context used\r
+                                  to identify the component being measured.\r
+  @param  Token                   Pointer to a Null-terminated ASCII string\r
+                                  that identifies the component being measured.\r
+  @param  Module                  Pointer to a Null-terminated ASCII string\r
+                                  that identifies the module being measured.\r
+  @param  TimeStamp               64-bit time stamp.\r
+\r
+  @retval RETURN_SUCCESS          The end of  the measurement was recorded.\r
+  @retval RETURN_NOT_FOUND        The specified measurement record could not be found.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+EndPerformanceMeasurement (\r
+  IN CONST VOID   *Handle,  OPTIONAL\r
+  IN CONST CHAR8  *Token,   OPTIONAL\r
+  IN CONST CHAR8  *Module,  OPTIONAL\r
+  IN UINT64       TimeStamp\r
+  )\r
+{\r
+  return EndPerformanceMeasurementEx (Handle, Token, Module, TimeStamp, 0);\r
+}\r
+\r
+/**\r
+  Attempts to retrieve a performance measurement log entry from the performance measurement log.\r
+  It can also retrieve the log created by StartPerformanceMeasurementEx and EndPerformanceMeasurementEx,\r
+  and then eliminate the Identifier.\r
+\r
+  Attempts to retrieve the performance log entry specified by LogEntryKey.  If LogEntryKey is\r
+  zero on entry, then an attempt is made to retrieve the first entry from the performance log,\r
+  and the key for the second entry in the log is returned.  If the performance log is empty,\r
+  then no entry is retrieved and zero is returned.  If LogEntryKey is not zero, then the performance\r
+  log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is\r
+  returned.  If LogEntryKey is the key for the last entry in the log, then the last log entry is\r
+  retrieved and an implementation specific non-zero key value that specifies the end of the performance\r
+  log is returned.  If LogEntryKey is equal this implementation specific non-zero key value, then no entry\r
+  is retrieved and zero is returned.  In the cases where a performance log entry can be returned,\r
+  the log entry is returned in Handle, Token, Module, StartTimeStamp, and EndTimeStamp.\r
+  If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().\r
+  If Handle is NULL, then ASSERT().\r
+  If Token is NULL, then ASSERT().\r
+  If Module is NULL, then ASSERT().\r
+  If StartTimeStamp is NULL, then ASSERT().\r
+  If EndTimeStamp is NULL, then ASSERT().\r
+\r
+  @param  LogEntryKey             On entry, the key of the performance measurement log entry to retrieve.\r
+                                  0, then the first performance measurement log entry is retrieved.\r
+                                  On exit, the key of the next performance log entry.\r
+  @param  Handle                  Pointer to environment specific context used to identify the component\r
+                                  being measured.\r
+  @param  Token                   Pointer to a Null-terminated ASCII string that identifies the component\r
+                                  being measured.\r
+  @param  Module                  Pointer to a Null-terminated ASCII string that identifies the module\r
+                                  being measured.\r
+  @param  StartTimeStamp          Pointer to the 64-bit time stamp that was recorded when the measurement\r
+                                  was started.\r
+  @param  EndTimeStamp            Pointer to the 64-bit time stamp that was recorded when the measurement\r
+                                  was ended.\r
+\r
+  @return The key for the next performance log entry (in general case).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+GetPerformanceMeasurement (\r
+  IN  UINTN       LogEntryKey,\r
+  OUT CONST VOID  **Handle,\r
+  OUT CONST CHAR8 **Token,\r
+  OUT CONST CHAR8 **Module,\r
+  OUT UINT64      *StartTimeStamp,\r
+  OUT UINT64      *EndTimeStamp\r
+  )\r
+{\r
+  UINT32 Identifier;\r
+  return GetPerformanceMeasurementEx (LogEntryKey, Handle, Token, Module, StartTimeStamp, EndTimeStamp, &Identifier);\r
+}\r
+\r
 /**\r
   Returns TRUE if the performance measurement macros are enabled.\r
 \r
index 886fa462e444af62d562ebe70517fd866e1b2f52..c043848a2fed0169e450ff1ff4ccb97916977d02 100644 (file)
@@ -2,11 +2,11 @@
 #  Performance library instance used in DXE phase.\r
 #  \r
 #  This library instance provides infrastructure for DXE phase drivers to log performance\r
-#  data. It consumes Performance Protocol published by DxeCorePerformanceLib\r
-#  to log performance data. If Performance Protocol is not available, it does not log any\r
+#  data. It consumes PerformanceEx or Performance Protocol published by DxeCorePerformanceLib\r
+#  to log performance data. If both PerformanceEx and Performance Protocol are not available, it does not log any\r
 #  performance information.\r
 #  \r
-#  Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
+#  Copyright (c) 2006 - 2012, 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
@@ -47,7 +47,8 @@
 \r
 \r
 [Guids]\r
-  gPerformanceProtocolGuid  ## CONSUMES ## PROTOCOL\r
+  gPerformanceProtocolGuid      ## SOMETIMES_CONSUMES ## PROTOCOL\r
+  gPerformanceExProtocolGuid    ## SOMETIMES_CONSUMES ## PROTOCOL\r
 \r
 \r
 [Pcd]\r
index 19e9877cbfbaef5b48240c99f16f7e353ca25301..3ceda5ef6ee3417933c66411a268c39f0ab52851 100644 (file)
@@ -2,7 +2,8 @@
   Performance library instance used in DXE phase to dump SMM performance data.\r
 \r
   This library instance allows a DXE driver or UEFI application to dump the SMM performance data.\r
-  StartPerformanceMeasurement() and EndPerformanceMeasurement() are not implemented.\r
+  StartPerformanceMeasurement(), EndPerformanceMeasurement(), StartPerformanceMeasurementEx()\r
+  and EndPerformanceMeasurementEx() are not implemented.\r
 \r
   Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
@@ -39,16 +40,16 @@ EFI_SMM_COMMUNICATION_PROTOCOL  *mSmmCommunication = NULL;
 UINT8                           mSmmPerformanceBuffer[SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE];\r
 GAUGE_DATA_ENTRY                *mGaugeData = NULL;\r
 UINTN                           mGaugeNumberOfEntries = 0;\r
-\r
+GAUGE_DATA_ENTRY_EX             *mGaugeDataEx = NULL;\r
+UINTN                           mGaugeNumberOfEntriesEx = 0;\r
 \r
 /**\r
-  The constructor function caches the pointer to SMM Communication protocol.\r
+  The function caches the pointer to SMM Communication protocol.\r
 \r
-  The constructor function locates Performance protocol from protocol database.\r
-  It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.\r
+  The function locates SMM Communication protocol from protocol database.\r
 \r
-  @retval EFI_SUCCESS     Performance protocol is successfully located.\r
-  @retval Other           Performance protocol is not located to log performance.\r
+  @retval EFI_SUCCESS     SMM Communication protocol is successfully located.\r
+  @retval Other           SMM Communication protocol is not located to log performance.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -75,6 +76,78 @@ GetCommunicationProtocol (
   return Status;\r
 }\r
 \r
+/**\r
+  Creates a record for the beginning of a performance measurement.\r
+\r
+  Creates a record that contains the Handle, Token, Module and Identifier.\r
+  If TimeStamp is not zero, then TimeStamp is added to the record as the start time.\r
+  If TimeStamp is zero, then this function reads the current time stamp\r
+  and adds that time stamp value to the record as the start time.\r
+\r
+  @param  Handle                  Pointer to environment specific context used\r
+                                  to identify the component being measured.\r
+  @param  Token                   Pointer to a Null-terminated ASCII string\r
+                                  that identifies the component being measured.\r
+  @param  Module                  Pointer to a Null-terminated ASCII string\r
+                                  that identifies the module being measured.\r
+  @param  TimeStamp               64-bit time stamp.\r
+  @param  Identifier              32-bit identifier. If the value is 0, the created record\r
+                                  is same as the one created by StartPerformanceMeasurement.\r
+\r
+  @retval RETURN_SUCCESS          The start of the measurement was recorded.\r
+  @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+StartPerformanceMeasurementEx (\r
+  IN CONST VOID   *Handle,  OPTIONAL\r
+  IN CONST CHAR8  *Token,   OPTIONAL\r
+  IN CONST CHAR8  *Module,  OPTIONAL\r
+  IN UINT64       TimeStamp,\r
+  IN UINT32       Identifier\r
+  )\r
+{\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Fills in the end time of a performance measurement.\r
+\r
+  Looks up the record that matches Handle, Token, Module and Identifier.\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
+  If the record is found and TimeStamp is zero, then this function reads\r
+  the current time stamp and adds that time stamp value to the record as the end time.\r
+\r
+  @param  Handle                  Pointer to environment specific context used\r
+                                  to identify the component being measured.\r
+  @param  Token                   Pointer to a Null-terminated ASCII string\r
+                                  that identifies the component being measured.\r
+  @param  Module                  Pointer to a Null-terminated ASCII string\r
+                                  that identifies the module being measured.\r
+  @param  TimeStamp               64-bit time stamp.\r
+  @param  Identifier              32-bit identifier. If the value is 0, the found record\r
+                                  is same as the one found by EndPerformanceMeasurement.\r
+\r
+  @retval RETURN_SUCCESS          The end of  the measurement was recorded.\r
+  @retval RETURN_NOT_FOUND        The specified measurement record could not be found.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+EndPerformanceMeasurementEx (\r
+  IN CONST VOID   *Handle,  OPTIONAL\r
+  IN CONST CHAR8  *Token,   OPTIONAL\r
+  IN CONST CHAR8  *Module,  OPTIONAL\r
+  IN UINT64       TimeStamp,\r
+  IN UINT32       Identifier\r
+  )\r
+{\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
 /**\r
   Creates a record for the beginning of a performance measurement.\r
 \r
@@ -104,7 +177,7 @@ StartPerformanceMeasurement (
   IN UINT64       TimeStamp\r
   )\r
 {\r
-  return EFI_UNSUPPORTED;\r
+  return RETURN_SUCCESS;\r
 }\r
 \r
 /**\r
@@ -138,7 +211,7 @@ EndPerformanceMeasurement (
   IN UINT64       TimeStamp\r
   )\r
 {\r
-  return EFI_UNSUPPORTED;\r
+  return RETURN_SUCCESS;\r
 }\r
 \r
 /**\r
@@ -149,7 +222,7 @@ EndPerformanceMeasurement (
   @retval !NULL           Get all gauge data success.\r
   @retval NULL            Get all guage data failed.\r
 **/\r
-GAUGE_DATA_ENTRY*\r
+GAUGE_DATA_ENTRY *\r
 EFIAPI\r
 GetAllSmmGaugeData (VOID)\r
 {\r
@@ -171,22 +244,20 @@ GetAllSmmGaugeData (VOID)
   //\r
   // Initialize communicate buffer \r
   //\r
-  SmmCommBufferHeader = (EFI_SMM_COMMUNICATE_HEADER*)mSmmPerformanceBuffer;\r
-  SmmPerfCommData = (SMM_PERF_COMMUNICATE*)SmmCommBufferHeader->Data;\r
+  SmmCommBufferHeader = (EFI_SMM_COMMUNICATE_HEADER *)mSmmPerformanceBuffer;\r
+  SmmPerfCommData = (SMM_PERF_COMMUNICATE *)SmmCommBufferHeader->Data;\r
   ZeroMem((UINT8*)SmmPerfCommData, sizeof(SMM_PERF_COMMUNICATE));\r
     \r
   CopyGuid (&SmmCommBufferHeader->HeaderGuid, &gSmmPerformanceProtocolGuid);\r
   SmmCommBufferHeader->MessageLength = sizeof(SMM_PERF_COMMUNICATE);\r
-  CommSize = OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)  + sizeof(SMM_PERF_COMMUNICATE);\r
+  CommSize = SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE;\r
 \r
   //\r
   // Get totol number of SMM gauge entries\r
   //\r
   SmmPerfCommData->Function = SMM_PERF_FUNCTION_GET_GAUGE_ENTRY_NUMBER;\r
   Status = mSmmCommunication->Communicate (mSmmCommunication, mSmmPerformanceBuffer, &CommSize);\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  if (EFI_ERROR (SmmPerfCommData->ReturnStatus) || SmmPerfCommData->NumberOfEntries == 0) {\r
+  if (EFI_ERROR (Status) || EFI_ERROR (SmmPerfCommData->ReturnStatus) || SmmPerfCommData->NumberOfEntries == 0) {\r
     return NULL;\r
   }\r
 \r
@@ -194,7 +265,7 @@ GetAllSmmGaugeData (VOID)
   \r
   DataSize = mGaugeNumberOfEntries * sizeof(GAUGE_DATA_ENTRY);\r
   mGaugeData = AllocateZeroPool(DataSize);\r
-  ASSERT_EFI_ERROR (Status);\r
+  ASSERT (mGaugeData != NULL);\r
   \r
   //\r
   // Get all SMM gauge data\r
@@ -204,54 +275,89 @@ GetAllSmmGaugeData (VOID)
   SmmPerfCommData->NumberOfEntries = mGaugeNumberOfEntries;\r
   SmmPerfCommData->GaugeData = mGaugeData;\r
   Status = mSmmCommunication->Communicate (mSmmCommunication, mSmmPerformanceBuffer, &CommSize);\r
-  ASSERT_EFI_ERROR (Status);\r
-  ASSERT_EFI_ERROR(SmmPerfCommData->ReturnStatus);\r
+  if (EFI_ERROR (Status) || EFI_ERROR (SmmPerfCommData->ReturnStatus)) {\r
+    FreePool (mGaugeData);\r
+    mGaugeData = NULL;\r
+    mGaugeNumberOfEntries = 0;\r
+  }\r
 \r
-  return mGaugeData; \r
+  return mGaugeData;\r
 }\r
 \r
 /**\r
-  Retrieves a previously logged performance measurement.\r
-\r
-  Retrieves the performance log entry from the performance log specified by LogEntryKey.\r
-  If it stands for a valid entry, then EFI_SUCCESS is returned and\r
-  GaugeDataEntry stores the pointer to that entry.\r
-\r
-  @param  LogEntryKey             The key for the previous performance measurement log entry.\r
-                                  If 0, then the first performance measurement log entry is retrieved.\r
-  @param  GaugeDataEntry          The indirect pointer to the gauge data entry specified by LogEntryKey\r
-                                  if the retrieval is successful.\r
-\r
-  @retval EFI_SUCCESS             The GuageDataEntry is successfully found based on LogEntryKey.\r
-  @retval EFI_NOT_FOUND           The LogEntryKey is the last entry (equals to the total entry number).\r
-  @retval EFI_INVALIDE_PARAMETER  The LogEntryKey is not a valid entry (greater than the total entry number).\r
-  @retval EFI_INVALIDE_PARAMETER  GaugeDataEntry is NULL.\r
+  Retrieves all previous logged performance measurement.\r
+  Function will use SMM communicate protocol to get all previous SMM performance measurement data.\r
+  If success, data buffer will be returned. If fail function will return NULL.\r
 \r
+  @retval !NULL           Get all gauge data success.\r
+  @retval NULL            Get all guage data failed.\r
 **/\r
-EFI_STATUS\r
+GAUGE_DATA_ENTRY_EX *\r
 EFIAPI\r
-GetGauge (\r
-  IN  UINTN               LogEntryKey,\r
-  OUT GAUGE_DATA_ENTRY    **GaugeDataEntry\r
-  )\r
+GetAllSmmGaugeDataEx (VOID)\r
 {\r
-  if (LogEntryKey > mGaugeNumberOfEntries) {\r
-    return EFI_INVALID_PARAMETER;\r
+  EFI_STATUS                  Status;\r
+  EFI_SMM_COMMUNICATE_HEADER  *SmmCommBufferHeader;\r
+  SMM_PERF_COMMUNICATE_EX     *SmmPerfCommData;\r
+  UINTN                       CommSize;\r
+  UINTN                       DataSize;\r
+\r
+  if (mGaugeDataEx != NULL) {\r
+    return mGaugeDataEx;\r
   }\r
-  if (LogEntryKey == mGaugeNumberOfEntries) {\r
-    return EFI_NOT_FOUND;\r
+\r
+  Status = GetCommunicationProtocol ();\r
+  if (EFI_ERROR (Status)) {\r
+    return NULL;\r
   }\r
 \r
-  if (GaugeDataEntry == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
+  //\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
+  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
+  //\r
+  SmmPerfCommData->Function = SMM_PERF_FUNCTION_GET_GAUGE_ENTRY_NUMBER;\r
+  Status = mSmmCommunication->Communicate (mSmmCommunication, mSmmPerformanceBuffer, &CommSize);\r
+  if (EFI_ERROR (Status) || EFI_ERROR (SmmPerfCommData->ReturnStatus) || SmmPerfCommData->NumberOfEntries == 0) {\r
+    return NULL;\r
   }\r
-  *GaugeDataEntry = &mGaugeData[LogEntryKey];\r
 \r
-  return EFI_SUCCESS;\r
+  mGaugeNumberOfEntriesEx = SmmPerfCommData->NumberOfEntries;\r
+  \r
+  DataSize = mGaugeNumberOfEntriesEx * sizeof(GAUGE_DATA_ENTRY_EX);\r
+  mGaugeDataEx = AllocateZeroPool(DataSize);\r
+  ASSERT (mGaugeDataEx != NULL);\r
+  \r
+  //\r
+  // Get all SMM gauge data\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
+  return mGaugeDataEx;\r
 }\r
 \r
 /**\r
   Attempts to retrieve a performance measurement log entry from the performance measurement log.\r
+  It can also retrieve the log created by StartPerformanceMeasurement and EndPerformanceMeasurement,\r
+  and then assign the Identifier with 0.\r
 \r
   Attempts to retrieve the performance log entry specified by LogEntryKey.  If LogEntryKey is\r
   zero on entry, then an attempt is made to retrieve the first entry from the performance log,\r
@@ -262,13 +368,14 @@ GetGauge (
   retrieved and an implementation specific non-zero key value that specifies the end of the performance\r
   log is returned.  If LogEntryKey is equal this implementation specific non-zero key value, then no entry\r
   is retrieved and zero is returned.  In the cases where a performance log entry can be returned,\r
-  the log entry is returned in Handle, Token, Module, StartTimeStamp, and EndTimeStamp.\r
+  the log entry is returned in Handle, Token, Module, StartTimeStamp, EndTimeStamp and Identifier.\r
   If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().\r
   If Handle is NULL, then ASSERT().\r
   If Token is NULL, then ASSERT().\r
   If Module is NULL, then ASSERT().\r
   If StartTimeStamp is NULL, then ASSERT().\r
   If EndTimeStamp is NULL, then ASSERT().\r
+  If Identifier is NULL, then ASSERT().\r
 \r
   @param  LogEntryKey             On entry, the key of the performance measurement log entry to retrieve.\r
                                   0, then the first performance measurement log entry is retrieved.\r
@@ -283,23 +390,24 @@ GetGauge (
                                   was started.\r
   @param  EndTimeStamp            Pointer to the 64-bit time stamp that was recorded when the measurement\r
                                   was ended.\r
+  @param  Identifier              Pointer to the 32-bit identifier that was recorded.\r
 \r
   @return The key for the next performance log entry (in general case).\r
 \r
 **/\r
 UINTN\r
 EFIAPI\r
-GetPerformanceMeasurement (\r
-  IN  UINTN       LogEntryKey,\r
+GetPerformanceMeasurementEx (\r
+  IN  UINTN       LogEntryKey, \r
   OUT CONST VOID  **Handle,\r
   OUT CONST CHAR8 **Token,\r
   OUT CONST CHAR8 **Module,\r
   OUT UINT64      *StartTimeStamp,\r
-  OUT UINT64      *EndTimeStamp\r
+  OUT UINT64      *EndTimeStamp,\r
+  OUT UINT32      *Identifier\r
   )\r
 {\r
-  EFI_STATUS                    Status;\r
-  GAUGE_DATA_ENTRY      *GaugeData;\r
+  GAUGE_DATA_ENTRY_EX   *GaugeData;\r
 \r
   GaugeData = NULL;\r
 \r
@@ -308,29 +416,40 @@ GetPerformanceMeasurement (
   ASSERT (Module != NULL);\r
   ASSERT (StartTimeStamp != NULL);\r
   ASSERT (EndTimeStamp != NULL);\r
+  ASSERT (Identifier != NULL);\r
 \r
-  mGaugeData = GetAllSmmGaugeData();\r
-  if (mGaugeData == NULL) {\r
-    return 0;\r
-  }\r
-\r
-  Status = GetGauge (LogEntryKey++, &GaugeData);\r
-\r
-  //\r
-  // Make sure that LogEntryKey is a valid log entry key,\r
-  //\r
-  ASSERT (Status != EFI_INVALID_PARAMETER);\r
-\r
-  if (EFI_ERROR (Status)) {\r
+  mGaugeDataEx = GetAllSmmGaugeDataEx();\r
+  if (mGaugeDataEx != NULL) {\r
     //\r
-    // The LogEntryKey is the last entry (equals to the total entry number).\r
+    // Make sure that LogEntryKey is a valid log entry key.\r
     //\r
-    return 0;\r
-\r
+    ASSERT (LogEntryKey <= mGaugeNumberOfEntriesEx);\r
+\r
+    if (LogEntryKey == mGaugeNumberOfEntriesEx) {\r
+      return 0;\r
+    }\r
+\r
+    GaugeData = &mGaugeDataEx[LogEntryKey++];\r
+    *Identifier = GaugeData->Identifier;\r
+  } else {\r
+    mGaugeData = GetAllSmmGaugeData();\r
+    if (mGaugeData != NULL) {\r
+      //\r
+      // Make sure that LogEntryKey is a valid log entry key.\r
+      //\r
+      ASSERT (LogEntryKey <= mGaugeNumberOfEntries);\r
+\r
+      if (LogEntryKey == mGaugeNumberOfEntries) {\r
+        return 0;\r
+      }\r
+\r
+      GaugeData = (GAUGE_DATA_ENTRY_EX *) &mGaugeData[LogEntryKey++];\r
+      *Identifier = 0;\r
+    } else {\r
+      return 0;\r
+    }\r
   }\r
 \r
-  ASSERT (GaugeData != NULL);\r
-\r
   *Handle         = (VOID *) (UINTN) GaugeData->Handle;\r
   *Token          = GaugeData->Token;\r
   *Module         = GaugeData->Module;\r
@@ -340,6 +459,60 @@ GetPerformanceMeasurement (
   return LogEntryKey;\r
 }\r
 \r
+/**\r
+  Attempts to retrieve a performance measurement log entry from the performance measurement log.\r
+  It can also retrieve the log created by StartPerformanceMeasurementEx and EndPerformanceMeasurementEx,\r
+  and then eliminate the Identifier.\r
+\r
+  Attempts to retrieve the performance log entry specified by LogEntryKey.  If LogEntryKey is\r
+  zero on entry, then an attempt is made to retrieve the first entry from the performance log,\r
+  and the key for the second entry in the log is returned.  If the performance log is empty,\r
+  then no entry is retrieved and zero is returned.  If LogEntryKey is not zero, then the performance\r
+  log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is\r
+  returned.  If LogEntryKey is the key for the last entry in the log, then the last log entry is\r
+  retrieved and an implementation specific non-zero key value that specifies the end of the performance\r
+  log is returned.  If LogEntryKey is equal this implementation specific non-zero key value, then no entry\r
+  is retrieved and zero is returned.  In the cases where a performance log entry can be returned,\r
+  the log entry is returned in Handle, Token, Module, StartTimeStamp, and EndTimeStamp.\r
+  If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().\r
+  If Handle is NULL, then ASSERT().\r
+  If Token is NULL, then ASSERT().\r
+  If Module is NULL, then ASSERT().\r
+  If StartTimeStamp is NULL, then ASSERT().\r
+  If EndTimeStamp is NULL, then ASSERT().\r
+\r
+  @param  LogEntryKey             On entry, the key of the performance measurement log entry to retrieve.\r
+                                  0, then the first performance measurement log entry is retrieved.\r
+                                  On exit, the key of the next performance log entry.\r
+  @param  Handle                  Pointer to environment specific context used to identify the component\r
+                                  being measured.\r
+  @param  Token                   Pointer to a Null-terminated ASCII string that identifies the component\r
+                                  being measured.\r
+  @param  Module                  Pointer to a Null-terminated ASCII string that identifies the module\r
+                                  being measured.\r
+  @param  StartTimeStamp          Pointer to the 64-bit time stamp that was recorded when the measurement\r
+                                  was started.\r
+  @param  EndTimeStamp            Pointer to the 64-bit time stamp that was recorded when the measurement\r
+                                  was ended.\r
+\r
+  @return The key for the next performance log entry (in general case).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+GetPerformanceMeasurement (\r
+  IN  UINTN       LogEntryKey,\r
+  OUT CONST VOID  **Handle,\r
+  OUT CONST CHAR8 **Token,\r
+  OUT CONST CHAR8 **Module,\r
+  OUT UINT64      *StartTimeStamp,\r
+  OUT UINT64      *EndTimeStamp\r
+  )\r
+{\r
+  UINT32 Identifier;\r
+  return GetPerformanceMeasurementEx (LogEntryKey, Handle, Token, Module, StartTimeStamp, EndTimeStamp, &Identifier);\r
+}\r
+\r
 /**\r
   Returns TRUE if the performance measurement macros are enabled.\r
 \r
index 997187c38ff40fb2d27f4e895bd371994d7718e3..5fdaf051af14fc922bb972886a27612ebc6e50ad 100644 (file)
@@ -2,9 +2,10 @@
 #  Performance library instance used in DXE phase to dump SMM performance data.\r
 #  \r
 #  This library instance allows a DXE driver or UEFI application to dump the SMM performance data.\r
-#  StartPerformanceMeasurement() and EndPerformanceMeasurement() are not implemented.\r
+#  StartPerformanceMeasurement(), EndPerformanceMeasurement(), StartPerformanceMeasurementEx()\r
+#  and EndPerformanceMeasurementEx() are not implemented.\r
 #  \r
-#  Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
+#  Copyright (c) 2011 - 2012, 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
@@ -48,7 +49,8 @@
   MemoryAllocationLib\r
 \r
 [Guids]\r
-  gSmmPerformanceProtocolGuid            ## CONSUMES\r
+  gSmmPerformanceProtocolGuid            ## SOMETIMES_CONSUMES\r
+  gSmmPerformanceExProtocolGuid          ## SOMETIMES_CONSUMES\r
 \r
 [Protocols]\r
   gEfiSmmCommunicationProtocolGuid       ## CONSUMES\r
index 3b6a44c9b295c9de2bf8b7ee64c76cc770c407e8..49011b701c3749bb36d5c8545a0614be29708502 100644 (file)
@@ -32,30 +32,27 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 \r
 \r
 /**\r
-  Gets PEI the GUID HOB for PEI performance.\r
+  Gets the GUID HOB for PEI performance.\r
 \r
   This internal function searches for the GUID HOB for PEI performance.\r
   If that GUID HOB is not found, it will build a new one.\r
-  It returns the data area of that GUID HOB to record performance log.\r
+  It outputs the data area of that GUID HOB to record performance log.\r
 \r
-  @param  Handle                  Pointer to environment specific context used\r
-                                  to identify the component being measured.\r
-  @param  Token                   Pointer to a Null-terminated ASCII string\r
-                                  that identifies the component being measured.\r
-  @param  Module                  Pointer to a Null-terminated ASCII string\r
-                                  that identifies the module being measured.\r
-\r
-  @retval The index of log entry in the array.\r
+  @param    PeiPerformanceLog           Pointer to Pointer to PEI performance log header.\r
+  @param    PeiPerformanceIdArray       Pointer to Pointer to PEI performance identifier array.\r
 \r
 **/\r
-PEI_PERFORMANCE_LOG_HEADER *\r
+VOID\r
 InternalGetPerformanceHobLog (\r
-  VOID\r
+  OUT PEI_PERFORMANCE_LOG_HEADER    **PeiPerformanceLog,\r
+  OUT UINT32                        **PeiPerformanceIdArray\r
   )\r
 {\r
   EFI_HOB_GUID_TYPE           *GuidHob;\r
-  PEI_PERFORMANCE_LOG_HEADER  *PeiPerformanceLog;\r
-  UINTN                       PeiPerformanceLogSize;\r
+  UINTN                       PeiPerformanceSize;\r
+\r
+  ASSERT (PeiPerformanceLog != NULL);\r
+  ASSERT (PeiPerformanceIdArray != NULL);\r
 \r
   GuidHob = GetFirstGuidHob (&gPerformanceProtocolGuid);\r
 \r
@@ -63,25 +60,31 @@ InternalGetPerformanceHobLog (
     //\r
     // PEI Performance HOB was found, then return the existing one.\r
     //\r
-    PeiPerformanceLog = GET_GUID_HOB_DATA (GuidHob);\r
+    *PeiPerformanceLog = GET_GUID_HOB_DATA (GuidHob);\r
+\r
+    GuidHob = GetFirstGuidHob (&gPerformanceExProtocolGuid);\r
+    ASSERT (GuidHob != NULL);\r
+    *PeiPerformanceIdArray = GET_GUID_HOB_DATA (GuidHob);\r
   } else {\r
     //\r
     // PEI Performance HOB was not found, then build one.\r
     //\r
-    PeiPerformanceLogSize = sizeof (PEI_PERFORMANCE_LOG_HEADER) +\r
-                            sizeof (PEI_PERFORMANCE_LOG_ENTRY) * PcdGet8 (PcdMaxPeiPerformanceLogEntries);\r
-    PeiPerformanceLog     = BuildGuidHob (&gPerformanceProtocolGuid, PeiPerformanceLogSize);\r
-    PeiPerformanceLog     = ZeroMem (PeiPerformanceLog, PeiPerformanceLogSize);\r
+    PeiPerformanceSize     = sizeof (PEI_PERFORMANCE_LOG_HEADER) +\r
+                             sizeof (PEI_PERFORMANCE_LOG_ENTRY) * PcdGet8 (PcdMaxPeiPerformanceLogEntries);\r
+    *PeiPerformanceLog     = BuildGuidHob (&gPerformanceProtocolGuid, PeiPerformanceSize);\r
+    *PeiPerformanceLog     = ZeroMem (*PeiPerformanceLog, PeiPerformanceSize);\r
+\r
+    PeiPerformanceSize     = sizeof (UINT32) * PcdGet8 (PcdMaxPeiPerformanceLogEntries);\r
+    *PeiPerformanceIdArray = BuildGuidHob (&gPerformanceExProtocolGuid, PeiPerformanceSize);\r
+    *PeiPerformanceIdArray = ZeroMem (*PeiPerformanceIdArray, PeiPerformanceSize);\r
   }\r
-\r
-  return PeiPerformanceLog;\r
 }\r
 \r
 /**\r
-  Searches in the log array with keyword Handle, Token and Module.\r
+  Searches in the log array with keyword Handle, Token, Module and Identifier.\r
 \r
   This internal function searches for the log entry in the log array.\r
-  If there is an entry that exactly matches the given key word triple\r
+  If there is an entry that exactly matches the given keywords\r
   and its end time stamp is zero, then the index of that log entry is returned;\r
   otherwise, the the number of log entries in the array is returned.\r
 \r
@@ -93,6 +96,7 @@ InternalGetPerformanceHobLog (
                                   that identifies the component being measured.\r
   @param  Module                  Pointer to a Null-terminated ASCII string\r
                                   that identifies the module being measured.\r
+  @param  Identifier              32-bit identifier.\r
 \r
   @retval The index of log entry in the array.\r
 \r
@@ -100,9 +104,11 @@ InternalGetPerformanceHobLog (
 UINT32\r
 InternalSearchForLogEntry (\r
   IN PEI_PERFORMANCE_LOG_HEADER *PeiPerformanceLog,\r
+  IN UINT32                     *PeiPerformanceIdArray,\r
   IN CONST VOID                 *Handle,  OPTIONAL\r
   IN CONST CHAR8                *Token,   OPTIONAL\r
-  IN CONST CHAR8                *Module   OPTIONAL\r
+  IN CONST CHAR8                *Module,   OPTIONAL\r
+  IN UINT32                     Identifier\r
   )\r
 {\r
   UINT32                    Index;\r
@@ -123,6 +129,7 @@ InternalSearchForLogEntry (
     if ((LogEntryArray[Index].Handle == (EFI_PHYSICAL_ADDRESS) (UINTN) Handle) &&\r
          AsciiStrnCmp (LogEntryArray[Index].Token, Token, PEI_PERFORMANCE_STRING_LENGTH) == 0 &&\r
          AsciiStrnCmp (LogEntryArray[Index].Module, Module, PEI_PERFORMANCE_STRING_LENGTH) == 0 &&\r
+         (PeiPerformanceIdArray[Index] == Identifier) &&\r
          LogEntryArray[Index].EndTimeStamp == 0\r
        ) {\r
       break;\r
@@ -134,7 +141,7 @@ InternalSearchForLogEntry (
 /**\r
   Creates a record for the beginning of a performance measurement.\r
 \r
-  Creates a record that contains the Handle, Token, and Module.\r
+  Creates a record that contains the Handle, Token, Module and Identifier.\r
   If TimeStamp is not zero, then TimeStamp is added to the record as the start time.\r
   If TimeStamp is zero, then this function reads the current time stamp\r
   and adds that time stamp value to the record as the start time.\r
@@ -146,6 +153,8 @@ InternalSearchForLogEntry (
   @param  Module                  Pointer to a Null-terminated ASCII string\r
                                   that identifies the module being measured.\r
   @param  TimeStamp               64-bit time stamp.\r
+  @param  Identifier              32-bit identifier. If the value is 0, the created record\r
+                                  is same as the one created by StartPerformanceMeasurement.\r
 \r
   @retval RETURN_SUCCESS          The start of the measurement was recorded.\r
   @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.\r
@@ -153,18 +162,20 @@ InternalSearchForLogEntry (
 **/\r
 RETURN_STATUS\r
 EFIAPI\r
-StartPerformanceMeasurement (\r
+StartPerformanceMeasurementEx (\r
   IN CONST VOID   *Handle,  OPTIONAL\r
   IN CONST CHAR8  *Token,   OPTIONAL\r
   IN CONST CHAR8  *Module,  OPTIONAL\r
-  IN UINT64       TimeStamp\r
+  IN UINT64       TimeStamp,\r
+  IN UINT32       Identifier\r
   )\r
 {\r
   PEI_PERFORMANCE_LOG_HEADER  *PeiPerformanceLog;\r
+  UINT32                      *PeiPerformanceIdArray;\r
   PEI_PERFORMANCE_LOG_ENTRY   *LogEntryArray;\r
   UINT32                      Index;\r
 \r
-  PeiPerformanceLog = InternalGetPerformanceHobLog ();\r
+  InternalGetPerformanceHobLog (&PeiPerformanceLog, &PeiPerformanceIdArray);\r
 \r
   if (PeiPerformanceLog->NumberOfEntries >= PcdGet8 (PcdMaxPeiPerformanceLogEntries)) {\r
     return RETURN_OUT_OF_RESOURCES;\r
@@ -180,6 +191,9 @@ StartPerformanceMeasurement (
     AsciiStrnCpy (LogEntryArray[Index].Module, Module, PEI_PERFORMANCE_STRING_LENGTH);\r
   }\r
 \r
+  LogEntryArray[Index].EndTimeStamp = 0;\r
+  PeiPerformanceIdArray[Index] = Identifier;\r
+\r
   if (TimeStamp == 0) {\r
     TimeStamp = GetPerformanceCounter ();\r
   }\r
@@ -191,7 +205,7 @@ StartPerformanceMeasurement (
 /**\r
   Fills in the end time of a performance measurement.\r
 \r
-  Looks up the record that matches Handle, Token, and Module.\r
+  Looks up the record that matches Handle, Token, Module and Identifier.\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
@@ -205,6 +219,8 @@ StartPerformanceMeasurement (
   @param  Module                  Pointer to a Null-terminated ASCII string\r
                                   that identifies the module being measured.\r
   @param  TimeStamp               64-bit time stamp.\r
+  @param  Identifier              32-bit identifier. If the value is 0, the found record\r
+                                  is same as the one found by EndPerformanceMeasurement.\r
 \r
   @retval RETURN_SUCCESS          The end of  the measurement was recorded.\r
   @retval RETURN_NOT_FOUND        The specified measurement record could not be found.\r
@@ -212,14 +228,16 @@ StartPerformanceMeasurement (
 **/\r
 RETURN_STATUS\r
 EFIAPI\r
-EndPerformanceMeasurement (\r
+EndPerformanceMeasurementEx (\r
   IN CONST VOID   *Handle,  OPTIONAL\r
   IN CONST CHAR8  *Token,   OPTIONAL\r
   IN CONST CHAR8  *Module,  OPTIONAL\r
-  IN UINT64       TimeStamp\r
+  IN UINT64       TimeStamp,\r
+  IN UINT32       Identifier\r
   )\r
 {\r
   PEI_PERFORMANCE_LOG_HEADER  *PeiPerformanceLog;\r
+  UINT32                      *PeiPerformanceIdArray;\r
   PEI_PERFORMANCE_LOG_ENTRY   *LogEntryArray;\r
   UINT32                      Index;\r
 \r
@@ -227,8 +245,8 @@ EndPerformanceMeasurement (
     TimeStamp = GetPerformanceCounter ();\r
   }\r
 \r
-  PeiPerformanceLog = InternalGetPerformanceHobLog ();\r
-  Index             = InternalSearchForLogEntry (PeiPerformanceLog, Handle, Token, Module);\r
+  InternalGetPerformanceHobLog (&PeiPerformanceLog, &PeiPerformanceIdArray);\r
+  Index             = InternalSearchForLogEntry (PeiPerformanceLog, PeiPerformanceIdArray, Handle, Token, Module, Identifier);\r
   if (Index >= PeiPerformanceLog->NumberOfEntries) {\r
     return RETURN_NOT_FOUND;\r
   }\r
@@ -240,6 +258,8 @@ EndPerformanceMeasurement (
 \r
 /**\r
   Attempts to retrieve a performance measurement log entry from the performance measurement log.\r
+  It can also retrieve the log created by StartPerformanceMeasurement and EndPerformanceMeasurement,\r
+  and then assign the Identifier with 0.\r
 \r
   Attempts to retrieve the performance log entry specified by LogEntryKey.  If LogEntryKey is\r
   zero on entry, then an attempt is made to retrieve the first entry from the performance log,\r
@@ -250,17 +270,18 @@ EndPerformanceMeasurement (
   retrieved and an implementation specific non-zero key value that specifies the end of the performance\r
   log is returned.  If LogEntryKey is equal this implementation specific non-zero key value, then no entry\r
   is retrieved and zero is returned.  In the cases where a performance log entry can be returned,\r
-  the log entry is returned in Handle, Token, Module, StartTimeStamp, and EndTimeStamp.\r
+  the log entry is returned in Handle, Token, Module, StartTimeStamp, EndTimeStamp and Identifier.\r
   If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().\r
   If Handle is NULL, then ASSERT().\r
   If Token is NULL, then ASSERT().\r
   If Module is NULL, then ASSERT().\r
   If StartTimeStamp is NULL, then ASSERT().\r
   If EndTimeStamp is NULL, then ASSERT().\r
+  If Identifier is NULL, then ASSERT().\r
 \r
   @param  LogEntryKey             On entry, the key of the performance measurement log entry to retrieve.\r
                                   0, then the first performance measurement log entry is retrieved.\r
-                                  On exit, the key of the next performance lof entry entry.\r
+                                  On exit, the key of the next performance of entry entry.\r
   @param  Handle                  Pointer to environment specific context used to identify the component\r
                                   being measured.\r
   @param  Token                   Pointer to a Null-terminated ASCII string that identifies the component\r
@@ -271,22 +292,25 @@ EndPerformanceMeasurement (
                                   was started.\r
   @param  EndTimeStamp            Pointer to the 64-bit time stamp that was recorded when the measurement\r
                                   was ended.\r
+  @param  Identifier              Pointer to the 32-bit identifier that was recorded.\r
 \r
   @return The key for the next performance log entry (in general case).\r
 \r
 **/\r
 UINTN\r
 EFIAPI\r
-GetPerformanceMeasurement (\r
+GetPerformanceMeasurementEx (\r
   IN  UINTN       LogEntryKey,\r
   OUT CONST VOID  **Handle,\r
   OUT CONST CHAR8 **Token,\r
   OUT CONST CHAR8 **Module,\r
   OUT UINT64      *StartTimeStamp,\r
-  OUT UINT64      *EndTimeStamp\r
+  OUT UINT64      *EndTimeStamp,\r
+  OUT UINT32      *Identifier\r
   )\r
 {\r
   PEI_PERFORMANCE_LOG_HEADER  *PeiPerformanceLog;\r
+  UINT32                      *PeiPerformanceIdArray;\r
   PEI_PERFORMANCE_LOG_ENTRY   *CurrentLogEntry;\r
   PEI_PERFORMANCE_LOG_ENTRY   *LogEntryArray;\r
   UINTN                       NumberOfEntries;\r
@@ -296,8 +320,9 @@ GetPerformanceMeasurement (
   ASSERT (Module != NULL);\r
   ASSERT (StartTimeStamp != NULL);\r
   ASSERT (EndTimeStamp != NULL);\r
+  ASSERT (Identifier != NULL);\r
 \r
-  PeiPerformanceLog = InternalGetPerformanceHobLog ();\r
+  InternalGetPerformanceHobLog (&PeiPerformanceLog, &PeiPerformanceIdArray);\r
 \r
   NumberOfEntries   = (UINTN) (PeiPerformanceLog->NumberOfEntries);\r
   LogEntryArray     = (PEI_PERFORMANCE_LOG_ENTRY *) (PeiPerformanceLog + 1);\r
@@ -310,17 +335,138 @@ GetPerformanceMeasurement (
     return 0;\r
   }\r
 \r
-  CurrentLogEntry = &(LogEntryArray[LogEntryKey++]);\r
+  CurrentLogEntry = &(LogEntryArray[LogEntryKey]);\r
 \r
   *Handle         = (VOID *) (UINTN) (CurrentLogEntry->Handle);\r
   *Token          = CurrentLogEntry->Token;\r
   *Module         = CurrentLogEntry->Module;\r
   *StartTimeStamp = CurrentLogEntry->StartTimeStamp;\r
   *EndTimeStamp   = CurrentLogEntry->EndTimeStamp;\r
+  *Identifier     = PeiPerformanceIdArray[LogEntryKey++];\r
 \r
   return LogEntryKey;\r
 }\r
 \r
+/**\r
+  Creates a record for the beginning of a performance measurement.\r
+\r
+  Creates a record that contains the Handle, Token, and Module.\r
+  If TimeStamp is not zero, then TimeStamp is added to the record as the start time.\r
+  If TimeStamp is zero, then this function reads the current time stamp\r
+  and adds that time stamp value to the record as the start time.\r
+\r
+  @param  Handle                  Pointer to environment specific context used\r
+                                  to identify the component being measured.\r
+  @param  Token                   Pointer to a Null-terminated ASCII string\r
+                                  that identifies the component being measured.\r
+  @param  Module                  Pointer to a Null-terminated ASCII string\r
+                                  that identifies the module being measured.\r
+  @param  TimeStamp               64-bit time stamp.\r
+\r
+  @retval RETURN_SUCCESS          The start of the measurement was recorded.\r
+  @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+StartPerformanceMeasurement (\r
+  IN CONST VOID   *Handle,  OPTIONAL\r
+  IN CONST CHAR8  *Token,   OPTIONAL\r
+  IN CONST CHAR8  *Module,  OPTIONAL\r
+  IN UINT64       TimeStamp\r
+  )\r
+{\r
+  return StartPerformanceMeasurementEx (Handle, Token, Module, TimeStamp, 0);\r
+}\r
+\r
+/**\r
+  Fills in the end time of a performance measurement.\r
+\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
+  If the record is found and TimeStamp is zero, then this function reads\r
+  the current time stamp and adds that time stamp value to the record as the end time.\r
+\r
+  @param  Handle                  Pointer to environment specific context used\r
+                                  to identify the component being measured.\r
+  @param  Token                   Pointer to a Null-terminated ASCII string\r
+                                  that identifies the component being measured.\r
+  @param  Module                  Pointer to a Null-terminated ASCII string\r
+                                  that identifies the module being measured.\r
+  @param  TimeStamp               64-bit time stamp.\r
+\r
+  @retval RETURN_SUCCESS          The end of  the measurement was recorded.\r
+  @retval RETURN_NOT_FOUND        The specified measurement record could not be found.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+EndPerformanceMeasurement (\r
+  IN CONST VOID   *Handle,  OPTIONAL\r
+  IN CONST CHAR8  *Token,   OPTIONAL\r
+  IN CONST CHAR8  *Module,  OPTIONAL\r
+  IN UINT64       TimeStamp\r
+  )\r
+{\r
+  return EndPerformanceMeasurementEx (Handle, Token, Module, TimeStamp, 0);\r
+}\r
+\r
+/**\r
+  Attempts to retrieve a performance measurement log entry from the performance measurement log.\r
+  It can also retrieve the log created by StartPerformanceMeasurementEx and EndPerformanceMeasurementEx,\r
+  and then eliminate the Identifier.\r
+\r
+  Attempts to retrieve the performance log entry specified by LogEntryKey.  If LogEntryKey is\r
+  zero on entry, then an attempt is made to retrieve the first entry from the performance log,\r
+  and the key for the second entry in the log is returned.  If the performance log is empty,\r
+  then no entry is retrieved and zero is returned.  If LogEntryKey is not zero, then the performance\r
+  log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is\r
+  returned.  If LogEntryKey is the key for the last entry in the log, then the last log entry is\r
+  retrieved and an implementation specific non-zero key value that specifies the end of the performance\r
+  log is returned.  If LogEntryKey is equal this implementation specific non-zero key value, then no entry\r
+  is retrieved and zero is returned.  In the cases where a performance log entry can be returned,\r
+  the log entry is returned in Handle, Token, Module, StartTimeStamp, and EndTimeStamp.\r
+  If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().\r
+  If Handle is NULL, then ASSERT().\r
+  If Token is NULL, then ASSERT().\r
+  If Module is NULL, then ASSERT().\r
+  If StartTimeStamp is NULL, then ASSERT().\r
+  If EndTimeStamp is NULL, then ASSERT().\r
+\r
+  @param  LogEntryKey             On entry, the key of the performance measurement log entry to retrieve.\r
+                                  0, then the first performance measurement log entry is retrieved.\r
+                                  On exit, the key of the next performance of entry entry.\r
+  @param  Handle                  Pointer to environment specific context used to identify the component\r
+                                  being measured.\r
+  @param  Token                   Pointer to a Null-terminated ASCII string that identifies the component\r
+                                  being measured.\r
+  @param  Module                  Pointer to a Null-terminated ASCII string that identifies the module\r
+                                  being measured.\r
+  @param  StartTimeStamp          Pointer to the 64-bit time stamp that was recorded when the measurement\r
+                                  was started.\r
+  @param  EndTimeStamp            Pointer to the 64-bit time stamp that was recorded when the measurement\r
+                                  was ended.\r
+\r
+  @return The key for the next performance log entry (in general case).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+GetPerformanceMeasurement (\r
+  IN  UINTN       LogEntryKey,\r
+  OUT CONST VOID  **Handle,\r
+  OUT CONST CHAR8 **Token,\r
+  OUT CONST CHAR8 **Module,\r
+  OUT UINT64      *StartTimeStamp,\r
+  OUT UINT64      *EndTimeStamp\r
+  )\r
+{\r
+  UINT32 Identifier;\r
+  return GetPerformanceMeasurementEx (LogEntryKey, Handle, Token, Module, StartTimeStamp, EndTimeStamp, &Identifier);\r
+}\r
+\r
 /**\r
   Returns TRUE if the performance measurement macros are enabled.\r
 \r
index cee14196a084baf1f9a649fe6b777ff8b8d85cd4..572ec5422bd811c200cb794c5f3b3ee499fd0c41 100644 (file)
@@ -6,7 +6,7 @@
 #  and consumes GUIDed HOB for performance logging. The GUIDed HOB is passed to DXE phase\r
 #  so that it can be taken over by DxeCorePerformanceLib.  \r
 #  \r
-#  Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
+#  Copyright (c) 2006 - 2012, 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
@@ -50,7 +50,8 @@
 \r
 \r
 [Guids]\r
-  gPerformanceProtocolGuid ## HOB\r
+  gPerformanceProtocolGuid     ## PRODUCES ## HOB\r
+  gPerformanceExProtocolGuid   ## PRODUCES ## HOB\r
 \r
 [Pcd]\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdMaxPeiPerformanceLogEntries\r
index 98426c302c2d3d8d0c4fd420564e1bceb0c18d69..5ee1f603d158ecb992e24e6d8e117e94f144dcba 100644 (file)
@@ -3,13 +3,13 @@
 \r
   This library provides the performance measurement interfaces and initializes performance\r
   logging for the SMM phase.\r
-  It initializes SMM phase performance logging by publishing the Performance Protocol,\r
+  It initializes SMM phase performance logging by publishing the SMM Performance and PerformanceEx Protocol,\r
   which is consumed by SmmPerformanceLib to logging performance data in SMM phase.\r
 \r
   This library is mainly used by SMM Core to start performance logging to ensure that\r
-  SMM Performance Protocol is installed at the very beginning of SMM phase.\r
+  SMM Performance and PerformanceEx Protocol are installed at the very beginning of SMM phase.\r
 \r
-Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2011 - 2012, 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
@@ -48,7 +48,7 @@ EFI_SMRAM_DESCRIPTOR    *mSmramRanges;
 UINTN                   mSmramRangeCount;\r
 \r
 //\r
-// Interfaces for performance protocol.\r
+// Interfaces for SMM Performance Protocol.\r
 //\r
 PERFORMANCE_PROTOCOL mPerformanceInterface = {\r
   StartGauge,\r
@@ -56,11 +56,20 @@ PERFORMANCE_PROTOCOL mPerformanceInterface = {
   GetGauge\r
 };\r
 \r
+//\r
+// Interfaces for SMM PerformanceEx Protocol.\r
+//\r
+PERFORMANCE_EX_PROTOCOL mPerformanceExInterface = {\r
+  StartGaugeEx,\r
+  EndGaugeEx,\r
+  GetGaugeEx\r
+};\r
+\r
 /**\r
-  Searches in the gauge array with keyword Handle, Token and Module.\r
+  Searches in the gauge array with keyword Handle, Token, Module and Identfier.\r
 \r
   This internal function searches for the gauge entry in the gauge array.\r
-  If there is an entry that exactly matches the given key word triple\r
+  If there is an entry that exactly matches the given keywords\r
   and its end time stamp is zero, then the index of that gauge entry is returned;\r
   otherwise, the the number of gauge entries in the array is returned.\r
 \r
@@ -70,6 +79,7 @@ PERFORMANCE_PROTOCOL mPerformanceInterface = {
                                   that identifies the component being measured.\r
   @param  Module                  Pointer to a Null-terminated ASCII string\r
                                   that identifies the module being measured.\r
+  @param  Identifier              32-bit identifier.\r
 \r
   @retval The index of gauge entry in the array.\r
 \r
@@ -78,12 +88,13 @@ UINT32
 SmmSearchForGaugeEntry (\r
   IN CONST VOID                 *Handle,  OPTIONAL\r
   IN CONST CHAR8                *Token,   OPTIONAL\r
-  IN CONST CHAR8                *Module   OPTIONAL\r
+  IN CONST CHAR8                *Module,   OPTIONAL\r
+  IN CONST UINT32               Identifier\r
   )\r
 {\r
   UINT32                    Index;\r
   UINT32                    NumberOfEntries;\r
-  GAUGE_DATA_ENTRY          *GaugeEntryArray;\r
+  GAUGE_DATA_ENTRY_EX       *GaugeEntryExArray;\r
 \r
   if (Token == NULL) {\r
     Token = "";\r
@@ -93,13 +104,14 @@ SmmSearchForGaugeEntry (
   }\r
 \r
   NumberOfEntries = mGaugeData->NumberOfEntries;\r
-  GaugeEntryArray = (GAUGE_DATA_ENTRY *) (mGaugeData + 1);\r
+  GaugeEntryExArray = (GAUGE_DATA_ENTRY_EX *) (mGaugeData + 1);\r
 \r
   for (Index = 0; Index < NumberOfEntries; Index++) {\r
-    if ((GaugeEntryArray[Index].Handle == (EFI_PHYSICAL_ADDRESS) (UINTN) Handle) &&\r
-         AsciiStrnCmp (GaugeEntryArray[Index].Token, Token, SMM_PERFORMANCE_STRING_LENGTH) == 0 &&\r
-         AsciiStrnCmp (GaugeEntryArray[Index].Module, Module, SMM_PERFORMANCE_STRING_LENGTH) == 0 &&\r
-         GaugeEntryArray[Index].EndTimeStamp == 0) {\r
+    if ((GaugeEntryExArray[Index].Handle == (EFI_PHYSICAL_ADDRESS) (UINTN) Handle) &&\r
+         AsciiStrnCmp (GaugeEntryExArray[Index].Token, Token, SMM_PERFORMANCE_STRING_LENGTH) == 0 &&\r
+         AsciiStrnCmp (GaugeEntryExArray[Index].Module, Module, SMM_PERFORMANCE_STRING_LENGTH) == 0 &&\r
+         (GaugeEntryExArray[Index].Identifier == Identifier) &&\r
+         GaugeEntryExArray[Index].EndTimeStamp == 0) {\r
       break;\r
     }\r
   }\r
@@ -112,7 +124,7 @@ SmmSearchForGaugeEntry (
   that records the start time of a performance measurement.\r
 \r
   Adds a record to the end of the performance measurement log\r
-  that contains the Handle, Token, and Module.\r
+  that contains the Handle, Token, Module and Identifier.\r
   The end time of the new record must be set to zero.\r
   If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.\r
   If TimeStamp is zero, the start time in the record is filled in with the value\r
@@ -125,6 +137,8 @@ SmmSearchForGaugeEntry (
   @param  Module                  Pointer to a Null-terminated ASCII string\r
                                   that identifies the module being measured.\r
   @param  TimeStamp               64-bit time stamp.\r
+  @param  Identifier              32-bit identifier. If the value is 0, the created record\r
+                                  is same as the one created by StartGauge of PERFORMANCE_PROTOCOL.\r
 \r
   @retval EFI_SUCCESS             The data was read correctly from the device.\r
   @retval EFI_OUT_OF_RESOURCES    There are not enough resources to record the measurement.\r
@@ -132,15 +146,17 @@ SmmSearchForGaugeEntry (
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-StartGauge (\r
+StartGaugeEx (\r
   IN CONST VOID   *Handle,  OPTIONAL\r
   IN CONST CHAR8  *Token,   OPTIONAL\r
   IN CONST CHAR8  *Module,  OPTIONAL\r
-  IN UINT64       TimeStamp\r
+  IN UINT64       TimeStamp,\r
+  IN UINT32       Identifier\r
   )\r
 {\r
-  GAUGE_DATA_ENTRY          *GaugeEntryArray;\r
+  GAUGE_DATA_ENTRY_EX       *GaugeEntryExArray;\r
   UINTN                     GaugeDataSize;\r
+  GAUGE_DATA_HEADER         *NewGaugeData;\r
   UINTN                     OldGaugeDataSize;\r
   GAUGE_DATA_HEADER         *OldGaugeData;\r
   UINT32                    Index;\r
@@ -153,15 +169,19 @@ StartGauge (
     // Try to enlarge the scale of gauge array.\r
     //\r
     OldGaugeData      = mGaugeData;\r
-    OldGaugeDataSize  = sizeof (GAUGE_DATA_HEADER) + sizeof (GAUGE_DATA_ENTRY) * mMaxGaugeRecords;\r
+    OldGaugeDataSize  = sizeof (GAUGE_DATA_HEADER) + sizeof (GAUGE_DATA_ENTRY_EX) * mMaxGaugeRecords;\r
 \r
-    mMaxGaugeRecords *= 2;\r
-    GaugeDataSize     = sizeof (GAUGE_DATA_HEADER) + sizeof (GAUGE_DATA_ENTRY) * mMaxGaugeRecords;\r
+    GaugeDataSize     = sizeof (GAUGE_DATA_HEADER) + sizeof (GAUGE_DATA_ENTRY_EX) * mMaxGaugeRecords * 2;\r
 \r
-    mGaugeData = AllocateZeroPool (GaugeDataSize);\r
-    if (mGaugeData == NULL) {\r
+    NewGaugeData = AllocateZeroPool (GaugeDataSize);\r
+    if (NewGaugeData == NULL) {\r
+      ReleaseSpinLock (&mSmmPerfLock);\r
       return EFI_OUT_OF_RESOURCES;\r
     }\r
+\r
+    mGaugeData = NewGaugeData;\r
+    mMaxGaugeRecords *= 2;\r
+\r
     //\r
     // Initialize new data array and migrate old data one.\r
     //\r
@@ -170,20 +190,23 @@ StartGauge (
     FreePool (OldGaugeData);\r
   }\r
 \r
-  GaugeEntryArray               = (GAUGE_DATA_ENTRY *) (mGaugeData + 1);\r
-  GaugeEntryArray[Index].Handle = (EFI_PHYSICAL_ADDRESS) (UINTN) Handle;\r
+  GaugeEntryExArray               = (GAUGE_DATA_ENTRY_EX *) (mGaugeData + 1);\r
+  GaugeEntryExArray[Index].Handle = (EFI_PHYSICAL_ADDRESS) (UINTN) Handle;\r
 \r
   if (Token != NULL) {\r
-    AsciiStrnCpy (GaugeEntryArray[Index].Token, Token, SMM_PERFORMANCE_STRING_LENGTH);\r
+    AsciiStrnCpy (GaugeEntryExArray[Index].Token, Token, SMM_PERFORMANCE_STRING_LENGTH);\r
   }\r
   if (Module != NULL) {\r
-    AsciiStrnCpy (GaugeEntryArray[Index].Module, Module, SMM_PERFORMANCE_STRING_LENGTH);\r
+    AsciiStrnCpy (GaugeEntryExArray[Index].Module, Module, SMM_PERFORMANCE_STRING_LENGTH);\r
   }\r
 \r
+  GaugeEntryExArray[Index].EndTimeStamp = 0;\r
+  GaugeEntryExArray[Index].Identifier = Identifier;\r
+\r
   if (TimeStamp == 0) {\r
     TimeStamp = GetPerformanceCounter ();\r
   }\r
-  GaugeEntryArray[Index].StartTimeStamp = TimeStamp;\r
+  GaugeEntryExArray[Index].StartTimeStamp = TimeStamp;\r
 \r
   mGaugeData->NumberOfEntries++;\r
 \r
@@ -197,7 +220,7 @@ StartGauge (
   for the first matching record that contains a zero end time and fills in a valid end time.\r
 \r
   Searches the performance measurement log from the beginning of the log\r
-  for the first record that matches Handle, Token, and Module and has an end time value of zero.\r
+  for the first record that matches Handle, Token, Module and Identifier and has an end time value of zero.\r
   If the record can not be found then return EFI_NOT_FOUND.\r
   If the record is found and TimeStamp is not zero,\r
   then the end time in the record is filled in with the value specified by TimeStamp.\r
@@ -211,6 +234,8 @@ StartGauge (
   @param  Module                  Pointer to a Null-terminated ASCII string\r
                                   that identifies the module being measured.\r
   @param  TimeStamp               64-bit time stamp.\r
+  @param  Identifier              32-bit identifier. If the value is 0, the found record\r
+                                  is same as the one found by EndGauge of PERFORMANCE_PROTOCOL.\r
 \r
   @retval EFI_SUCCESS             The end of  the measurement was recorded.\r
   @retval EFI_NOT_FOUND           The specified measurement record could not be found.\r
@@ -218,57 +243,65 @@ StartGauge (
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-EndGauge (\r
+EndGaugeEx (\r
   IN CONST VOID   *Handle,  OPTIONAL\r
   IN CONST CHAR8  *Token,   OPTIONAL\r
   IN CONST CHAR8  *Module,  OPTIONAL\r
-  IN UINT64       TimeStamp\r
+  IN UINT64       TimeStamp,\r
+  IN UINT32       Identifier\r
   )\r
 {\r
-  GAUGE_DATA_ENTRY  *GaugeEntryArray;\r
-  UINT32            Index;\r
+  GAUGE_DATA_ENTRY_EX *GaugeEntryExArray;\r
+  UINT32              Index;\r
+\r
+  AcquireSpinLock (&mSmmPerfLock);\r
 \r
   if (TimeStamp == 0) {\r
     TimeStamp = GetPerformanceCounter ();\r
   }\r
 \r
-  Index = SmmSearchForGaugeEntry (Handle, Token, Module);\r
+  Index = SmmSearchForGaugeEntry (Handle, Token, Module, Identifier);\r
   if (Index >= mGaugeData->NumberOfEntries) {\r
+    ReleaseSpinLock (&mSmmPerfLock);\r
     return EFI_NOT_FOUND;\r
   }\r
-  GaugeEntryArray = (GAUGE_DATA_ENTRY  *) (mGaugeData + 1);\r
-  GaugeEntryArray[Index].EndTimeStamp = TimeStamp;\r
+  GaugeEntryExArray = (GAUGE_DATA_ENTRY_EX *) (mGaugeData + 1);\r
+  GaugeEntryExArray[Index].EndTimeStamp = TimeStamp;\r
+\r
+  ReleaseSpinLock (&mSmmPerfLock);\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
   Retrieves a previously logged performance measurement.\r
+  It can also retrieve the log created by StartGauge and EndGauge of PERFORMANCE_PROTOCOL,\r
+  and then assign the Identifier with 0.\r
 \r
   Retrieves the performance log entry from the performance log specified by LogEntryKey.\r
   If it stands for a valid entry, then EFI_SUCCESS is returned and\r
-  GaugeDataEntry stores the pointer to that entry.\r
+  GaugeDataEntryEx stores the pointer to that entry.\r
 \r
   @param  LogEntryKey             The key for the previous performance measurement log entry.\r
                                   If 0, then the first performance measurement log entry is retrieved.\r
-  @param  GaugeDataEntry          The indirect pointer to the gauge data entry specified by LogEntryKey\r
+  @param  GaugeDataEntryEx        The indirect pointer to the extended gauge data entry specified by LogEntryKey\r
                                   if the retrieval is successful.\r
 \r
-  @retval EFI_SUCCESS             The GuageDataEntry is successfully found based on LogEntryKey.\r
+  @retval EFI_SUCCESS             The GuageDataEntryEx is successfully found based on LogEntryKey.\r
   @retval EFI_NOT_FOUND           The LogEntryKey is the last entry (equals to the total entry number).\r
   @retval EFI_INVALIDE_PARAMETER  The LogEntryKey is not a valid entry (greater than the total entry number).\r
-  @retval EFI_INVALIDE_PARAMETER  GaugeDataEntry is NULL.\r
+  @retval EFI_INVALIDE_PARAMETER  GaugeDataEntryEx is NULL.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-GetGauge (\r
-  IN  UINTN               LogEntryKey,\r
-  OUT GAUGE_DATA_ENTRY    **GaugeDataEntry\r
+GetGaugeEx (\r
+  IN  UINTN                 LogEntryKey,\r
+  OUT GAUGE_DATA_ENTRY_EX   **GaugeDataEntryEx\r
   )\r
 {\r
   UINTN               NumberOfEntries;\r
-  GAUGE_DATA_ENTRY    *LogEntryArray;\r
+  GAUGE_DATA_ENTRY_EX *GaugeEntryExArray;\r
 \r
   NumberOfEntries = (UINTN) (mGaugeData->NumberOfEntries);\r
   if (LogEntryKey > NumberOfEntries) {\r
@@ -278,16 +311,130 @@ GetGauge (
     return EFI_NOT_FOUND;\r
   }\r
 \r
-  LogEntryArray   = (GAUGE_DATA_ENTRY *) (mGaugeData + 1);\r
+  GaugeEntryExArray = (GAUGE_DATA_ENTRY_EX *) (mGaugeData + 1);\r
 \r
-  if (GaugeDataEntry == NULL) {\r
+  if (GaugeDataEntryEx == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
-  *GaugeDataEntry = &LogEntryArray[LogEntryKey];\r
+  *GaugeDataEntryEx = &GaugeEntryExArray[LogEntryKey];\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Adds a record at the end of the performance measurement log\r
+  that records the start time of a performance measurement.\r
+\r
+  Adds a record to the end of the performance measurement log\r
+  that contains the Handle, Token, and Module.\r
+  The end time of the new record must be set to zero.\r
+  If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.\r
+  If TimeStamp is zero, the start time in the record is filled in with the value\r
+  read from the current time stamp.\r
+\r
+  @param  Handle                  Pointer to environment specific context used\r
+                                  to identify the component being measured.\r
+  @param  Token                   Pointer to a Null-terminated ASCII string\r
+                                  that identifies the component being measured.\r
+  @param  Module                  Pointer to a Null-terminated ASCII string\r
+                                  that identifies the module being measured.\r
+  @param  TimeStamp               64-bit time stamp.\r
+\r
+  @retval EFI_SUCCESS             The data was read correctly from the device.\r
+  @retval EFI_OUT_OF_RESOURCES    There are not enough resources to record the measurement.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+StartGauge (\r
+  IN CONST VOID   *Handle,  OPTIONAL\r
+  IN CONST CHAR8  *Token,   OPTIONAL\r
+  IN CONST CHAR8  *Module,  OPTIONAL\r
+  IN UINT64       TimeStamp\r
+  )\r
+{\r
+  return StartGaugeEx (Handle, Token, Module, TimeStamp, 0);\r
+}\r
+\r
+/**\r
+  Searches the performance measurement log from the beginning of the log\r
+  for the first matching record that contains a zero end time and fills in a valid end time.\r
+\r
+  Searches the performance measurement log from the beginning of the log\r
+  for the first record that matches Handle, Token, and Module and has an end time value of zero.\r
+  If the record can not be found then return EFI_NOT_FOUND.\r
+  If the record is found and TimeStamp is not zero,\r
+  then the end time in the record is filled in with the value specified by TimeStamp.\r
+  If the record is found and TimeStamp is zero, then the end time in the matching record\r
+  is filled in with the current time stamp value.\r
+\r
+  @param  Handle                  Pointer to environment specific context used\r
+                                  to identify the component being measured.\r
+  @param  Token                   Pointer to a Null-terminated ASCII string\r
+                                  that identifies the component being measured.\r
+  @param  Module                  Pointer to a Null-terminated ASCII string\r
+                                  that identifies the module being measured.\r
+  @param  TimeStamp               64-bit time stamp.\r
+\r
+  @retval EFI_SUCCESS             The end of  the measurement was recorded.\r
+  @retval EFI_NOT_FOUND           The specified measurement record could not be found.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EndGauge (\r
+  IN CONST VOID   *Handle,  OPTIONAL\r
+  IN CONST CHAR8  *Token,   OPTIONAL\r
+  IN CONST CHAR8  *Module,  OPTIONAL\r
+  IN UINT64       TimeStamp\r
+  )\r
+{\r
+  return EndGaugeEx (Handle, Token, Module, TimeStamp, 0);\r
+}\r
+\r
+/**\r
+  Retrieves a previously logged performance measurement.\r
+  It can also retrieve the log created by StartGaugeEx and EndGaugeEx of PERFORMANCE_EX_PROTOCOL,\r
+  and then eliminate the Identifier.\r
+\r
+  Retrieves the performance log entry from the performance log specified by LogEntryKey.\r
+  If it stands for a valid entry, then EFI_SUCCESS is returned and\r
+  GaugeDataEntry stores the pointer to that entry.\r
+\r
+  @param  LogEntryKey             The key for the previous performance measurement log entry.\r
+                                  If 0, then the first performance measurement log entry is retrieved.\r
+  @param  GaugeDataEntry          The indirect pointer to the gauge data entry specified by LogEntryKey\r
+                                  if the retrieval is successful.\r
+\r
+  @retval EFI_SUCCESS             The GuageDataEntry is successfully found based on LogEntryKey.\r
+  @retval EFI_NOT_FOUND           The LogEntryKey is the last entry (equals to the total entry number).\r
+  @retval EFI_INVALIDE_PARAMETER  The LogEntryKey is not a valid entry (greater than the total entry number).\r
+  @retval EFI_INVALIDE_PARAMETER  GaugeDataEntry is NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetGauge (\r
+  IN  UINTN               LogEntryKey,\r
+  OUT GAUGE_DATA_ENTRY    **GaugeDataEntry\r
+  )\r
+{\r
+  EFI_STATUS          Status;\r
+  GAUGE_DATA_ENTRY_EX *GaugeEntryEx;\r
+\r
+  Status = GetGaugeEx (LogEntryKey, &GaugeEntryEx);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  if (GaugeDataEntry == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  *GaugeDataEntry = (GAUGE_DATA_ENTRY *) GaugeEntryEx;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
 \r
 /**\r
   This function check if the address is in SMRAM.\r
@@ -319,7 +466,88 @@ IsAddressInSmram (
 /**\r
   Communication service SMI Handler entry.\r
 \r
-  This SMI handler provides services for the variable wrapper driver.\r
+  This SMI handler provides services for the performance wrapper driver.\r
+\r
+  @param[in]     DispatchHandle  The unique handle assigned to this handler by SmiHandlerRegister().\r
+  @param[in]     RegisterContext Points to an optional handler context which was specified when the\r
+                                 handler was registered.\r
+  @param[in, out] CommBuffer     A pointer to a collection of data in memory that will\r
+                                 be conveyed from a non-SMM environment into an SMM environment.\r
+  @param[in, out] CommBufferSize The size of the CommBuffer.\r
+\r
+  @retval EFI_SUCCESS                         The interrupt was handled and quiesced. No other handlers \r
+                                              should still be called.\r
+  @retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED  The interrupt has been quiesced but other handlers should \r
+                                              still be called.\r
+  @retval EFI_WARN_INTERRUPT_SOURCE_PENDING   The interrupt is still pending and other handlers should still \r
+                                              be called.\r
+  @retval EFI_INTERRUPT_PENDING               The interrupt could not be quiesced.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmmPerformanceHandlerEx (\r
+  IN     EFI_HANDLE                    DispatchHandle,\r
+  IN     CONST VOID                   *RegisterContext,\r
+  IN OUT VOID                          *CommBuffer,\r
+  IN OUT UINTN                         *CommBufferSize\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  SMM_PERF_COMMUNICATE_EX   *SmmPerfCommData;\r
+  GAUGE_DATA_ENTRY_EX       *GaugeEntryExArray;\r
+  UINTN                     DataSize;\r
+\r
+  GaugeEntryExArray = NULL;\r
+\r
+  ASSERT (CommBuffer != NULL);\r
+\r
+  SmmPerfCommData = (SMM_PERF_COMMUNICATE_EX *)CommBuffer;\r
+\r
+  switch (SmmPerfCommData->Function) {\r
+    case SMM_PERF_FUNCTION_GET_GAUGE_ENTRY_NUMBER :\r
+       SmmPerfCommData->NumberOfEntries = mGaugeData->NumberOfEntries;\r
+       Status = EFI_SUCCESS;\r
+       break;\r
+\r
+    case SMM_PERF_FUNCTION_GET_GAUGE_DATA :\r
+       if ( SmmPerfCommData->GaugeDataEx == NULL || SmmPerfCommData->NumberOfEntries == 0 ||\r
+         (SmmPerfCommData->LogEntryKey + SmmPerfCommData->NumberOfEntries) > mGaugeData->NumberOfEntries) {\r
+         Status = EFI_INVALID_PARAMETER;\r
+         break;\r
+       }\r
+\r
+       //\r
+       // Sanity check\r
+       //\r
+       DataSize = SmmPerfCommData->NumberOfEntries * sizeof(GAUGE_DATA_ENTRY_EX);\r
+       if (IsAddressInSmram ((EFI_PHYSICAL_ADDRESS)(UINTN)SmmPerfCommData->GaugeDataEx, DataSize)) {\r
+         DEBUG ((EFI_D_ERROR, "Smm Performance Data buffer is in SMRAM!\n"));\r
+         Status = EFI_ACCESS_DENIED;\r
+         break ;\r
+       }\r
+\r
+       GaugeEntryExArray = (GAUGE_DATA_ENTRY_EX *) (mGaugeData + 1);\r
+       CopyMem(\r
+         (UINT8 *) (SmmPerfCommData->GaugeDataEx),\r
+         (UINT8 *) &GaugeEntryExArray[SmmPerfCommData->LogEntryKey],\r
+         DataSize\r
+         );\r
+       Status = EFI_SUCCESS;\r
+       break;\r
+\r
+    default:\r
+       ASSERT (FALSE);\r
+       Status = EFI_UNSUPPORTED;\r
+  }\r
+\r
+  SmmPerfCommData->ReturnStatus = Status;\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Communication service SMI Handler entry.\r
+\r
+  This SMI handler provides services for the performance wrapper driver.\r
 \r
   @param[in]     DispatchHandle  The unique handle assigned to this handler by SmiHandlerRegister().\r
   @param[in]     RegisterContext Points to an optional handler context which was specified when the\r
@@ -341,39 +569,36 @@ EFIAPI
 SmmPerformanceHandler (\r
   IN     EFI_HANDLE                    DispatchHandle,\r
   IN     CONST VOID                   *RegisterContext,\r
-  IN OUT VOID                           *CommBuffer,\r
-  IN OUT UINTN                          *CommBufferSize\r
+  IN OUT VOID                          *CommBuffer,\r
+  IN OUT UINTN                         *CommBufferSize\r
   )\r
 {\r
   EFI_STATUS            Status;\r
   SMM_PERF_COMMUNICATE  *SmmPerfCommData;\r
-  GAUGE_DATA_ENTRY      *GaugeData; \r
+  GAUGE_DATA_ENTRY_EX   *GaugeEntryExArray;\r
   UINTN                 DataSize;\r
+  UINTN                 Index;\r
+  UINTN                 LogEntryKey;\r
+\r
+  GaugeEntryExArray = NULL;\r
 \r
-  GaugeData = NULL;\r
-  \r
   ASSERT (CommBuffer != NULL);\r
 \r
-  SmmPerfCommData = (SMM_PERF_COMMUNICATE*)CommBuffer;\r
+  SmmPerfCommData = (SMM_PERF_COMMUNICATE *)CommBuffer;\r
 \r
   switch (SmmPerfCommData->Function) {\r
     case SMM_PERF_FUNCTION_GET_GAUGE_ENTRY_NUMBER :\r
        SmmPerfCommData->NumberOfEntries = mGaugeData->NumberOfEntries;\r
-       return Status = EFI_SUCCESS;\r
+       Status = EFI_SUCCESS;\r
        break;\r
 \r
     case SMM_PERF_FUNCTION_GET_GAUGE_DATA :\r
-       if ( SmmPerfCommData->GaugeData == NULL || SmmPerfCommData->NumberOfEntries <= 0 ||\r
-            (SmmPerfCommData->LogEntryKey + SmmPerfCommData->NumberOfEntries) > mGaugeData->NumberOfEntries) {\r
+       if ( SmmPerfCommData->GaugeData == NULL || SmmPerfCommData->NumberOfEntries == 0 ||\r
+         (SmmPerfCommData->LogEntryKey + SmmPerfCommData->NumberOfEntries) > mGaugeData->NumberOfEntries) {\r
          Status = EFI_INVALID_PARAMETER;\r
          break;\r
-       } \r
-\r
-       Status = GetGauge(SmmPerfCommData->LogEntryKey, &GaugeData);\r
-       if (EFI_ERROR(Status)) {\r
-         break;\r
        }\r
-          \r
+\r
        //\r
        // Sanity check\r
        //\r
@@ -384,17 +609,23 @@ SmmPerformanceHandler (
          break ;\r
        }\r
 \r
-       CopyMem(\r
-         (UINT8*)SmmPerfCommData->GaugeData, \r
-         (UINT8*)GaugeData, \r
-         DataSize\r
-         );\r
+       GaugeEntryExArray = (GAUGE_DATA_ENTRY_EX *) (mGaugeData + 1);\r
+\r
+       LogEntryKey = SmmPerfCommData->LogEntryKey;\r
+       for (Index = 0; Index < SmmPerfCommData->NumberOfEntries; Index++) {\r
+         CopyMem(\r
+           (UINT8 *) &(SmmPerfCommData->GaugeData[Index]),\r
+           (UINT8 *) &GaugeEntryExArray[LogEntryKey++],\r
+           sizeof (GAUGE_DATA_ENTRY)\r
+           );\r
+       }\r
+       Status = EFI_SUCCESS;\r
        break;\r
 \r
     default:\r
        ASSERT (FALSE);\r
        Status = EFI_UNSUPPORTED;\r
-  }            \r
+  }\r
 \r
   SmmPerfCommData->ReturnStatus = Status;\r
   return EFI_SUCCESS;\r
@@ -402,7 +633,7 @@ SmmPerformanceHandler (
 \r
 /**\r
   SmmBase2 protocol notify callback function, when SMST and SMM memory service get initialized \r
-  this function is callbacked to to initialize the Smm Performance Lib \r
+  this function is callbacked to initialize the Smm Performance Lib \r
 \r
   @param  Event    The event of notify protocol.\r
   @param  Context  Notify event context.\r
@@ -426,9 +657,9 @@ InitializeSmmCorePerformanceLib (
   //\r
   InitializeSpinLock (&mSmmPerfLock);\r
 \r
-  mMaxGaugeRecords = INIT_SMM_GAUGE_DATA_ENTRIES + PcdGet8 (PcdMaxPeiPerformanceLogEntries);\r
+  mMaxGaugeRecords = INIT_SMM_GAUGE_DATA_ENTRIES;\r
 \r
-  mGaugeData = AllocateZeroPool (sizeof (GAUGE_DATA_HEADER) + (sizeof (GAUGE_DATA_ENTRY) * mMaxGaugeRecords));\r
+  mGaugeData = AllocateZeroPool (sizeof (GAUGE_DATA_HEADER) + (sizeof (GAUGE_DATA_ENTRY_EX) * mMaxGaugeRecords));\r
   ASSERT (mGaugeData != NULL);\r
   \r
   //\r
@@ -464,19 +695,27 @@ InitializeSmmCorePerformanceLib (
                     );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
+  Status = gSmst->SmmInstallProtocolInterface (\r
+                    &mHandle,\r
+                    &gSmmPerformanceExProtocolGuid,\r
+                    EFI_NATIVE_INTERFACE,\r
+                    &mPerformanceExInterface\r
+                    );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
   ///\r
   /// Register SMM Performance SMI handler\r
   ///\r
   Handle = NULL;\r
   Status = gSmst->SmiHandlerRegister (SmmPerformanceHandler, &gSmmPerformanceProtocolGuid, &Handle);\r
   ASSERT_EFI_ERROR (Status);\r
+  Status = gSmst->SmiHandlerRegister (SmmPerformanceHandlerEx, &gSmmPerformanceExProtocolGuid, &Handle);\r
+  ASSERT_EFI_ERROR (Status);\r
 }\r
 \r
 /**\r
-  The constructor function initializes Performance infrastructure for DXE phase.\r
-\r
-  The constructor function publishes Performance protocol, allocates memory to log DXE performance\r
-  and merges PEI performance data to DXE performance log.\r
+  The constructor function initializes the Performance Measurement Enable flag and \r
+  registers SmmBase2 protocol notify callback.\r
   It will ASSERT() if one of these operations fails and it will always return EFI_SUCCESS.\r
 \r
   @param  ImageHandle   The firmware allocated handle for the EFI image.\r
@@ -535,7 +774,7 @@ SmmCorePerformanceLibConstructor (
   that records the start time of a performance measurement.\r
 \r
   Adds a record to the end of the performance measurement log\r
-  that contains the Handle, Token, and Module.\r
+  that contains the Handle, Token, Module and Identifier.\r
   The end time of the new record must be set to zero.\r
   If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.\r
   If TimeStamp is zero, the start time in the record is filled in with the value\r
@@ -548,6 +787,8 @@ SmmCorePerformanceLibConstructor (
   @param  Module                  Pointer to a Null-terminated ASCII string\r
                                   that identifies the module being measured.\r
   @param  TimeStamp               64-bit time stamp.\r
+  @param  Identifier              32-bit identifier. If the value is 0, the created record\r
+                                  is same as the one created by StartPerformanceMeasurement.\r
 \r
   @retval RETURN_SUCCESS          The start of the measurement was recorded.\r
   @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.\r
@@ -555,17 +796,15 @@ SmmCorePerformanceLibConstructor (
 **/\r
 RETURN_STATUS\r
 EFIAPI\r
-StartPerformanceMeasurement (\r
+StartPerformanceMeasurementEx (\r
   IN CONST VOID   *Handle,  OPTIONAL\r
   IN CONST CHAR8  *Token,   OPTIONAL\r
   IN CONST CHAR8  *Module,  OPTIONAL\r
-  IN UINT64       TimeStamp\r
+  IN UINT64       TimeStamp,\r
+  IN UINT32       Identifier\r
   )\r
 {\r
-  EFI_STATUS  Status;\r
-\r
-  Status = StartGauge (Handle, Token, Module, TimeStamp);\r
-  return (RETURN_STATUS) Status;\r
+  return (RETURN_STATUS) StartGaugeEx (Handle, Token, Module, TimeStamp, Identifier);\r
 }\r
 \r
 /**\r
@@ -573,7 +812,7 @@ StartPerformanceMeasurement (
   for the first matching record that contains a zero end time and fills in a valid end time.\r
 \r
   Searches the performance measurement log from the beginning of the log\r
-  for the first record that matches Handle, Token, and Module and has an end time value of zero.\r
+  for the first record that matches Handle, Token, Module and Identifier and has an end time value of zero.\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 the end time in the record is filled in with the value specified by TimeStamp.\r
@@ -587,6 +826,8 @@ StartPerformanceMeasurement (
   @param  Module                  Pointer to a Null-terminated ASCII string\r
                                   that identifies the module being measured.\r
   @param  TimeStamp               64-bit time stamp.\r
+  @param  Identifier              32-bit identifier. If the value is 0, the found record\r
+                                  is same as the one found by EndPerformanceMeasurement.\r
 \r
   @retval RETURN_SUCCESS          The end of  the measurement was recorded.\r
   @retval RETURN_NOT_FOUND        The specified measurement record could not be found.\r
@@ -594,21 +835,21 @@ StartPerformanceMeasurement (
 **/\r
 RETURN_STATUS\r
 EFIAPI\r
-EndPerformanceMeasurement (\r
+EndPerformanceMeasurementEx (\r
   IN CONST VOID   *Handle,  OPTIONAL\r
   IN CONST CHAR8  *Token,   OPTIONAL\r
   IN CONST CHAR8  *Module,  OPTIONAL\r
-  IN UINT64       TimeStamp\r
+  IN UINT64       TimeStamp,\r
+  IN UINT32       Identifier\r
   )\r
 {\r
-  EFI_STATUS  Status;\r
-\r
-  Status = EndGauge (Handle, Token, Module, TimeStamp);\r
-  return (RETURN_STATUS) Status;\r
+  return (RETURN_STATUS) EndGaugeEx (Handle, Token, Module, TimeStamp, Identifier);\r
 }\r
 \r
 /**\r
   Attempts to retrieve a performance measurement log entry from the performance measurement log.\r
+  It can also retrieve the log created by StartPerformanceMeasurement and EndPerformanceMeasurement,\r
+  and then assign the Identifier with 0.\r
 \r
   Attempts to retrieve the performance log entry specified by LogEntryKey.  If LogEntryKey is\r
   zero on entry, then an attempt is made to retrieve the first entry from the performance log,\r
@@ -619,13 +860,14 @@ EndPerformanceMeasurement (
   retrieved and an implementation specific non-zero key value that specifies the end of the performance\r
   log is returned.  If LogEntryKey is equal this implementation specific non-zero key value, then no entry\r
   is retrieved and zero is returned.  In the cases where a performance log entry can be returned,\r
-  the log entry is returned in Handle, Token, Module, StartTimeStamp, and EndTimeStamp.\r
+  the log entry is returned in Handle, Token, Module, StartTimeStamp, EndTimeStamp and Identifier.\r
   If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().\r
   If Handle is NULL, then ASSERT().\r
   If Token is NULL, then ASSERT().\r
   If Module is NULL, then ASSERT().\r
   If StartTimeStamp is NULL, then ASSERT().\r
   If EndTimeStamp is NULL, then ASSERT().\r
+  If Identifier is NULL, then ASSERT().\r
 \r
   @param  LogEntryKey             On entry, the key of the performance measurement log entry to retrieve.\r
                                   0, then the first performance measurement log entry is retrieved.\r
@@ -640,23 +882,25 @@ EndPerformanceMeasurement (
                                   was started.\r
   @param  EndTimeStamp            Pointer to the 64-bit time stamp that was recorded when the measurement\r
                                   was ended.\r
+  @param  Identifier              Pointer to the 32-bit identifier that was recorded.\r
 \r
   @return The key for the next performance log entry (in general case).\r
 \r
 **/\r
 UINTN\r
 EFIAPI\r
-GetPerformanceMeasurement (\r
-  IN  UINTN       LogEntryKey,\r
+GetPerformanceMeasurementEx (\r
+  IN  UINTN       LogEntryKey, \r
   OUT CONST VOID  **Handle,\r
   OUT CONST CHAR8 **Token,\r
   OUT CONST CHAR8 **Module,\r
   OUT UINT64      *StartTimeStamp,\r
-  OUT UINT64      *EndTimeStamp\r
+  OUT UINT64      *EndTimeStamp,\r
+  OUT UINT32      *Identifier\r
   )\r
 {\r
-  EFI_STATUS        Status;\r
-  GAUGE_DATA_ENTRY  *GaugeData;\r
+  EFI_STATUS           Status;\r
+  GAUGE_DATA_ENTRY_EX  *GaugeData;\r
 \r
   GaugeData = NULL;\r
   \r
@@ -665,8 +909,9 @@ GetPerformanceMeasurement (
   ASSERT (Module != NULL);\r
   ASSERT (StartTimeStamp != NULL);\r
   ASSERT (EndTimeStamp != NULL);\r
+  ASSERT (Identifier != NULL);\r
 \r
-  Status = GetGauge (LogEntryKey++, &GaugeData);\r
+  Status = GetGaugeEx (LogEntryKey++, &GaugeData);\r
 \r
   //\r
   // Make sure that LogEntryKey is a valid log entry key,\r
@@ -687,10 +932,136 @@ GetPerformanceMeasurement (
   *Module         = GaugeData->Module;\r
   *StartTimeStamp = GaugeData->StartTimeStamp;\r
   *EndTimeStamp   = GaugeData->EndTimeStamp;\r
+  *Identifier     = GaugeData->Identifier;\r
 \r
   return LogEntryKey;\r
 }\r
 \r
+/**\r
+  Adds a record at the end of the performance measurement log\r
+  that records the start time of a performance measurement.\r
+\r
+  Adds a record to the end of the performance measurement log\r
+  that contains the Handle, Token, and Module.\r
+  The end time of the new record must be set to zero.\r
+  If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.\r
+  If TimeStamp is zero, the start time in the record is filled in with the value\r
+  read from the current time stamp.\r
+\r
+  @param  Handle                  Pointer to environment specific context used\r
+                                  to identify the component being measured.\r
+  @param  Token                   Pointer to a Null-terminated ASCII string\r
+                                  that identifies the component being measured.\r
+  @param  Module                  Pointer to a Null-terminated ASCII string\r
+                                  that identifies the module being measured.\r
+  @param  TimeStamp               64-bit time stamp.\r
+\r
+  @retval RETURN_SUCCESS          The start of the measurement was recorded.\r
+  @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+StartPerformanceMeasurement (\r
+  IN CONST VOID   *Handle,  OPTIONAL\r
+  IN CONST CHAR8  *Token,   OPTIONAL\r
+  IN CONST CHAR8  *Module,  OPTIONAL\r
+  IN UINT64       TimeStamp\r
+  )\r
+{\r
+  return StartPerformanceMeasurementEx (Handle, Token, Module, TimeStamp, 0);\r
+}\r
+\r
+/**\r
+  Searches the performance measurement log from the beginning of the log\r
+  for the first matching record that contains a zero end time and fills in a valid end time.\r
+\r
+  Searches the performance measurement log from the beginning of the log\r
+  for the first record that matches Handle, Token, and Module and has an end time value of zero.\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 the end time in the record is filled in with the value specified by TimeStamp.\r
+  If the record is found and TimeStamp is zero, then the end time in the matching record\r
+  is filled in with the current time stamp value.\r
+\r
+  @param  Handle                  Pointer to environment specific context used\r
+                                  to identify the component being measured.\r
+  @param  Token                   Pointer to a Null-terminated ASCII string\r
+                                  that identifies the component being measured.\r
+  @param  Module                  Pointer to a Null-terminated ASCII string\r
+                                  that identifies the module being measured.\r
+  @param  TimeStamp               64-bit time stamp.\r
+\r
+  @retval RETURN_SUCCESS          The end of  the measurement was recorded.\r
+  @retval RETURN_NOT_FOUND        The specified measurement record could not be found.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+EndPerformanceMeasurement (\r
+  IN CONST VOID   *Handle,  OPTIONAL\r
+  IN CONST CHAR8  *Token,   OPTIONAL\r
+  IN CONST CHAR8  *Module,  OPTIONAL\r
+  IN UINT64       TimeStamp\r
+  )\r
+{\r
+  return EndPerformanceMeasurementEx (Handle, Token, Module, TimeStamp, 0);\r
+}\r
+\r
+/**\r
+  Attempts to retrieve a performance measurement log entry from the performance measurement log.\r
+  It can also retrieve the log created by StartPerformanceMeasurementEx and EndPerformanceMeasurementEx,\r
+  and then eliminate the Identifier.\r
+\r
+  Attempts to retrieve the performance log entry specified by LogEntryKey.  If LogEntryKey is\r
+  zero on entry, then an attempt is made to retrieve the first entry from the performance log,\r
+  and the key for the second entry in the log is returned.  If the performance log is empty,\r
+  then no entry is retrieved and zero is returned.  If LogEntryKey is not zero, then the performance\r
+  log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is\r
+  returned.  If LogEntryKey is the key for the last entry in the log, then the last log entry is\r
+  retrieved and an implementation specific non-zero key value that specifies the end of the performance\r
+  log is returned.  If LogEntryKey is equal this implementation specific non-zero key value, then no entry\r
+  is retrieved and zero is returned.  In the cases where a performance log entry can be returned,\r
+  the log entry is returned in Handle, Token, Module, StartTimeStamp, and EndTimeStamp.\r
+  If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().\r
+  If Handle is NULL, then ASSERT().\r
+  If Token is NULL, then ASSERT().\r
+  If Module is NULL, then ASSERT().\r
+  If StartTimeStamp is NULL, then ASSERT().\r
+  If EndTimeStamp is NULL, then ASSERT().\r
+\r
+  @param  LogEntryKey             On entry, the key of the performance measurement log entry to retrieve.\r
+                                  0, then the first performance measurement log entry is retrieved.\r
+                                  On exit, the key of the next performance log entry.\r
+  @param  Handle                  Pointer to environment specific context used to identify the component\r
+                                  being measured.\r
+  @param  Token                   Pointer to a Null-terminated ASCII string that identifies the component\r
+                                  being measured.\r
+  @param  Module                  Pointer to a Null-terminated ASCII string that identifies the module\r
+                                  being measured.\r
+  @param  StartTimeStamp          Pointer to the 64-bit time stamp that was recorded when the measurement\r
+                                  was started.\r
+  @param  EndTimeStamp            Pointer to the 64-bit time stamp that was recorded when the measurement\r
+                                  was ended.\r
+\r
+  @return The key for the next performance log entry (in general case).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+GetPerformanceMeasurement (\r
+  IN  UINTN       LogEntryKey,\r
+  OUT CONST VOID  **Handle,\r
+  OUT CONST CHAR8 **Token,\r
+  OUT CONST CHAR8 **Module,\r
+  OUT UINT64      *StartTimeStamp,\r
+  OUT UINT64      *EndTimeStamp\r
+  )\r
+{\r
+  UINT32 Identifier;\r
+  return GetPerformanceMeasurementEx (LogEntryKey, Handle, Token, Module, StartTimeStamp, EndTimeStamp, &Identifier);\r
+}\r
+\r
 /**\r
   Returns TRUE if the performance measurement macros are enabled.\r
 \r
@@ -711,5 +1082,3 @@ PerformanceMeasurementEnabled (
 {\r
   return mPerformanceMeasurementEnabled;\r
 }\r
-\r
-\r
index cbf2c545f6852949ad138b4ec2d63c1ef3709b6d..0cc367f971acdbee2a53fc51e5514fafe471d860 100644 (file)
@@ -3,12 +3,12 @@
 #  \r
 #  This library provides the performance measurement interfaces and initializes performance\r
 #  logging for the SMM phase. \r
-#  It initializes SMM phase performance logging by publishing the Performance Protocol,\r
+#  It initializes SMM phase performance logging by publishing the SMM Performance and PerformanceEx Protocol,\r
 #  which is consumed by SmmPerformanceLib to logging performance data in SMM phase.\r
 #  This library is mainly used by SMM Core to start performance logging to ensure that\r
-#  SMM Performance Protocol is installed at the very beginning of SMM phase.\r
+#  SMM Performance and PerformanceEx Protocol are installed at the very beginning of SMM phase.\r
 #  \r
-#  Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
+#  Copyright (c) 2011 - 2012, 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
@@ -54,6 +54,7 @@
   BaseLib\r
   DebugLib\r
   SynchronizationLib\r
+  SmmServicesTableLib\r
 \r
 [Protocols]\r
   gEfiSmmBase2ProtocolGuid                  ## CONSUMES\r
@@ -61,7 +62,7 @@
 \r
 [Guids]\r
   gSmmPerformanceProtocolGuid               ## PRODUCES\r
+  gSmmPerformanceExProtocolGuid             ## PRODUCES\r
 \r
 [Pcd]\r
-  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxPeiPerformanceLogEntries\r
   gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask\r
index 159d92b4a2f7f103ae1ff3e3154278d4c395a512..a02368827885ac789dbdfe68cf7ea99ef600034d 100644 (file)
@@ -1,10 +1,10 @@
 /** @file\r
   Master header files for SmmCorePerformanceLib instance.\r
 \r
-  This header file holds the prototypes of the Performance Protocol published by this\r
+  This header file holds the prototypes of the SMM Performance and PerformanceEx Protocol published by this\r
   library instance at its constructor.\r
 \r
-Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2011 - 2012, 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
@@ -37,7 +37,108 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Protocol/SmmAccess2.h>\r
 \r
 //\r
-// Interface declarations for Performance Protocol.\r
+// Interface declarations for SMM PerformanceEx Protocol.\r
+//\r
+/**\r
+  Adds a record at the end of the performance measurement log\r
+  that records the start time of a performance measurement.\r
+\r
+  Adds a record to the end of the performance measurement log\r
+  that contains the Handle, Token, Module and Identifier.\r
+  The end time of the new record must be set to zero.\r
+  If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.\r
+  If TimeStamp is zero, the start time in the record is filled in with the value\r
+  read from the current time stamp.\r
+\r
+  @param  Handle                  Pointer to environment specific context used\r
+                                  to identify the component being measured.\r
+  @param  Token                   Pointer to a Null-terminated ASCII string\r
+                                  that identifies the component being measured.\r
+  @param  Module                  Pointer to a Null-terminated ASCII string\r
+                                  that identifies the module being measured.\r
+  @param  TimeStamp               64-bit time stamp.\r
+  @param  Identifier              32-bit identifier. If the value is 0, the created record\r
+                                  is same as the one created by StartGauge of PERFORMANCE_PROTOCOL.\r
+\r
+  @retval EFI_SUCCESS             The data was read correctly from the device.\r
+  @retval EFI_OUT_OF_RESOURCES    There are not enough resources to record the measurement.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+StartGaugeEx (\r
+  IN CONST VOID   *Handle,  OPTIONAL\r
+  IN CONST CHAR8  *Token,   OPTIONAL\r
+  IN CONST CHAR8  *Module,  OPTIONAL\r
+  IN UINT64       TimeStamp,\r
+  IN UINT32       Identifier\r
+  );\r
+\r
+/**\r
+  Searches the performance measurement log from the beginning of the log\r
+  for the first matching record that contains a zero end time and fills in a valid end time.\r
+\r
+  Searches the performance measurement log from the beginning of the log\r
+  for the first record that matches Handle, Token, Module and Identifier and has an end time value of zero.\r
+  If the record can not be found then return EFI_NOT_FOUND.\r
+  If the record is found and TimeStamp is not zero,\r
+  then the end time in the record is filled in with the value specified by TimeStamp.\r
+  If the record is found and TimeStamp is zero, then the end time in the matching record\r
+  is filled in with the current time stamp value.\r
+\r
+  @param  Handle                  Pointer to environment specific context used\r
+                                  to identify the component being measured.\r
+  @param  Token                   Pointer to a Null-terminated ASCII string\r
+                                  that identifies the component being measured.\r
+  @param  Module                  Pointer to a Null-terminated ASCII string\r
+                                  that identifies the module being measured.\r
+  @param  TimeStamp               64-bit time stamp.\r
+  @param  Identifier              32-bit identifier. If the value is 0, the found record\r
+                                  is same as the one found by EndGauge of PERFORMANCE_PROTOCOL.\r
+\r
+  @retval EFI_SUCCESS             The end of  the measurement was recorded.\r
+  @retval EFI_NOT_FOUND           The specified measurement record could not be found.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EndGaugeEx (\r
+  IN CONST VOID   *Handle,  OPTIONAL\r
+  IN CONST CHAR8  *Token,   OPTIONAL\r
+  IN CONST CHAR8  *Module,  OPTIONAL\r
+  IN UINT64       TimeStamp,\r
+  IN UINT32       Identifier\r
+  );\r
+\r
+/**\r
+  Retrieves a previously logged performance measurement.\r
+  It can also retrieve the log created by StartGauge and EndGauge of PERFORMANCE_PROTOCOL,\r
+  and then assign the Identifier with 0.\r
+\r
+  Retrieves the performance log entry from the performance log specified by LogEntryKey.\r
+  If it stands for a valid entry, then EFI_SUCCESS is returned and\r
+  GaugeDataEntryEx stores the pointer to that entry.\r
+\r
+  @param  LogEntryKey             The key for the previous performance measurement log entry.\r
+                                  If 0, then the first performance measurement log entry is retrieved.\r
+  @param  GaugeDataEntryEx        The indirect pointer to the extended gauge data entry specified by LogEntryKey\r
+                                  if the retrieval is successful.\r
+\r
+  @retval EFI_SUCCESS             The GuageDataEntryEx is successfully found based on LogEntryKey.\r
+  @retval EFI_NOT_FOUND           The LogEntryKey is the last entry (equals to the total entry number).\r
+  @retval EFI_INVALIDE_PARAMETER  The LogEntryKey is not a valid entry (greater than the total entry number).\r
+  @retval EFI_INVALIDE_PARAMETER  GaugeDataEntryEx is NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetGaugeEx (\r
+  IN  UINTN                 LogEntryKey,\r
+  OUT GAUGE_DATA_ENTRY_EX   **GaugeDataEntryEx\r
+  );\r
+\r
+//\r
+// Interface declarations for SMM Performance Protocol.\r
 //\r
 /**\r
   Adds a record at the end of the performance measurement log\r
@@ -106,6 +207,8 @@ EndGauge (
 \r
 /**\r
   Retrieves a previously logged performance measurement.\r
+  It can also retrieve the log created by StartGaugeEx and EndGaugeEx of PERFORMANCE_EX_PROTOCOL,\r
+  and then eliminate the Identifier.\r
 \r
   Retrieves the performance log entry from the performance log specified by LogEntryKey.\r
   If it stands for a valid entry, then EFI_SUCCESS is returned and\r
index 3644824e7bd1c5bc811045f083e0f8b4fadc5e60..c01d16d1eb42c2ed419b6a50b04ce4fd1327610b 100644 (file)
@@ -2,8 +2,8 @@
   Performance Library used in SMM phase.\r
 \r
   This library instance provides infrastructure for SMM drivers to log performance\r
-  data. It consumes SMM Performance Protocol published by SmmCorePerformanceLib\r
-  to log performance data. If Performance Protocol is not available, it does not log any\r
+  data. It consumes SMM PerformanceEx or Performance Protocol published by SmmCorePerformanceLib\r
+  to log performance data. If both SMM PerformanceEx and Performance Protocol are not available, it does not log any\r
   performance information.\r
 \r
   Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>\r
@@ -26,21 +26,15 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/PcdLib.h>\r
 #include <Library/BaseMemoryLib.h>\r
 \r
-#include <Protocol/SmmCommunication.h>\r
-\r
 //\r
-// The cached performance protocol interface.\r
+// The cached SMM Performance Protocol and SMM PerformanceEx Protocol interface.\r
 //\r
-PERFORMANCE_PROTOCOL  *mPerformance = NULL;\r
-BOOLEAN               mPerformanceMeasurementEnabled;\r
-\r
+PERFORMANCE_PROTOCOL        *mPerformance = NULL;\r
+PERFORMANCE_EX_PROTOCOL     *mPerformanceEx = NULL;\r
+BOOLEAN                     mPerformanceMeasurementEnabled;\r
 \r
 /**\r
-  The constructor function initializes Performance infrastructure for DXE phase.\r
-\r
-  The constructor function publishes Performance protocol, allocates memory to log DXE performance\r
-  and merges PEI performance data to DXE performance log.\r
-  It will ASSERT() if one of these operations fails and it will always return EFI_SUCCESS.\r
+  The constructor function initializes the Performance Measurement Enable flag\r
 \r
   @param  ImageHandle   The firmware allocated handle for the EFI image.\r
   @param  SystemTable   A pointer to the EFI System Table.\r
@@ -62,13 +56,12 @@ SmmPerformanceLibConstructor (
 }\r
 \r
 /**\r
-  The constructor function caches the pointer to Performance protocol.\r
+  The function caches the pointers to SMM PerformanceEx protocol and Performance Protocol.\r
 \r
-  The constructor function locates SMM erformance protocol from the SMM protocol database.\r
-  It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.\r
+  The function locates SMM PerformanceEx protocol and Performance Protocol from protocol database.\r
 \r
-  @retval EFI_SUCCESS     Performance protocol is successfully located.\r
-  @retval Other           Performance protocol is not located to log performance.\r
+  @retval EFI_SUCCESS     SMM PerformanceEx protocol or Performance Protocol is successfully located.\r
+  @retval EFI_NOT_FOUND   Both SMM PerformanceEx protocol and Performance Protocol are not located to log performance.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -76,10 +69,21 @@ GetPerformanceProtocol (
   VOID\r
   )\r
 {\r
-  EFI_STATUS            Status;\r
-  PERFORMANCE_PROTOCOL  *Performance;\r
+  EFI_STATUS                Status;\r
+  PERFORMANCE_PROTOCOL      *Performance;\r
+  PERFORMANCE_EX_PROTOCOL   *PerformanceEx;\r
 \r
-  if (mPerformance != NULL) {\r
+  if (mPerformanceEx != NULL || mPerformance != NULL) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  Status = gSmst->SmmLocateProtocol (&gSmmPerformanceExProtocolGuid, NULL, (VOID **) &PerformanceEx);\r
+  if (!EFI_ERROR (Status)) {\r
+    ASSERT (PerformanceEx != NULL);\r
+    //\r
+    // Cache PerformanceEx Protocol.\r
+    //\r
+    mPerformanceEx = PerformanceEx;\r
     return EFI_SUCCESS;\r
   }\r
 \r
@@ -90,15 +94,16 @@ GetPerformanceProtocol (
     // Cache performance protocol.\r
     //\r
     mPerformance = Performance;\r
+    return EFI_SUCCESS;\r
   }\r
 \r
-  return Status;\r
+  return EFI_NOT_FOUND;\r
 }\r
 \r
 /**\r
   Creates a record for the beginning of a performance measurement.\r
 \r
-  Creates a record that contains the Handle, Token, and Module.\r
+  Creates a record that contains the Handle, Token, Module and Identifier.\r
   If TimeStamp is not zero, then TimeStamp is added to the record as the start time.\r
   If TimeStamp is zero, then this function reads the current time stamp\r
   and adds that time stamp value to the record as the start time.\r
@@ -110,6 +115,8 @@ GetPerformanceProtocol (
   @param  Module                  Pointer to a Null-terminated ASCII string\r
                                   that identifies the module being measured.\r
   @param  TimeStamp               64-bit time stamp.\r
+  @param  Identifier              32-bit identifier. If the value is 0, the created record\r
+                                  is same as the one created by StartPerformanceMeasurement.\r
 \r
   @retval RETURN_SUCCESS          The start of the measurement was recorded.\r
   @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.\r
@@ -117,11 +124,12 @@ GetPerformanceProtocol (
 **/\r
 RETURN_STATUS\r
 EFIAPI\r
-StartPerformanceMeasurement (\r
+StartPerformanceMeasurementEx (\r
   IN CONST VOID   *Handle,  OPTIONAL\r
   IN CONST CHAR8  *Token,   OPTIONAL\r
   IN CONST CHAR8  *Module,  OPTIONAL\r
-  IN UINT64       TimeStamp\r
+  IN UINT64       TimeStamp,\r
+  IN UINT32       Identifier\r
   )\r
 {\r
   EFI_STATUS  Status;\r
@@ -131,7 +139,13 @@ StartPerformanceMeasurement (
     return RETURN_OUT_OF_RESOURCES;\r
   }\r
 \r
-  Status = mPerformance->StartGauge (Handle, Token, Module, TimeStamp);\r
+  if (mPerformanceEx != NULL) {\r
+    Status = mPerformanceEx->StartGaugeEx (Handle, Token, Module, TimeStamp, Identifier);\r
+  } else if (mPerformance != NULL) {\r
+    Status = mPerformance->StartGauge (Handle, Token, Module, TimeStamp);\r
+  } else {\r
+    ASSERT (FALSE);\r
+  }\r
 \r
   return (RETURN_STATUS) Status;\r
 }\r
@@ -139,7 +153,7 @@ StartPerformanceMeasurement (
 /**\r
   Fills in the end time of a performance measurement.\r
 \r
-  Looks up the record that matches Handle, Token, and Module.\r
+  Looks up the record that matches Handle, Token, Module and Identifier.\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
@@ -153,6 +167,8 @@ StartPerformanceMeasurement (
   @param  Module                  Pointer to a Null-terminated ASCII string\r
                                   that identifies the module being measured.\r
   @param  TimeStamp               64-bit time stamp.\r
+  @param  Identifier              32-bit identifier. If the value is 0, the found record\r
+                                  is same as the one found by EndPerformanceMeasurement.\r
 \r
   @retval RETURN_SUCCESS          The end of  the measurement was recorded.\r
   @retval RETURN_NOT_FOUND        The specified measurement record could not be found.\r
@@ -160,11 +176,12 @@ StartPerformanceMeasurement (
 **/\r
 RETURN_STATUS\r
 EFIAPI\r
-EndPerformanceMeasurement (\r
+EndPerformanceMeasurementEx (\r
   IN CONST VOID   *Handle,  OPTIONAL\r
   IN CONST CHAR8  *Token,   OPTIONAL\r
   IN CONST CHAR8  *Module,  OPTIONAL\r
-  IN UINT64       TimeStamp\r
+  IN UINT64       TimeStamp,\r
+  IN UINT32       Identifier\r
   )\r
 {\r
   EFI_STATUS  Status;\r
@@ -174,13 +191,21 @@ EndPerformanceMeasurement (
     return RETURN_NOT_FOUND;\r
   }\r
 \r
-  Status = mPerformance->EndGauge (Handle, Token, Module, TimeStamp);\r
+  if (mPerformanceEx != NULL) {\r
+    Status = mPerformanceEx->EndGaugeEx (Handle, Token, Module, TimeStamp, Identifier);\r
+  } else if (mPerformance != NULL) {\r
+    Status = mPerformance->EndGauge (Handle, Token, Module, TimeStamp);\r
+  } else {\r
+    ASSERT (FALSE);\r
+  }\r
 \r
   return (RETURN_STATUS) Status;\r
 }\r
 \r
 /**\r
   Attempts to retrieve a performance measurement log entry from the performance measurement log.\r
+  It can also retrieve the log created by StartPerformanceMeasurement and EndPerformanceMeasurement,\r
+  and then assign the Identifier with 0.\r
 \r
   Attempts to retrieve the performance log entry specified by LogEntryKey.  If LogEntryKey is\r
   zero on entry, then an attempt is made to retrieve the first entry from the performance log,\r
@@ -191,13 +216,14 @@ EndPerformanceMeasurement (
   retrieved and an implementation specific non-zero key value that specifies the end of the performance\r
   log is returned.  If LogEntryKey is equal this implementation specific non-zero key value, then no entry\r
   is retrieved and zero is returned.  In the cases where a performance log entry can be returned,\r
-  the log entry is returned in Handle, Token, Module, StartTimeStamp, and EndTimeStamp.\r
+  the log entry is returned in Handle, Token, Module, StartTimeStamp, EndTimeStamp and Identifier.\r
   If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().\r
   If Handle is NULL, then ASSERT().\r
   If Token is NULL, then ASSERT().\r
   If Module is NULL, then ASSERT().\r
   If StartTimeStamp is NULL, then ASSERT().\r
   If EndTimeStamp is NULL, then ASSERT().\r
+  If Identifier is NULL, then ASSERT().\r
 \r
   @param  LogEntryKey             On entry, the key of the performance measurement log entry to retrieve.\r
                                   0, then the first performance measurement log entry is retrieved.\r
@@ -212,24 +238,26 @@ EndPerformanceMeasurement (
                                   was started.\r
   @param  EndTimeStamp            Pointer to the 64-bit time stamp that was recorded when the measurement\r
                                   was ended.\r
+  @param  Identifier              Pointer to the 32-bit identifier that was recorded.\r
 \r
   @return The key for the next performance log entry (in general case).\r
 \r
 **/\r
 UINTN\r
 EFIAPI\r
-GetPerformanceMeasurement (\r
-  IN  UINTN       LogEntryKey,\r
+GetPerformanceMeasurementEx (\r
+  IN  UINTN       LogEntryKey, \r
   OUT CONST VOID  **Handle,\r
   OUT CONST CHAR8 **Token,\r
   OUT CONST CHAR8 **Module,\r
   OUT UINT64      *StartTimeStamp,\r
-  OUT UINT64      *EndTimeStamp\r
+  OUT UINT64      *EndTimeStamp,\r
+  OUT UINT32      *Identifier\r
   )\r
 {\r
-  EFI_STATUS        Status;\r
-  GAUGE_DATA_ENTRY  *GaugeData;\r
-       \r
+  EFI_STATUS            Status;\r
+  GAUGE_DATA_ENTRY_EX   *GaugeData;\r
+\r
   GaugeData = NULL;\r
 \r
   ASSERT (Handle != NULL);\r
@@ -237,13 +265,21 @@ GetPerformanceMeasurement (
   ASSERT (Module != NULL);\r
   ASSERT (StartTimeStamp != NULL);\r
   ASSERT (EndTimeStamp != NULL);\r
+  ASSERT (Identifier != NULL);\r
 \r
   Status = GetPerformanceProtocol ();\r
   if (EFI_ERROR (Status)) {\r
     return 0;\r
   }\r
 \r
-  Status = mPerformance->GetGauge (LogEntryKey++, &GaugeData);\r
+  if (mPerformanceEx != NULL) {\r
+    Status = mPerformanceEx->GetGaugeEx (LogEntryKey++, &GaugeData);\r
+  } else if (mPerformance != NULL) {\r
+    Status = mPerformance->GetGauge (LogEntryKey++, (GAUGE_DATA_ENTRY **) &GaugeData);\r
+  } else {\r
+    ASSERT (FALSE);\r
+    return 0;\r
+  }\r
 \r
   //\r
   // Make sure that LogEntryKey is a valid log entry key,\r
@@ -264,10 +300,135 @@ GetPerformanceMeasurement (
   *Module         = GaugeData->Module;\r
   *StartTimeStamp = GaugeData->StartTimeStamp;\r
   *EndTimeStamp   = GaugeData->EndTimeStamp;\r
+  if (mPerformanceEx != NULL) {\r
+    *Identifier   = GaugeData->Identifier;\r
+  } else {\r
+    *Identifier   = 0;\r
+  }\r
 \r
   return LogEntryKey;\r
 }\r
 \r
+/**\r
+  Creates a record for the beginning of a performance measurement.\r
+\r
+  Creates a record that contains the Handle, Token, and Module.\r
+  If TimeStamp is not zero, then TimeStamp is added to the record as the start time.\r
+  If TimeStamp is zero, then this function reads the current time stamp\r
+  and adds that time stamp value to the record as the start time.\r
+\r
+  @param  Handle                  Pointer to environment specific context used\r
+                                  to identify the component being measured.\r
+  @param  Token                   Pointer to a Null-terminated ASCII string\r
+                                  that identifies the component being measured.\r
+  @param  Module                  Pointer to a Null-terminated ASCII string\r
+                                  that identifies the module being measured.\r
+  @param  TimeStamp               64-bit time stamp.\r
+\r
+  @retval RETURN_SUCCESS          The start of the measurement was recorded.\r
+  @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+StartPerformanceMeasurement (\r
+  IN CONST VOID   *Handle,  OPTIONAL\r
+  IN CONST CHAR8  *Token,   OPTIONAL\r
+  IN CONST CHAR8  *Module,  OPTIONAL\r
+  IN UINT64       TimeStamp\r
+  )\r
+{\r
+  return StartPerformanceMeasurementEx (Handle, Token, Module, TimeStamp, 0);\r
+}\r
+\r
+/**\r
+  Fills in the end time of a performance measurement.\r
+\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
+  If the record is found and TimeStamp is zero, then this function reads\r
+  the current time stamp and adds that time stamp value to the record as the end time.\r
+\r
+  @param  Handle                  Pointer to environment specific context used\r
+                                  to identify the component being measured.\r
+  @param  Token                   Pointer to a Null-terminated ASCII string\r
+                                  that identifies the component being measured.\r
+  @param  Module                  Pointer to a Null-terminated ASCII string\r
+                                  that identifies the module being measured.\r
+  @param  TimeStamp               64-bit time stamp.\r
+\r
+  @retval RETURN_SUCCESS          The end of  the measurement was recorded.\r
+  @retval RETURN_NOT_FOUND        The specified measurement record could not be found.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+EndPerformanceMeasurement (\r
+  IN CONST VOID   *Handle,  OPTIONAL\r
+  IN CONST CHAR8  *Token,   OPTIONAL\r
+  IN CONST CHAR8  *Module,  OPTIONAL\r
+  IN UINT64       TimeStamp\r
+  )\r
+{\r
+  return EndPerformanceMeasurementEx (Handle, Token, Module, TimeStamp, 0);\r
+}\r
+\r
+/**\r
+  Attempts to retrieve a performance measurement log entry from the performance measurement log.\r
+  It can also retrieve the log created by StartPerformanceMeasurementEx and EndPerformanceMeasurementEx,\r
+  and then eliminate the Identifier.\r
+\r
+  Attempts to retrieve the performance log entry specified by LogEntryKey.  If LogEntryKey is\r
+  zero on entry, then an attempt is made to retrieve the first entry from the performance log,\r
+  and the key for the second entry in the log is returned.  If the performance log is empty,\r
+  then no entry is retrieved and zero is returned.  If LogEntryKey is not zero, then the performance\r
+  log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is\r
+  returned.  If LogEntryKey is the key for the last entry in the log, then the last log entry is\r
+  retrieved and an implementation specific non-zero key value that specifies the end of the performance\r
+  log is returned.  If LogEntryKey is equal this implementation specific non-zero key value, then no entry\r
+  is retrieved and zero is returned.  In the cases where a performance log entry can be returned,\r
+  the log entry is returned in Handle, Token, Module, StartTimeStamp, and EndTimeStamp.\r
+  If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().\r
+  If Handle is NULL, then ASSERT().\r
+  If Token is NULL, then ASSERT().\r
+  If Module is NULL, then ASSERT().\r
+  If StartTimeStamp is NULL, then ASSERT().\r
+  If EndTimeStamp is NULL, then ASSERT().\r
+\r
+  @param  LogEntryKey             On entry, the key of the performance measurement log entry to retrieve.\r
+                                  0, then the first performance measurement log entry is retrieved.\r
+                                  On exit, the key of the next performance log entry.\r
+  @param  Handle                  Pointer to environment specific context used to identify the component\r
+                                  being measured.\r
+  @param  Token                   Pointer to a Null-terminated ASCII string that identifies the component\r
+                                  being measured.\r
+  @param  Module                  Pointer to a Null-terminated ASCII string that identifies the module\r
+                                  being measured.\r
+  @param  StartTimeStamp          Pointer to the 64-bit time stamp that was recorded when the measurement\r
+                                  was started.\r
+  @param  EndTimeStamp            Pointer to the 64-bit time stamp that was recorded when the measurement\r
+                                  was ended.\r
+\r
+  @return The key for the next performance log entry (in general case).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+GetPerformanceMeasurement (\r
+  IN  UINTN       LogEntryKey,\r
+  OUT CONST VOID  **Handle,\r
+  OUT CONST CHAR8 **Token,\r
+  OUT CONST CHAR8 **Module,\r
+  OUT UINT64      *StartTimeStamp,\r
+  OUT UINT64      *EndTimeStamp\r
+  )\r
+{\r
+  UINT32 Identifier;\r
+  return GetPerformanceMeasurementEx (LogEntryKey, Handle, Token, Module, StartTimeStamp, EndTimeStamp, &Identifier);\r
+}\r
+\r
 /**\r
   Returns TRUE if the performance measurement macros are enabled.\r
 \r
index 9397fec3681cca692fdbf6424303b43c27e88824..ac25a434d2b4b22f5f374d4c25d55e1152d5a2aa 100644 (file)
@@ -2,11 +2,11 @@
 #  Performance library instance used in SMM phase.\r
 #  \r
 #  This library instance provides infrastructure for SMM drivers to log performance\r
-#  data. It consumes SMM Performance Protocol published by SmmCorePerformanceLib\r
-#  to log performance data. If Performance Protocol is not available, it does not log any\r
+#  data. It consumes SMM PerformanceEx or Performance Protocol published by SmmCorePerformanceLib\r
+#  to log performance data. If both SMM PerformanceEx and Performance Protocol are not available, it does not log any\r
 #  performance information.\r
 #  \r
-#  Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
+#  Copyright (c) 2011 - 2012, 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
   DebugLib\r
   BaseMemoryLib\r
 \r
-[Protocols]\r
-  gEfiSmmCommunicationProtocolGuid      ## CONSUMES\r
-\r
-\r
 [Guids]\r
-  gSmmPerformanceProtocolGuid           ## CONSUMES\r
-\r
+  gSmmPerformanceProtocolGuid           ## SOMETIMES_CONSUMES\r
+  gSmmPerformanceExProtocolGuid         ## SOMETIMES_CONSUMES\r
 \r
 [Pcd]\r
   gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask\r
-\r
-[Depex]\r
-  gEfiSmmCommunicationProtocolGuid\r
index 7facc063797d4d4f51d7333d7b6ead54cd2c683d..775dfa614dadf0e78e249c0070d069217952a55c 100644 (file)
   \r
   ## Performance protocol guid that also acts as the performance HOB guid and performance variable GUID\r
   #  Include/Guid/Performance.h\r
-  gPerformanceProtocolGuid       = { 0x76B6BDFA, 0x2ACD, 0x4462, { 0x9E, 0x3F, 0xCB, 0x58, 0xC9, 0x69, 0xD9, 0x37 }}\r
-  gSmmPerformanceProtocolGuid    = { 0xf866226a, 0xeaa5, 0x4f5a, { 0xa9, 0xa, 0x6c, 0xfb, 0xa5, 0x7c, 0x58, 0x8e } }\r
+  gPerformanceProtocolGuid       = { 0x76B6BDFA, 0x2ACD, 0x4462, { 0x9E, 0x3F, 0xCB, 0x58, 0xC9, 0x69, 0xD9, 0x37 } }\r
+  gSmmPerformanceProtocolGuid    = { 0xf866226a, 0xeaa5, 0x4f5a, { 0xa9, 0xa,  0x6c, 0xfb, 0xa5, 0x7c, 0x58, 0x8e } }\r
+  gPerformanceExProtocolGuid     = { 0x1ea81bec, 0xf01a, 0x4d98, { 0xa2, 0x1,  0x4a, 0x61, 0xce, 0x2f, 0xc0, 0x22 } }\r
+  gSmmPerformanceExProtocolGuid  = { 0x931fc048, 0xc71d, 0x4455, { 0x89, 0x30, 0x47, 0x6,  0x30, 0xe3, 0xe,  0xe5 } }\r
 \r
   ## Guid is defined for CRC32 encapsulation scheme.\r
   #  Include/Guid/Crc32GuidedSectionExtraction.h\r