public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [patch 0/9] Add new Perf macros
@ 2018-06-19  7:23 Dandan Bi
  2018-06-19  7:23 ` [patch 1/9] MdeModulePkg: Add PERFORMANCE_MEASUREMENT_PROTOCOL Dandan Bi
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: Dandan Bi @ 2018-06-19  7:23 UTC (permalink / raw)
  To: edk2-devel; +Cc: Liming Gao, Star Zeng, Michael Kinney

Add a group of new Perf macros in performance library for performance
logging. Which will simplify the usage model of performance measurement.
And also introduce new control functionality to disable different
perf types.

Patch 1-2:
Add a new internal protocol PERFORMANCE_MEASUREMENT_PROTOCOL,
which can be used to log performance info.

Patch 3-5:
Add new Perf macros and update library instances in MdeModulePkg
to for the implementation of new perf macros.

Patch 6:
Enhance the logic in DP tool since some new record and control
functionality are introduced by new Perf macros.

Patch 7-9:
update the consumer codes in core to use the new Perf macros.

Unit test:
1.DP tool can dump the performance data saved in the ACPI FPDT
  when set PcdEdkiiFpdtStringRecordEnableOnly to TRUE/FALSE.
2.Can disable specific knids of Perf entry through
  setting PcdPerformanceLibraryPropertyMask.

Cc: Liming Gao <liming.gao@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Michael Kinney <michael.d.kinney@intel.com>

Dandan Bi (9):
  MdeModulePkg: Add PERFORMANCE_MEASUREMENT_PROTOCOL
  MdeModulePkg: Update Performance instances to use new protocol
  MdePkg/PerformanceLib.h: Add new Perf macros
  MdeModulePkg/ExtendedFirmwarePerf: Remove PerfId definitions
  MdeModulePkg: Update performance library instances
  ShellPkg/dp: Update dp tool to parse new Perf record
  MdeModulePkg: Use new added Perf macros
  SecurityPkg: Use new added Perf macros
  UefiCpuPkg: Use new added Perf macros

 MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c      |   7 +
 MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c            |   8 +-
 MdeModulePkg/Core/Dxe/Hand/DriverSupport.c         |   8 +-
 MdeModulePkg/Core/Dxe/Image/Image.c                |  30 +-
 MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c      |   8 +-
 MdeModulePkg/Core/Pei/PeiMain/PeiMain.c            |  17 +-
 MdeModulePkg/Core/PiSmmCore/Dispatcher.c           |  15 +-
 MdeModulePkg/Core/PiSmmCore/PiSmmCore.c            |   4 +-
 .../Include/Guid/ExtendedFirmwarePerformance.h     |  25 -
 MdeModulePkg/Include/Guid/PerformanceMeasurement.h |  91 +++
 .../DxeCorePerformanceLib/DxeCorePerformanceLib.c  | 893 +++++++++++++++------
 .../DxeCorePerformanceLib.inf                      |   7 +-
 .../DxeCorePerformanceLibInternal.h                | 217 +----
 .../Library/DxePerformanceLib/DxePerformanceLib.c  | 193 +++--
 .../DxePerformanceLib/DxePerformanceLib.inf        |   5 +-
 .../Library/PeiPerformanceLib/PeiPerformanceLib.c  | 442 ++++++++--
 .../SmmCorePerformanceLib/SmmCorePerformanceLib.c  | 689 ++++++++++------
 .../SmmCorePerformanceLib.inf                      |   7 +-
 .../SmmCorePerformanceLibInternal.h                | 215 +----
 .../Library/SmmPerformanceLib/SmmPerformanceLib.c  | 198 ++---
 .../SmmPerformanceLib/SmmPerformanceLib.inf        |   5 +-
 MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c   |   2 +-
 .../Library/UefiBootManagerLib/BmConsole.c         |   9 +-
 MdeModulePkg/MdeModulePkg.dec                      |   3 +
 MdeModulePkg/Universal/BdsDxe/BdsEntry.c           |  21 +-
 MdePkg/Include/Library/PerformanceLib.h            | 408 +++++++++-
 .../BasePerformanceLibNull/PerformanceLib.c        |  57 +-
 MdePkg/MdePkg.dec                                  |   9 +-
 MdePkg/MdePkg.uni                                  |   6 +
 .../DxeRsa2048Sha256GuidedSectionExtractLib.c      |  16 +-
 .../PeiRsa2048Sha256GuidedSectionExtractLib.c      |  16 +-
 ShellPkg/DynamicCommand/DpDynamicCommand/Dp.c      |  75 +-
 ShellPkg/DynamicCommand/DpDynamicCommand/Dp.h      |   1 +
 UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c  |  16 +-
 34 files changed, 2460 insertions(+), 1263 deletions(-)
 create mode 100644 MdeModulePkg/Include/Guid/PerformanceMeasurement.h

-- 
2.14.3.windows.1



^ permalink raw reply	[flat|nested] 10+ messages in thread

* [patch 1/9] MdeModulePkg: Add PERFORMANCE_MEASUREMENT_PROTOCOL
  2018-06-19  7:23 [patch 0/9] Add new Perf macros Dandan Bi
@ 2018-06-19  7:23 ` Dandan Bi
  2018-06-19  7:23 ` [patch 2/9] MdeModulePkg: Update Performance instances to use new protocol Dandan Bi
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Dandan Bi @ 2018-06-19  7:23 UTC (permalink / raw)
  To: edk2-devel; +Cc: Liming Gao, Star Zeng

Add PerformanceMeasurement protocol to log performance info.

Cc: Liming Gao <liming.gao@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Dandan Bi <dandan.bi@intel.com>
---
 MdeModulePkg/Include/Guid/PerformanceMeasurement.h | 91 ++++++++++++++++++++++
 MdeModulePkg/MdeModulePkg.dec                      |  3 +
 2 files changed, 94 insertions(+)
 create mode 100644 MdeModulePkg/Include/Guid/PerformanceMeasurement.h

diff --git a/MdeModulePkg/Include/Guid/PerformanceMeasurement.h b/MdeModulePkg/Include/Guid/PerformanceMeasurement.h
new file mode 100644
index 00000000000..f2955c73589
--- /dev/null
+++ b/MdeModulePkg/Include/Guid/PerformanceMeasurement.h
@@ -0,0 +1,91 @@
+/** @file
+
+Copyright (c) 2017, Microsoft Corporation
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+
+All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+1. Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Performance measurement protocol, allows logging performance data.
+
+**/
+
+#ifndef _PERFORMANCE_MEASUREMENT_H_
+#define _PERFORMANCE_MEASUREMENT_H_
+
+//
+// GUID for Performance measurement Protocol
+//
+#define PERFORMANCE_MEASUREMENT_PROTOCOL_GUID \
+  { 0xc85d06be, 0x5f75, 0x48ce, {0xa8, 0x0f, 0x12, 0x36, 0xba, 0x3b, 0x87, 0xb1 } }
+
+#define SMM_PERFORMANCE_MEASUREMENT_PROTOCOL_GUID \
+  { 0xd56b6d73, 0x1a7b, 0x4015, {0x9b, 0xb4, 0x7b, 0x07, 0x17, 0x29, 0xed, 0x24 } }
+
+typedef struct _EDKII_PERFORMANCE_MEASUREMENT_PROTOCOL EDKII_PERFORMANCE_MEASUREMENT_PROTOCOL;
+
+typedef enum {
+  PerfStartEntry,                        // used in StartPerformanceMeasurement()/StartPerformanceMeasurementEx()
+                                         // (map to PERF_START/PERF_START_EX)
+  PerfEndEntry,                          // used in EndPerformanceMeasurement()/EndPerformanceMeasurementEx()
+                                         // (map to PERF_END/PERF_END_EX)
+  PerfEntry                              // used in LogPerformanceMeasurement()
+                                         // (map to other Perf macros except above 4 macros)
+} PERF_MEASUREMENT_ATTRIBUTE;
+
+/**
+  Create performance record with event description and a timestamp.
+
+  @param CallerIdentifier  - Image handle or pointer to caller ID GUID.
+  @param Guid              - Pointer to a GUID.
+  @param String            - Pointer to a string describing the measurement.
+  @param TimeStamp         - 64-bit time stamp.
+  @param Address           - Pointer to a location in memory relevant to the measurement.
+  @param Identifier        - Performance identifier describing the type of measurement.
+  @param Attribute         - The attribute of the measurement. According to attribute can create a start
+                             record for PERF_START/PERF_START_EX, or a end record for PERF_END/PERF_END_EX,
+                             or a general record for other Perf macros.
+
+  @retval EFI_SUCCESS           - Successfully created performance record.
+  @retval EFI_OUT_OF_RESOURCES  - Ran out of space to store the records.
+  @retval EFI_INVALID_PARAMETER - Invalid parameter passed to function - NULL
+                                  pointer or invalid PerfId.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *CREATE_PERFORMANCE_MEASUREMENT)(
+  IN CONST VOID                        *CallerIdentifier, OPTIONAL
+  IN CONST VOID                        *Guid,     OPTIONAL
+  IN CONST CHAR8                       *String,   OPTIONAL
+  IN       UINT64                      TimeStamp, OPTIONAL
+  IN       UINT64                      Address,   OPTIONAL
+  IN       UINT32                      Identifier,
+  IN       PERF_MEASUREMENT_ATTRIBUTE  Attribute
+  );
+
+struct _EDKII_PERFORMANCE_MEASUREMENT_PROTOCOL {
+  CREATE_PERFORMANCE_MEASUREMENT CreatePerformanceMeasurement;
+};
+
+extern EFI_GUID gEdkiiPerformanceMeasurementProtocolGuid;
+extern EFI_GUID gEdkiiSmmPerformanceMeasurementProtocolGuid;
+
+#endif // _PERFORMANCE_MEASUREMENT_H_
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index 3802b6e0b86..108accc2c29 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -258,10 +258,13 @@
   #  Include/Guid/Performance.h
   gPerformanceProtocolGuid       = { 0x76B6BDFA, 0x2ACD, 0x4462, { 0x9E, 0x3F, 0xCB, 0x58, 0xC9, 0x69, 0xD9, 0x37 } }
   gSmmPerformanceProtocolGuid    = { 0xf866226a, 0xeaa5, 0x4f5a, { 0xa9, 0xa,  0x6c, 0xfb, 0xa5, 0x7c, 0x58, 0x8e } }
   gPerformanceExProtocolGuid     = { 0x1ea81bec, 0xf01a, 0x4d98, { 0xa2, 0x1,  0x4a, 0x61, 0xce, 0x2f, 0xc0, 0x22 } }
   gSmmPerformanceExProtocolGuid  = { 0x931fc048, 0xc71d, 0x4455, { 0x89, 0x30, 0x47, 0x6,  0x30, 0xe3, 0xe,  0xe5 } }
+  #  Include/Guid/PerformanceMeasurement.h
+  gEdkiiPerformanceMeasurementProtocolGuid      = { 0xc85d06be, 0x5f75, 0x48ce, { 0xa8, 0x0f, 0x12, 0x36, 0xba, 0x3b, 0x87, 0xb1 } }
+  gEdkiiSmmPerformanceMeasurementProtocolGuid   = { 0xd56b6d73, 0x1a7b, 0x4015, { 0x9b, 0xb4, 0x7b, 0x07, 0x17, 0x29, 0xed, 0x24 } }
 
   ## Guid is defined for CRC32 encapsulation scheme.
   #  Include/Guid/Crc32GuidedSectionExtraction.h
   gEfiCrc32GuidedSectionExtractionGuid = { 0xFC1BCDB0, 0x7D31, 0x49aa, {0x93, 0x6A, 0xA4, 0x60, 0x0D, 0x9D, 0xD0, 0x83 } }
 
-- 
2.14.3.windows.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [patch 2/9] MdeModulePkg: Update Performance instances to use new protocol
  2018-06-19  7:23 [patch 0/9] Add new Perf macros Dandan Bi
  2018-06-19  7:23 ` [patch 1/9] MdeModulePkg: Add PERFORMANCE_MEASUREMENT_PROTOCOL Dandan Bi
@ 2018-06-19  7:23 ` Dandan Bi
  2018-06-19  7:23 ` [patch 3/9] MdePkg/PerformanceLib.h: Add new Perf macros Dandan Bi
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Dandan Bi @ 2018-06-19  7:23 UTC (permalink / raw)
  To: edk2-devel; +Cc: Liming Gao, Star Zeng

Update Update Performance instances in MdeModulePkg to use new
PerformanceMeasurement protocol.

Cc: Liming Gao <liming.gao@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Dandan Bi <dandan.bi@intel.com>
---
 .../DxeCorePerformanceLib/DxeCorePerformanceLib.c  | 325 +++++---------------
 .../DxeCorePerformanceLib.inf                      |   6 +-
 .../DxeCorePerformanceLibInternal.h                | 216 ++------------
 .../Library/DxePerformanceLib/DxePerformanceLib.c  | 125 +++-----
 .../DxePerformanceLib/DxePerformanceLib.inf        |   5 +-
 .../SmmCorePerformanceLib/SmmCorePerformanceLib.c  | 327 +++++----------------
 .../SmmCorePerformanceLib.inf                      |   7 +-
 .../SmmCorePerformanceLibInternal.h                | 215 ++------------
 .../Library/SmmPerformanceLib/SmmPerformanceLib.c  | 130 +++-----
 .../SmmPerformanceLib/SmmPerformanceLib.inf        |   5 +-
 10 files changed, 283 insertions(+), 1078 deletions(-)

diff --git a/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.c b/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.c
index 68b29ac5a9e..79820605184 100644
--- a/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.c
+++ b/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.c
@@ -80,25 +80,14 @@ UINT8   *mBootRecordBuffer    = NULL;
 BOOLEAN  mLockInsertRecord    = FALSE;
 
 EFI_DEVICE_PATH_TO_TEXT_PROTOCOL  *mDevicePathToText = NULL;
 
 //
-// Interfaces for Performance Protocol.
+// Interfaces for PerformanceMeasurement Protocol.
 //
-PERFORMANCE_PROTOCOL mPerformanceInterface = {
-  StartGauge,
-  EndGauge,
-  GetGauge
-  };
-
-//
-// Interfaces for PerformanceEx Protocol.
-//
-PERFORMANCE_EX_PROTOCOL mPerformanceExInterface = {
-  StartGaugeEx,
-  EndGaugeEx,
-  GetGaugeEx
+EDKII_PERFORMANCE_MEASUREMENT_PROTOCOL mPerformanceMeasurementInterface = {
+  CreatePerformanceMeasurement,
   };
 
 PERFORMANCE_PROPERTY  mPerformanceProperty;
 
 /**
@@ -797,22 +786,15 @@ InsertFpdtMeasurement (
 
   StringPtr     = NULL;
   UseModuleName = FALSE;
   ZeroMem (ModuleName, sizeof (ModuleName));
 
-  if (mLockInsertRecord) {
-    return EFI_UNSUPPORTED;
-  }
-
-  mLockInsertRecord = TRUE;
-
   //
   // Get record info (type, size, ProgressID and Module Guid).
   //
   Status = GetFpdtRecordInfo (IsStart, Handle, Token, Module, &RecordInfo, &UseModuleName);
   if (EFI_ERROR (Status)) {
-    mLockInsertRecord = FALSE;
     return Status;
   }
 
   //
   // If PERF_START()/PERF_END() have specified the ProgressID,it has high priority.
@@ -822,11 +804,10 @@ InsertFpdtMeasurement (
   // If it is start pref: the lower 4 bits of the ID should be 0.
   // If it is end pref: the lower 4 bits of the ID should not be 0.
   // If input ID doesn't follow the rule, we will adjust it.
   //
   if ((Identifier != 0) && (IsKnownID (Identifier)) && (!IsKnownTokens (Token))) {
-    mLockInsertRecord = FALSE;
     return EFI_UNSUPPORTED;
   } else if ((Identifier != 0) && (!IsKnownID (Identifier)) && (!IsKnownTokens (Token))) {
     if (IsStart && ((Identifier & 0x000F) != 0)) {
       Identifier &= 0xFFF0;
     } else if ((!IsStart) && ((Identifier & 0x000F) == 0)) {
@@ -842,11 +823,10 @@ InsertFpdtMeasurement (
     if (mBootRecordSize + RecordInfo.RecordSize > mBootRecordMaxSize) {
       if (!mLackSpaceIsReported) {
         DEBUG ((DEBUG_INFO, "DxeCorePerformanceLib: No enough space to save boot records\n"));
         mLackSpaceIsReported = TRUE;
       }
-      mLockInsertRecord = FALSE;
       return EFI_OUT_OF_RESOURCES;
     } else {
       //
       // Save boot record into BootPerformance table
       //
@@ -864,11 +844,10 @@ InsertFpdtMeasurement (
                               mPerformanceLength + RecordInfo.RecordSize + FIRMWARE_RECORD_BUFFER,
                               mPerformancePointer
                               );
 
       if (mPerformancePointer == NULL) {
-        mLockInsertRecord = FALSE;
         return EFI_OUT_OF_RESOURCES;
       }
       mMaxPerformanceLength = mPerformanceLength + RecordInfo.RecordSize + FIRMWARE_RECORD_BUFFER;
     }
     //
@@ -961,15 +940,13 @@ InsertFpdtMeasurement (
 
   default:
     //
     // Record is not supported in current DXE phase, return EFI_ABORTED
     //
-    mLockInsertRecord = FALSE;
     return EFI_UNSUPPORTED;
   }
 
-  mLockInsertRecord = FALSE;
   return EFI_SUCCESS;
 }
 
 /**
   Dumps all the PEI performance.
@@ -1061,223 +1038,10 @@ ReportFpdtRecordBuffer (
     //
     mFpdtBufferIsReported = TRUE;
   }
 }
 
-/**
-  Adds a record at the end of the performance measurement log
-  that records the start time of a performance measurement.
-
-  Adds a record to the end of the performance measurement log
-  that contains the Handle, Token, Module and Identifier.
-  The end time of the new record must be set to zero.
-  If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.
-  If TimeStamp is zero, the start time in the record is filled in with the value
-  read from the current time stamp.
-
-  @param  Handle                  Pointer to environment specific context used
-                                  to identify the component being measured.
-  @param  Token                   Pointer to a Null-terminated ASCII string
-                                  that identifies the component being measured.
-  @param  Module                  Pointer to a Null-terminated ASCII string
-                                  that identifies the module being measured.
-  @param  TimeStamp               64-bit time stamp.
-  @param  Identifier              32-bit identifier. If the value is 0, the created record
-                                  is same as the one created by StartGauge of PERFORMANCE_PROTOCOL.
-
-  @retval EFI_SUCCESS             The data was read correctly from the device.
-  @retval EFI_OUT_OF_RESOURCES    There are not enough resources to record the measurement.
-
-**/
-EFI_STATUS
-EFIAPI
-StartGaugeEx (
-  IN CONST VOID   *Handle,  OPTIONAL
-  IN CONST CHAR8  *Token,   OPTIONAL
-  IN CONST CHAR8  *Module,  OPTIONAL
-  IN UINT64       TimeStamp,
-  IN UINT32       Identifier
-  )
-{
-  return InsertFpdtMeasurement (TRUE, Handle, Token, Module, TimeStamp, Identifier);
-}
-
-/**
-  Searches the performance measurement log from the beginning of the log
-  for the first matching record that contains a zero end time and fills in a valid end time.
-
-  Searches the performance measurement log from the beginning of the log
-  for the first record that matches Handle, Token, Module and Identifier and has an end time value of zero.
-  If the record can not be found then return EFI_NOT_FOUND.
-  If the record is found and TimeStamp is not zero,
-  then the end time in the record is filled in with the value specified by TimeStamp.
-  If the record is found and TimeStamp is zero, then the end time in the matching record
-  is filled in with the current time stamp value.
-
-  @param  Handle                  Pointer to environment specific context used
-                                  to identify the component being measured.
-  @param  Token                   Pointer to a Null-terminated ASCII string
-                                  that identifies the component being measured.
-  @param  Module                  Pointer to a Null-terminated ASCII string
-                                  that identifies the module being measured.
-  @param  TimeStamp               64-bit time stamp.
-  @param  Identifier              32-bit identifier. If the value is 0, the found record
-                                  is same as the one found by EndGauge of PERFORMANCE_PROTOCOL.
-
-  @retval EFI_SUCCESS             The end of  the measurement was recorded.
-  @retval EFI_NOT_FOUND           The specified measurement record could not be found.
-
-**/
-EFI_STATUS
-EFIAPI
-EndGaugeEx (
-  IN CONST VOID   *Handle,  OPTIONAL
-  IN CONST CHAR8  *Token,   OPTIONAL
-  IN CONST CHAR8  *Module,  OPTIONAL
-  IN UINT64       TimeStamp,
-  IN UINT32       Identifier
-  )
-{
-  return InsertFpdtMeasurement (FALSE, Handle, Token, Module, TimeStamp, Identifier);
-}
-
-/**
-  Retrieves a previously logged performance measurement.
-  It can also retrieve the log created by StartGauge and EndGauge of PERFORMANCE_PROTOCOL,
-  and then assign the Identifier with 0.
-
-    !!! Not support!!!
-
-  Retrieves the performance log entry from the performance log specified by LogEntryKey.
-  If it stands for a valid entry, then EFI_SUCCESS is returned and
-  GaugeDataEntryEx stores the pointer to that entry.
-
-  @param  LogEntryKey             The key for the previous performance measurement log entry.
-                                  If 0, then the first performance measurement log entry is retrieved.
-  @param  GaugeDataEntryEx        The indirect pointer to the extended gauge data entry specified by LogEntryKey
-                                  if the retrieval is successful.
-
-  @retval EFI_SUCCESS             The GuageDataEntryEx is successfully found based on LogEntryKey.
-  @retval EFI_NOT_FOUND           The LogEntryKey is the last entry (equals to the total entry number).
-  @retval EFI_INVALIDE_PARAMETER  The LogEntryKey is not a valid entry (greater than the total entry number).
-  @retval EFI_INVALIDE_PARAMETER  GaugeDataEntryEx is NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-GetGaugeEx (
-  IN  UINTN                 LogEntryKey,
-  OUT GAUGE_DATA_ENTRY_EX   **GaugeDataEntryEx
-  )
-{
-  return EFI_UNSUPPORTED;
-}
-
-/**
-  Adds a record at the end of the performance measurement log
-  that records the start time of a performance measurement.
-
-  Adds a record to the end of the performance measurement log
-  that contains the Handle, Token, and Module.
-  The end time of the new record must be set to zero.
-  If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.
-  If TimeStamp is zero, the start time in the record is filled in with the value
-  read from the current time stamp.
-
-  @param  Handle                  Pointer to environment specific context used
-                                  to identify the component being measured.
-  @param  Token                   Pointer to a Null-terminated ASCII string
-                                  that identifies the component being measured.
-  @param  Module                  Pointer to a Null-terminated ASCII string
-                                  that identifies the module being measured.
-  @param  TimeStamp               64-bit time stamp.
-
-  @retval EFI_SUCCESS             The data was read correctly from the device.
-  @retval EFI_OUT_OF_RESOURCES    There are not enough resources to record the measurement.
-
-**/
-EFI_STATUS
-EFIAPI
-StartGauge (
-  IN CONST VOID   *Handle,  OPTIONAL
-  IN CONST CHAR8  *Token,   OPTIONAL
-  IN CONST CHAR8  *Module,  OPTIONAL
-  IN UINT64       TimeStamp
-  )
-{
-  return StartGaugeEx (Handle, Token, Module, TimeStamp, 0);
-}
-
-/**
-  Searches the performance measurement log from the beginning of the log
-  for the first matching record that contains a zero end time and fills in a valid end time.
-
-  Searches the performance measurement log from the beginning of the log
-  for the first record that matches Handle, Token, and Module and has an end time value of zero.
-  If the record can not be found then return EFI_NOT_FOUND.
-  If the record is found and TimeStamp is not zero,
-  then the end time in the record is filled in with the value specified by TimeStamp.
-  If the record is found and TimeStamp is zero, then the end time in the matching record
-  is filled in with the current time stamp value.
-
-  @param  Handle                  Pointer to environment specific context used
-                                  to identify the component being measured.
-  @param  Token                   Pointer to a Null-terminated ASCII string
-                                  that identifies the component being measured.
-  @param  Module                  Pointer to a Null-terminated ASCII string
-                                  that identifies the module being measured.
-  @param  TimeStamp               64-bit time stamp.
-
-  @retval EFI_SUCCESS             The end of  the measurement was recorded.
-  @retval EFI_NOT_FOUND           The specified measurement record could not be found.
-
-**/
-EFI_STATUS
-EFIAPI
-EndGauge (
-  IN CONST VOID   *Handle,  OPTIONAL
-  IN CONST CHAR8  *Token,   OPTIONAL
-  IN CONST CHAR8  *Module,  OPTIONAL
-  IN UINT64       TimeStamp
-  )
-{
-  return EndGaugeEx (Handle, Token, Module, TimeStamp, 0);
-}
-
-/**
-  Retrieves a previously logged performance measurement.
-  It can also retrieve the log created by StartGaugeEx and EndGaugeEx of PERFORMANCE_EX_PROTOCOL,
-  and then eliminate the Identifier.
-
-    !!! Not support!!!
-
-  Retrieves the performance log entry from the performance log specified by LogEntryKey.
-  If it stands for a valid entry, then EFI_SUCCESS is returned and
-  GaugeDataEntry stores the pointer to that entry.
-
-  @param  LogEntryKey             The key for the previous performance measurement log entry.
-                                  If 0, then the first performance measurement log entry is retrieved.
-  @param  GaugeDataEntry          The indirect pointer to the gauge data entry specified by LogEntryKey
-                                  if the retrieval is successful.
-
-  @retval EFI_SUCCESS             The GuageDataEntry is successfully found based on LogEntryKey.
-  @retval EFI_NOT_FOUND           The LogEntryKey is the last entry (equals to the total entry number).
-  @retval EFI_INVALIDE_PARAMETER  The LogEntryKey is not a valid entry (greater than the total entry number).
-  @retval EFI_INVALIDE_PARAMETER  GaugeDataEntry is NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-GetGauge (
-  IN  UINTN               LogEntryKey,
-  OUT GAUGE_DATA_ENTRY    **GaugeDataEntry
-  )
-{
-  return EFI_UNSUPPORTED;
-}
-
-
 /**
   The constructor function initializes Performance infrastructure for DXE phase.
 
   The constructor function publishes Performance and PerformanceEx protocol, allocates memory to log DXE performance
   and merges PEI performance data to DXE performance log.
@@ -1317,14 +1081,12 @@ DxeCorePerformanceLibConstructor (
   // Install the protocol interfaces for DXE performance library instance.
   //
   Handle = NULL;
   Status = gBS->InstallMultipleProtocolInterfaces (
                   &Handle,
-                  &gPerformanceProtocolGuid,
-                  &mPerformanceInterface,
-                  &gPerformanceExProtocolGuid,
-                  &mPerformanceExInterface,
+                  &gEdkiiPerformanceMeasurementProtocolGuid,
+                  &mPerformanceMeasurementInterface,
                   NULL
                   );
   ASSERT_EFI_ERROR (Status);
 
   //
@@ -1357,10 +1119,59 @@ DxeCorePerformanceLibConstructor (
   }
 
   return EFI_SUCCESS;
 }
 
+/**
+  Create performance record with event description and a timestamp.
+
+  @param CallerIdentifier  - Image handle or pointer to caller ID GUID.
+  @param Guid              - Pointer to a GUID.
+  @param String            - Pointer to a string describing the measurement.
+  @param TimeStamp         - 64-bit time stamp.
+  @param Address           - Pointer to a location in memory relevant to the measurement.
+  @param Identifier        - Performance identifier describing the type of measurement.
+  @param Attribute         - The attribute of the measurement. According to attribute can create a start
+                             record for PERF_START/PERF_START_EX, or a end record for PERF_END/PERF_END_EX,
+                             or a general record for other Perf macros.
+
+  @retval EFI_SUCCESS           - Successfully created performance record.
+  @retval EFI_OUT_OF_RESOURCES  - Ran out of space to store the records.
+  @retval EFI_INVALID_PARAMETER - Invalid parameter passed to function - NULL
+                                  pointer or invalid PerfId.
+**/
+EFI_STATUS
+EFIAPI
+CreatePerformanceMeasurement (
+  IN CONST VOID                        *CallerIdentifier,
+  IN CONST VOID                        *Guid,   OPTIONAL
+  IN CONST CHAR8                       *String, OPTIONAL
+  IN       UINT64                      TimeStamp,
+  IN       UINT64                      Address,  OPTIONAL
+  IN       UINT32                      Identifier,
+  IN       PERF_MEASUREMENT_ATTRIBUTE  Attribute
+  )
+{
+  EFI_STATUS   Status;
+
+  Status = EFI_SUCCESS;
+
+  if (mLockInsertRecord) {
+    return EFI_INVALID_PARAMETER;
+  }
+  mLockInsertRecord = TRUE;
+
+  if (Attribute == PerfStartEntry) {
+    Status = InsertFpdtMeasurement (TRUE, CallerIdentifier, String, String, TimeStamp, Identifier);
+  } else if (Attribute == PerfEndEntry) {
+    Status = InsertFpdtMeasurement (FALSE, CallerIdentifier, String, String, TimeStamp, Identifier);
+  }
+  mLockInsertRecord = FALSE;
+
+  return Status;
+}
+
 /**
   Adds a record at the end of the performance measurement log
   that records the start time of a performance measurement.
 
   Adds a record to the end of the performance measurement log
@@ -1392,11 +1203,21 @@ StartPerformanceMeasurementEx (
   IN CONST CHAR8  *Module,  OPTIONAL
   IN UINT64       TimeStamp,
   IN UINT32       Identifier
   )
 {
-  return InsertFpdtMeasurement (TRUE, Handle, Token, Module, TimeStamp, Identifier);
+  CONST CHAR8     *String;
+
+  if (Token != NULL) {
+    String = Token;
+  } else if (Module != NULL) {
+    String = Module;
+  } else {
+    String = NULL;
+  }
+
+  return (RETURN_STATUS)CreatePerformanceMeasurement (Handle, NULL, String, TimeStamp, 0, Identifier, PerfStartEntry);
 }
 
 /**
   Searches the performance measurement log from the beginning of the log
   for the first matching record that contains a zero end time and fills in a valid end time.
@@ -1431,11 +1252,21 @@ EndPerformanceMeasurementEx (
   IN CONST CHAR8  *Module,  OPTIONAL
   IN UINT64       TimeStamp,
   IN UINT32       Identifier
   )
 {
-  return InsertFpdtMeasurement (FALSE, Handle, Token, Module, TimeStamp, Identifier);
+  CONST CHAR8     *String;
+
+  if (Token != NULL) {
+    String = Token;
+  } else if (Module != NULL) {
+    String = Module;
+  } else {
+    String = NULL;
+  }
+
+  return (RETURN_STATUS)CreatePerformanceMeasurement (Handle, NULL, String, TimeStamp, 0, Identifier, PerfEndEntry);
 }
 
 /**
   Attempts to retrieve a performance measurement log entry from the performance measurement log.
   It can also retrieve the log created by StartPerformanceMeasurement and EndPerformanceMeasurement,
@@ -1525,11 +1356,11 @@ StartPerformanceMeasurement (
   IN CONST CHAR8  *Token,   OPTIONAL
   IN CONST CHAR8  *Module,  OPTIONAL
   IN UINT64       TimeStamp
   )
 {
-  return InsertFpdtMeasurement (TRUE, Handle, Token, Module, TimeStamp, 0);
+  return StartPerformanceMeasurementEx (Handle, Token, Module, TimeStamp, 0);
 }
 
 /**
   Searches the performance measurement log from the beginning of the log
   for the first matching record that contains a zero end time and fills in a valid end time.
@@ -1561,11 +1392,11 @@ EndPerformanceMeasurement (
   IN CONST CHAR8  *Token,   OPTIONAL
   IN CONST CHAR8  *Module,  OPTIONAL
   IN UINT64       TimeStamp
   )
 {
-  return InsertFpdtMeasurement (FALSE, Handle, Token, Module, TimeStamp, 0);
+  return EndPerformanceMeasurementEx (Handle, Token, Module, TimeStamp, 0);
 }
 
 /**
   Attempts to retrieve a performance measurement log entry from the performance measurement log.
   It can also retrieve the log created by StartPerformanceMeasurementEx and EndPerformanceMeasurementEx,
diff --git a/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf b/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf
index e752a93d837..68cd76da5b3 100644
--- a/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf
+++ b/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf
@@ -65,22 +65,18 @@
 [Protocols]
   gEfiSmmCommunicationProtocolGuid              ## SOMETIMES_CONSUMES
 
 
 [Guids]
-  ## SOMETIMES_CONSUMES   ## HOB
-  ## PRODUCES             ## UNDEFINED # Install protocol
   ## PRODUCES             ## SystemTable
   gPerformanceProtocolGuid
-  ## SOMETIMES_CONSUMES   ## HOB
-  ## PRODUCES             ## UNDEFINED # Install protocol
-  gPerformanceExProtocolGuid
   gZeroGuid                                     ## SOMETIMES_CONSUMES ## GUID
   gEfiFirmwarePerformanceGuid                   ## SOMETIMES_PRODUCES ## UNDEFINED # StatusCode Data
   gEdkiiFpdtExtendedFirmwarePerformanceGuid     ## SOMETIMES_CONSUMES ## HOB # StatusCode Data
   gEfiEventReadyToBootGuid                      ## CONSUMES           ## Event
   gEdkiiPiSmmCommunicationRegionTableGuid       ## SOMETIMES_CONSUMES    ## SystemTable
+  gEdkiiPerformanceMeasurementProtocolGuid      ## PRODUCES           ## UNDEFINED # Install protocol
 
 [Pcd]
   gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask         ## CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdEdkiiFpdtStringRecordEnableOnly  ## CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdExtFpdtBootRecordPadSize         ## CONSUMES
diff --git a/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLibInternal.h b/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLibInternal.h
index 7e79675f940..f9800e34941 100644
--- a/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLibInternal.h
+++ b/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLibInternal.h
@@ -20,10 +20,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 
 
 #include <PiDxe.h>
 
 #include <Guid/Performance.h>
+#include <Guid/PerformanceMeasurement.h>
 #include <Guid/ExtendedFirmwarePerformance.h>
 #include <Guid/ZeroGuid.h>
 #include <Guid/EventGroup.h>
 #include <Guid/FirmwarePerformance.h>
 #include <Guid/PiSmmCommunicationRegionTable.h>
@@ -47,203 +48,36 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/UefiLib.h>
 #include <Library/ReportStatusCodeLib.h>
 #include <Library/DxeServicesLib.h>
 #include <Library/PeCoffGetEntryPointLib.h>
 
-//
-// Interface declarations for PerformanceEx Protocol.
-//
 /**
-  Adds a record at the end of the performance measurement log
-  that records the start time of a performance measurement.
-
-  Adds a record to the end of the performance measurement log
-  that contains the Handle, Token, Module and Identifier.
-  The end time of the new record must be set to zero.
-  If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.
-  If TimeStamp is zero, the start time in the record is filled in with the value
-  read from the current time stamp.
-
-  @param  Handle                  Pointer to environment specific context used
-                                  to identify the component being measured.
-  @param  Token                   Pointer to a Null-terminated ASCII string
-                                  that identifies the component being measured.
-  @param  Module                  Pointer to a Null-terminated ASCII string
-                                  that identifies the module being measured.
-  @param  TimeStamp               64-bit time stamp.
-  @param  Identifier              32-bit identifier. If the value is 0, the created record
-                                  is same as the one created by StartGauge of PERFORMANCE_PROTOCOL.
-
-  @retval EFI_SUCCESS             The data was read correctly from the device.
-  @retval EFI_OUT_OF_RESOURCES    There are not enough resources to record the measurement.
-
-**/
-EFI_STATUS
-EFIAPI
-StartGaugeEx (
-  IN CONST VOID   *Handle,  OPTIONAL
-  IN CONST CHAR8  *Token,   OPTIONAL
-  IN CONST CHAR8  *Module,  OPTIONAL
-  IN UINT64       TimeStamp,
-  IN UINT32       Identifier
-  );
-
-/**
-  Searches the performance measurement log from the beginning of the log
-  for the first matching record that contains a zero end time and fills in a valid end time.
-
-  Searches the performance measurement log from the beginning of the log
-  for the first record that matches Handle, Token, Module and Identifier and has an end time value of zero.
-  If the record can not be found then return EFI_NOT_FOUND.
-  If the record is found and TimeStamp is not zero,
-  then the end time in the record is filled in with the value specified by TimeStamp.
-  If the record is found and TimeStamp is zero, then the end time in the matching record
-  is filled in with the current time stamp value.
-
-  @param  Handle                  Pointer to environment specific context used
-                                  to identify the component being measured.
-  @param  Token                   Pointer to a Null-terminated ASCII string
-                                  that identifies the component being measured.
-  @param  Module                  Pointer to a Null-terminated ASCII string
-                                  that identifies the module being measured.
-  @param  TimeStamp               64-bit time stamp.
-  @param  Identifier              32-bit identifier. If the value is 0, the found record
-                                  is same as the one found by EndGauge of PERFORMANCE_PROTOCOL.
-
-  @retval EFI_SUCCESS             The end of  the measurement was recorded.
-  @retval EFI_NOT_FOUND           The specified measurement record could not be found.
-
+  Create performance record with event description and a timestamp.
+
+  @param CallerIdentifier  - Image handle or pointer to caller ID GUID.
+  @param Guid              - Pointer to a GUID.
+  @param String            - Pointer to a string describing the measurement.
+  @param TimeStamp         - 64-bit time stamp.
+  @param Address           - Pointer to a location in memory relevant to the measurement.
+  @param Identifier        - Performance identifier describing the type of measurement.
+  @param Attribute         - The attribute of the measurement. According to attribute can create a start
+                             record for PERF_START/PERF_START_EX, or a end record for PERF_END/PERF_END_EX,
+                             or a general record for other Perf macros.
+
+  @retval EFI_SUCCESS           - Successfully created performance record.
+  @retval EFI_OUT_OF_RESOURCES  - Ran out of space to store the records.
+  @retval EFI_INVALID_PARAMETER - Invalid parameter passed to function - NULL
+                                  pointer or invalid PerfId.
 **/
 EFI_STATUS
 EFIAPI
-EndGaugeEx (
-  IN CONST VOID   *Handle,  OPTIONAL
-  IN CONST CHAR8  *Token,   OPTIONAL
-  IN CONST CHAR8  *Module,  OPTIONAL
-  IN UINT64       TimeStamp,
-  IN UINT32       Identifier
+CreatePerformanceMeasurement(
+  IN CONST VOID                        *CallerIdentifier, OPTIONAL
+  IN CONST VOID                        *Guid,     OPTIONAL
+  IN CONST CHAR8                       *String,   OPTIONAL
+  IN       UINT64                      TimeStamp, OPTIONAL
+  IN       UINT64                      Address,   OPTIONAL
+  IN       UINT32                      Identifier,
+  IN       PERF_MEASUREMENT_ATTRIBUTE  Attribute
   );
 
-/**
-  Retrieves a previously logged performance measurement.
-  It can also retrieve the log created by StartGauge and EndGauge of PERFORMANCE_PROTOCOL,
-  and then assign the Identifier with 0.
-
-  Retrieves the performance log entry from the performance log specified by LogEntryKey.
-  If it stands for a valid entry, then EFI_SUCCESS is returned and
-  GaugeDataEntryEx stores the pointer to that entry.
-
-  @param  LogEntryKey             The key for the previous performance measurement log entry.
-                                  If 0, then the first performance measurement log entry is retrieved.
-  @param  GaugeDataEntryEx        The indirect pointer to the extended gauge data entry specified by LogEntryKey
-                                  if the retrieval is successful.
-
-  @retval EFI_SUCCESS             The GuageDataEntryEx is successfully found based on LogEntryKey.
-  @retval EFI_NOT_FOUND           The LogEntryKey is the last entry (equals to the total entry number).
-  @retval EFI_INVALIDE_PARAMETER  The LogEntryKey is not a valid entry (greater than the total entry number).
-  @retval EFI_INVALIDE_PARAMETER  GaugeDataEntryEx is NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-GetGaugeEx (
-  IN  UINTN                 LogEntryKey,
-  OUT GAUGE_DATA_ENTRY_EX   **GaugeDataEntryEx
-  );
-
-//
-// Interface declarations for Performance Protocol.
-//
-/**
-  Adds a record at the end of the performance measurement log
-  that records the start time of a performance measurement.
-
-  Adds a record to the end of the performance measurement log
-  that contains the Handle, Token, and Module.
-  The end time of the new record must be set to zero.
-  If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.
-  If TimeStamp is zero, the start time in the record is filled in with the value
-  read from the current time stamp.
-
-  @param  Handle                  Pointer to environment specific context used
-                                  to identify the component being measured.
-  @param  Token                   Pointer to a Null-terminated ASCII string
-                                  that identifies the component being measured.
-  @param  Module                  Pointer to a Null-terminated ASCII string
-                                  that identifies the module being measured.
-  @param  TimeStamp               64-bit time stamp.
-
-  @retval EFI_SUCCESS             The data was read correctly from the device.
-  @retval EFI_OUT_OF_RESOURCES    There are not enough resources to record the measurement.
-
-**/
-EFI_STATUS
-EFIAPI
-StartGauge (
-  IN CONST VOID   *Handle,  OPTIONAL
-  IN CONST CHAR8  *Token,   OPTIONAL
-  IN CONST CHAR8  *Module,  OPTIONAL
-  IN UINT64       TimeStamp
-  );
-
-/**
-  Searches the performance measurement log from the beginning of the log
-  for the first matching record that contains a zero end time and fills in a valid end time.
-
-  Searches the performance measurement log from the beginning of the log
-  for the first record that matches Handle, Token, and Module and has an end time value of zero.
-  If the record can not be found then return EFI_NOT_FOUND.
-  If the record is found and TimeStamp is not zero,
-  then the end time in the record is filled in with the value specified by TimeStamp.
-  If the record is found and TimeStamp is zero, then the end time in the matching record
-  is filled in with the current time stamp value.
-
-  @param  Handle                  Pointer to environment specific context used
-                                  to identify the component being measured.
-  @param  Token                   Pointer to a Null-terminated ASCII string
-                                  that identifies the component being measured.
-  @param  Module                  Pointer to a Null-terminated ASCII string
-                                  that identifies the module being measured.
-  @param  TimeStamp               64-bit time stamp.
-
-  @retval EFI_SUCCESS             The end of  the measurement was recorded.
-  @retval EFI_NOT_FOUND           The specified measurement record could not be found.
-
-**/
-EFI_STATUS
-EFIAPI
-EndGauge (
-  IN CONST VOID   *Handle,  OPTIONAL
-  IN CONST CHAR8  *Token,   OPTIONAL
-  IN CONST CHAR8  *Module,  OPTIONAL
-  IN UINT64       TimeStamp
-  );
-
-/**
-  Retrieves a previously logged performance measurement.
-  It can also retrieve the log created by StartGaugeEx and EndGaugeEx of PERFORMANCE_EX_PROTOCOL,
-  and then eliminate the Identifier.
-
-  Retrieves the performance log entry from the performance log specified by LogEntryKey.
-  If it stands for a valid entry, then EFI_SUCCESS is returned and
-  GaugeDataEntry stores the pointer to that entry.
-
-  @param  LogEntryKey             The key for the previous performance measurement log entry.
-                                  If 0, then the first performance measurement log entry is retrieved.
-  @param  GaugeDataEntry          The indirect pointer to the gauge data entry specified by LogEntryKey
-                                  if the retrieval is successful.
-
-  @retval EFI_SUCCESS             The GuageDataEntry is successfully found based on LogEntryKey.
-  @retval EFI_NOT_FOUND           The LogEntryKey is the last entry (equals to the total entry number).
-  @retval EFI_INVALIDE_PARAMETER  The LogEntryKey is not a valid entry (greater than the total entry number).
-  @retval EFI_INVALIDE_PARAMETER  GaugeDataEntry is NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-GetGauge (
-  IN  UINTN               LogEntryKey,
-  OUT GAUGE_DATA_ENTRY    **GaugeDataEntry
-  );
-
-
 #endif
diff --git a/MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.c b/MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.c
index cb62d522f3d..9ed50d22b8d 100644
--- a/MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.c
+++ b/MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.c
@@ -18,22 +18,21 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 **/
 
 
 #include <PiDxe.h>
 
-#include <Guid/Performance.h>
+#include <Guid/PerformanceMeasurement.h>
 
 #include <Library/PerformanceLib.h>
 #include <Library/DebugLib.h>
 #include <Library/UefiBootServicesTableLib.h>
 #include <Library/PcdLib.h>
 
 //
 // The cached Performance Protocol and PerformanceEx Protocol interface.
 //
-PERFORMANCE_PROTOCOL        *mPerformance = NULL;
-PERFORMANCE_EX_PROTOCOL     *mPerformanceEx = NULL;
+EDKII_PERFORMANCE_MEASUREMENT_PROTOCOL      *mPerformanceMeasurement = NULL;
 
 /**
   The function caches the pointers to PerformanceEx protocol and Performance Protocol.
 
   The function locates PerformanceEx protocol and Performance Protocol from protocol database.
@@ -41,39 +40,28 @@ PERFORMANCE_EX_PROTOCOL     *mPerformanceEx = NULL;
   @retval EFI_SUCCESS     PerformanceEx protocol or Performance Protocol is successfully located.
   @retval EFI_NOT_FOUND   Both PerformanceEx protocol and Performance Protocol are not located to log performance.
 
 **/
 EFI_STATUS
-GetPerformanceProtocol (
+GetPerformanceMeasurementProtocol (
   VOID
   )
 {
   EFI_STATUS                Status;
-  PERFORMANCE_PROTOCOL      *Performance;
-  PERFORMANCE_EX_PROTOCOL   *PerformanceEx;
+  EDKII_PERFORMANCE_MEASUREMENT_PROTOCOL   *PerformanceMeasurement;
 
-  if (mPerformanceEx != NULL || mPerformance != NULL) {
+  if (mPerformanceMeasurement != NULL) {
     return EFI_SUCCESS;
   }
 
-  Status = gBS->LocateProtocol (&gPerformanceExProtocolGuid, NULL, (VOID **) &PerformanceEx);
+  Status = gBS->LocateProtocol (&gEdkiiPerformanceMeasurementProtocolGuid, NULL, (VOID **) &PerformanceMeasurement);
   if (!EFI_ERROR (Status)) {
-    ASSERT (PerformanceEx != NULL);
+    ASSERT (PerformanceMeasurement != NULL);
     //
-    // Cache PerformanceEx Protocol.
+    // Cache PerformanceMeasurement Protocol.
     //
-    mPerformanceEx = PerformanceEx;
-    return EFI_SUCCESS;
-  }
-
-  Status = gBS->LocateProtocol (&gPerformanceProtocolGuid, NULL, (VOID **) &Performance);
-  if (!EFI_ERROR (Status)) {
-    ASSERT (Performance != NULL);
-    //
-    // Cache performance protocol.
-    //
-    mPerformance = Performance;
+    mPerformanceMeasurement = PerformanceMeasurement;
     return EFI_SUCCESS;
   }
 
   return EFI_NOT_FOUND;
 }
@@ -108,21 +96,28 @@ StartPerformanceMeasurementEx (
   IN CONST CHAR8  *Module,  OPTIONAL
   IN UINT64       TimeStamp,
   IN UINT32       Identifier
   )
 {
-  EFI_STATUS  Status;
+  EFI_STATUS    Status;
+  CONST CHAR8*  String;
 
-  Status = GetPerformanceProtocol ();
+  Status = GetPerformanceMeasurementProtocol ();
   if (EFI_ERROR (Status)) {
-    return RETURN_OUT_OF_RESOURCES;
+    return RETURN_NOT_FOUND;
+  }
+
+  if (Token != NULL) {
+    String = Token;
+  } else if (Module != NULL) {
+    String = Module;
+  } else {
+    String = NULL;
   }
 
-  if (mPerformanceEx != NULL) {
-    Status = mPerformanceEx->StartGaugeEx (Handle, Token, Module, TimeStamp, Identifier);
-  } else if (mPerformance != NULL) {
-    Status = mPerformance->StartGauge (Handle, Token, Module, TimeStamp);
+  if (mPerformanceMeasurement != NULL) {
+    Status = mPerformanceMeasurement->CreatePerformanceMeasurement (Handle, NULL, String, TimeStamp, 0, Identifier, PerfStartEntry);
   } else {
     ASSERT (FALSE);
   }
 
   return (RETURN_STATUS) Status;
@@ -160,21 +155,28 @@ EndPerformanceMeasurementEx (
   IN CONST CHAR8  *Module,  OPTIONAL
   IN UINT64       TimeStamp,
   IN UINT32       Identifier
   )
 {
-  EFI_STATUS  Status;
+  EFI_STATUS    Status;
+  CONST CHAR8*  String;
 
-  Status = GetPerformanceProtocol ();
+  Status = GetPerformanceMeasurementProtocol ();
   if (EFI_ERROR (Status)) {
     return RETURN_NOT_FOUND;
   }
 
-  if (mPerformanceEx != NULL) {
-    Status = mPerformanceEx->EndGaugeEx (Handle, Token, Module, TimeStamp, Identifier);
-  } else if (mPerformance != NULL) {
-    Status = mPerformance->EndGauge (Handle, Token, Module, TimeStamp);
+  if (Token != NULL) {
+    String = Token;
+  } else if (Module != NULL) {
+    String = Module;
+  } else {
+    String = NULL;
+  }
+
+  if (mPerformanceMeasurement != NULL) {
+    Status = mPerformanceMeasurement->CreatePerformanceMeasurement (Handle, NULL, String, TimeStamp, 0, Identifier, PerfEndEntry);
   } else {
     ASSERT (FALSE);
   }
 
   return (RETURN_STATUS) Status;
@@ -231,62 +233,12 @@ GetPerformanceMeasurementEx (
   OUT UINT64      *StartTimeStamp,
   OUT UINT64      *EndTimeStamp,
   OUT UINT32      *Identifier
   )
 {
-  EFI_STATUS            Status;
-  GAUGE_DATA_ENTRY_EX   *GaugeData;
-
-  GaugeData = NULL;
-
-  ASSERT (Handle != NULL);
-  ASSERT (Token != NULL);
-  ASSERT (Module != NULL);
-  ASSERT (StartTimeStamp != NULL);
-  ASSERT (EndTimeStamp != NULL);
-  ASSERT (Identifier != NULL);
-
-  Status = GetPerformanceProtocol ();
-  if (EFI_ERROR (Status)) {
-    return 0;
-  }
-
-  if (mPerformanceEx != NULL) {
-    Status = mPerformanceEx->GetGaugeEx (LogEntryKey++, &GaugeData);
-  } else if (mPerformance != NULL) {
-    Status = mPerformance->GetGauge (LogEntryKey++, (GAUGE_DATA_ENTRY **) &GaugeData);
-  } else {
-    ASSERT (FALSE);
-    return 0;
-  }
-
-  //
-  // Make sure that LogEntryKey is a valid log entry key,
-  //
-  ASSERT (Status != EFI_INVALID_PARAMETER);
-
-  if (EFI_ERROR (Status)) {
-    //
-    // The LogEntryKey is the last entry (equals to the total entry number).
-    //
-    return 0;
-  }
-
-  ASSERT (GaugeData != NULL);
-
-  *Handle         = (VOID *) (UINTN) GaugeData->Handle;
-  *Token          = GaugeData->Token;
-  *Module         = GaugeData->Module;
-  *StartTimeStamp = GaugeData->StartTimeStamp;
-  *EndTimeStamp   = GaugeData->EndTimeStamp;
-  if (mPerformanceEx != NULL) {
-    *Identifier   = GaugeData->Identifier;
-  } else {
-    *Identifier   = 0;
-  }
+  return 0;
 
-  return LogEntryKey;
 }
 
 /**
   Creates a record for the beginning of a performance measurement.
 
@@ -401,12 +353,11 @@ GetPerformanceMeasurement (
   OUT CONST CHAR8 **Module,
   OUT UINT64      *StartTimeStamp,
   OUT UINT64      *EndTimeStamp
   )
 {
-  UINT32 Identifier;
-  return GetPerformanceMeasurementEx (LogEntryKey, Handle, Token, Module, StartTimeStamp, EndTimeStamp, &Identifier);
+  return 0;
 }
 
 /**
   Returns TRUE if the performance measurement macros are enabled.
 
diff --git a/MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf b/MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
index edc63c6f0b6..c7d06a3a1b1 100644
--- a/MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
+++ b/MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
@@ -4,11 +4,11 @@
 #  This library instance provides infrastructure for DXE phase drivers to log performance
 #  data. It consumes PerformanceEx or Performance Protocol published by DxeCorePerformanceLib
 #  to log performance data. If both PerformanceEx and Performance Protocol are not available,
 #  it does not log any performance information.
 #  
-#  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions of the BSD License
 #  which accompanies this distribution.  The full text of the license may be found at
 #  http://opensource.org/licenses/bsd-license.php
 #  
@@ -46,12 +46,11 @@
   UefiBootServicesTableLib
   DebugLib
 
 
 [Guids]
-  gPerformanceProtocolGuid      ## SOMETIMES_CONSUMES   ## UNDEFINED # Locate protocol
-  gPerformanceExProtocolGuid    ## SOMETIMES_CONSUMES   ## UNDEFINED # Locate protocol
+  gEdkiiPerformanceMeasurementProtocolGuid    ## SOMETIMES_CONSUMES   ## UNDEFINED # Locate protocol
 
 
 [Pcd]
   gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask    ## CONSUMES
 
diff --git a/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.c b/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.c
index dbc1166f254..e630773562f 100644
--- a/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.c
+++ b/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.c
@@ -52,25 +52,14 @@ BOOLEAN              mLackSpaceIsReport    = FALSE;
 CHAR8                *mPlatformLanguage    = NULL;
 SPIN_LOCK            mSmmFpdtLock;
 PERFORMANCE_PROPERTY  mPerformanceProperty;
 
 //
-// Interfaces for SMM Performance Protocol.
+// Interfaces for SMM PerformanceMeasurement Protocol.
 //
-PERFORMANCE_PROTOCOL mPerformanceInterface = {
-  StartGauge,
-  EndGauge,
-  GetGauge
-};
-
-//
-// Interfaces for SMM PerformanceEx Protocol.
-//
-PERFORMANCE_EX_PROTOCOL mPerformanceExInterface = {
-  StartGaugeEx,
-  EndGaugeEx,
-  GetGaugeEx
+EDKII_PERFORMANCE_MEASUREMENT_PROTOCOL mPerformanceMeasurementInterface = {
+  CreatePerformanceMeasurement,
 };
 
 /**
 Check whether the Token is a known one which is uesed by core.
 
@@ -641,239 +630,10 @@ InsertFpdtMeasurement (
   mSmmBootPerformanceTable->Header.Length += FpdtRecordPtr.RecordHeader->Length;
 
   return EFI_SUCCESS;
 }
 
-/**
-  Adds a record at the end of the performance measurement log
-  that records the start time of a performance measurement.
-
-  Adds a record to the end of the performance measurement log
-  that contains the Handle, Token, Module and Identifier.
-  The end time of the new record must be set to zero.
-  If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.
-  If TimeStamp is zero, the start time in the record is filled in with the value
-  read from the current time stamp.
-
-  @param  Handle                  Pointer to environment specific context used
-                                  to identify the component being measured.
-  @param  Token                   Pointer to a Null-terminated ASCII string
-                                  that identifies the component being measured.
-  @param  Module                  Pointer to a Null-terminated ASCII string
-                                  that identifies the module being measured.
-  @param  TimeStamp               64-bit time stamp.
-  @param  Identifier              32-bit identifier. If the value is 0, the created record
-                                  is same as the one created by StartGauge of PERFORMANCE_PROTOCOL.
-
-  @retval EFI_SUCCESS             The data was read correctly from the device.
-  @retval EFI_OUT_OF_RESOURCES    There are not enough resources to record the measurement.
-
-**/
-EFI_STATUS
-EFIAPI
-StartGaugeEx (
-  IN CONST VOID   *Handle,  OPTIONAL
-  IN CONST CHAR8  *Token,   OPTIONAL
-  IN CONST CHAR8  *Module,  OPTIONAL
-  IN UINT64       TimeStamp,
-  IN UINT32       Identifier
-  )
-{
-  EFI_STATUS    Status;
-
-  AcquireSpinLock (&mSmmFpdtLock);
-
-  Status = InsertFpdtMeasurement (TRUE, Handle, Token, Module, TimeStamp, Identifier);
-
-  ReleaseSpinLock (&mSmmFpdtLock);
-
-  return Status;
-}
-
-/**
-  Searches the performance measurement log from the beginning of the log
-  for the first matching record that contains a zero end time and fills in a valid end time.
-
-  Searches the performance measurement log from the beginning of the log
-  for the first record that matches Handle, Token, Module and Identifier and has an end time value of zero.
-  If the record can not be found then return EFI_NOT_FOUND.
-  If the record is found and TimeStamp is not zero,
-  then the end time in the record is filled in with the value specified by TimeStamp.
-  If the record is found and TimeStamp is zero, then the end time in the matching record
-  is filled in with the current time stamp value.
-
-  @param  Handle                  Pointer to environment specific context used
-                                  to identify the component being measured.
-  @param  Token                   Pointer to a Null-terminated ASCII string
-                                  that identifies the component being measured.
-  @param  Module                  Pointer to a Null-terminated ASCII string
-                                  that identifies the module being measured.
-  @param  TimeStamp               64-bit time stamp.
-  @param  Identifier              32-bit identifier. If the value is 0, the found record
-                                  is same as the one found by EndGauge of PERFORMANCE_PROTOCOL.
-
-  @retval EFI_SUCCESS             The end of  the measurement was recorded.
-  @retval EFI_NOT_FOUND           The specified measurement record could not be found.
-
-**/
-EFI_STATUS
-EFIAPI
-EndGaugeEx (
-  IN CONST VOID   *Handle,  OPTIONAL
-  IN CONST CHAR8  *Token,   OPTIONAL
-  IN CONST CHAR8  *Module,  OPTIONAL
-  IN UINT64       TimeStamp,
-  IN UINT32       Identifier
-  )
-{
-  EFI_STATUS     Status;
-
-  AcquireSpinLock (&mSmmFpdtLock);
-
-  Status = InsertFpdtMeasurement (FALSE, Handle, Token, Module, TimeStamp, Identifier);
-
-  ReleaseSpinLock (&mSmmFpdtLock);
-
-  return Status;
-}
-
-/**
-  Retrieves a previously logged performance measurement.
-  It can also retrieve the log created by StartGauge and EndGauge of PERFORMANCE_PROTOCOL,
-  and then assign the Identifier with 0.
-
-  !!! Not Support!!!
-
-  Retrieves the performance log entry from the performance log specified by LogEntryKey.
-  If it stands for a valid entry, then EFI_SUCCESS is returned and
-  GaugeDataEntryEx stores the pointer to that entry.
-
-  @param  LogEntryKey             The key for the previous performance measurement log entry.
-                                  If 0, then the first performance measurement log entry is retrieved.
-  @param  GaugeDataEntryEx        The indirect pointer to the extended gauge data entry specified by LogEntryKey
-                                  if the retrieval is successful.
-
-  @retval EFI_SUCCESS             The GuageDataEntryEx is successfully found based on LogEntryKey.
-  @retval EFI_NOT_FOUND           The LogEntryKey is the last entry (equals to the total entry number).
-  @retval EFI_INVALIDE_PARAMETER  The LogEntryKey is not a valid entry (greater than the total entry number).
-  @retval EFI_INVALIDE_PARAMETER  GaugeDataEntryEx is NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-GetGaugeEx (
-  IN  UINTN                 LogEntryKey,
-  OUT GAUGE_DATA_ENTRY_EX   **GaugeDataEntryEx
-  )
-{
-  return EFI_UNSUPPORTED;
-}
-
-/**
-  Adds a record at the end of the performance measurement log
-  that records the start time of a performance measurement.
-
-  Adds a record to the end of the performance measurement log
-  that contains the Handle, Token, and Module.
-  The end time of the new record must be set to zero.
-  If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.
-  If TimeStamp is zero, the start time in the record is filled in with the value
-  read from the current time stamp.
-
-  @param  Handle                  Pointer to environment specific context used
-                                  to identify the component being measured.
-  @param  Token                   Pointer to a Null-terminated ASCII string
-                                  that identifies the component being measured.
-  @param  Module                  Pointer to a Null-terminated ASCII string
-                                  that identifies the module being measured.
-  @param  TimeStamp               64-bit time stamp.
-
-  @retval EFI_SUCCESS             The data was read correctly from the device.
-  @retval EFI_OUT_OF_RESOURCES    There are not enough resources to record the measurement.
-
-**/
-EFI_STATUS
-EFIAPI
-StartGauge (
-  IN CONST VOID   *Handle,  OPTIONAL
-  IN CONST CHAR8  *Token,   OPTIONAL
-  IN CONST CHAR8  *Module,  OPTIONAL
-  IN UINT64       TimeStamp
-  )
-{
-  return StartGaugeEx (Handle, Token, Module, TimeStamp, 0);
-}
-
-/**
-  Searches the performance measurement log from the beginning of the log
-  for the first matching record that contains a zero end time and fills in a valid end time.
-
-  Searches the performance measurement log from the beginning of the log
-  for the first record that matches Handle, Token, and Module and has an end time value of zero.
-  If the record can not be found then return EFI_NOT_FOUND.
-  If the record is found and TimeStamp is not zero,
-  then the end time in the record is filled in with the value specified by TimeStamp.
-  If the record is found and TimeStamp is zero, then the end time in the matching record
-  is filled in with the current time stamp value.
-
-  @param  Handle                  Pointer to environment specific context used
-                                  to identify the component being measured.
-  @param  Token                   Pointer to a Null-terminated ASCII string
-                                  that identifies the component being measured.
-  @param  Module                  Pointer to a Null-terminated ASCII string
-                                  that identifies the module being measured.
-  @param  TimeStamp               64-bit time stamp.
-
-  @retval EFI_SUCCESS             The end of  the measurement was recorded.
-  @retval EFI_NOT_FOUND           The specified measurement record could not be found.
-
-**/
-EFI_STATUS
-EFIAPI
-EndGauge (
-  IN CONST VOID   *Handle,  OPTIONAL
-  IN CONST CHAR8  *Token,   OPTIONAL
-  IN CONST CHAR8  *Module,  OPTIONAL
-  IN UINT64       TimeStamp
-  )
-{
-  return EndGaugeEx (Handle, Token, Module, TimeStamp, 0);
-}
-
-/**
-  Retrieves a previously logged performance measurement.
-  It can also retrieve the log created by StartGaugeEx and EndGaugeEx of PERFORMANCE_EX_PROTOCOL,
-  and then eliminate the Identifier.
-
-  !!! Not Support!!!
-
-  Retrieves the performance log entry from the performance log specified by LogEntryKey.
-  If it stands for a valid entry, then EFI_SUCCESS is returned and
-  GaugeDataEntry stores the pointer to that entry.
-
-  @param  LogEntryKey             The key for the previous performance measurement log entry.
-                                  If 0, then the first performance measurement log entry is retrieved.
-  @param  GaugeDataEntry          The indirect pointer to the gauge data entry specified by LogEntryKey
-                                  if the retrieval is successful.
-
-  @retval EFI_SUCCESS             The GuageDataEntry is successfully found based on LogEntryKey.
-  @retval EFI_NOT_FOUND           The LogEntryKey is the last entry (equals to the total entry number).
-  @retval EFI_INVALIDE_PARAMETER  The LogEntryKey is not a valid entry (greater than the total entry number).
-  @retval EFI_INVALIDE_PARAMETER  GaugeDataEntry is NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-GetGauge (
-  IN  UINTN               LogEntryKey,
-  OUT GAUGE_DATA_ENTRY    **GaugeDataEntry
-  )
-{
-  return EFI_UNSUPPORTED;
-}
-
-
 /**
   SmmReadyToBoot protocol notification event handler.
 
   @param  Protocol   Points to the protocol's unique identifier
   @param  Interface  Points to the interface instance
@@ -940,20 +700,13 @@ InitializeSmmCorePerformanceLib (
   // Install the protocol interfaces for SMM performance library instance.
   //
   Handle = NULL;
   Status = gSmst->SmmInstallProtocolInterface (
                     &Handle,
-                    &gSmmPerformanceProtocolGuid,
-                    EFI_NATIVE_INTERFACE,
-                    &mPerformanceInterface
-                    );
-  ASSERT_EFI_ERROR (Status);
-  Status = gSmst->SmmInstallProtocolInterface (
-                    &Handle,
-                    &gSmmPerformanceExProtocolGuid,
+                    &gEdkiiSmmPerformanceMeasurementProtocolGuid,
                     EFI_NATIVE_INTERFACE,
-                    &mPerformanceExInterface
+                    &mPerformanceMeasurementInterface
                     );
   ASSERT_EFI_ERROR (Status);
 
   Status = gSmst->SmmRegisterProtocolNotify (
                     &gEdkiiSmmReadyToBootProtocolGuid,
@@ -1029,10 +782,52 @@ SmmCorePerformanceLibConstructor (
   ASSERT_EFI_ERROR (Status);
 
   return EFI_SUCCESS;
 }
 
+/**
+  Create performance record with event description and a timestamp.
+
+  @param CallerIdentifier  - Image handle or pointer to caller ID GUID.
+  @param Guid              - Pointer to a GUID.
+  @param String            - Pointer to a string describing the measurement.
+  @param TimeStamp         - 64-bit time stamp.
+  @param Address           - Pointer to a location in memory relevant to the measurement.
+  @param Identifier        - Performance identifier describing the type of measurement.
+  @param Attribute         - The attribute of the measurement. According to attribute can create a start
+                             record for PERF_START/PERF_START_EX, or a end record for PERF_END/PERF_END_EX,
+                             or a general record for other Perf macros.
+
+  @retval EFI_SUCCESS           - Successfully created performance record.
+  @retval EFI_OUT_OF_RESOURCES  - Ran out of space to store the records.
+  @retval EFI_INVALID_PARAMETER - Invalid parameter passed to function - NULL
+                                  pointer or invalid PerfId.
+**/
+EFI_STATUS
+EFIAPI
+CreatePerformanceMeasurement(
+  IN CONST VOID                        *CallerIdentifier, OPTIONAL
+  IN CONST VOID                        *Guid,     OPTIONAL
+  IN CONST CHAR8                       *String,   OPTIONAL
+  IN       UINT64                      TimeStamp, OPTIONAL
+  IN       UINT64                      Address,   OPTIONAL
+  IN       UINT32                      Identifier,
+  IN       PERF_MEASUREMENT_ATTRIBUTE  Attribute
+  )
+{
+  EFI_STATUS   Status;
+
+  AcquireSpinLock (&mSmmFpdtLock);
+  if (Attribute == PerfStartEntry) {
+    Status = InsertFpdtMeasurement (TRUE, CallerIdentifier, String, String, TimeStamp, Identifier);
+  } else if (Attribute == PerfEndEntry) {
+    Status = InsertFpdtMeasurement (FALSE, CallerIdentifier, String, String, TimeStamp, Identifier);
+  }
+  ReleaseSpinLock (&mSmmFpdtLock);
+  return Status;
+}
+
 /**
   Adds a record at the end of the performance measurement log
   that records the start time of a performance measurement.
 
   Adds a record to the end of the performance measurement log
@@ -1064,11 +859,21 @@ StartPerformanceMeasurementEx (
   IN CONST CHAR8  *Module,  OPTIONAL
   IN UINT64       TimeStamp,
   IN UINT32       Identifier
   )
 {
-  return (RETURN_STATUS) StartGaugeEx (Handle, Token, Module, TimeStamp, Identifier);
+  CONST CHAR8     *String;
+
+  if (Token != NULL) {
+    String = Token;
+  } else if (Module != NULL) {
+    String = Module;
+  } else {
+    String = NULL;
+  }
+
+  return (RETURN_STATUS)CreatePerformanceMeasurement (Handle, NULL, String, TimeStamp, 0, Identifier, PerfStartEntry);
 }
 
 /**
   Searches the performance measurement log from the beginning of the log
   for the first matching record that contains a zero end time and fills in a valid end time.
@@ -1103,11 +908,21 @@ EndPerformanceMeasurementEx (
   IN CONST CHAR8  *Module,  OPTIONAL
   IN UINT64       TimeStamp,
   IN UINT32       Identifier
   )
 {
-  return (RETURN_STATUS) EndGaugeEx (Handle, Token, Module, TimeStamp, Identifier);
+  CONST CHAR8     *String;
+
+  if (Token != NULL) {
+    String = Token;
+  } else if (Module != NULL) {
+    String = Module;
+  } else {
+    String = NULL;
+  }
+
+  return (RETURN_STATUS)CreatePerformanceMeasurement (Handle, NULL, String, TimeStamp, 0, Identifier, PerfEndEntry);
 }
 
 /**
   Attempts to retrieve a performance measurement log entry from the performance measurement log.
   It can also retrieve the log created by StartPerformanceMeasurement and EndPerformanceMeasurement,
@@ -1196,11 +1011,11 @@ StartPerformanceMeasurement (
   IN CONST CHAR8  *Token,   OPTIONAL
   IN CONST CHAR8  *Module,  OPTIONAL
   IN UINT64       TimeStamp
   )
 {
-  return StartGaugeEx (Handle, Token, Module, TimeStamp, 0);
+  return StartPerformanceMeasurementEx (Handle, Token, Module, TimeStamp, 0);
 }
 
 /**
   Searches the performance measurement log from the beginning of the log
   for the first matching record that contains a zero end time and fills in a valid end time.
@@ -1232,11 +1047,11 @@ EndPerformanceMeasurement (
   IN CONST CHAR8  *Token,   OPTIONAL
   IN CONST CHAR8  *Module,  OPTIONAL
   IN UINT64       TimeStamp
   )
 {
-  return EndGaugeEx (Handle, Token, Module, TimeStamp, 0);
+  return EndPerformanceMeasurementEx (Handle, Token, Module, TimeStamp, 0);
 }
 
 /**
   Attempts to retrieve a performance measurement log entry from the performance measurement log.
   It can also retrieve the log created by StartPerformanceMeasurementEx and EndPerformanceMeasurementEx,
diff --git a/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.inf b/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.inf
index 01d8604eb61..61b92836657 100644
--- a/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.inf
+++ b/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.inf
@@ -64,19 +64,14 @@
 [Protocols]
   gEfiSmmBase2ProtocolGuid                  ## CONSUMES
   gEdkiiSmmReadyToBootProtocolGuid          ## NOTIFY
 
 [Guids]
-  ## PRODUCES ## UNDEFINED # Install protocol
-  ## CONSUMES ## UNDEFINED # SmiHandlerRegister
-  gSmmPerformanceProtocolGuid
-  ## PRODUCES ## UNDEFINED # Install protocol
-  ## CONSUMES ## UNDEFINED # SmiHandlerRegister
-  gSmmPerformanceExProtocolGuid
   ## PRODUCES ## SystemTable
   gPerformanceProtocolGuid
   gEdkiiFpdtExtendedFirmwarePerformanceGuid ## SOMETIMES_PRODUCES ## UNDEFINED # StatusCode Data
   gZeroGuid                                 ## SOMETIMES_CONSUMES ## GUID
+  gEdkiiSmmPerformanceMeasurementProtocolGuid             ## PRODUCES ## UNDEFINED # Install protocol
 
 [Pcd]
   gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask        ## CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdEdkiiFpdtStringRecordEnableOnly ## CONSUMES
diff --git a/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLibInternal.h b/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLibInternal.h
index 9d24d9ff7a0..76f24984735 100644
--- a/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLibInternal.h
+++ b/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLibInternal.h
@@ -18,10 +18,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #ifndef _SMM_CORE_PERFORMANCE_LIB_INTERNAL_H_
 #define _SMM_CORE_PERFORMANCE_LIB_INTERNAL_H_
 
 
 #include <Guid/Performance.h>
+#include <Guid/PerformanceMeasurement.h>
 #include <Guid/ExtendedFirmwarePerformance.h>
 #include <Guid/FirmwarePerformance.h>
 #include <Guid/ZeroGuid.h>
 #include <Guid/EventGroup.h>
 
@@ -44,202 +45,38 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Protocol/SmmBase2.h>
 #include <Protocol/LoadedImage.h>
 #include <Protocol/DevicePathToText.h>
 
 //
-// Interface declarations for SMM PerformanceEx Protocol.
+// Interface declarations for SMM PerformanceMeasurement Protocol.
 //
 /**
-  Adds a record at the end of the performance measurement log
-  that records the start time of a performance measurement.
-
-  Adds a record to the end of the performance measurement log
-  that contains the Handle, Token, Module and Identifier.
-  The end time of the new record must be set to zero.
-  If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.
-  If TimeStamp is zero, the start time in the record is filled in with the value
-  read from the current time stamp.
-
-  @param  Handle                  Pointer to environment specific context used
-                                  to identify the component being measured.
-  @param  Token                   Pointer to a Null-terminated ASCII string
-                                  that identifies the component being measured.
-  @param  Module                  Pointer to a Null-terminated ASCII string
-                                  that identifies the module being measured.
-  @param  TimeStamp               64-bit time stamp.
-  @param  Identifier              32-bit identifier. If the value is 0, the created record
-                                  is same as the one created by StartGauge of PERFORMANCE_PROTOCOL.
-
-  @retval EFI_SUCCESS             The data was read correctly from the device.
-  @retval EFI_OUT_OF_RESOURCES    There are not enough resources to record the measurement.
-
+  Create performance record with event description and a timestamp.
+
+  @param CallerIdentifier  - Image handle or pointer to caller ID GUID.
+  @param Guid              - Pointer to a GUID.
+  @param String            - Pointer to a string describing the measurement.
+  @param TimeStamp         - 64-bit time stamp.
+  @param Address           - Pointer to a location in memory relevant to the measurement.
+  @param Identifier        - Performance identifier describing the type of measurement.
+  @param Attribute         - The attribute of the measurement. According to attribute can create a start
+                             record for PERF_START/PERF_START_EX, or a end record for PERF_END/PERF_END_EX,
+                             or a general record for other Perf macros.
+
+  @retval EFI_SUCCESS           - Successfully created performance record.
+  @retval EFI_OUT_OF_RESOURCES  - Ran out of space to store the records.
+  @retval EFI_INVALID_PARAMETER - Invalid parameter passed to function - NULL
+                                  pointer or invalid PerfId.
 **/
 EFI_STATUS
 EFIAPI
-StartGaugeEx (
-  IN CONST VOID   *Handle,  OPTIONAL
-  IN CONST CHAR8  *Token,   OPTIONAL
-  IN CONST CHAR8  *Module,  OPTIONAL
-  IN UINT64       TimeStamp,
-  IN UINT32       Identifier
+CreatePerformanceMeasurement(
+  IN CONST VOID                        *CallerIdentifier, OPTIONAL
+  IN CONST VOID                        *Guid,     OPTIONAL
+  IN CONST CHAR8                       *String,   OPTIONAL
+  IN       UINT64                      TimeStamp, OPTIONAL
+  IN       UINT64                      Address,   OPTIONAL
+  IN       UINT32                      Identifier,
+  IN       PERF_MEASUREMENT_ATTRIBUTE  Attribute
   );
 
-/**
-  Searches the performance measurement log from the beginning of the log
-  for the first matching record that contains a zero end time and fills in a valid end time.
-
-  Searches the performance measurement log from the beginning of the log
-  for the first record that matches Handle, Token, Module and Identifier and has an end time value of zero.
-  If the record can not be found then return EFI_NOT_FOUND.
-  If the record is found and TimeStamp is not zero,
-  then the end time in the record is filled in with the value specified by TimeStamp.
-  If the record is found and TimeStamp is zero, then the end time in the matching record
-  is filled in with the current time stamp value.
-
-  @param  Handle                  Pointer to environment specific context used
-                                  to identify the component being measured.
-  @param  Token                   Pointer to a Null-terminated ASCII string
-                                  that identifies the component being measured.
-  @param  Module                  Pointer to a Null-terminated ASCII string
-                                  that identifies the module being measured.
-  @param  TimeStamp               64-bit time stamp.
-  @param  Identifier              32-bit identifier. If the value is 0, the found record
-                                  is same as the one found by EndGauge of PERFORMANCE_PROTOCOL.
-
-  @retval EFI_SUCCESS             The end of  the measurement was recorded.
-  @retval EFI_NOT_FOUND           The specified measurement record could not be found.
-
-**/
-EFI_STATUS
-EFIAPI
-EndGaugeEx (
-  IN CONST VOID   *Handle,  OPTIONAL
-  IN CONST CHAR8  *Token,   OPTIONAL
-  IN CONST CHAR8  *Module,  OPTIONAL
-  IN UINT64       TimeStamp,
-  IN UINT32       Identifier
-  );
-
-/**
-  Retrieves a previously logged performance measurement.
-  It can also retrieve the log created by StartGauge and EndGauge of PERFORMANCE_PROTOCOL,
-  and then assign the Identifier with 0.
-
-  Retrieves the performance log entry from the performance log specified by LogEntryKey.
-  If it stands for a valid entry, then EFI_SUCCESS is returned and
-  GaugeDataEntryEx stores the pointer to that entry.
-
-  @param  LogEntryKey             The key for the previous performance measurement log entry.
-                                  If 0, then the first performance measurement log entry is retrieved.
-  @param  GaugeDataEntryEx        The indirect pointer to the extended gauge data entry specified by LogEntryKey
-                                  if the retrieval is successful.
-
-  @retval EFI_SUCCESS             The GuageDataEntryEx is successfully found based on LogEntryKey.
-  @retval EFI_NOT_FOUND           The LogEntryKey is the last entry (equals to the total entry number).
-  @retval EFI_INVALIDE_PARAMETER  The LogEntryKey is not a valid entry (greater than the total entry number).
-  @retval EFI_INVALIDE_PARAMETER  GaugeDataEntryEx is NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-GetGaugeEx (
-  IN  UINTN                 LogEntryKey,
-  OUT GAUGE_DATA_ENTRY_EX   **GaugeDataEntryEx
-  );
-
-//
-// Interface declarations for SMM Performance Protocol.
-//
-/**
-  Adds a record at the end of the performance measurement log
-  that records the start time of a performance measurement.
-
-  Adds a record to the end of the performance measurement log
-  that contains the Handle, Token, and Module.
-  The end time of the new record must be set to zero.
-  If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.
-  If TimeStamp is zero, the start time in the record is filled in with the value
-  read from the current time stamp.
-
-  @param  Handle                  Pointer to environment specific context used
-                                  to identify the component being measured.
-  @param  Token                   Pointer to a Null-terminated ASCII string
-                                  that identifies the component being measured.
-  @param  Module                  Pointer to a Null-terminated ASCII string
-                                  that identifies the module being measured.
-  @param  TimeStamp               64-bit time stamp.
-
-  @retval EFI_SUCCESS             The data was read correctly from the device.
-  @retval EFI_OUT_OF_RESOURCES    There are not enough resources to record the measurement.
-
-**/
-EFI_STATUS
-EFIAPI
-StartGauge (
-  IN CONST VOID   *Handle,  OPTIONAL
-  IN CONST CHAR8  *Token,   OPTIONAL
-  IN CONST CHAR8  *Module,  OPTIONAL
-  IN UINT64       TimeStamp
-  );
-
-/**
-  Searches the performance measurement log from the beginning of the log
-  for the first matching record that contains a zero end time and fills in a valid end time.
-
-  Searches the performance measurement log from the beginning of the log
-  for the first record that matches Handle, Token, and Module and has an end time value of zero.
-  If the record can not be found then return EFI_NOT_FOUND.
-  If the record is found and TimeStamp is not zero,
-  then the end time in the record is filled in with the value specified by TimeStamp.
-  If the record is found and TimeStamp is zero, then the end time in the matching record
-  is filled in with the current time stamp value.
-
-  @param  Handle                  Pointer to environment specific context used
-                                  to identify the component being measured.
-  @param  Token                   Pointer to a Null-terminated ASCII string
-                                  that identifies the component being measured.
-  @param  Module                  Pointer to a Null-terminated ASCII string
-                                  that identifies the module being measured.
-  @param  TimeStamp               64-bit time stamp.
-
-  @retval EFI_SUCCESS             The end of  the measurement was recorded.
-  @retval EFI_NOT_FOUND           The specified measurement record could not be found.
-
-**/
-EFI_STATUS
-EFIAPI
-EndGauge (
-  IN CONST VOID   *Handle,  OPTIONAL
-  IN CONST CHAR8  *Token,   OPTIONAL
-  IN CONST CHAR8  *Module,  OPTIONAL
-  IN UINT64       TimeStamp
-  );
-
-/**
-  Retrieves a previously logged performance measurement.
-  It can also retrieve the log created by StartGaugeEx and EndGaugeEx of PERFORMANCE_EX_PROTOCOL,
-  and then eliminate the Identifier.
-
-  Retrieves the performance log entry from the performance log specified by LogEntryKey.
-  If it stands for a valid entry, then EFI_SUCCESS is returned and
-  GaugeDataEntry stores the pointer to that entry.
-
-  @param  LogEntryKey             The key for the previous performance measurement log entry.
-                                  If 0, then the first performance measurement log entry is retrieved.
-  @param  GaugeDataEntry          The indirect pointer to the gauge data entry specified by LogEntryKey
-                                  if the retrieval is successful.
-
-  @retval EFI_SUCCESS             The GuageDataEntry is successfully found based on LogEntryKey.
-  @retval EFI_NOT_FOUND           The LogEntryKey is the last entry (equals to the total entry number).
-  @retval EFI_INVALIDE_PARAMETER  The LogEntryKey is not a valid entry (greater than the total entry number).
-  @retval EFI_INVALIDE_PARAMETER  GaugeDataEntry is NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-GetGauge (
-  IN  UINTN               LogEntryKey,
-  OUT GAUGE_DATA_ENTRY    **GaugeDataEntry
-  );
-
-
 #endif
diff --git a/MdeModulePkg/Library/SmmPerformanceLib/SmmPerformanceLib.c b/MdeModulePkg/Library/SmmPerformanceLib/SmmPerformanceLib.c
index 4a08c24789c..fd820c0e49c 100644
--- a/MdeModulePkg/Library/SmmPerformanceLib/SmmPerformanceLib.c
+++ b/MdeModulePkg/Library/SmmPerformanceLib/SmmPerformanceLib.c
@@ -16,24 +16,22 @@ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 
 **/
 
 
-#include <Guid/Performance.h>
+#include <Guid/PerformanceMeasurement.h>
 
 #include <Library/PerformanceLib.h>
 #include <Library/DebugLib.h>
 #include <Library/SmmServicesTableLib.h>
 #include <Library/PcdLib.h>
 #include <Library/BaseMemoryLib.h>
 
 //
 // The cached SMM Performance Protocol and SMM PerformanceEx Protocol interface.
-//
-PERFORMANCE_PROTOCOL        *mPerformance = NULL;
-PERFORMANCE_EX_PROTOCOL     *mPerformanceEx = NULL;
-BOOLEAN                     mPerformanceMeasurementEnabled;
+EDKII_PERFORMANCE_MEASUREMENT_PROTOCOL  *mPerformanceMeasurement = NULL;
+BOOLEAN                                 mPerformanceMeasurementEnabled;
 
 /**
   The constructor function initializes the Performance Measurement Enable flag
 
   @param  ImageHandle   The firmware allocated handle for the EFI image.
@@ -63,42 +61,30 @@ SmmPerformanceLibConstructor (
   @retval EFI_SUCCESS     SMM PerformanceEx protocol or Performance Protocol is successfully located.
   @retval EFI_NOT_FOUND   Both SMM PerformanceEx protocol and Performance Protocol are not located to log performance.
 
 **/
 EFI_STATUS
-GetPerformanceProtocol (
+GetPerformanceMeasurementProtocol (
   VOID
   )
 {
   EFI_STATUS                Status;
-  PERFORMANCE_PROTOCOL      *Performance;
-  PERFORMANCE_EX_PROTOCOL   *PerformanceEx;
+  EDKII_PERFORMANCE_MEASUREMENT_PROTOCOL   *PerformanceMeasurement;
 
-  if (mPerformanceEx != NULL || mPerformance != NULL) {
+  if (mPerformanceMeasurement != NULL) {
     return EFI_SUCCESS;
   }
 
-  Status = gSmst->SmmLocateProtocol (&gSmmPerformanceExProtocolGuid, NULL, (VOID **) &PerformanceEx);
+  Status = gSmst->SmmLocateProtocol (&gEdkiiSmmPerformanceMeasurementProtocolGuid, NULL, (VOID **) &PerformanceMeasurement);
   if (!EFI_ERROR (Status)) {
-    ASSERT (PerformanceEx != NULL);
+    ASSERT (PerformanceMeasurement != NULL);
     //
-    // Cache PerformanceEx Protocol.
+    // Cache PerformanceMeasurement Protocol.
     //
-    mPerformanceEx = PerformanceEx;
+    mPerformanceMeasurement = PerformanceMeasurement;
     return EFI_SUCCESS;
   }
-
-  Status = gSmst->SmmLocateProtocol (&gSmmPerformanceProtocolGuid, NULL, (VOID **) &Performance);
-  if (!EFI_ERROR (Status)) {
-    ASSERT (Performance != NULL);
-    //
-    // Cache performance protocol.
-    //
-    mPerformance = Performance;
-    return EFI_SUCCESS;
-  }
-
   return EFI_NOT_FOUND;
 }
 
 /**
   Creates a record for the beginning of a performance measurement.
@@ -130,21 +116,28 @@ StartPerformanceMeasurementEx (
   IN CONST CHAR8  *Module,  OPTIONAL
   IN UINT64       TimeStamp,
   IN UINT32       Identifier
   )
 {
-  EFI_STATUS  Status;
+  EFI_STATUS    Status;
+  CONST CHAR8*  String;
 
-  Status = GetPerformanceProtocol ();
+  Status = GetPerformanceMeasurementProtocol ();
   if (EFI_ERROR (Status)) {
-    return RETURN_OUT_OF_RESOURCES;
+    return RETURN_NOT_FOUND;
   }
 
-  if (mPerformanceEx != NULL) {
-    Status = mPerformanceEx->StartGaugeEx (Handle, Token, Module, TimeStamp, Identifier);
-  } else if (mPerformance != NULL) {
-    Status = mPerformance->StartGauge (Handle, Token, Module, TimeStamp);
+  if (Token != NULL) {
+    String = Token;
+  } else if (Module != NULL) {
+    String = Module;
+  } else {
+    String = NULL;
+  }
+
+  if (mPerformanceMeasurement != NULL) {
+    Status = mPerformanceMeasurement->CreatePerformanceMeasurement (Handle, NULL, String, TimeStamp, 0, Identifier, PerfStartEntry);
   } else {
     ASSERT (FALSE);
   }
 
   return (RETURN_STATUS) Status;
@@ -182,21 +175,28 @@ EndPerformanceMeasurementEx (
   IN CONST CHAR8  *Module,  OPTIONAL
   IN UINT64       TimeStamp,
   IN UINT32       Identifier
   )
 {
-  EFI_STATUS  Status;
+  EFI_STATUS    Status;
+  CONST CHAR8*  String;
 
-  Status = GetPerformanceProtocol ();
+  Status = GetPerformanceMeasurementProtocol ();
   if (EFI_ERROR (Status)) {
     return RETURN_NOT_FOUND;
   }
 
-  if (mPerformanceEx != NULL) {
-    Status = mPerformanceEx->EndGaugeEx (Handle, Token, Module, TimeStamp, Identifier);
-  } else if (mPerformance != NULL) {
-    Status = mPerformance->EndGauge (Handle, Token, Module, TimeStamp);
+  if (Token != NULL) {
+    String = Token;
+  } else if (Module != NULL) {
+    String = Module;
+  } else {
+    String = NULL;
+  }
+
+  if (mPerformanceMeasurement != NULL) {
+    Status = mPerformanceMeasurement->CreatePerformanceMeasurement (Handle, NULL, String, TimeStamp, 0, Identifier, PerfEndEntry);
   } else {
     ASSERT (FALSE);
   }
 
   return (RETURN_STATUS) Status;
@@ -253,62 +253,11 @@ GetPerformanceMeasurementEx (
   OUT UINT64      *StartTimeStamp,
   OUT UINT64      *EndTimeStamp,
   OUT UINT32      *Identifier
   )
 {
-  EFI_STATUS            Status;
-  GAUGE_DATA_ENTRY_EX   *GaugeData;
-
-  GaugeData = NULL;
-
-  ASSERT (Handle != NULL);
-  ASSERT (Token != NULL);
-  ASSERT (Module != NULL);
-  ASSERT (StartTimeStamp != NULL);
-  ASSERT (EndTimeStamp != NULL);
-  ASSERT (Identifier != NULL);
-
-  Status = GetPerformanceProtocol ();
-  if (EFI_ERROR (Status)) {
-    return 0;
-  }
-
-  if (mPerformanceEx != NULL) {
-    Status = mPerformanceEx->GetGaugeEx (LogEntryKey++, &GaugeData);
-  } else if (mPerformance != NULL) {
-    Status = mPerformance->GetGauge (LogEntryKey++, (GAUGE_DATA_ENTRY **) &GaugeData);
-  } else {
-    ASSERT (FALSE);
-    return 0;
-  }
-
-  //
-  // Make sure that LogEntryKey is a valid log entry key,
-  //
-  ASSERT (Status != EFI_INVALID_PARAMETER);
-
-  if (EFI_ERROR (Status)) {
-    //
-    // The LogEntryKey is the last entry (equals to the total entry number).
-    //
-    return 0;
-  }
-
-  ASSERT (GaugeData != NULL);
-
-  *Handle         = (VOID *) (UINTN) GaugeData->Handle;
-  *Token          = GaugeData->Token;
-  *Module         = GaugeData->Module;
-  *StartTimeStamp = GaugeData->StartTimeStamp;
-  *EndTimeStamp   = GaugeData->EndTimeStamp;
-  if (mPerformanceEx != NULL) {
-    *Identifier   = GaugeData->Identifier;
-  } else {
-    *Identifier   = 0;
-  }
-
-  return LogEntryKey;
+  return 0;
 }
 
 /**
   Creates a record for the beginning of a performance measurement.
 
@@ -423,12 +372,11 @@ GetPerformanceMeasurement (
   OUT CONST CHAR8 **Module,
   OUT UINT64      *StartTimeStamp,
   OUT UINT64      *EndTimeStamp
   )
 {
-  UINT32 Identifier;
-  return GetPerformanceMeasurementEx (LogEntryKey, Handle, Token, Module, StartTimeStamp, EndTimeStamp, &Identifier);
+  return 0;
 }
 
 /**
   Returns TRUE if the performance measurement macros are enabled.
 
diff --git a/MdeModulePkg/Library/SmmPerformanceLib/SmmPerformanceLib.inf b/MdeModulePkg/Library/SmmPerformanceLib/SmmPerformanceLib.inf
index c3d01a1e51d..174ed3f1e59 100644
--- a/MdeModulePkg/Library/SmmPerformanceLib/SmmPerformanceLib.inf
+++ b/MdeModulePkg/Library/SmmPerformanceLib/SmmPerformanceLib.inf
@@ -4,11 +4,11 @@
 #  This library instance provides infrastructure for SMM drivers to log performance
 #  data. It consumes SMM PerformanceEx or Performance Protocol published by SmmCorePerformanceLib
 #  to log performance data. If both SMM PerformanceEx and Performance Protocol are not available,
 #  it does not log any performance information.
 #  
-#  Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions of the BSD License
 #  which accompanies this distribution.  The full text of the license may be found at
 #  http://opensource.org/licenses/bsd-license.php
 #  
@@ -48,10 +48,9 @@
   SmmServicesTableLib
   DebugLib
   BaseMemoryLib
 
 [Guids]
-  gSmmPerformanceProtocolGuid           ## SOMETIMES_CONSUMES   ## UNDEFINED # Locate protocol
-  gSmmPerformanceExProtocolGuid         ## SOMETIMES_CONSUMES   ## UNDEFINED # Locate protocol
+  gEdkiiSmmPerformanceMeasurementProtocolGuid          ## SOMETIMES_CONSUMES   ## UNDEFINED # Locate protocol
 
 [Pcd]
   gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask    ## CONSUMES
-- 
2.14.3.windows.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [patch 3/9] MdePkg/PerformanceLib.h: Add new Perf macros
  2018-06-19  7:23 [patch 0/9] Add new Perf macros Dandan Bi
  2018-06-19  7:23 ` [patch 1/9] MdeModulePkg: Add PERFORMANCE_MEASUREMENT_PROTOCOL Dandan Bi
  2018-06-19  7:23 ` [patch 2/9] MdeModulePkg: Update Performance instances to use new protocol Dandan Bi
@ 2018-06-19  7:23 ` Dandan Bi
  2018-06-19  7:24 ` [patch 4/9] MdeModulePkg/ExtendedFirmwarePerf: Remove PerfId definitions Dandan Bi
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Dandan Bi @ 2018-06-19  7:23 UTC (permalink / raw)
  To: edk2-devel; +Cc: Liming Gao, Michael Kinney

1. Add new Perf macros for performance measurement
and related APIs and definitions in Performance
library class.

2. Update NULL performance library instance in MdePkg.

Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael Kinney <michael.d.kinney@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Dandan Bi <dandan.bi@intel.com>
---
 MdePkg/Include/Library/PerformanceLib.h            | 408 ++++++++++++++++++++-
 .../BasePerformanceLibNull/PerformanceLib.c        |  57 ++-
 MdePkg/MdePkg.dec                                  |   9 +-
 MdePkg/MdePkg.uni                                  |   6 +
 4 files changed, 477 insertions(+), 3 deletions(-)

diff --git a/MdePkg/Include/Library/PerformanceLib.h b/MdePkg/Include/Library/PerformanceLib.h
index 3ecd62bd201..8a8f5e3694a 100644
--- a/MdePkg/Include/Library/PerformanceLib.h
+++ b/MdePkg/Include/Library/PerformanceLib.h
@@ -1,9 +1,9 @@
 /** @file
   Provides services to log the execution times and retrieve them later.
 
-Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD License
 which accompanies this distribution.  The full text of the license may be found at
 http://opensource.org/licenses/bsd-license.php
 
@@ -18,10 +18,49 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 ///
 /// Performance library propery mask bits
 ///
 #define PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED  0x00000001
 
+//
+// Public Progress Identifiers for Event Records.
+//
+#define PERF_EVENT_ID                   0x00
+
+#define MODULE_START_ID                 0x01
+#define MODULE_END_ID                   0x02
+#define MODULE_LOADIMAGE_START_ID       0x03
+#define MODULE_LOADIMAGE_END_ID         0x04
+#define MODULE_DB_START_ID              0x05
+#define MODULE_DB_END_ID                0x06
+#define MODULE_DB_SUPPORT_START_ID      0x07
+#define MODULE_DB_SUPPORT_END_ID        0x08
+#define MODULE_DB_STOP_START_ID         0x09
+#define MODULE_DB_STOP_END_ID           0x0A
+
+#define PERF_EVENTSIGNAL_START_ID       0x10
+#define PERF_EVENTSIGNAL_END_ID         0x11
+#define PERF_CALLBACK_START_ID          0x20
+#define PERF_CALLBACK_END_ID            0x21
+#define PERF_FUNCTION_START_ID          0x30
+#define PERF_FUNCTION_END_ID            0x31
+#define PERF_INMODULE_START_ID          0x40
+#define PERF_INMODULE_END_ID            0x41
+#define PERF_CROSSMODULE_START_ID       0x50
+#define PERF_CROSSMODULE_END_ID         0x51
+
+//
+// Declare bits for PcdPerformanceLibraryPropertyMask and
+// also used as the Type parameter of LogPerformanceMeasurementEnabled().
+//
+#define PERF_CORE_START_IMAGE            0x0002
+#define PERF_CORE_LOAD_IMAGE             0x0004
+#define PERF_CORE_DB_SUPPORT             0x0008
+#define PERF_CORE_DB_START               0x0010
+#define PERF_CORE_DB_STOP                0x0020
+
+#define PERF_GENERAL_TYPE                0x0040
+
 /**
   Creates a record for the beginning of a performance measurement. 
   
   Creates a record that contains the Handle, Token, and Module.
   If TimeStamp is not zero, then TimeStamp is added to the record as the start time.
@@ -269,10 +308,377 @@ BOOLEAN
 EFIAPI
 PerformanceMeasurementEnabled (
   VOID
   );
 
+
+/**
+  Check whether the specified performance measurement can be logged.
+
+  This function returns TRUE when the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set
+  and the Type disable bit in PcdPerformanceLibraryPropertyMask is not set.
+
+  @param Type        - Type of the performance measurement entry.
+
+  @retval TRUE         The performance measurement can be logged.
+  @retval FALSE        The performance measurement can NOT be logged.
+
+**/
+BOOLEAN
+EFIAPI
+LogPerformanceMeasurementEnabled (
+  IN  CONST UINTN        Type
+  );
+
+/**
+  Create performance record with event description.
+
+  @param CallerIdentifier - Image handle or pointer to caller ID GUID
+  @param Guid             - Pointer to a GUID.
+                            Used for event signal perf and callback perf to cache the event guid.
+  @param String           - Pointer to a string describing the measurement
+  @param Address          - Pointer to a location in memory relevant to the measurement.
+  @param Identifier       - Performance identifier describing the type of measurement.
+
+  @retval RETURN_SUCCESS           - Successfully created performance record
+  @retval RETURN_OUT_OF_RESOURCES  - Ran out of space to store the records
+  @retval RETURN_INVALID_PARAMETER - Invalid parameter passed to function - NULL
+                                     pointer or invalid Identifier.
+
+**/
+RETURN_STATUS
+EFIAPI
+LogPerformanceMeasurement (
+  IN CONST VOID   *CallerIdentifier, OPTIONAL
+  IN CONST VOID   *Guid,    OPTIONAL
+  IN CONST CHAR8  *String,  OPTIONAL
+  IN UINT64       Address,  OPTIONAL
+  IN UINT32       Identifier
+  );
+
+/**
+  Begin Macro to measure the performance of StartImage in core.
+
+  If the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set,
+  and the BIT1(dsiable PERF_CORE_START_IMAGE) of PcdPerformanceLibraryPropertyMask is not set.
+  then LogPerformanceMeasurement() is called.
+
+**/
+#define PERF_START_IMAGE_BEGIN(ModuleHandle) \
+  do { \
+    if (LogPerformanceMeasurementEnabled (PERF_CORE_START_IMAGE)) { \
+      LogPerformanceMeasurement (ModuleHandle, NULL, NULL, 0, MODULE_START_ID); \
+    } \
+  } while (FALSE)
+
+/**
+  End Macro to measure the performance of StartImage in core.
+
+  If the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set,
+  and the BIT1 (dsiable PERF_CORE_START_IMAGE)of PcdPerformanceLibraryPropertyMask is not set.
+  then LogPerformanceMeasurement() is called.
+
+**/
+#define PERF_START_IMAGE_END(ModuleHandle) \
+  do { \
+    if (LogPerformanceMeasurementEnabled (PERF_CORE_START_IMAGE)) { \
+      LogPerformanceMeasurement (ModuleHandle, NULL, NULL, 0, MODULE_END_ID); \
+    } \
+  } while (FALSE)
+
+/**
+  Begin Macro to measure the performance of LoadImage in core.
+
+  If the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set,
+  and the BIT2 (dsiable PERF_CORE_LOAD_IAMGE) of PcdPerformanceLibraryPropertyMask is not set.
+  then LogPerformanceMeasurement() is called.
+
+**/
+#define PERF_LOAD_IMAGE_BEGIN(ModuleHandle) \
+  do { \
+    if (LogPerformanceMeasurementEnabled (PERF_CORE_LOAD_IMAGE)) { \
+      LogPerformanceMeasurement (ModuleHandle, NULL, NULL, 0, MODULE_LOADIMAGE_START_ID); \
+    } \
+  } while (FALSE)
+
+/**
+  End Macro to measure the performance of LoadImage in core.
+
+  If the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set,
+  and the BIT2 (dsiable PERF_CORE_LOAD_IAMGE) of PcdPerformanceLibraryPropertyMask is not set.
+  then LogPerformanceMeasurement() is called.
+
+**/
+#define PERF_LOAD_IMAGE_END(ModuleHandle) \
+  do { \
+    if (LogPerformanceMeasurementEnabled (PERF_CORE_LOAD_IMAGE)) { \
+      LogPerformanceMeasurement (ModuleHandle, NULL, NULL, 0, MODULE_LOADIMAGE_END_ID); \
+    } \
+  } while (FALSE)
+
+/**
+  Start Macro to measure the performance of DriverBinding Support in core.
+
+  If the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set,
+  and the BIT3 (dsiable PERF_CORE_DB_SUPPORT) of PcdPerformanceLibraryPropertyMask is not set.
+  then LogPerformanceMeasurement() is called.
+
+**/
+#define PERF_DRIVER_BINDING_SUPPORT_BEGIN(ModuleHandle, ControllerHandle) \
+  do { \
+    if (LogPerformanceMeasurementEnabled (PERF_CORE_DB_SUPPORT)) { \
+      LogPerformanceMeasurement (ModuleHandle, NULL, NULL, (UINT64)(UINTN)ControllerHandle, MODULE_DB_SUPPORT_START_ID); \
+    } \
+  } while (FALSE)
+
+/**
+  End Macro to measure the performance of DriverBinding Support in core.
+
+  If the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set,
+  and the BIT3 (dsiable PERF_CORE_DB_SUPPORT) of PcdPerformanceLibraryPropertyMask is not set.
+  then LogPerformanceMeasurement() is called.
+
+**/
+#define PERF_DRIVER_BINDING_SUPPORT_END(ModuleHandle, ControllerHandle) \
+  do { \
+    if (LogPerformanceMeasurementEnabled (PERF_CORE_DB_SUPPORT)) { \
+      LogPerformanceMeasurement (ModuleHandle, NULL, NULL, (UINT64)(UINTN)ControllerHandle, MODULE_DB_SUPPORT_END_ID); \
+    } \
+  } while (FALSE)
+
+/**
+  Begin Macro to measure the performance of DriverBinding Start in core.
+
+  If the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set,
+  and the BIT4 (dsiable PERF_CORE_DB_START) of PcdPerformanceLibraryPropertyMask is not set.
+  then LogPerformanceMeasurement() is called.
+
+**/
+#define PERF_DRIVER_BINDING_START_BEGIN(ModuleHandle, ControllerHandle) \
+  do { \
+    if (LogPerformanceMeasurementEnabled (PERF_CORE_DB_START)) { \
+      LogPerformanceMeasurement (ModuleHandle, NULL, NULL, (UINT64)(UINTN)ControllerHandle, MODULE_DB_START_ID); \
+    } \
+  } while (FALSE)
+
+/**
+  End Macro to measure the performance of DriverBinding Start in core.
+
+  If the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set,
+  and the BIT4 (dsiable PERF_CORE_DB_START) of PcdPerformanceLibraryPropertyMask is not set.
+  then LogPerformanceMeasurement() is called.
+
+**/
+#define PERF_DRIVER_BINDING_START_END(ModuleHandle, ControllerHandle) \
+  do { \
+    if (LogPerformanceMeasurementEnabled (PERF_CORE_DB_START)) { \
+      LogPerformanceMeasurement (ModuleHandle, NULL, NULL, (UINT64)(UINTN)ControllerHandle, MODULE_DB_END_ID); \
+    } \
+  } while (FALSE)
+
+/**
+  Start Macro to measure the performance of DriverBinding Stop in core.
+
+  If the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set,
+  and the BIT5 (dsiable PERF_CORE_DB_STOP) of PcdPerformanceLibraryPropertyMask is not set.
+  then LogPerformanceMeasurement() is called.
+
+**/
+#define PERF_DRIVER_BINDING_STOP_BEGIN(ModuleHandle, ControllerHandle) \
+  do { \
+    if (LogPerformanceMeasurementEnabled (PERF_CORE_DB_STOP)) { \
+      LogPerformanceMeasurement (ModuleHandle, NULL, NULL, (UINT64)(UINTN)ControllerHandle, MODULE_DB_STOP_START_ID); \
+    } \
+  } while (FALSE)
+
+/**
+  End Macro to measure the performance of DriverBinding Stop in core.
+
+  If the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set,
+  and the BIT5 (dsiable PERF_CORE_DB_STOP) of PcdPerformanceLibraryPropertyMask is not set.
+  then LogPerformanceMeasurement() is called.
+
+**/
+#define PERF_DRIVER_BINDING_STOP_END(ModuleHandle, ControllerHandle) \
+  do { \
+    if (LogPerformanceMeasurementEnabled (PERF_CORE_DB_STOP)) { \
+      LogPerformanceMeasurement (ModuleHandle, NULL, NULL, (UINT64)(UINTN)ControllerHandle, MODULE_DB_STOP_END_ID); \
+    } \
+  } while (FALSE)
+
+/**
+  Macro to measure the time from power-on to this macro execution.
+  It can be used to log a meaningful thing which happens at a time point.
+
+  If the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set,
+  and the BIT6 (dsiable PERF_GENERAL_TYPE) of PcdPerformanceLibraryPropertyMask is not set.
+  then LogPerformanceMeasurement() is called.
+
+**/
+#define PERF_EVENT(EventString) \
+  do { \
+    if (LogPerformanceMeasurementEnabled (PERF_GENERAL_TYPE)) { \
+      LogPerformanceMeasurement (&gEfiCallerIdGuid, NULL, EventString , 0, PERF_EVENT_ID); \
+    } \
+  } while (FALSE)
+
+/**
+  Begin Macro to measure the perofrmance of evnent signal behavior in any module.
+  The event guid will be passed with this macro.
+
+  If the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set,
+  and the BIT6 (dsiable PERF_GENERAL_TYPE) of PcdPerformanceLibraryPropertyMask is not set.
+  then LogPerformanceMeasurement() is called.
+
+**/
+#define PERF_EVENT_SIGNAL_BEGIN(EventGuid) \
+  do { \
+    if (LogPerformanceMeasurementEnabled (PERF_GENERAL_TYPE)) { \
+      LogPerformanceMeasurement (&gEfiCallerIdGuid, EventGuid, __FUNCTION__ , 0, PERF_EVENTSIGNAL_START_ID); \
+    } \
+  } while (FALSE)
+
+/**
+  End Macro to measure the perofrmance of evnent signal behavior in any module.
+  The event guid will be passed with this macro.
+
+  If the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set,
+  and the BIT6 (dsiable PERF_GENERAL_TYPE) of PcdPerformanceLibraryPropertyMask is not set.
+  then LogPerformanceMeasurement() is called.
+
+**/
+#define PERF_EVENT_SIGNAL_END(EventGuid) \
+  do { \
+    if (LogPerformanceMeasurementEnabled (PERF_GENERAL_TYPE)) { \
+      LogPerformanceMeasurement (&gEfiCallerIdGuid, EventGuid, __FUNCTION__ , 0, PERF_EVENTSIGNAL_END_ID); \
+    } \
+  } while (FALSE)
+
+/**
+  Begin Macro to measure the perofrmance of a callback function in any module.
+  The event guid which trigger the callback function will be passed with this macro.
+
+  If the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set,
+  and the BIT6 (dsiable PERF_GENERAL_TYPE) of PcdPerformanceLibraryPropertyMask is not set.
+  then LogPerformanceMeasurement() is called.
+
+**/
+#define PERF_CALLBACK_BEGIN(TriggerGuid) \
+  do { \
+    if (LogPerformanceMeasurementEnabled (PERF_GENERAL_TYPE)) { \
+      LogPerformanceMeasurement (&gEfiCallerIdGuid, TriggerGuid, __FUNCTION__ , 0, PERF_CALLBACK_START_ID); \
+    } \
+  } while (FALSE)
+
+/**
+  End Macro to measure the perofrmance of a callback function in any module.
+  The event guid which trigger the callback function will be passed with this macro.
+
+  If the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set,
+  and the BIT6 (dsiable PERF_GENERAL_TYPE) of PcdPerformanceLibraryPropertyMask is not set.
+  then LogPerformanceMeasurement() is called.
+
+**/
+#define PERF_CALLBACK_END(TriggerGuid) \
+  do { \
+    if (LogPerformanceMeasurementEnabled (PERF_GENERAL_TYPE)) { \
+      LogPerformanceMeasurement (&gEfiCallerIdGuid, TriggerGuid, __FUNCTION__ , 0, PERF_CALLBACK_END_ID); \
+    } \
+  } while (FALSE)
+
+/**
+  Begin Macro to measure the perofrmance of a general function in any module.
+
+  If the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set,
+  and the BIT6 (dsiable PERF_GENERAL_TYPE) of PcdPerformanceLibraryPropertyMask is not set.
+  then LogPerformanceMeasurement() is called.
+
+**/
+#define PERF_FUNCTION_BEGIN() \
+  do { \
+    if (LogPerformanceMeasurementEnabled (PERF_GENERAL_TYPE)) { \
+      LogPerformanceMeasurement (&gEfiCallerIdGuid, NULL, __FUNCTION__ , 0, PERF_FUNCTION_START_ID); \
+    } \
+  } while (FALSE)
+
+/**
+  End Macro to measure the perofrmance of a general function in any module.
+
+  If the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set,
+  and the BIT6 (dsiable PERF_GENERAL_TYPE) of PcdPerformanceLibraryPropertyMask is not set.
+  then LogPerformanceMeasurement() is called.
+
+**/
+#define PERF_FUNCTION_END() \
+  do { \
+    if (LogPerformanceMeasurementEnabled (PERF_GENERAL_TYPE)) { \
+      LogPerformanceMeasurement (&gEfiCallerIdGuid, NULL, __FUNCTION__ , 0, PERF_FUNCTION_END_ID); \
+    } \
+  } while (FALSE)
+
+/**
+  Begin Macro to measure the perofrmance of a behavior within one module.
+
+  If the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set,
+  and the BIT6 (dsiable PERF_GENERAL_TYPE) of PcdPerformanceLibraryPropertyMask is not set.
+  then LogPerformanceMeasurement() is called.
+
+**/
+#define PERF_INMODULE_BEGIN(MeasurementString) \
+  do { \
+    if (LogPerformanceMeasurementEnabled (PERF_GENERAL_TYPE)) { \
+      LogPerformanceMeasurement (&gEfiCallerIdGuid, NULL, MeasurementString, 0, PERF_INMODULE_START_ID); \
+    } \
+  } while (FALSE)
+
+/**
+  End Macro to measure the perofrmance of a behavior within one module.
+
+  If the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set,
+  and the BIT6 (dsiable PERF_GENERAL_TYPE) of PcdPerformanceLibraryPropertyMask is not set.
+  then LogPerformanceMeasurement() is called.
+
+**/
+#define PERF_INMODULE_END(MeasurementString) \
+  do { \
+    if (LogPerformanceMeasurementEnabled (PERF_GENERAL_TYPE)) { \
+      LogPerformanceMeasurement (&gEfiCallerIdGuid, NULL, MeasurementString, 0, PERF_INMODULE_END_ID); \
+    } \
+  } while (FALSE)
+
+/**
+  Begin Macro to measure the perofrmance of a behavior in different modules.
+  Such as the performance of PEI phase, DXE phase, BDS phase.
+
+  If the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set,
+  and the BIT6 (dsiable PERF_GENERAL_TYPE) of PcdPerformanceLibraryPropertyMask is not set.
+  then LogPerformanceMeasurement() is called.
+
+**/
+#define PERF_CROSSMODULE_BEGIN(MeasurementString) \
+  do { \
+    if (LogPerformanceMeasurementEnabled (PERF_GENERAL_TYPE)) { \
+      LogPerformanceMeasurement (&gEfiCallerIdGuid, NULL, MeasurementString, 0, PERF_CROSSMODULE_START_ID); \
+    } \
+  } while (FALSE)
+
+/**
+  End Macro to measure the perofrmance of a behavior in different modules.
+  Such as the performance of PEI phase, DXE phase, BDS phase.
+
+  If the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set,
+  and the BIT6 (dsiable PERF_GENERAL_TYPE) of PcdPerformanceLibraryPropertyMask is not set.
+  then LogPerformanceMeasurement() is called.
+
+**/
+#define PERF_CROSSMODULE_END(MeasurementString) \
+  do { \
+    if (LogPerformanceMeasurementEnabled (PERF_GENERAL_TYPE)) { \
+      LogPerformanceMeasurement (&gEfiCallerIdGuid, NULL, MeasurementString, 0, PERF_CROSSMODULE_END_ID); \
+    } \
+  } while (FALSE)
+
 /**
   Macro that calls EndPerformanceMeasurement().
 
   If the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set,
   then EndPerformanceMeasurement() is called.
diff --git a/MdePkg/Library/BasePerformanceLibNull/PerformanceLib.c b/MdePkg/Library/BasePerformanceLibNull/PerformanceLib.c
index e35235d9a29..a68ea90d4f0 100644
--- a/MdePkg/Library/BasePerformanceLibNull/PerformanceLib.c
+++ b/MdePkg/Library/BasePerformanceLibNull/PerformanceLib.c
@@ -1,9 +1,9 @@
 /** @file
   Base Performance Library which provides no service.
 
-  Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
   This program and the accompanying materials
   are licensed and made available under the terms and conditions of the BSD License
   which accompanies this distribution.  The full text of the license may be found at
   http://opensource.org/licenses/bsd-license.php.
 
@@ -302,5 +302,60 @@ PerformanceMeasurementEnabled (
   VOID
   )
 {
   return (BOOLEAN) ((PcdGet8(PcdPerformanceLibraryPropertyMask) & PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED) != 0);
 }
+
+/**
+  Create performance record with event description and a timestamp.
+
+  @param CallerIdentifier  - Image handle or pointer to caller ID GUID
+  @param Guid              - Pointer to a GUID
+  @param String            - Pointer to a string describing the measurement
+  @param Address           - Pointer to a location in memory relevant to the measurement
+  @param Identifier        - Performance identifier describing the type of measurement
+
+  @retval RETURN_SUCCESS           - Successfully created performance record
+  @retval RETURN_OUT_OF_RESOURCES  - Ran out of space to store the records
+  @retval RETURN_INVALID_PARAMETER - Invalid parameter passed to function - NULL
+                                     pointer or invalid PerfId
+
+**/
+RETURN_STATUS
+EFIAPI
+LogPerformanceMeasurement (
+  IN CONST VOID   *CallerIdentifier,OPTIONAL
+  IN CONST VOID   *Guid,    OPTIONAL
+  IN CONST CHAR8  *String,  OPTIONAL
+  IN UINT64       Address,  OPTIONAL
+  IN UINT32       Identifier
+  )
+{
+  return RETURN_SUCCESS;
+}
+
+/**
+  Check whether the specified performance measurement can be logged.
+
+  This function returns TRUE when the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set
+  and the Type disable bit in PcdPerformanceLibraryPropertyMask is not set.
+
+  @param Type        - Type of the performance measurement entry.
+
+  @retval TRUE         The performance measurement can be logged.
+  @retval FALSE        The performance measurement can NOT be logged.
+
+**/
+BOOLEAN
+EFIAPI
+LogPerformanceMeasurementEnabled (
+  IN  CONST UINTN        Type
+  )
+{
+  //
+  // When Performance measurement is enabled and the type is not filtered, the performance can be logged.
+  //
+  if (PerformanceMeasurementEnabled () && (PcdGet8(PcdPerformanceLibraryPropertyMask) & Type) == 0) {
+    return TRUE;
+  }
+  return FALSE;
+}
diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
index 0e64f22f4a7..432de804c5d 100644
--- a/MdePkg/MdePkg.dec
+++ b/MdePkg/MdePkg.dec
@@ -2167,12 +2167,19 @@
   # @Prompt Value to Clear Memory.
   gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue|0xAF|UINT8|0x00000008
 
   ## The mask is used to control PerformanceLib behavior.<BR><BR>
   #  BIT0 - Enable Performance Measurement.<BR>
+  #  BIT1 - Disable Start Image Logging.<BR>
+  #  BIT2 - Disable Load Image logging.<BR>
+  #  BIT3 - Disable Binding Support logging.<BR>
+  #  BIT4 - Disable Binding Start logging.<BR>
+  #  BIT5 - Disable Binding Stop logging.<BR>
+  #  BIT6 - Disable all other general Perfs.<BR>
+  #  BIT1-BIT6 are evaluated when BIT0 is set.<BR>
   # @Prompt Performance Measurement Property.
-  # @Expression  0x80000002 | (gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask & 0xFE) == 0
+  # @Expression  0x80000002 | (gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask & 0x80) == 0
   gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|0|UINT8|0x00000009
 
   ## The mask is used to control PostCodeLib behavior.<BR><BR>
   #  BIT0 - Enable Post Code.<BR>
   #  BIT1 - Enable Post Code with Description.<BR>
diff --git a/MdePkg/MdePkg.uni b/MdePkg/MdePkg.uni
index a110e453df8..18bb01f2199 100644
--- a/MdePkg/MdePkg.uni
+++ b/MdePkg/MdePkg.uni
@@ -243,10 +243,16 @@
 
 #string STR_gEfiMdePkgTokenSpaceGuid_PcdPerformanceLibraryPropertyMask_PROMPT  #language en-US "Performance Measurement Property"
 
 #string STR_gEfiMdePkgTokenSpaceGuid_PcdPerformanceLibraryPropertyMask_HELP  #language en-US "The mask is used to control PerformanceLib behavior.<BR><BR>\n"
                                                                                              "BIT0 - Enable Performance Measurement.<BR>"
+                                                                                             "BIT1 - Disable Start Image Logging.<BR>"
+                                                                                             "BIT2 - Disable Load Image logging.<BR>"
+                                                                                             "BIT3 - Disable Binding Support logging.<BR>"
+                                                                                             "BIT4 - Disable Binding Start logging.<BR>"
+                                                                                             "BIT5 - Disable Binding Stop logging.<BR>"
+                                                                                             "BIT6 - Disable all other general Perfs.<BR>"
 
 #string STR_gEfiMdePkgTokenSpaceGuid_PcdPostCodePropertyMask_PROMPT  #language en-US "Post Code Property"
 
 #string STR_gEfiMdePkgTokenSpaceGuid_PcdPostCodePropertyMask_HELP  #language en-US "The mask is used to control PostCodeLib behavior.<BR><BR>\n"
                                                                                    "BIT0 - Enable Post Code.<BR>\n"
-- 
2.14.3.windows.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [patch 4/9] MdeModulePkg/ExtendedFirmwarePerf: Remove PerfId definitions
  2018-06-19  7:23 [patch 0/9] Add new Perf macros Dandan Bi
                   ` (2 preceding siblings ...)
  2018-06-19  7:23 ` [patch 3/9] MdePkg/PerformanceLib.h: Add new Perf macros Dandan Bi
@ 2018-06-19  7:24 ` Dandan Bi
  2018-06-19  7:24 ` [patch 5/9] MdeModulePkg: Update performance library instances Dandan Bi
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Dandan Bi @ 2018-06-19  7:24 UTC (permalink / raw)
  To: edk2-devel; +Cc: Liming Gao, Star Zeng

Remove the definitions of performance identifier since they
have been added into PerformanceLib.h.

Cc: Liming Gao <liming.gao@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Dandan Bi <dandan.bi@intel.com>
---
 .../Include/Guid/ExtendedFirmwarePerformance.h     | 25 ----------------------
 1 file changed, 25 deletions(-)

diff --git a/MdeModulePkg/Include/Guid/ExtendedFirmwarePerformance.h b/MdeModulePkg/Include/Guid/ExtendedFirmwarePerformance.h
index f2db02ddf49..465b4082750 100644
--- a/MdeModulePkg/Include/Guid/ExtendedFirmwarePerformance.h
+++ b/MdeModulePkg/Include/Guid/ExtendedFirmwarePerformance.h
@@ -30,35 +30,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #define DRIVERBINDING_STOP_TOK          "DB:Stop:"        ///< Driver Binding Stop() function call
 #define LOAD_IMAGE_TOK                  "LoadImage:"      ///< Load a dispatched module
 #define START_IMAGE_TOK                 "StartImage:"     ///< Dispatched Modules Entry Point execution
 #define PEIM_TOK                        "PEIM"            ///< PEIM Modules Entry Point execution
 
-//
-// Public Progress Identifiers for Event Records to map the above known token
-//
-#define MODULE_START_ID                 0x01
-#define MODULE_END_ID                   0x02
-#define MODULE_LOADIMAGE_START_ID       0x03
-#define MODULE_LOADIMAGE_END_ID         0x04
-#define MODULE_DB_START_ID              0x05
-#define MODULE_DB_END_ID                0x06
-#define MODULE_DB_SUPPORT_START_ID      0x07
-#define MODULE_DB_SUPPORT_END_ID        0x08
-#define MODULE_DB_STOP_START_ID         0x09
-#define MODULE_DB_STOP_END_ID           0x0A
-
-#define PERF_EVENTSIGNAL_START_ID       0x10
-#define PERF_EVENTSIGNAL_END_ID         0x11
-#define PERF_CALLBACK_START_ID          0x20
-#define PERF_CALLBACK_END_ID            0x21
-#define PERF_FUNCTION_START_ID          0x30
-#define PERF_FUNCTION_END_ID            0x31
-#define PERF_INMODULE_START_ID          0x40
-#define PERF_INMODULE_END_ID            0x41
-#define PERF_CROSSMODULE_START_ID       0x50
-#define PERF_CROSSMODULE_END_ID         0x51
-
 //
 // Misc defines
 //
 #define FPDT_RECORD_REVISION_1      (0x01)
 
-- 
2.14.3.windows.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [patch 5/9] MdeModulePkg: Update performance library instances
  2018-06-19  7:23 [patch 0/9] Add new Perf macros Dandan Bi
                   ` (3 preceding siblings ...)
  2018-06-19  7:24 ` [patch 4/9] MdeModulePkg/ExtendedFirmwarePerf: Remove PerfId definitions Dandan Bi
@ 2018-06-19  7:24 ` Dandan Bi
  2018-06-19  7:24 ` [patch 6/9] ShellPkg/dp: Update dp tool to parse new Perf record Dandan Bi
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Dandan Bi @ 2018-06-19  7:24 UTC (permalink / raw)
  To: edk2-devel; +Cc: Liming Gao, Star Zeng

Update the performance library instances in MdeModulePkg
to implement the APIs used for new added Perf macros.

Cc: Liming Gao <liming.gao@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Dandan Bi <dandan.bi@intel.com>
---
 .../DxeCorePerformanceLib/DxeCorePerformanceLib.c  | 664 +++++++++++++++++++--
 .../DxeCorePerformanceLib.inf                      |   1 +
 .../DxeCorePerformanceLibInternal.h                |   1 +
 .../Library/DxePerformanceLib/DxePerformanceLib.c  |  68 +++
 .../Library/PeiPerformanceLib/PeiPerformanceLib.c  | 442 ++++++++++++--
 .../SmmCorePerformanceLib/SmmCorePerformanceLib.c  | 440 ++++++++++++--
 .../Library/SmmPerformanceLib/SmmPerformanceLib.c  |  68 +++
 7 files changed, 1550 insertions(+), 134 deletions(-)

diff --git a/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.c b/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.c
index 79820605184..68724ce9e1c 100644
--- a/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.c
+++ b/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.c
@@ -69,17 +69,19 @@ UINTN           mCachePairCount = 0;
 UINT32  mLoadImageCount       = 0;
 UINT32  mPerformanceLength    = 0;
 UINT32  mMaxPerformanceLength = 0;
 UINT32  mBootRecordSize       = 0;
 UINT32  mBootRecordMaxSize    = 0;
+UINT32  mCachedLength         = 0;
 
 BOOLEAN mFpdtBufferIsReported = FALSE;
 BOOLEAN mLackSpaceIsReported  = FALSE;
 CHAR8   *mPlatformLanguage    = NULL;
 UINT8   *mPerformancePointer  = NULL;
 UINT8   *mBootRecordBuffer    = NULL;
 BOOLEAN  mLockInsertRecord    = FALSE;
+CHAR8   *mDevicePathString    = NULL;
 
 EFI_DEVICE_PATH_TO_TEXT_PROTOCOL  *mDevicePathToText = NULL;
 
 //
 // Interfaces for PerformanceMeasurement Protocol.
@@ -88,10 +90,64 @@ EDKII_PERFORMANCE_MEASUREMENT_PROTOCOL mPerformanceMeasurementInterface = {
   CreatePerformanceMeasurement,
   };
 
 PERFORMANCE_PROPERTY  mPerformanceProperty;
 
+/**
+  Return the pointer to the FPDT record in the allocated memory.
+
+  @param  RecordSize             The size of FPDT record.
+  @param  FpdtRecordPtr          Pointer the FPDT record in the allocated memory.
+
+  @retval EFI_SUCCESS            Successfully get the pointer to the FPDT record.
+  @retval EFI_OUT_OF_RESOURCES   Ran out of space to store the records.
+**/
+EFI_STATUS
+GetFpdtRecordPtr (
+  IN     UINT8               RecordSize,
+  IN OUT FPDT_RECORD_PTR     *FpdtRecordPtr
+)
+{
+  if (mFpdtBufferIsReported) {
+    //
+    // Append Boot records to the boot performance table.
+    //
+    if (mBootRecordSize + RecordSize > mBootRecordMaxSize) {
+      if (!mLackSpaceIsReported) {
+        DEBUG ((DEBUG_INFO, "DxeCorePerformanceLib: No enough space to save boot records\n"));
+        mLackSpaceIsReported = TRUE;
+      }
+      return EFI_OUT_OF_RESOURCES;
+    } else {
+      //
+      // Save boot record into BootPerformance table
+      //
+      FpdtRecordPtr->RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)(mBootRecordBuffer + mBootRecordSize);
+    }
+  } else {
+    //
+    // Check if pre-allocated buffer is full
+    //
+    if (mPerformanceLength + RecordSize > mMaxPerformanceLength) {
+      mPerformancePointer = ReallocatePool (
+                              mPerformanceLength,
+                              mPerformanceLength + RecordSize + FIRMWARE_RECORD_BUFFER,
+                              mPerformancePointer
+                              );
+      if (mPerformancePointer == NULL) {
+         return EFI_OUT_OF_RESOURCES;
+       }
+      mMaxPerformanceLength = mPerformanceLength + RecordSize + FIRMWARE_RECORD_BUFFER;
+    }
+    //
+    // Covert buffer to FPDT Ptr Union type.
+    //
+    FpdtRecordPtr->RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)(mPerformancePointer + mPerformanceLength);
+  }
+  return EFI_SUCCESS;
+}
+
 /**
 Check whether the Token is a known one which is uesed by core.
 
 @param  Token      Pointer to a Null-terminated ASCII string
 
@@ -814,49 +870,13 @@ InsertFpdtMeasurement (
       Identifier += 1;
     }
     RecordInfo.ProgressID = (UINT16)Identifier;
   }
 
-  if (mFpdtBufferIsReported) {
-    //
-    // Append Boot records to the boot performance table.
-    //
-    if (mBootRecordSize + RecordInfo.RecordSize > mBootRecordMaxSize) {
-      if (!mLackSpaceIsReported) {
-        DEBUG ((DEBUG_INFO, "DxeCorePerformanceLib: No enough space to save boot records\n"));
-        mLackSpaceIsReported = TRUE;
-      }
-      return EFI_OUT_OF_RESOURCES;
-    } else {
-      //
-      // Save boot record into BootPerformance table
-      //
-      FpdtRecordPtr.RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)(mBootRecordBuffer + mBootRecordSize);
-      mBootRecordSize += RecordInfo.RecordSize;
-      mAcpiBootPerformanceTable->Header.Length += RecordInfo.RecordSize;
-    }
-  } else {
-    //
-    // Check if pre-allocated buffer is full
-    //
-    if (mPerformanceLength + RecordInfo.RecordSize > mMaxPerformanceLength) {
-      mPerformancePointer = ReallocatePool (
-                              mPerformanceLength,
-                              mPerformanceLength + RecordInfo.RecordSize + FIRMWARE_RECORD_BUFFER,
-                              mPerformancePointer
-                              );
-
-      if (mPerformancePointer == NULL) {
-        return EFI_OUT_OF_RESOURCES;
-      }
-      mMaxPerformanceLength = mPerformanceLength + RecordInfo.RecordSize + FIRMWARE_RECORD_BUFFER;
-    }
-    //
-    // Covert buffer to FPDT Ptr Union type.
-    //
-    FpdtRecordPtr.RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)(mPerformancePointer + mPerformanceLength);
-    mPerformanceLength += RecordInfo.RecordSize;
+  Status = GetFpdtRecordPtr (RecordInfo.RecordSize, &FpdtRecordPtr);
+  if (EFI_ERROR (Status)) {
+    return Status;
   }
 
   //
   // Get the TimeStamp.
   //
@@ -942,11 +962,16 @@ InsertFpdtMeasurement (
     //
     // Record is not supported in current DXE phase, return EFI_ABORTED
     //
     return EFI_UNSUPPORTED;
   }
-
+  if (mFpdtBufferIsReported) {
+    mBootRecordSize += FpdtRecordPtr.RecordHeader->Length;
+    mAcpiBootPerformanceTable->Header.Length += FpdtRecordPtr.RecordHeader->Length;
+  } else {
+    mPerformanceLength += FpdtRecordPtr.RecordHeader->Length;
+  }
   return EFI_SUCCESS;
 }
 
 /**
   Dumps all the PEI performance.
@@ -1038,10 +1063,512 @@ ReportFpdtRecordBuffer (
     //
     mFpdtBufferIsReported = TRUE;
   }
 }
 
+/**
+  Get a string description for device for the given controller handle.
+  If ComponentName2 GetControllerName is supported, the value is
+  included in the string,followed by device path, otherwise just device path.
+
+  @param Handle              - Image handle
+  @param ControllerHandle    - Controller handle.
+  @param Length              - Pointer to record length to be updated
+
+  @retval EFI_SUCCESS     - Successfully got string description for device
+  @retval EFI_UNSUPPORTED - Neither ComponentName2 ControllerName nor DevicePath were found.
+
+**/
+EFI_STATUS
+GetDeviceInfoFromHandleAndUpdateLength (
+  IN CONST VOID        *Handle,
+  IN EFI_HANDLE        ControllerHandle,
+  IN OUT UINT8         *Length
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL      *DevicePathProtocol;
+  EFI_COMPONENT_NAME2_PROTOCOL  *ComponentName2;
+  EFI_STATUS                    Status;
+  CHAR16                        *StringPtr;
+  CHAR8                         *AsciiStringPtr;
+  UINTN                         ControllerNameStringSize;
+  UINTN                         DevicePathStringSize;
+
+  ControllerNameStringSize = 0;
+
+  Status = gBS->HandleProtocol (
+                  (EFI_HANDLE) Handle,
+                  &gEfiComponentName2ProtocolGuid,
+                  (VOID **) &ComponentName2
+                  );
+
+  if (!EFI_ERROR(Status)) {
+    //
+    // Get the current platform language setting
+    //
+    if (mPlatformLanguage == NULL) {
+      GetEfiGlobalVariable2 (L"PlatformLang", (VOID **)&mPlatformLanguage, NULL);
+    }
+
+    Status = ComponentName2->GetControllerName (
+                               ComponentName2,
+                               ControllerHandle,
+                               NULL,
+                               mPlatformLanguage != NULL ? mPlatformLanguage:"en-US",
+                               &StringPtr
+                               );
+  }
+
+  if (!EFI_ERROR (Status)) {
+    //
+    // This will produce the size of the unicode string, which is twice as large as the ASCII one
+    // This must be an even number, so ok to divide by 2
+    //
+    ControllerNameStringSize = StrSize(StringPtr) / 2;
+
+    //
+    // The + 1 is because we want to add a space between the ControllerName and the device path
+    //
+    if ((ControllerNameStringSize + (*Length) + 1) > FPDT_MAX_PERF_RECORD_SIZE) {
+      //
+      // Only copy enough to fill MAX_PERF_RECORD_SIZE worth of the record
+      //
+      ControllerNameStringSize = FPDT_MAX_PERF_RECORD_SIZE - (*Length) - 1;
+    }
+
+    mDevicePathString = AllocateZeroPool (ControllerNameStringSize + 1);
+    if (mDevicePathString == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+
+    UnicodeStrToAsciiStrS(StringPtr, mDevicePathString, ControllerNameStringSize);
+
+    //
+    // Add a space in the end of the ControllerName
+    //
+    AsciiStringPtr = mDevicePathString + ControllerNameStringSize - 1;
+    *AsciiStringPtr = 0x20;
+    AsciiStringPtr++;
+    *AsciiStringPtr = 0;
+    ControllerNameStringSize++;
+
+    *Length += (UINT8)ControllerNameStringSize;
+  }
+
+  //
+  // This function returns the device path protocol from the handle specified by Handle. If Handle is
+  // NULL or Handle does not contain a device path protocol, then NULL is returned.
+  //
+  DevicePathProtocol = DevicePathFromHandle(ControllerHandle);
+
+  if (DevicePathProtocol != NULL) {
+    StringPtr = ConvertDevicePathToText (DevicePathProtocol, TRUE, FALSE);
+    if (StringPtr != NULL) {
+      //
+      // This will produce the size of the unicode string, which is twice as large as the ASCII one
+      // This must be an even number, so ok to divide by 2
+      //
+      DevicePathStringSize = StrSize(StringPtr) / 2;
+
+      if ((DevicePathStringSize + (*Length)) > FPDT_MAX_PERF_RECORD_SIZE) {
+        //
+        // Only copy enough to fill MAX_PERF_RECORD_SIZE worth of the record
+        //
+        DevicePathStringSize = FPDT_MAX_PERF_RECORD_SIZE - (*Length);
+      }
+      if (ControllerNameStringSize != 0) {
+        mDevicePathString = ReallocatePool(
+                          ControllerNameStringSize + 1,
+                          ControllerNameStringSize + DevicePathStringSize + 1,
+                          mDevicePathString
+                          );
+      } else {
+        mDevicePathString = AllocateZeroPool(DevicePathStringSize + 1);
+      }
+      if (mDevicePathString == NULL) {
+        return EFI_OUT_OF_RESOURCES;
+      }
+      if (ControllerNameStringSize != 0) {
+        AsciiStringPtr = mDevicePathString + ControllerNameStringSize - 1;
+      } else {
+        AsciiStringPtr = mDevicePathString;
+      }
+
+      UnicodeStrToAsciiStrS(StringPtr, AsciiStringPtr, DevicePathStringSize);
+      *Length += (UINT8)DevicePathStringSize;
+      return EFI_SUCCESS;
+    }
+  }
+
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Get the FPDT record size.
+
+  @param  Handle                   Pointer to environment specific context used
+                                   to identify the component being measured.
+  @param  String                   Pointer to a Null-terminated ASCII string
+                                   that identifies the component being measured.
+  @param  Address                  Pointer to a location in memory relevant to the measurement.
+                                   For DriverBinding Perf, it's the Controller handle.
+                                   For other Perf, it's NULL.
+  @param  PerfId                   Performance identifier.
+  @param  RecordSize               On return, pointer to the size of record.
+
+  @retval EFI_SUCCESS              Get record size successfully.
+  @retval EFI_INVALID_PARAMETER    Invalid Performance identifier.
+
+**/
+EFI_STATUS
+GetFpdtRecordSize (
+  IN CONST VOID                    *Handle,
+  IN CONST CHAR8                   *String,
+  IN       UINT64                  Address,
+  IN       UINT16                  PerfId,
+  OUT      UINT8                   *RecordSize
+  )
+{
+  UINTN    StringSize;
+
+  if (PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
+    if (PerfId == MODULE_DB_SUPPORT_START_ID || PerfId ==  MODULE_DB_SUPPORT_END_ID) {
+      return EFI_UNSUPPORTED;
+    }
+    *RecordSize = (UINT8)(sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD) + STRING_SIZE);
+  } else {
+    switch (PerfId) {
+    case MODULE_START_ID:
+    case MODULE_END_ID:
+      *RecordSize = sizeof (FPDT_GUID_EVENT_RECORD);
+      break;
+
+    case MODULE_LOADIMAGE_START_ID:
+    case MODULE_LOADIMAGE_END_ID:
+      *RecordSize = sizeof (FPDT_GUID_QWORD_EVENT_RECORD);
+      break;
+
+    case MODULE_DB_START_ID:
+    case MODULE_DB_SUPPORT_START_ID:
+    case MODULE_DB_SUPPORT_END_ID:
+    case MODULE_DB_STOP_START_ID:
+    case MODULE_DB_STOP_END_ID:
+      *RecordSize = sizeof (FPDT_GUID_QWORD_EVENT_RECORD);
+      break;
+
+    case MODULE_DB_END_ID:
+      *RecordSize = sizeof (FPDT_GUID_QWORD_STRING_EVENT_RECORD);
+      GetDeviceInfoFromHandleAndUpdateLength(Handle, (EFI_HANDLE)(UINTN)Address, RecordSize);
+      break;
+
+    case PERF_EVENTSIGNAL_START_ID:
+    case PERF_EVENTSIGNAL_END_ID:
+    case PERF_CALLBACK_START_ID:
+    case PERF_CALLBACK_END_ID:
+      if (String == NULL) {
+        return EFI_INVALID_PARAMETER;
+      }
+      StringSize = AsciiStrSize (String);
+      if (StringSize > STRING_SIZE) {
+        StringSize = STRING_SIZE;
+      }
+      *RecordSize = (UINT8)(sizeof (FPDT_DUAL_GUID_STRING_EVENT_RECORD) + StringSize);
+      break;
+
+    case PERF_EVENT_ID:
+    case PERF_FUNCTION_START_ID:
+    case PERF_FUNCTION_END_ID:
+    case PERF_INMODULE_START_ID:
+    case PERF_INMODULE_END_ID:
+    case PERF_CROSSMODULE_START_ID:
+    case PERF_CROSSMODULE_END_ID:
+      if (String == NULL) {
+        return EFI_INVALID_PARAMETER;
+      }
+      StringSize = AsciiStrSize (String);
+      if (StringSize > STRING_SIZE) {
+        StringSize = STRING_SIZE;
+      }
+      *RecordSize = (UINT8)(sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD) + StringSize);
+      break;
+
+    default:
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Create performance record with event description and a timestamp.
+
+  @param CallerIdentifier  - Image handle or pointer to caller ID GUID.
+  @param Guid              - Pointer to a GUID
+  @param String            - Pointer to a string describing the measurement
+  @param Address           - Pointer to a location in memory relevant to the measurement
+  @param PerfId            - Performance identifier describing the type of measurement
+
+  @retval EFI_SUCCESS           - Successfully created performance record
+  @retval EFI_OUT_OF_RESOURCES  - Ran out of space to store the records
+  @retval EFI_INVALID_PARAMETER - Invalid parameter passed to function - NULL
+                                  pointer or invalid PerfId
+
+**/
+EFI_STATUS
+InsertFpdtRecord (
+  IN CONST VOID                    *CallerIdentifier,  OPTIONAL
+  IN CONST VOID                    *Guid,    OPTIONAL
+  IN CONST CHAR8                   *String,  OPTIONAL
+  IN       UINT64                  Address,  OPTIONAL
+  IN       UINT16                  PerfId
+  )
+{
+  EFI_GUID                     ModuleGuid;
+  CHAR8                        ModuleName[FPDT_STRING_EVENT_RECORD_NAME_LENGTH];
+  FPDT_RECORD_PTR              FpdtRecordPtr;
+  FPDT_RECORD_PTR              CachedFpdtRecordPtr;
+  UINT64                       TimeStamp;
+  UINT64                       TimeStampCounter;
+  CONST CHAR8                  *StringPtr;
+  UINT8                        RecordSize;
+  UINTN                        DestMax;
+  UINTN                        StringLen;
+  EFI_STATUS                   Status;
+
+  StringPtr     = NULL;
+  RecordSize    = 0;
+  ZeroMem (ModuleName, sizeof (ModuleName));
+
+  Status = GetFpdtRecordSize(CallerIdentifier, String, Address, PerfId, &RecordSize);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = GetFpdtRecordPtr (RecordSize, &FpdtRecordPtr);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Get the TimeStamp.
+  //
+  TimeStampCounter = GetPerformanceCounter ();
+  TimeStamp        = GetTimeInNanoSecond (TimeStampCounter);
+
+  switch (PerfId) {
+  case MODULE_START_ID:
+  case MODULE_END_ID:
+    //
+    // Get the ModuleGuid and ModuleName from the handle.
+    //
+    GetModuleInfoFromHandle ((EFI_HANDLE *)CallerIdentifier, ModuleName, sizeof (ModuleName), &ModuleGuid);
+    StringPtr = ModuleName;
+    if (PerfId == MODULE_START_ID) {
+      if (mFpdtBufferIsReported) {
+        mCachedLength = mBootRecordSize;
+      } else {
+        mCachedLength = mPerformanceLength;
+      }
+    }
+    if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
+      FpdtRecordPtr.GuidEvent->Header.Type                = FPDT_GUID_EVENT_TYPE;
+      FpdtRecordPtr.GuidEvent->Header.Length              = RecordSize;
+      FpdtRecordPtr.GuidEvent->Header.Revision            = FPDT_RECORD_REVISION_1;
+      FpdtRecordPtr.GuidEvent->ProgressID                 = PerfId;
+      FpdtRecordPtr.GuidEvent->Timestamp                  = TimeStamp;
+      CopyMem (&FpdtRecordPtr.GuidEvent->Guid, &ModuleGuid, sizeof (FpdtRecordPtr.GuidEvent->Guid));
+      if (PerfId == MODULE_END_ID && mCachedLength != 0) {
+        if (mFpdtBufferIsReported) {
+          CachedFpdtRecordPtr.RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)(mBootRecordBuffer + mCachedLength);
+        } else {
+          CachedFpdtRecordPtr.RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)(mPerformancePointer + mCachedLength);
+        }
+        CopyMem (&CachedFpdtRecordPtr.GuidEvent->Guid, &ModuleGuid, sizeof (CachedFpdtRecordPtr.GuidEvent->Guid));
+        mCachedLength = 0;
+      }
+    }
+    break;
+
+  case MODULE_LOADIMAGE_START_ID:
+  case MODULE_LOADIMAGE_END_ID:
+    GetModuleInfoFromHandle ((EFI_HANDLE *)CallerIdentifier, ModuleName, sizeof (ModuleName), &ModuleGuid);
+    StringPtr = ModuleName;
+    if (PerfId == MODULE_LOADIMAGE_START_ID) {
+      mLoadImageCount ++;
+      if (mFpdtBufferIsReported) {
+        mCachedLength = mBootRecordSize;
+      } else {
+        mCachedLength = mPerformanceLength;
+      }
+    }
+    if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
+      FpdtRecordPtr.GuidQwordEvent->Header.Type           = FPDT_GUID_QWORD_EVENT_TYPE;
+      FpdtRecordPtr.GuidQwordEvent->Header.Length         = RecordSize;
+      FpdtRecordPtr.GuidQwordEvent->Header.Revision       = FPDT_RECORD_REVISION_1;
+      FpdtRecordPtr.GuidQwordEvent->ProgressID            = PerfId;
+      FpdtRecordPtr.GuidQwordEvent->Timestamp             = TimeStamp;
+      FpdtRecordPtr.GuidQwordEvent->Qword                 = mLoadImageCount;
+      CopyMem (&FpdtRecordPtr.GuidQwordEvent->Guid, &ModuleGuid, sizeof (FpdtRecordPtr.GuidQwordEvent->Guid));
+      if (PerfId == MODULE_LOADIMAGE_END_ID && mCachedLength != 0) {
+        if (mFpdtBufferIsReported) {
+          CachedFpdtRecordPtr.RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)(mBootRecordBuffer + mCachedLength);
+        } else {
+          CachedFpdtRecordPtr.RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)(mPerformancePointer + mCachedLength);
+        }
+        CopyMem (&CachedFpdtRecordPtr.GuidQwordEvent->Guid, &ModuleGuid, sizeof (CachedFpdtRecordPtr.GuidQwordEvent->Guid));
+        mCachedLength = 0;
+      }
+    }
+    break;
+
+  case MODULE_DB_START_ID:
+  case MODULE_DB_SUPPORT_START_ID:
+  case MODULE_DB_SUPPORT_END_ID:
+  case MODULE_DB_STOP_START_ID:
+  case MODULE_DB_STOP_END_ID:
+    if (Address == 0) {
+      return EFI_INVALID_PARAMETER;
+    }
+    GetModuleInfoFromHandle ((EFI_HANDLE *)CallerIdentifier, ModuleName, sizeof (ModuleName), &ModuleGuid);
+    StringPtr = ModuleName;
+    if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
+      FpdtRecordPtr.GuidQwordEvent->Header.Type           = FPDT_GUID_QWORD_EVENT_TYPE;
+      FpdtRecordPtr.GuidQwordEvent->Header.Length         = RecordSize;
+      FpdtRecordPtr.GuidQwordEvent->Header.Revision       = FPDT_RECORD_REVISION_1;
+      FpdtRecordPtr.GuidQwordEvent->ProgressID            = PerfId;
+      FpdtRecordPtr.GuidQwordEvent->Timestamp             = TimeStamp;
+      FpdtRecordPtr.GuidQwordEvent->Qword                 = Address;
+      CopyMem (&FpdtRecordPtr.GuidQwordEvent->Guid, &ModuleGuid, sizeof (FpdtRecordPtr.GuidQwordEvent->Guid));
+    }
+    break;
+
+  case MODULE_DB_END_ID:
+    if (Address == 0) {
+      return EFI_INVALID_PARAMETER;
+    }
+    GetModuleInfoFromHandle ((EFI_HANDLE *)CallerIdentifier, ModuleName, sizeof (ModuleName), &ModuleGuid);
+    StringPtr = ModuleName;
+    if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
+      FpdtRecordPtr.GuidQwordStringEvent->Header.Type     = FPDT_GUID_QWORD_STRING_EVENT_TYPE;
+      FpdtRecordPtr.GuidQwordStringEvent->Header.Length   = RecordSize;
+      FpdtRecordPtr.GuidQwordStringEvent->Header.Revision = FPDT_RECORD_REVISION_1;
+      FpdtRecordPtr.GuidQwordStringEvent->ProgressID      = PerfId;
+      FpdtRecordPtr.GuidQwordStringEvent->Timestamp       = TimeStamp;
+      FpdtRecordPtr.GuidQwordStringEvent->Qword           = Address;
+      CopyMem (&FpdtRecordPtr.GuidQwordStringEvent->Guid, &ModuleGuid, sizeof (FpdtRecordPtr.GuidQwordStringEvent->Guid));
+      DestMax = (RecordSize - sizeof (FPDT_GUID_QWORD_STRING_EVENT_RECORD)) / sizeof (CHAR8);
+      if (mDevicePathString != NULL) {
+        AsciiStrCpyS (FpdtRecordPtr.GuidQwordStringEvent->String, DestMax, mDevicePathString);
+        FreePool (mDevicePathString);
+        mDevicePathString = NULL;
+      }
+    }
+    break;
+
+  case PERF_EVENTSIGNAL_START_ID:
+  case PERF_EVENTSIGNAL_END_ID:
+  case PERF_CALLBACK_START_ID:
+  case PERF_CALLBACK_END_ID:
+    if (CallerIdentifier == NULL || Guid ==NULL || String == NULL) {
+      return EFI_INVALID_PARAMETER;
+    }
+    //
+    // Cache the event guid in string event record when PcdEdkiiFpdtStringRecordEnableOnly == TRUE
+    //
+    CopyGuid (&ModuleGuid, Guid);
+    StringPtr = String;
+    if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
+      FpdtRecordPtr.DualGuidStringEvent->Header.Type      = FPDT_DUAL_GUID_STRING_EVENT_TYPE;
+      FpdtRecordPtr.DualGuidStringEvent->Header.Length    = RecordSize;
+      FpdtRecordPtr.DualGuidStringEvent->Header.Revision  = FPDT_RECORD_REVISION_1;
+      FpdtRecordPtr.DualGuidStringEvent->ProgressID       = PerfId;
+      FpdtRecordPtr.DualGuidStringEvent->Timestamp        = TimeStamp;
+      CopyMem (&FpdtRecordPtr.DualGuidStringEvent->Guid1, CallerIdentifier, sizeof (FpdtRecordPtr.DualGuidStringEvent->Guid1));
+      CopyMem (&FpdtRecordPtr.DualGuidStringEvent->Guid2, Guid, sizeof (FpdtRecordPtr.DualGuidStringEvent->Guid2));
+      DestMax = (RecordSize - sizeof (FPDT_DUAL_GUID_STRING_EVENT_RECORD)) / sizeof (CHAR8);
+      StringLen = AsciiStrLen (StringPtr);
+      if (StringLen >= DestMax) {
+        StringLen = DestMax -1;
+      }
+      AsciiStrnCpyS (FpdtRecordPtr.DualGuidStringEvent->String, DestMax, StringPtr, StringLen);
+    }
+    break;
+
+  case PERF_EVENT_ID:
+  case PERF_FUNCTION_START_ID:
+  case PERF_FUNCTION_END_ID:
+  case PERF_INMODULE_START_ID:
+  case PERF_INMODULE_END_ID:
+  case PERF_CROSSMODULE_START_ID:
+  case PERF_CROSSMODULE_END_ID:
+    if (CallerIdentifier == NULL || String == NULL) {
+      return EFI_INVALID_PARAMETER;
+    }
+    CopyGuid (&ModuleGuid, (EFI_GUID *) CallerIdentifier);
+    StringPtr = String;
+    if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
+      FpdtRecordPtr.DynamicStringEvent->Header.Type       = FPDT_DYNAMIC_STRING_EVENT_TYPE;
+      FpdtRecordPtr.DynamicStringEvent->Header.Length     = RecordSize;
+      FpdtRecordPtr.DynamicStringEvent->Header.Revision   = FPDT_RECORD_REVISION_1;
+      FpdtRecordPtr.DynamicStringEvent->ProgressID        = PerfId;
+      FpdtRecordPtr.DynamicStringEvent->Timestamp         = TimeStamp;
+      CopyMem (&FpdtRecordPtr.DynamicStringEvent->Guid, CallerIdentifier, sizeof (FpdtRecordPtr.DynamicStringEvent->Guid));
+      DestMax = (RecordSize - sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD)) / sizeof (CHAR8);
+      StringLen = AsciiStrLen (StringPtr);
+      if (StringLen >= DestMax) {
+        StringLen = DestMax -1;
+      }
+      AsciiStrnCpyS (FpdtRecordPtr.DynamicStringEvent->String, DestMax, StringPtr, StringLen);
+    }
+    break;
+
+  default:
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
+    FpdtRecordPtr.DynamicStringEvent->Header.Type       = FPDT_DYNAMIC_STRING_EVENT_TYPE;
+    FpdtRecordPtr.DynamicStringEvent->Header.Length     = RecordSize;
+    FpdtRecordPtr.DynamicStringEvent->Header.Revision   = FPDT_RECORD_REVISION_1;
+    FpdtRecordPtr.DynamicStringEvent->ProgressID        = PerfId;
+    FpdtRecordPtr.DynamicStringEvent->Timestamp         = TimeStamp;
+    DestMax = (RecordSize - sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD)) / sizeof (CHAR8);
+    if (StringPtr != NULL && AsciiStrLen (StringPtr) == 0) {
+      StringPtr = "unknown name";
+    }
+    if (StringPtr != NULL) {
+      StringLen = AsciiStrLen (StringPtr);
+      if (StringLen >= DestMax) {
+        StringLen = DestMax -1;
+      }
+    }
+    CopyMem (&FpdtRecordPtr.DynamicStringEvent->Guid, &ModuleGuid, sizeof (FpdtRecordPtr.DynamicStringEvent->Guid));
+    AsciiStrnCpyS (FpdtRecordPtr.DynamicStringEvent->String, DestMax, StringPtr, StringLen);
+
+    if ((PerfId == MODULE_LOADIMAGE_END_ID) || (PerfId == MODULE_END_ID)) {
+      if (mCachedLength != 0) {
+        if (mFpdtBufferIsReported) {
+          CachedFpdtRecordPtr.RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)(mBootRecordBuffer + mCachedLength);
+        } else {
+          CachedFpdtRecordPtr.RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)(mPerformancePointer + mCachedLength);
+        }
+        CopyMem (&CachedFpdtRecordPtr.DynamicStringEvent->Guid, &ModuleGuid, sizeof (CachedFpdtRecordPtr.DynamicStringEvent->Guid));
+        AsciiStrnCpyS (CachedFpdtRecordPtr.DynamicStringEvent->String, DestMax, StringPtr, StringLen);
+        mCachedLength = 0;
+      }
+    }
+  }
+  if (mFpdtBufferIsReported) {
+    mBootRecordSize += FpdtRecordPtr.RecordHeader->Length;
+    mAcpiBootPerformanceTable->Header.Length += FpdtRecordPtr.RecordHeader->Length;
+  } else {
+    mPerformanceLength += FpdtRecordPtr.RecordHeader->Length;
+  }
+  return EFI_SUCCESS;
+}
+
 /**
   The constructor function initializes Performance infrastructure for DXE phase.
 
   The constructor function publishes Performance and PerformanceEx protocol, allocates memory to log DXE performance
   and merges PEI performance data to DXE performance log.
@@ -1162,10 +1689,12 @@ CreatePerformanceMeasurement (
 
   if (Attribute == PerfStartEntry) {
     Status = InsertFpdtMeasurement (TRUE, CallerIdentifier, String, String, TimeStamp, Identifier);
   } else if (Attribute == PerfEndEntry) {
     Status = InsertFpdtMeasurement (FALSE, CallerIdentifier, String, String, TimeStamp, Identifier);
+  } else if ( Attribute == PerfEntry) {
+    Status = InsertFpdtRecord (CallerIdentifier, Guid, String, Address, (UINT16) Identifier);
   }
   mLockInsertRecord = FALSE;
 
   return Status;
 }
@@ -1470,5 +1999,60 @@ PerformanceMeasurementEnabled (
   VOID
   )
 {
   return (BOOLEAN) ((PcdGet8(PcdPerformanceLibraryPropertyMask) & PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED) != 0);
 }
+
+/**
+  Create performance record with event description and a timestamp.
+
+  @param CallerIdentifier  - Image handle or pointer to caller ID GUID
+  @param Guid              - Pointer to a GUID
+  @param String            - Pointer to a string describing the measurement
+  @param Address           - Pointer to a location in memory relevant to the measurement
+  @param Identifier        - Performance identifier describing the type of measurement
+
+  @retval RETURN_SUCCESS           - Successfully created performance record
+  @retval RETURN_OUT_OF_RESOURCES  - Ran out of space to store the records
+  @retval RETURN_INVALID_PARAMETER - Invalid parameter passed to function - NULL
+                                     pointer or invalid PerfId
+
+**/
+RETURN_STATUS
+EFIAPI
+LogPerformanceMeasurement (
+  IN CONST VOID   *CallerIdentifier,
+  IN CONST VOID   *Guid,    OPTIONAL
+  IN CONST CHAR8  *String,  OPTIONAL
+  IN UINT64       Address, OPTIONAL
+  IN UINT32       Identifier
+  )
+{
+  return (RETURN_STATUS)CreatePerformanceMeasurement (CallerIdentifier, Guid, String, 0, Address, Identifier, PerfEntry);
+}
+
+/**
+  Check whether the specified performance measurement can be logged.
+
+  This function returns TRUE when the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set
+  and the Type disable bit in PcdPerformanceLibraryPropertyMask is not set.
+
+  @param Type        - Type of the performance measurement entry.
+
+  @retval TRUE         The performance measurement can be logged.
+  @retval FALSE        The performance measurement can NOT be logged.
+
+**/
+BOOLEAN
+EFIAPI
+LogPerformanceMeasurementEnabled (
+  IN  CONST UINTN        Type
+  )
+{
+  //
+  // When Performance measurement is enabled and the type is not filtered, the performance can be logged.
+  //
+  if (PerformanceMeasurementEnabled () && (PcdGet8(PcdPerformanceLibraryPropertyMask) & Type) == 0) {
+    return TRUE;
+  }
+  return FALSE;
+}
diff --git a/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf b/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf
index 68cd76da5b3..3e77f9cd57a 100644
--- a/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf
+++ b/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf
@@ -59,10 +59,11 @@
   DebugLib
   UefiLib
   ReportStatusCodeLib
   DxeServicesLib
   PeCoffGetEntryPointLib
+  DevicePathLib
 
 [Protocols]
   gEfiSmmCommunicationProtocolGuid              ## SOMETIMES_CONSUMES
 
 
diff --git a/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLibInternal.h b/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLibInternal.h
index f9800e34941..a96f4081503 100644
--- a/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLibInternal.h
+++ b/MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLibInternal.h
@@ -40,10 +40,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/HobLib.h>
 #include <Library/BaseLib.h>
 #include <Library/BaseMemoryLib.h>
 #include <Library/TimerLib.h>
 #include <Library/PcdLib.h>
+#include <Library/DevicePathLib.h>
 #include <Library/UefiBootServicesTableLib.h>
 #include <Library/UefiRuntimeServicesTableLib.h>
 #include <Library/MemoryAllocationLib.h>
 #include <Library/UefiLib.h>
 #include <Library/ReportStatusCodeLib.h>
diff --git a/MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.c b/MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.c
index 9ed50d22b8d..664e8261af9 100644
--- a/MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.c
+++ b/MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.c
@@ -376,5 +376,73 @@ PerformanceMeasurementEnabled (
   VOID
   )
 {
   return (BOOLEAN) ((PcdGet8(PcdPerformanceLibraryPropertyMask) & PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED) != 0);
 }
+
+/**
+  Create performance record with event description and a timestamp.
+
+  @param CallerIdentifier  - Image handle or pointer to caller ID GUID
+  @param Guid              - Pointer to a GUID
+  @param String            - Pointer to a string describing the measurement
+  @param Address           - Pointer to a location in memory relevant to the measurement
+  @param Identifier        - Performance identifier describing the type of measurement
+
+  @retval RETURN_SUCCESS           - Successfully created performance record
+  @retval RETURN_OUT_OF_RESOURCES  - Ran out of space to store the records
+  @retval RETURN_INVALID_PARAMETER - Invalid parameter passed to function - NULL
+                                     pointer or invalid PerfId
+
+**/
+RETURN_STATUS
+EFIAPI
+LogPerformanceMeasurement (
+  IN CONST VOID   *CallerIdentifier,
+  IN CONST VOID   *Guid,    OPTIONAL
+  IN CONST CHAR8  *String,  OPTIONAL
+  IN  UINT64       Address, OPTIONAL
+  IN UINT32       Identifier
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = GetPerformanceMeasurementProtocol ();
+  if (EFI_ERROR (Status)) {
+    return RETURN_OUT_OF_RESOURCES;
+  }
+
+  if (mPerformanceMeasurement != NULL) {
+    Status = mPerformanceMeasurement->CreatePerformanceMeasurement (CallerIdentifier, Guid, String, 0, Address, Identifier, PerfEntry);
+  } else {
+    ASSERT (FALSE);
+  }
+
+  return (RETURN_STATUS) Status;
+}
+
+/**
+  Check whether the specified performance measurement can be logged.
+
+  This function returns TRUE when the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set
+  and the Type disable bit in PcdPerformanceLibraryPropertyMask is not set.
+
+  @param Type        - Type of the performance measurement entry.
+
+  @retval TRUE         The performance measurement can be logged.
+  @retval FALSE        The performance measurement can NOT be logged.
+
+**/
+BOOLEAN
+EFIAPI
+LogPerformanceMeasurementEnabled (
+  IN  CONST UINTN        Type
+  )
+{
+  //
+  // When Performance measurement is enabled and the type is not filtered, the performance can be logged.
+  //
+  if (PerformanceMeasurementEnabled () && (PcdGet8(PcdPerformanceLibraryPropertyMask) & Type) == 0) {
+    return TRUE;
+  }
+  return FALSE;
+}
diff --git a/MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.c b/MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.c
index f770a35a995..d7b652c5771 100644
--- a/MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.c
+++ b/MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.c
@@ -31,11 +31,88 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/TimerLib.h>
 #include <Library/PcdLib.h>
 #include <Library/BaseMemoryLib.h>
 
 #define  STRING_SIZE            (FPDT_STRING_EVENT_RECORD_NAME_LENGTH * sizeof (CHAR8))
-#define  MAX_RECORD_SIZE        (sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD) + STRING_SIZE)
+#define  PEI_MAX_RECORD_SIZE    (sizeof (FPDT_DUAL_GUID_STRING_EVENT_RECORD) + STRING_SIZE)
+
+/**
+  Return the pointer to the FPDT record in the allocated memory.
+
+  @param  RecordSize                The size of FPDT record.
+  @param  FpdtRecordPtr             Pointer the FPDT record in the allocated memory.
+  @param  PeiPerformanceLogHeader   Pointer to the header of the PEI Performance records in the GUID Hob.
+
+  @retval EFI_SUCCESS               Successfully get the pointer to the FPDT record.
+  @retval EFI_OUT_OF_RESOURCES      Ran out of space to store the records.
+**/
+EFI_STATUS
+GetFpdtRecordPtr (
+  IN     UINT8                     RecordSize,
+  IN OUT FPDT_RECORD_PTR           *FpdtRecordPtr,
+  IN OUT FPDT_PEI_EXT_PERF_HEADER  **PeiPerformanceLogHeader
+)
+{
+  UINT16                                PeiPerformanceLogEntries;
+  UINTN                                 PeiPerformanceSize;
+  UINT8                                 *PeiFirmwarePerformance;
+  EFI_HOB_GUID_TYPE                     *GuidHob;
+
+  //
+  // Get the number of PeiPerformanceLogEntries form PCD.
+  //
+  PeiPerformanceLogEntries = (UINT16) (PcdGet16 (PcdMaxPeiPerformanceLogEntries16) != 0 ?
+                                       PcdGet16 (PcdMaxPeiPerformanceLogEntries16) :
+                                       PcdGet8 (PcdMaxPeiPerformanceLogEntries));
+
+  //
+  // Create GUID HOB Data.
+  //
+  GuidHob = GetFirstGuidHob (&gEdkiiFpdtExtendedFirmwarePerformanceGuid);
+  PeiFirmwarePerformance = NULL;
+  while (GuidHob != NULL) {
+    //
+    // PEI Performance HOB was found, then return the existing one.
+    //
+    PeiFirmwarePerformance  = (UINT8*)GET_GUID_HOB_DATA (GuidHob);
+    *PeiPerformanceLogHeader = (FPDT_PEI_EXT_PERF_HEADER *)PeiFirmwarePerformance;
+    if (!(*PeiPerformanceLogHeader)->HobIsFull && (*PeiPerformanceLogHeader)->SizeOfAllEntries + RecordSize > PeiPerformanceLogEntries * PEI_MAX_RECORD_SIZE) {
+      (*PeiPerformanceLogHeader)->HobIsFull = TRUE;
+    }
+    if (!(*PeiPerformanceLogHeader)->HobIsFull && (*PeiPerformanceLogHeader)->SizeOfAllEntries + RecordSize <= PeiPerformanceLogEntries * PEI_MAX_RECORD_SIZE) {
+      FpdtRecordPtr->RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)(PeiFirmwarePerformance + sizeof (FPDT_PEI_EXT_PERF_HEADER) + (*PeiPerformanceLogHeader)->SizeOfAllEntries);
+      break;
+    }
+    //
+    // Previous HOB is used, then find next one.
+    //
+    GuidHob = GetNextGuidHob (&gEdkiiFpdtExtendedFirmwarePerformanceGuid, GET_NEXT_HOB (GuidHob));
+  }
+
+  if (GuidHob == NULL) {
+    //
+    // PEI Performance HOB was not found, then build one.
+    //
+    PeiPerformanceSize      = sizeof (FPDT_PEI_EXT_PERF_HEADER) +
+                              PEI_MAX_RECORD_SIZE * PeiPerformanceLogEntries;
+    PeiFirmwarePerformance  = (UINT8*)BuildGuidHob (&gEdkiiFpdtExtendedFirmwarePerformanceGuid, PeiPerformanceSize);
+    if (PeiFirmwarePerformance != NULL) {
+      ZeroMem (PeiFirmwarePerformance, PeiPerformanceSize);
+      (*PeiPerformanceLogHeader) = (FPDT_PEI_EXT_PERF_HEADER *)PeiFirmwarePerformance;
+      FpdtRecordPtr->RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)(PeiFirmwarePerformance + sizeof (FPDT_PEI_EXT_PERF_HEADER));
+    }
+  }
+
+  if (PeiFirmwarePerformance == NULL) {
+    //
+    // there is no enough resource to store performance data
+    //
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  return EFI_SUCCESS;
+}
 
 /**
 Check whether the Token is a known one which is uesed by core.
 
 @param  Token      Pointer to a Null-terminated ASCII string
@@ -240,23 +317,19 @@ InsertPeiFpdtMeasurement (
   IN CONST CHAR8  *Module,  OPTIONAL
   IN UINT64       Ticker,
   IN UINT32       Identifier
   )
 {
-  EFI_HOB_GUID_TYPE                     *GuidHob;
-  UINTN                                 PeiPerformanceSize;
-  UINT8                                 *PeiFirmwarePerformance;
-  FPDT_PEI_EXT_PERF_HEADER              *PeiPerformanceLogHeader;
   FPDT_RECORD_PTR                       FpdtRecordPtr;
   FPDT_BASIC_RECORD_INFO                RecordInfo;
   CONST VOID                            *ModuleGuid;
   UINTN                                 DestMax;
   UINTN                                 StrLength;
   CONST CHAR8                           *StringPtr;
   EFI_STATUS                            Status;
-  UINT16                                PeiPerformanceLogEntries;
   UINT64                                TimeStamp;
+  FPDT_PEI_EXT_PERF_HEADER              *PeiPerformanceLogHeader;
 
   StringPtr = NULL;
   FpdtRecordPtr.RecordHeader = NULL;
   PeiPerformanceLogHeader = NULL;
 
@@ -286,60 +359,13 @@ InsertPeiFpdtMeasurement (
       Identifier += 1;
     }
     RecordInfo.ProgressID = (UINT16)Identifier;
   }
 
-  //
-  // Get the number of PeiPerformanceLogEntries form PCD.
-  //
-  PeiPerformanceLogEntries = (UINT16) (PcdGet16 (PcdMaxPeiPerformanceLogEntries16) != 0 ?
-                                       PcdGet16 (PcdMaxPeiPerformanceLogEntries16) :
-                                       PcdGet8 (PcdMaxPeiPerformanceLogEntries));
-
-  //
-  // Create GUID HOB Data.
-  //
-  GuidHob = GetFirstGuidHob (&gEdkiiFpdtExtendedFirmwarePerformanceGuid);
-  PeiFirmwarePerformance = NULL;
-  while (GuidHob != NULL) {
-    //
-    // PEI Performance HOB was found, then return the existing one.
-    //
-    PeiFirmwarePerformance  = (UINT8*)GET_GUID_HOB_DATA (GuidHob);
-    PeiPerformanceLogHeader = (FPDT_PEI_EXT_PERF_HEADER *)PeiFirmwarePerformance;
-    if (!PeiPerformanceLogHeader->HobIsFull && PeiPerformanceLogHeader->SizeOfAllEntries + RecordInfo.RecordSize > PeiPerformanceLogEntries * MAX_RECORD_SIZE) {
-      PeiPerformanceLogHeader->HobIsFull = TRUE;
-    }
-    if (!PeiPerformanceLogHeader->HobIsFull && PeiPerformanceLogHeader->SizeOfAllEntries + RecordInfo.RecordSize <= PeiPerformanceLogEntries * MAX_RECORD_SIZE) {
-      FpdtRecordPtr.RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)(PeiFirmwarePerformance + sizeof (FPDT_PEI_EXT_PERF_HEADER) + PeiPerformanceLogHeader->SizeOfAllEntries);
-      break;
-    }
-    //
-    // Previous HOB is used, then find next one.
-    //
-    GuidHob = GetNextGuidHob (&gEdkiiFpdtExtendedFirmwarePerformanceGuid, GET_NEXT_HOB (GuidHob));
-  }
-
-  if (GuidHob == NULL) {
-    //
-    // PEI Performance HOB was not found, then build one.
-    //
-    PeiPerformanceSize      = sizeof (FPDT_PEI_EXT_PERF_HEADER) +
-                              MAX_RECORD_SIZE * PeiPerformanceLogEntries;
-    PeiFirmwarePerformance  = (UINT8*)BuildGuidHob (&gEdkiiFpdtExtendedFirmwarePerformanceGuid, PeiPerformanceSize);
-    if (PeiFirmwarePerformance != NULL) {
-      ZeroMem (PeiFirmwarePerformance, PeiPerformanceSize);
-    }
-    PeiPerformanceLogHeader = (FPDT_PEI_EXT_PERF_HEADER *)PeiFirmwarePerformance;
-    FpdtRecordPtr.RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)(PeiFirmwarePerformance + sizeof (FPDT_PEI_EXT_PERF_HEADER));
-  }
-
-  if (PeiFirmwarePerformance == NULL) {
-    //
-    // there is no enough resource to store performance data
-    //
-    return EFI_OUT_OF_RESOURCES;
+  Status = GetFpdtRecordPtr (RecordInfo.RecordSize, &FpdtRecordPtr, &PeiPerformanceLogHeader);
+  if (EFI_ERROR (Status)) {
+    return Status;
   }
 
   //
   // Get the TimeStamp.
   //
@@ -690,5 +716,309 @@ PerformanceMeasurementEnabled (
   VOID
   )
 {
   return (BOOLEAN) ((PcdGet8(PcdPerformanceLibraryPropertyMask) & PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED) != 0);
 }
+
+/**
+  Get the FPDT record size.
+
+  @param  String                   Pointer to a Null-terminated ASCII string
+                                   that identifies the component being measured.
+  @param  PerfId                   Performance identifier.
+  @param  RecordSize               On return, pointer to the size of record.
+
+  @retval EFI_SUCCESS              Get record size successfully.
+  @retval EFI_INVALID_PARAMETER    Invalid Performance identifier.
+
+**/
+EFI_STATUS
+GetFpdtRecordSize (
+  IN CONST CHAR8                   *String,
+  IN       UINT16                  PerfId,
+  OUT      UINT8                   *RecordSize
+  )
+{
+  UINTN StringSize;
+
+  if (PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
+    *RecordSize = sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD) + STRING_SIZE;
+  } else {
+    switch (PerfId) {
+    case MODULE_START_ID:
+    case MODULE_END_ID:
+      *RecordSize = sizeof (FPDT_GUID_EVENT_RECORD);
+      break;
+
+    case MODULE_LOADIMAGE_START_ID:
+    case MODULE_LOADIMAGE_END_ID:
+      *RecordSize = sizeof (FPDT_GUID_QWORD_EVENT_RECORD);
+      break;
+
+    case PERF_EVENTSIGNAL_START_ID:
+    case PERF_EVENTSIGNAL_END_ID:
+    case PERF_CALLBACK_START_ID:
+    case PERF_CALLBACK_END_ID:
+      if (String == NULL) {
+        return EFI_INVALID_PARAMETER;
+      }
+      StringSize = AsciiStrSize (String);
+      if (StringSize > STRING_SIZE) {
+        StringSize = STRING_SIZE;
+      }
+      *RecordSize = (UINT8) (sizeof (FPDT_DUAL_GUID_STRING_EVENT_RECORD) + StringSize);
+      break;
+
+    case PERF_EVENT_ID:
+    case PERF_FUNCTION_START_ID:
+    case PERF_FUNCTION_END_ID:
+    case PERF_INMODULE_START_ID:
+    case PERF_INMODULE_END_ID:
+    case PERF_CROSSMODULE_START_ID:
+    case PERF_CROSSMODULE_END_ID:
+      if (String == NULL) {
+        return EFI_INVALID_PARAMETER;
+      }
+      StringSize = AsciiStrSize (String);
+      if (StringSize > STRING_SIZE) {
+        StringSize = STRING_SIZE;
+      }
+      *RecordSize = (UINT8) (sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD) + StringSize);
+      break;
+
+    default:
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  Create performance record with event description and a timestamp.
+
+  @param CallerIdentifier  - Image handle or pointer to caller ID GUID
+  @param Guid              - Pointer to a GUID
+  @param String            - Pointer to a string describing the measurement
+  @param Address           - Pointer to a location in memory relevant to the measurement
+  @param PerfId            - Performance identifier describing the type of measurement
+
+  @retval EFI_SUCCESS           - Successfully created performance record
+  @retval EFI_OUT_OF_RESOURCES  - Ran out of space to store the records
+  @retval EFI_INVALID_PARAMETER - Invalid parameter passed to function - NULL
+                                  pointer or invalid PerfId
+
+**/
+EFI_STATUS
+CreateFpdtRecord (
+  IN CONST VOID                    *CallerIdentifier,  OPTIONAL
+  IN CONST VOID                    *Guid,    OPTIONAL
+  IN CONST CHAR8                   *String,  OPTIONAL
+  IN       UINT64                  Address,  OPTIONAL
+  IN       UINT16                  PerfId
+  )
+{
+  FPDT_PEI_EXT_PERF_HEADER              *PeiPerformanceLogHeader;
+  FPDT_RECORD_PTR                       FpdtRecordPtr;
+  CONST CHAR8                           *StringPtr;
+  EFI_STATUS                            Status;
+  UINT64                                TimeStamp;
+  UINT64                                TimeStampCounter;
+  UINT8                                 RecordSize;
+  UINTN                                 DestMax;
+  UINTN                                 StringLen;
+
+  StringPtr     = NULL;
+  RecordSize    = 0;
+
+  Status = GetFpdtRecordSize(String, PerfId, &RecordSize);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = GetFpdtRecordPtr (RecordSize, &FpdtRecordPtr, &PeiPerformanceLogHeader);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Get the TimeStamp.
+  //
+  TimeStampCounter = GetPerformanceCounter ();
+  TimeStamp        = GetTimeInNanoSecond (TimeStampCounter);
+
+  switch (PerfId) {
+  case MODULE_START_ID:
+  case MODULE_END_ID:
+    if (CallerIdentifier == NULL) {
+      return EFI_INVALID_PARAMETER;
+    }
+    StringPtr = PEIM_TOK;
+    if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
+      FpdtRecordPtr.GuidEvent->Header.Type       = FPDT_GUID_EVENT_TYPE;
+      FpdtRecordPtr.GuidEvent->Header.Length     = RecordSize;;
+      FpdtRecordPtr.GuidEvent->Header.Revision   = FPDT_RECORD_REVISION_1;
+      FpdtRecordPtr.GuidEvent->ProgressID        = PerfId;
+      FpdtRecordPtr.GuidEvent->Timestamp         = TimeStamp;
+      CopyMem (&FpdtRecordPtr.GuidEvent->Guid, CallerIdentifier, sizeof (EFI_GUID));
+      PeiPerformanceLogHeader->SizeOfAllEntries += RecordSize;
+    }
+    break;
+
+  case MODULE_LOADIMAGE_START_ID:
+  case MODULE_LOADIMAGE_END_ID:
+    if (CallerIdentifier == NULL) {
+      return EFI_INVALID_PARAMETER;
+    }
+    StringPtr = LOAD_IMAGE_TOK;
+    if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
+      FpdtRecordPtr.GuidQwordEvent->Header.Type     = FPDT_GUID_QWORD_EVENT_TYPE;
+      FpdtRecordPtr.GuidQwordEvent->Header.Length   = RecordSize;;
+      FpdtRecordPtr.GuidQwordEvent->Header.Revision = FPDT_RECORD_REVISION_1;
+      FpdtRecordPtr.GuidQwordEvent->ProgressID      = PerfId;
+      FpdtRecordPtr.GuidQwordEvent->Timestamp       = TimeStamp;
+      if (PerfId == MODULE_LOADIMAGE_START_ID) {
+        PeiPerformanceLogHeader->LoadImageCount++;
+      }
+      FpdtRecordPtr.GuidQwordEvent->Qword           = PeiPerformanceLogHeader->LoadImageCount;
+      CopyMem (&FpdtRecordPtr.GuidQwordEvent->Guid, CallerIdentifier, sizeof (EFI_GUID));
+      PeiPerformanceLogHeader->SizeOfAllEntries += RecordSize;
+    }
+    break;
+
+  case PERF_EVENTSIGNAL_START_ID:
+  case PERF_EVENTSIGNAL_END_ID:
+  case PERF_CALLBACK_START_ID:
+  case PERF_CALLBACK_END_ID:
+    if (CallerIdentifier == NULL || Guid ==NULL || String == NULL) {
+      return EFI_INVALID_PARAMETER;
+    }
+    StringPtr = String;
+    if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
+      FpdtRecordPtr.DualGuidStringEvent->Header.Type      = FPDT_DUAL_GUID_STRING_EVENT_TYPE;
+      FpdtRecordPtr.DualGuidStringEvent->Header.Length    = RecordSize;
+      FpdtRecordPtr.DualGuidStringEvent->Header.Revision  = FPDT_RECORD_REVISION_1;
+      FpdtRecordPtr.DualGuidStringEvent->ProgressID       = PerfId;
+      FpdtRecordPtr.DualGuidStringEvent->Timestamp        = TimeStamp;
+      CopyMem (&FpdtRecordPtr.DualGuidStringEvent->Guid1, CallerIdentifier, sizeof (FpdtRecordPtr.DualGuidStringEvent->Guid1));
+      CopyMem (&FpdtRecordPtr.DualGuidStringEvent->Guid2, Guid, sizeof (FpdtRecordPtr.DualGuidStringEvent->Guid2));
+      DestMax = (RecordSize - sizeof (FPDT_DUAL_GUID_STRING_EVENT_RECORD)) / sizeof (CHAR8);
+      StringLen = AsciiStrLen (StringPtr);
+      if (StringLen >= DestMax) {
+        StringLen = DestMax -1;
+      }
+      AsciiStrnCpyS (FpdtRecordPtr.DualGuidStringEvent->String, DestMax, StringPtr, StringLen);
+      PeiPerformanceLogHeader->SizeOfAllEntries += RecordSize;
+    }
+    break;
+
+  case PERF_EVENT_ID:
+  case PERF_FUNCTION_START_ID:
+  case PERF_FUNCTION_END_ID:
+  case PERF_INMODULE_START_ID:
+  case PERF_INMODULE_END_ID:
+  case PERF_CROSSMODULE_START_ID:
+  case PERF_CROSSMODULE_END_ID:
+    if (CallerIdentifier == NULL || String == NULL) {
+      return EFI_INVALID_PARAMETER;
+    }
+    StringPtr = String;
+    if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
+      FpdtRecordPtr.DynamicStringEvent->Header.Type       = FPDT_DYNAMIC_STRING_EVENT_TYPE;
+      FpdtRecordPtr.DynamicStringEvent->Header.Length     = RecordSize;
+      FpdtRecordPtr.DynamicStringEvent->Header.Revision   = FPDT_RECORD_REVISION_1;
+      FpdtRecordPtr.DynamicStringEvent->ProgressID        = PerfId;
+      FpdtRecordPtr.DynamicStringEvent->Timestamp         = TimeStamp;
+      CopyMem (&FpdtRecordPtr.DynamicStringEvent->Guid, CallerIdentifier, sizeof (EFI_GUID));
+      DestMax = (RecordSize - sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD)) / sizeof (CHAR8);
+      StringLen = AsciiStrLen (StringPtr);
+      if (StringLen >= DestMax) {
+        StringLen = DestMax -1;
+      }
+      AsciiStrnCpyS (FpdtRecordPtr.DynamicStringEvent->String, DestMax, StringPtr, StringLen);
+      PeiPerformanceLogHeader->SizeOfAllEntries += RecordSize;
+    }
+    break;
+
+  default:
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
+    FpdtRecordPtr.DynamicStringEvent->Header.Type       = FPDT_DYNAMIC_STRING_EVENT_TYPE;
+    FpdtRecordPtr.DynamicStringEvent->Header.Length     = RecordSize;
+    FpdtRecordPtr.DynamicStringEvent->Header.Revision   = FPDT_RECORD_REVISION_1;
+    FpdtRecordPtr.DynamicStringEvent->ProgressID        = PerfId;
+    FpdtRecordPtr.DynamicStringEvent->Timestamp         = TimeStamp;
+    if (Guid != NULL) {
+      //
+      // Cache the event guid in string event record.
+      //
+      CopyMem (&FpdtRecordPtr.DynamicStringEvent->Guid, Guid, sizeof (EFI_GUID));
+    } else {
+      CopyMem (&FpdtRecordPtr.DynamicStringEvent->Guid, CallerIdentifier, sizeof (EFI_GUID));
+    }
+    DestMax = (RecordSize - sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD)) / sizeof (CHAR8);
+    StringLen = AsciiStrLen (StringPtr);
+    if (StringLen >= DestMax) {
+      StringLen = DestMax -1;
+    }
+    AsciiStrnCpyS (FpdtRecordPtr.DynamicStringEvent->String, DestMax, StringPtr, StringLen);
+    PeiPerformanceLogHeader->SizeOfAllEntries += RecordSize;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Create performance record with event description and a timestamp.
+
+  @param CallerIdentifier  - Image handle or pointer to caller ID GUID
+  @param Guid              - Pointer to a GUID
+  @param String            - Pointer to a string describing the measurement
+  @param Address           - Pointer to a location in memory relevant to the measurement
+  @param Identifier        - Performance identifier describing the type of measurement
+
+  @retval RETURN_SUCCESS           - Successfully created performance record
+  @retval RETURN_OUT_OF_RESOURCES  - Ran out of space to store the records
+  @retval RETURN_INVALID_PARAMETER - Invalid parameter passed to function - NULL
+                                     pointer or invalid PerfId
+
+**/
+RETURN_STATUS
+EFIAPI
+LogPerformanceMeasurement (
+  IN CONST VOID   *CallerIdentifier,
+  IN CONST VOID   *Guid,    OPTIONAL
+  IN CONST CHAR8  *String,  OPTIONAL
+  IN UINT64       Address, OPTIONAL
+  IN UINT32       Identifier
+  )
+{
+  return (RETURN_STATUS)CreateFpdtRecord (CallerIdentifier, Guid, String, Address, (UINT16)Identifier);
+}
+
+/**
+  Check whether the specified performance measurement can be logged.
+
+  This function returns TRUE when the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set
+  and the Type disable bit in PcdPerformanceLibraryPropertyMask is not set.
+
+  @param Type        - Type of the performance measurement entry.
+
+  @retval TRUE         The performance measurement can be logged.
+  @retval FALSE        The performance measurement can NOT be logged.
+
+**/
+BOOLEAN
+EFIAPI
+LogPerformanceMeasurementEnabled (
+  IN  CONST UINTN        Type
+  )
+{
+  //
+  // When Performance measurement is enabled and the type is not filtered, the performance can be logged.
+  //
+  if (PerformanceMeasurementEnabled () && (PcdGet8(PcdPerformanceLibraryPropertyMask) & Type) == 0) {
+    return TRUE;
+  }
+  return FALSE;
+}
diff --git a/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.c b/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.c
index e630773562f..efbde88220b 100644
--- a/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.c
+++ b/MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.c
@@ -45,23 +45,83 @@ typedef struct {
 HANDLE_GUID_MAP      mCacheHandleGuidTable[CACHE_HANDLE_GUID_COUNT];
 UINTN                mCachePairCount = 0;
 
 UINT32               mPerformanceLength    = 0;
 UINT32               mMaxPerformanceLength = 0;
+UINT32               mLoadImageCount       = 0;
 BOOLEAN              mFpdtDataIsReported   = FALSE;
 BOOLEAN              mLackSpaceIsReport    = FALSE;
 CHAR8                *mPlatformLanguage    = NULL;
 SPIN_LOCK            mSmmFpdtLock;
 PERFORMANCE_PROPERTY  mPerformanceProperty;
+UINT32               mCachedLength         = 0;
 
 //
 // Interfaces for SMM PerformanceMeasurement Protocol.
 //
 EDKII_PERFORMANCE_MEASUREMENT_PROTOCOL mPerformanceMeasurementInterface = {
   CreatePerformanceMeasurement,
 };
 
+/**
+  Return the pointer to the FPDT record in the allocated memory.
+
+  @param  RecordSize             The size of FPDT record.
+  @param  FpdtRecordPtr          Pointer the FPDT record in the allocated memory.
+
+  @retval EFI_SUCCESS            Successfully get the pointer to the FPDT record.
+  @retval EFI_OUT_OF_RESOURCES   Ran out of space to store the records.
+**/
+EFI_STATUS
+GetFpdtRecordPtr (
+  IN     UINT8               RecordSize,
+  IN OUT FPDT_RECORD_PTR     *FpdtRecordPtr
+)
+{
+  if (mFpdtDataIsReported) {
+    //
+    // Append Boot records after Smm boot performance records have been reported.
+    //
+    if (mPerformanceLength + RecordSize > mMaxPerformanceLength) {
+      if (!mLackSpaceIsReport) {
+        DEBUG ((DEBUG_INFO, "SmmCorePerformanceLib: No enough space to save boot records\n"));
+        mLackSpaceIsReport = TRUE;
+      }
+      return EFI_OUT_OF_RESOURCES;
+    } else {
+      //
+      // Covert buffer to FPDT Ptr Union type.
+      //
+      FpdtRecordPtr->RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)((UINT8*)mSmmBootPerformanceTable + mSmmBootPerformanceTable->Header.Length);
+    }
+  } else {
+    //
+    // Check if pre-allocated buffer is full
+    //
+    if (mPerformanceLength + RecordSize > mMaxPerformanceLength) {
+      mSmmBootPerformanceTable = ReallocatePool (
+                                   mPerformanceLength,
+                                   mPerformanceLength + sizeof (SMM_BOOT_PERFORMANCE_TABLE) + RecordSize + FIRMWARE_RECORD_BUFFER,
+                                   mSmmBootPerformanceTable
+                              );
+
+      if (mSmmBootPerformanceTable == NULL) {
+        return EFI_OUT_OF_RESOURCES;
+      }
+      mSmmBootPerformanceTable->Header.Length = sizeof (SMM_BOOT_PERFORMANCE_TABLE) + mPerformanceLength;
+      mMaxPerformanceLength = mPerformanceLength + sizeof (SMM_BOOT_PERFORMANCE_TABLE) + RecordSize + FIRMWARE_RECORD_BUFFER;
+    }
+    //
+    // Covert buffer to FPDT Ptr Union type.
+    //
+    FpdtRecordPtr->RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)((UINT8*)mSmmBootPerformanceTable + mSmmBootPerformanceTable->Header.Length);
+  }
+  FpdtRecordPtr->RecordHeader->Length = 0;
+  return EFI_SUCCESS;
+}
+
+
 /**
 Check whether the Token is a known one which is uesed by core.
 
 @param  Token      Pointer to a Null-terminated ASCII string
 
@@ -506,49 +566,14 @@ InsertFpdtMeasurement (
       Identifier += 1;
     }
     RecordInfo.ProgressID = (UINT16)Identifier;
   }
 
-  if (mFpdtDataIsReported) {
-    //
-    // Append Boot records after Smm boot performance records have been reported.
-    //
-    if (mPerformanceLength + RecordInfo.RecordSize > mMaxPerformanceLength) {
-      if (!mLackSpaceIsReport) {
-        DEBUG ((DEBUG_INFO, "SmmCorePerformanceLib: No enough space to save boot records\n"));
-        mLackSpaceIsReport = TRUE;
-      }
-      return EFI_OUT_OF_RESOURCES;
-    } else {
-      //
-      // Covert buffer to FPDT Ptr Union type.
-      //
-      FpdtRecordPtr.RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)((UINT8*)mSmmBootPerformanceTable + mSmmBootPerformanceTable->Header.Length);
-    }
-  } else {
-    //
-    // Check if pre-allocated buffer is full
-    //
-    if (mPerformanceLength + RecordInfo.RecordSize > mMaxPerformanceLength) {
-      mSmmBootPerformanceTable = ReallocatePool (
-                                   mPerformanceLength,
-                                   mPerformanceLength + sizeof (SMM_BOOT_PERFORMANCE_TABLE) + RecordInfo.RecordSize + FIRMWARE_RECORD_BUFFER,
-                                   mSmmBootPerformanceTable
-                              );
-
-      if (mSmmBootPerformanceTable == NULL) {
-        return EFI_OUT_OF_RESOURCES;
-      }
-      mSmmBootPerformanceTable->Header.Length = sizeof (SMM_BOOT_PERFORMANCE_TABLE) + mPerformanceLength;
-      mMaxPerformanceLength = mPerformanceLength + sizeof (SMM_BOOT_PERFORMANCE_TABLE) + RecordInfo.RecordSize + FIRMWARE_RECORD_BUFFER;
-    }
-    //
-    // Covert buffer to FPDT Ptr Union type.
-    //
-    FpdtRecordPtr.RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)((UINT8*)mSmmBootPerformanceTable + mSmmBootPerformanceTable->Header.Length);
+  Status = GetFpdtRecordPtr (RecordInfo.RecordSize, &FpdtRecordPtr);
+  if (EFI_ERROR (Status)) {
+    return Status;
   }
-  FpdtRecordPtr.RecordHeader->Length = 0;
 
   //
   // Get the TimeStamp.
   //
   if (Ticker == 0) {
@@ -630,10 +655,289 @@ InsertFpdtMeasurement (
   mSmmBootPerformanceTable->Header.Length += FpdtRecordPtr.RecordHeader->Length;
 
   return EFI_SUCCESS;
 }
 
+/**
+  Get the FPDT record size.
+
+  @param  String                   Pointer to a Null-terminated ASCII string
+                                   that identifies the component being measured.
+  @param  PerfId                   Performance identifier.
+  @param  RecordSize               On return, pointer to the size of record.
+
+  @retval EFI_SUCCESS              Get record size successfully.
+  @retval EFI_INVALID_PARAMETER    Invalid Performance identifier.
+
+**/
+EFI_STATUS
+GetFpdtRecordSize (
+  IN CONST CHAR8                   *String,
+  IN       UINT16                  PerfId,
+  OUT      UINT8                   *RecordSize
+  )
+{
+  UINTN    StringSize;
+
+  if (PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
+    *RecordSize = (UINT8)(sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD) + STRING_SIZE);
+  } else {
+    switch (PerfId) {
+    case MODULE_START_ID:
+    case MODULE_END_ID:
+      *RecordSize = sizeof (FPDT_GUID_EVENT_RECORD);
+      break;
+
+    case MODULE_LOADIMAGE_START_ID:
+    case MODULE_LOADIMAGE_END_ID:
+      *RecordSize = sizeof (FPDT_GUID_QWORD_EVENT_RECORD);
+      break;
+
+    case PERF_EVENTSIGNAL_START_ID:
+    case PERF_EVENTSIGNAL_END_ID:
+    case PERF_CALLBACK_START_ID:
+    case PERF_CALLBACK_END_ID:
+      if (String == NULL) {
+        return EFI_INVALID_PARAMETER;
+      }
+      StringSize = AsciiStrSize (String);
+      if (StringSize > STRING_SIZE) {
+        StringSize = STRING_SIZE;
+      }
+      *RecordSize = (UINT8) (sizeof (FPDT_DUAL_GUID_STRING_EVENT_RECORD) + StringSize);
+      break;
+
+    case PERF_EVENT_ID:
+    case PERF_FUNCTION_START_ID:
+    case PERF_FUNCTION_END_ID:
+    case PERF_INMODULE_START_ID:
+    case PERF_INMODULE_END_ID:
+    case PERF_CROSSMODULE_START_ID:
+    case PERF_CROSSMODULE_END_ID:
+      if (String == NULL) {
+        return EFI_INVALID_PARAMETER;
+      }
+      StringSize = AsciiStrSize (String);
+      if (StringSize > STRING_SIZE) {
+        StringSize = STRING_SIZE;
+      }
+      *RecordSize = (UINT8) (sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD) + StringSize);
+      break;
+
+    default:
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  Create performance record with event description and a timestamp.
+
+  @param CallerIdentifier  - Image handle or pointer to caller ID GUID
+  @param Guid              - Pointer to a GUID
+  @param String            - Pointer to a string describing the measurement
+  @param Address           - Pointer to a location in memory relevant to the measurement
+  @param PerfId            - Performance identifier describing the type of measurement
+
+  @retval EFI_SUCCESS           - Successfully created performance record
+  @retval EFI_OUT_OF_RESOURCES  - Ran out of space to store the records
+  @retval EFI_INVALID_PARAMETER - Invalid parameter passed to function - NULL
+                                  pointer or invalid PerfId
+
+**/
+EFI_STATUS
+InsertFpdtRecord (
+  IN CONST VOID                    *CallerIdentifier,  OPTIONAL
+  IN CONST VOID                    *Guid,    OPTIONAL
+  IN CONST CHAR8                   *String,  OPTIONAL
+  IN       UINT64                  Address,  OPTIONAL
+  IN       UINT16                  PerfId
+  )
+{
+  EFI_STATUS                   Status;
+  EFI_GUID                     ModuleGuid;
+  CHAR8                        ModuleName[FPDT_STRING_EVENT_RECORD_NAME_LENGTH];
+  FPDT_RECORD_PTR              FpdtRecordPtr;
+  FPDT_RECORD_PTR              CachedFpdtRecordPtr;
+  UINT64                       TimeStamp;
+  UINT64                       TimeStampCounter;
+  CONST CHAR8                  *StringPtr;
+  UINT8                        RecordSize;
+  UINTN                        DestMax;
+  UINTN                        StringLen;
+
+  StringPtr     = NULL;
+  RecordSize    = 0;
+  ZeroMem (ModuleName, sizeof (ModuleName));
+
+  Status = GetFpdtRecordSize(String, PerfId, &RecordSize);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = GetFpdtRecordPtr (RecordSize, &FpdtRecordPtr);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Get the TimeStamp.
+  //
+  TimeStampCounter = GetPerformanceCounter ();
+  TimeStamp        = GetTimeInNanoSecond (TimeStampCounter);
+
+  switch (PerfId) {
+  case MODULE_START_ID:
+  case MODULE_END_ID:
+    //
+    // Get the ModuleGuid from the handle.
+    //
+    GetModuleInfoFromHandle ((EFI_HANDLE *)CallerIdentifier, ModuleName, sizeof (ModuleName), &ModuleGuid);
+    StringPtr = ModuleName;
+    if (PerfId == MODULE_START_ID) {
+      mCachedLength = mSmmBootPerformanceTable->Header.Length;
+    }
+    if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
+      FpdtRecordPtr.GuidEvent->Header.Type                = FPDT_GUID_EVENT_TYPE;
+      FpdtRecordPtr.GuidEvent->Header.Length              = RecordSize;
+      FpdtRecordPtr.GuidEvent->Header.Revision            = FPDT_RECORD_REVISION_1;
+      FpdtRecordPtr.GuidEvent->ProgressID                 = PerfId;
+      FpdtRecordPtr.GuidEvent->Timestamp                  = TimeStamp;
+      CopyMem (&FpdtRecordPtr.GuidEvent->Guid, &ModuleGuid, sizeof (FpdtRecordPtr.GuidEvent->Guid));
+      if (PerfId == MODULE_END_ID && mCachedLength != 0) {
+        CachedFpdtRecordPtr.RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)((UINT8*)mSmmBootPerformanceTable + mCachedLength);
+        CopyMem (&CachedFpdtRecordPtr.GuidEvent->Guid, &ModuleGuid, sizeof (CachedFpdtRecordPtr.GuidEvent->Guid));
+        mCachedLength = 0;
+      }
+    }
+    break;
+
+  case MODULE_LOADIMAGE_START_ID:
+  case MODULE_LOADIMAGE_END_ID:
+    GetModuleInfoFromHandle ((EFI_HANDLE *)CallerIdentifier, ModuleName, sizeof (ModuleName), &ModuleGuid);
+    StringPtr = ModuleName;
+    if (PerfId == MODULE_LOADIMAGE_START_ID) {
+      mLoadImageCount++;
+      mCachedLength = mSmmBootPerformanceTable->Header.Length;
+    }
+    if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
+      FpdtRecordPtr.GuidQwordEvent->Header.Type           = FPDT_GUID_QWORD_EVENT_TYPE;
+      FpdtRecordPtr.GuidQwordEvent->Header.Length         = RecordSize;
+      FpdtRecordPtr.GuidQwordEvent->Header.Revision       = FPDT_RECORD_REVISION_1;
+      FpdtRecordPtr.GuidQwordEvent->ProgressID            = PerfId;
+      FpdtRecordPtr.GuidQwordEvent->Timestamp             = TimeStamp;
+      FpdtRecordPtr.GuidQwordEvent->Qword                 = mLoadImageCount;
+      CopyMem (&FpdtRecordPtr.GuidQwordEvent->Guid, &ModuleGuid, sizeof (FpdtRecordPtr.GuidQwordEvent->Guid));
+      if (PerfId == MODULE_LOADIMAGE_END_ID && mCachedLength != 0) {
+        CachedFpdtRecordPtr.RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)((UINT8*)mSmmBootPerformanceTable + mCachedLength);
+        CopyMem (&CachedFpdtRecordPtr.GuidQwordEvent->Guid, &ModuleGuid, sizeof (CachedFpdtRecordPtr.GuidQwordEvent->Guid));
+        mCachedLength = 0;
+      }
+    }
+    break;
+
+  case PERF_EVENTSIGNAL_START_ID:
+  case PERF_EVENTSIGNAL_END_ID:
+  case PERF_CALLBACK_START_ID:
+  case PERF_CALLBACK_END_ID:
+    if (CallerIdentifier == NULL || Guid ==NULL || String == NULL) {
+      return EFI_INVALID_PARAMETER;
+    }
+    //
+    // Cache the event guid in string event record when PcdEdkiiFpdtStringRecordEnableOnly == TRUE
+    //
+    CopyGuid (&ModuleGuid, Guid);
+    StringPtr = String;
+    if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
+      FpdtRecordPtr.DualGuidStringEvent->Header.Type      = FPDT_DUAL_GUID_STRING_EVENT_TYPE;
+      FpdtRecordPtr.DualGuidStringEvent->Header.Length    = RecordSize;
+      FpdtRecordPtr.DualGuidStringEvent->Header.Revision  = FPDT_RECORD_REVISION_1;
+      FpdtRecordPtr.DualGuidStringEvent->ProgressID       = PerfId;
+      FpdtRecordPtr.DualGuidStringEvent->Timestamp        = TimeStamp;
+      CopyMem (&FpdtRecordPtr.DualGuidStringEvent->Guid1, CallerIdentifier, sizeof (FpdtRecordPtr.DualGuidStringEvent->Guid1));
+      CopyMem (&FpdtRecordPtr.DualGuidStringEvent->Guid2, Guid, sizeof (FpdtRecordPtr.DualGuidStringEvent->Guid2));
+      DestMax = (RecordSize - sizeof (FPDT_DUAL_GUID_STRING_EVENT_RECORD)) / sizeof (CHAR8);
+      StringLen = AsciiStrLen (StringPtr);
+      if (StringLen >= DestMax) {
+        StringLen = DestMax -1;
+      }
+      AsciiStrnCpyS (FpdtRecordPtr.DualGuidStringEvent->String, DestMax, StringPtr, StringLen);
+    }
+    break;
+
+  case PERF_EVENT_ID:
+  case PERF_FUNCTION_START_ID:
+  case PERF_FUNCTION_END_ID:
+  case PERF_INMODULE_START_ID:
+  case PERF_INMODULE_END_ID:
+  case PERF_CROSSMODULE_START_ID:
+  case PERF_CROSSMODULE_END_ID:
+    if (CallerIdentifier == NULL || String == NULL) {
+      return EFI_INVALID_PARAMETER;
+    }
+    CopyGuid (&ModuleGuid, (EFI_GUID *) CallerIdentifier);
+    StringPtr = String;
+    if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
+      FpdtRecordPtr.DynamicStringEvent->Header.Type       = FPDT_DYNAMIC_STRING_EVENT_TYPE;
+      FpdtRecordPtr.DynamicStringEvent->Header.Length     = RecordSize;
+      FpdtRecordPtr.DynamicStringEvent->Header.Revision   = FPDT_RECORD_REVISION_1;
+      FpdtRecordPtr.DynamicStringEvent->ProgressID        = PerfId;
+      FpdtRecordPtr.DynamicStringEvent->Timestamp         = TimeStamp;
+      CopyMem (&FpdtRecordPtr.DynamicStringEvent->Guid, CallerIdentifier, sizeof (FpdtRecordPtr.DynamicStringEvent->Guid));
+      DestMax = (RecordSize - sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD)) / sizeof (CHAR8);
+      StringLen = AsciiStrLen (StringPtr);
+      if (StringLen >= DestMax) {
+        StringLen = DestMax -1;
+      }
+      AsciiStrnCpyS (FpdtRecordPtr.DynamicStringEvent->String, DestMax, StringPtr, StringLen);
+    }
+    break;
+
+  default:
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
+    FpdtRecordPtr.DynamicStringEvent->Header.Type       = FPDT_DYNAMIC_STRING_EVENT_TYPE;
+    FpdtRecordPtr.DynamicStringEvent->Header.Length     = RecordSize;
+    FpdtRecordPtr.DynamicStringEvent->Header.Revision   = FPDT_RECORD_REVISION_1;
+    FpdtRecordPtr.DynamicStringEvent->ProgressID        = PerfId;
+    FpdtRecordPtr.DynamicStringEvent->Timestamp         = TimeStamp;
+    DestMax = (RecordSize - sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD)) / sizeof (CHAR8);
+    if (StringPtr != NULL && AsciiStrLen (StringPtr) == 0) {
+      StringPtr = "unknown name";
+    }
+    if (StringPtr != NULL) {
+      StringLen = AsciiStrLen (StringPtr);
+      if (StringLen >= DestMax) {
+        StringLen = DestMax -1;
+      }
+    }
+
+    CopyMem (&FpdtRecordPtr.DynamicStringEvent->Guid, &ModuleGuid, sizeof (FpdtRecordPtr.DynamicStringEvent->Guid));
+    AsciiStrnCpyS (FpdtRecordPtr.DynamicStringEvent->String, DestMax, StringPtr, StringLen);
+
+    if ((PerfId == MODULE_LOADIMAGE_END_ID) || (PerfId == MODULE_END_ID)) {
+      if (mCachedLength != 0) {
+        CachedFpdtRecordPtr.RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)((UINT8*)mSmmBootPerformanceTable + mCachedLength);
+        CopyMem (&CachedFpdtRecordPtr.DynamicStringEvent->Guid, &ModuleGuid, sizeof (CachedFpdtRecordPtr.DynamicStringEvent->Guid));
+        AsciiStrnCpyS (CachedFpdtRecordPtr.DynamicStringEvent->String, DestMax, StringPtr, StringLen);
+        mCachedLength = 0;
+      }
+    }
+  }
+
+  //
+  // Update the cached FPDT record buffer.
+  //
+  mPerformanceLength += FpdtRecordPtr.RecordHeader->Length;
+  mSmmBootPerformanceTable->Header.Length += FpdtRecordPtr.RecordHeader->Length;
+
+  return EFI_SUCCESS;
+}
+
 /**
   SmmReadyToBoot protocol notification event handler.
 
   @param  Protocol   Points to the protocol's unique identifier
   @param  Interface  Points to the interface instance
@@ -814,15 +1118,19 @@ CreatePerformanceMeasurement(
   IN       PERF_MEASUREMENT_ATTRIBUTE  Attribute
   )
 {
   EFI_STATUS   Status;
 
+  Status = EFI_SUCCESS;
+
   AcquireSpinLock (&mSmmFpdtLock);
   if (Attribute == PerfStartEntry) {
     Status = InsertFpdtMeasurement (TRUE, CallerIdentifier, String, String, TimeStamp, Identifier);
   } else if (Attribute == PerfEndEntry) {
     Status = InsertFpdtMeasurement (FALSE, CallerIdentifier, String, String, TimeStamp, Identifier);
+  } else if (Attribute == PerfEntry) {
+    Status = InsertFpdtRecord (CallerIdentifier, Guid, String, Address, (UINT16) Identifier);
   }
   ReleaseSpinLock (&mSmmFpdtLock);
   return Status;
 }
 
@@ -1125,5 +1433,61 @@ PerformanceMeasurementEnabled (
   VOID
   )
 {
   return (BOOLEAN) ((PcdGet8(PcdPerformanceLibraryPropertyMask) & PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED) != 0);
 }
+
+/**
+  Create performance record with event description and a timestamp.
+
+  @param CallerIdentifier  - Image handle or pointer to caller ID GUID
+  @param Guid              - Pointer to a GUID
+  @param String            - Pointer to a string describing the measurement
+  @param Address           - Pointer to a location in memory relevant to the measurement
+  @param Identifier        - Performance identifier describing the type of measurement
+
+  @retval RETURN_SUCCESS           - Successfully created performance record
+  @retval RETURN_OUT_OF_RESOURCES  - Ran out of space to store the records
+  @retval RETURN_INVALID_PARAMETER - Invalid parameter passed to function - NULL
+                                     pointer or invalid PerfId
+
+**/
+RETURN_STATUS
+EFIAPI
+LogPerformanceMeasurement (
+  IN CONST VOID   *CallerIdentifier,
+  IN CONST VOID   *Guid,    OPTIONAL
+  IN CONST CHAR8  *String,  OPTIONAL
+  IN UINT64       Address, OPTIONAL
+  IN UINT32       Identifier
+  )
+{
+  return (RETURN_STATUS)CreatePerformanceMeasurement (CallerIdentifier, Guid, String, 0, Address, Identifier, PerfEntry);
+}
+
+/**
+  Check whether the specified performance measurement can be logged.
+
+  This function returns TRUE when the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set
+  and the Type disable bit in PcdPerformanceLibraryPropertyMask is not set.
+
+  @param Type        - Type of the performance measurement entry.
+
+  @retval TRUE         The performance measurement can be logged.
+  @retval FALSE        The performance measurement can NOT be logged.
+
+**/
+BOOLEAN
+EFIAPI
+LogPerformanceMeasurementEnabled (
+  IN  CONST UINTN        Type
+  )
+{
+  //
+  // When Performance measurement is enabled and the type is not filtered, the performance can be logged.
+  //
+  if (PerformanceMeasurementEnabled () && (PcdGet8(PcdPerformanceLibraryPropertyMask) & Type) == 0) {
+    return TRUE;
+  }
+  return FALSE;
+}
+
diff --git a/MdeModulePkg/Library/SmmPerformanceLib/SmmPerformanceLib.c b/MdeModulePkg/Library/SmmPerformanceLib/SmmPerformanceLib.c
index fd820c0e49c..830037befa6 100644
--- a/MdeModulePkg/Library/SmmPerformanceLib/SmmPerformanceLib.c
+++ b/MdeModulePkg/Library/SmmPerformanceLib/SmmPerformanceLib.c
@@ -395,5 +395,73 @@ PerformanceMeasurementEnabled (
   VOID
   )
 {
   return mPerformanceMeasurementEnabled;
 }
+
+/**
+  Create performance record with event description and a timestamp.
+
+  @param CallerIdentifier  - Image handle or pointer to caller ID GUID
+  @param Guid              - Pointer to a GUID
+  @param String            - Pointer to a string describing the measurement
+  @param Address           - Pointer to a location in memory relevant to the measurement
+  @param Identifier        - Performance identifier describing the type of measurement
+
+  @retval RETURN_SUCCESS           - Successfully created performance record
+  @retval RETURN_OUT_OF_RESOURCES  - Ran out of space to store the records
+  @retval RETURN_INVALID_PARAMETER - Invalid parameter passed to function - NULL
+                                     pointer or invalid PerfId
+
+**/
+RETURN_STATUS
+EFIAPI
+LogPerformanceMeasurement (
+  IN CONST VOID   *CallerIdentifier,
+  IN CONST VOID   *Guid,    OPTIONAL
+  IN CONST CHAR8  *String,  OPTIONAL
+  IN UINT64       Address, OPTIONAL
+  IN UINT32       Identifier
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = GetPerformanceMeasurementProtocol ();
+  if (EFI_ERROR (Status)) {
+    return RETURN_OUT_OF_RESOURCES;
+  }
+
+  if (mPerformanceMeasurement != NULL) {
+    Status = mPerformanceMeasurement->CreatePerformanceMeasurement (CallerIdentifier, Guid, String, 0, Address, Identifier, PerfEntry);
+  } else {
+    ASSERT (FALSE);
+  }
+
+  return (RETURN_STATUS) Status;
+}
+
+/**
+  Check whether the specified performance measurement can be logged.
+
+  This function returns TRUE when the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set
+  and the Type disable bit in PcdPerformanceLibraryPropertyMask is not set.
+
+  @param Type        - Type of the performance measurement entry.
+
+  @retval TRUE         The performance measurement can be logged.
+  @retval FALSE        The performance measurement can NOT be logged.
+
+**/
+BOOLEAN
+EFIAPI
+LogPerformanceMeasurementEnabled (
+  IN  CONST UINTN        Type
+  )
+{
+  //
+  // When Performance measurement is enabled and the type is not filtered, the performance can be logged.
+  //
+  if (PerformanceMeasurementEnabled () && (PcdGet8(PcdPerformanceLibraryPropertyMask) & Type) == 0) {
+    return TRUE;
+  }
+  return FALSE;
+}
-- 
2.14.3.windows.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [patch 6/9] ShellPkg/dp: Update dp tool to parse new Perf record
  2018-06-19  7:23 [patch 0/9] Add new Perf macros Dandan Bi
                   ` (4 preceding siblings ...)
  2018-06-19  7:24 ` [patch 5/9] MdeModulePkg: Update performance library instances Dandan Bi
@ 2018-06-19  7:24 ` Dandan Bi
  2018-06-19  7:24 ` [patch 7/9] MdeModulePkg: Use new added Perf macros Dandan Bi
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Dandan Bi @ 2018-06-19  7:24 UTC (permalink / raw)
  To: edk2-devel; +Cc: Liming Gao, Ruiyu Ni

Since performance library instances have been updated
to create new FPDT records for new Perf macros.
So enhance dp tool to parse the new FPDT records.
Enhancement mainly includes:
1. parse the single records for PERF_EVENT macro
2. Parse the new added FPDT_DUAL_GUID_STRING_EVENT_RECORD

Cc: Liming Gao <liming.gao@intel.com>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Dandan Bi <dandan.bi@intel.com>
---
 ShellPkg/DynamicCommand/DpDynamicCommand/Dp.c | 75 +++++++++++++++++++++++----
 ShellPkg/DynamicCommand/DpDynamicCommand/Dp.h |  1 +
 2 files changed, 66 insertions(+), 10 deletions(-)

diff --git a/ShellPkg/DynamicCommand/DpDynamicCommand/Dp.c b/ShellPkg/DynamicCommand/DpDynamicCommand/Dp.c
index 38766613175..925341303a4 100644
--- a/ShellPkg/DynamicCommand/DpDynamicCommand/Dp.c
+++ b/ShellPkg/DynamicCommand/DpDynamicCommand/Dp.c
@@ -428,15 +428,29 @@ GetMeasurementInfo (
       break;
     default:
       ASSERT(FALSE);
     }
 
-    if (AsciiStrCmp (Measurement->Token, ALit_PEIM) == 0) {
-      Measurement->Handle         = &(((FPDT_GUID_EVENT_RECORD *)RecordHeader)->Guid);
+    if (Measurement->Token != NULL && AsciiStrCmp (Measurement->Token, ALit_PEIM) == 0) {
+      Measurement->Handle         = &(((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Guid);
     } else {
       GetHandleFormModuleGuid(ModuleGuid, &StartHandle);
-      Measurement->Handle         = StartHandle;
+      Measurement->Handle = StartHandle;
+      //
+      // When no perf entry to record the PEI and DXE phase,
+      // For start image, we need detect the PEIM and non PEIM here.
+      //
+      if (Measurement->Token == NULL) {
+        if (StartHandle == NULL && !IsZeroGuid (ModuleGuid)) {
+          Measurement->Token      = ALit_PEIM;
+          Measurement->Module     = ALit_PEIM;
+          Measurement->Handle     = ModuleGuid;
+        } else {
+          Measurement->Token      = ALit_START_IMAGE;
+          Measurement->Module     = ALit_START_IMAGE;
+        }
+      }
     }
     break;
 
   case FPDT_DYNAMIC_STRING_EVENT_TYPE:
     ModuleGuid                    = &(((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Guid);
@@ -481,15 +495,27 @@ GetMeasurementInfo (
       break;
     }
 
     Measurement->Module           = ((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->String;
 
-    if (AsciiStrCmp (Measurement->Token, ALit_PEIM) == 0) {
+    if (Measurement->Token != NULL && AsciiStrCmp (Measurement->Token, ALit_PEIM) == 0) {
       Measurement->Handle         = &(((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Guid);
     } else {
       GetHandleFormModuleGuid(ModuleGuid, &StartHandle);
       Measurement->Handle = StartHandle;
+      //
+      // When no perf entry to record the PEI and DXE phase,
+      // For start image, we need detect the PEIM and non PEIM here.
+      //
+      if (Measurement->Token == NULL  && (Measurement->Identifier == MODULE_START_ID || Measurement->Identifier == MODULE_END_ID)) {
+        if (StartHandle == NULL && !IsZeroGuid (ModuleGuid)) {
+          Measurement->Token      = ALit_PEIM;
+          Measurement->Handle     = ModuleGuid;
+        } else {
+          Measurement->Token      = ALit_START_IMAGE;
+        }
+      }
     }
     break;
 
   case FPDT_GUID_QWORD_EVENT_TYPE:
     ModuleGuid                    = &(((FPDT_GUID_QWORD_EVENT_RECORD *)RecordHeader)->Guid);
@@ -551,10 +577,24 @@ GetMeasurementInfo (
     }
     GetHandleFormModuleGuid(ModuleGuid, &StartHandle);
     Measurement->Handle = StartHandle;
     break;
 
+  case FPDT_DUAL_GUID_STRING_EVENT_TYPE:
+    ModuleGuid                    = &(((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->Guid1);
+    Measurement->Identifier       = ((UINT32)((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->ProgressID);
+    if (IsStart) {
+      Measurement->StartTimeStamp = ((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;
+    } else {
+      Measurement->EndTimeStamp   = ((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;
+    }
+    Measurement->Token            = ((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->String;
+    Measurement->Module           = ((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->String;
+    GetHandleFormModuleGuid(ModuleGuid, &StartHandle);
+    Measurement->Handle = StartHandle;
+    break;
+
   default:
     break;
   }
 }
 
@@ -578,10 +618,18 @@ SearchMeasurement (
           (AsciiStrCmp (mMeasurementList[Index].Token, EndMeasureMent->Token) == 0) &&
           (AsciiStrCmp (mMeasurementList[Index].Module, EndMeasureMent->Module) == 0)) {
         mMeasurementList[Index].EndTimeStamp = EndMeasureMent->EndTimeStamp;
         break;
       }
+    } else if (EndMeasureMent->Identifier == PERF_CROSSMODULE_END_ID) {
+      if (mMeasurementList[Index].EndTimeStamp == 0 &&
+         (AsciiStrCmp (mMeasurementList[Index].Token, EndMeasureMent->Token) == 0) &&
+         (AsciiStrCmp (mMeasurementList[Index].Module, EndMeasureMent->Module) == 0) &&
+         mMeasurementList[Index].Identifier == PERF_CROSSMODULE_START_ID) {
+        mMeasurementList[Index].EndTimeStamp = EndMeasureMent->EndTimeStamp;
+        break;
+      }
     } else {
       if (mMeasurementList[Index].EndTimeStamp == 0 && mMeasurementList[Index].Handle == EndMeasureMent->Handle &&
          (AsciiStrCmp (mMeasurementList[Index].Token, EndMeasureMent->Token) == 0) &&
          (AsciiStrCmp (mMeasurementList[Index].Module, EndMeasureMent->Module) == 0)) {
         mMeasurementList[Index].EndTimeStamp = EndMeasureMent->EndTimeStamp;
@@ -618,29 +666,36 @@ BuildMeasurementList (
     RecordHeader      = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER*) PerformanceTablePtr;
     StartRecordEvent  = (UINT8 *)RecordHeader;
     StartProgressId   = ((FPDT_GUID_EVENT_RECORD *)StartRecordEvent)->ProgressID;
 
     //
+    // If the record with ProgressId 0, the record doesn't appear in pairs. The timestamp in the record is the EndTimeStamp, its StartTimeStamp is 0.
     // If the record is the start record, fill the info to the measurement in the mMeasurementList.
     // If the record is the end record, find the related start measurement in the mMeasurementList and fill the EndTimeStamp.
     //
-    if (((StartProgressId >= PERF_EVENTSIGNAL_START_ID && ((StartProgressId & 0x000F) == 0)) ||
+    if (StartProgressId == 0) {
+      GetMeasurementInfo (RecordHeader, FALSE, &(mMeasurementList[mMeasurementNum]));
+      mMeasurementNum ++;
+    } else if (((StartProgressId >= PERF_EVENTSIGNAL_START_ID && ((StartProgressId & 0x000F) == 0)) ||
         (StartProgressId < PERF_EVENTSIGNAL_START_ID && ((StartProgressId & 0x0001) != 0)))) {
       //
       // Since PEIM and StartImage has same Type and ID when PCD PcdEdkiiFpdtStringRecordEnableOnly = FALSE
       // So we need to identify these two kinds of record through different phase.
       //
-      if (AsciiStrCmp (((FPDT_DYNAMIC_STRING_EVENT_RECORD *)StartRecordEvent)->String, ALit_PEI) == 0) {
-        mPeiPhase = TRUE;
-      } else if (AsciiStrCmp (((FPDT_DYNAMIC_STRING_EVENT_RECORD *)StartRecordEvent)->String, ALit_DXE) == 0) {
-        mDxePhase = TRUE;
-        mPeiPhase = FALSE;
+      if(StartProgressId == PERF_CROSSMODULE_START_ID ){
+        if (AsciiStrCmp (((FPDT_DYNAMIC_STRING_EVENT_RECORD *)StartRecordEvent)->String, ALit_PEI) == 0) {
+          mPeiPhase = TRUE;
+        } else if (AsciiStrCmp (((FPDT_DYNAMIC_STRING_EVENT_RECORD *)StartRecordEvent)->String, ALit_DXE) == 0) {
+          mDxePhase = TRUE;
+          mPeiPhase = FALSE;
+        }
       }
       // Get measurement info form the start record to the mMeasurementList.
       GetMeasurementInfo (RecordHeader, TRUE, &(mMeasurementList[mMeasurementNum]));
       mMeasurementNum ++;
     } else {
+      ZeroMem(&MeasureMent, sizeof(MEASUREMENT_RECORD));
       GetMeasurementInfo (RecordHeader, FALSE, &MeasureMent);
       SearchMeasurement (&MeasureMent);
     }
     TableLength         += RecordHeader->Length;
     PerformanceTablePtr += RecordHeader->Length;
diff --git a/ShellPkg/DynamicCommand/DpDynamicCommand/Dp.h b/ShellPkg/DynamicCommand/DpDynamicCommand/Dp.h
index aae021334d6..96bc89db8dc 100644
--- a/ShellPkg/DynamicCommand/DpDynamicCommand/Dp.h
+++ b/ShellPkg/DynamicCommand/DpDynamicCommand/Dp.h
@@ -39,10 +39,11 @@
 #include <Library/PcdLib.h>
 #include <Library/SortLib.h>
 #include <Library/HiiLib.h>
 #include <Library/FileHandleLib.h>
 #include <Library/UefiHiiServicesLib.h>
+#include <Library/Performancelib.h>
 
 extern EFI_HANDLE mDpHiiHandle;
 
 #define DP_MAJOR_VERSION        2
 #define DP_MINOR_VERSION        5
-- 
2.14.3.windows.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [patch 7/9] MdeModulePkg: Use new added Perf macros
  2018-06-19  7:23 [patch 0/9] Add new Perf macros Dandan Bi
                   ` (5 preceding siblings ...)
  2018-06-19  7:24 ` [patch 6/9] ShellPkg/dp: Update dp tool to parse new Perf record Dandan Bi
@ 2018-06-19  7:24 ` Dandan Bi
  2018-06-19  7:24 ` [patch 8/9] SecurityPkg: " Dandan Bi
  2018-06-19  7:24 ` [patch 9/9] UefiCpuPkg: " Dandan Bi
  8 siblings, 0 replies; 10+ messages in thread
From: Dandan Bi @ 2018-06-19  7:24 UTC (permalink / raw)
  To: edk2-devel; +Cc: Liming Gao, Star Zeng, Eric Dong

Replace old Perf macros with the new added ones.

Cc: Liming Gao <liming.gao@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Dandan Bi <dandan.bi@intel.com>
---
 MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c      |  7 +++++
 MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c            |  8 ++----
 MdeModulePkg/Core/Dxe/Hand/DriverSupport.c         |  8 +++---
 MdeModulePkg/Core/Dxe/Image/Image.c                | 30 +++++-----------------
 MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c      |  8 +++---
 MdeModulePkg/Core/Pei/PeiMain/PeiMain.c            | 17 ++++++------
 MdeModulePkg/Core/PiSmmCore/Dispatcher.c           | 15 ++++-------
 MdeModulePkg/Core/PiSmmCore/PiSmmCore.c            |  4 +--
 MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c   |  2 +-
 .../Library/UefiBootManagerLib/BmConsole.c         |  9 +++----
 MdeModulePkg/Universal/BdsDxe/BdsEntry.c           | 21 ++++++++-------
 11 files changed, 53 insertions(+), 76 deletions(-)

diff --git a/MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c b/MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c
index 088cd810631..4c6ca761a60 100644
--- a/MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c
+++ b/MdeModulePkg/Core/Dxe/Dispatcher/Dispatcher.c
@@ -417,10 +417,11 @@ CoreDispatcher (
   LIST_ENTRY                      *Link;
   EFI_CORE_DRIVER_ENTRY           *DriverEntry;
   BOOLEAN                         ReadyToRun;
   EFI_EVENT                       DxeDispatchEvent;
   
+  PERF_FUNCTION_BEGIN ();
 
   if (gDispatcherRunning) {
     //
     // If the dispatcher is running don't let it be restarted.
     //
@@ -582,10 +583,12 @@ CoreDispatcher (
   //
   CoreCloseEvent (DxeDispatchEvent);
 
   gDispatcherRunning = FALSE;
 
+  PERF_FUNCTION_END ();
+
   return ReturnStatus;
 }
 
 
 /**
@@ -1435,17 +1438,21 @@ CoreFwVolEventProtocolNotify (
 VOID
 CoreInitializeDispatcher (
   VOID
   )
 {
+  PERF_FUNCTION_BEGIN ();
+
   mFwVolEvent = EfiCreateProtocolNotifyEvent (
                   &gEfiFirmwareVolume2ProtocolGuid,
                   TPL_CALLBACK,
                   CoreFwVolEventProtocolNotify,
                   NULL,
                   &mFwVolEventRegistration
                   );
+
+  PERF_FUNCTION_END ();
 }
 
 //
 // Function only used in debug builds
 //
diff --git a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c
index 07c74034624..3f753738a27 100644
--- a/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c
+++ b/MdeModulePkg/Core/Dxe/DxeMain/DxeMain.c
@@ -299,12 +299,12 @@ DxeMain (
 
   //
   // Call constructor for all libraries
   //
   ProcessLibraryConstructorList (gDxeCoreImageHandle, gDxeCoreST);
-  PERF_END   (NULL,"PEI", NULL, 0) ;
-  PERF_START (NULL,"DXE", NULL, 0) ;
+  PERF_CROSSMODULE_END   ("PEI");
+  PERF_CROSSMODULE_BEGIN ("DXE");
 
   //
   // Report DXE Core image information to the PE/COFF Extra Action Library
   //
   ZeroMem (&ImageContext, sizeof (ImageContext));
@@ -497,20 +497,16 @@ DxeMain (
   ASSERT_EFI_ERROR (Status);
 
   //
   // Initialize the DXE Dispatcher
   //
-  PERF_START (NULL,"CoreInitializeDispatcher", "DxeMain", 0) ;
   CoreInitializeDispatcher ();
-  PERF_END (NULL,"CoreInitializeDispatcher", "DxeMain", 0) ;
 
   //
   // Invoke the DXE Dispatcher
   //
-  PERF_START (NULL, "CoreDispatcher", "DxeMain", 0);
   CoreDispatcher ();
-  PERF_END (NULL, "CoreDispatcher", "DxeMain", 0);
 
   //
   // Display Architectural protocols that were not loaded if this is DEBUG build
   //
   DEBUG_CODE_BEGIN ();
diff --git a/MdeModulePkg/Core/Dxe/Hand/DriverSupport.c b/MdeModulePkg/Core/Dxe/Hand/DriverSupport.c
index 33dd0bd0b7c..ab3cc0c07e5 100644
--- a/MdeModulePkg/Core/Dxe/Hand/DriverSupport.c
+++ b/MdeModulePkg/Core/Dxe/Hand/DriverSupport.c
@@ -625,32 +625,32 @@ CoreConnectSingleController (
     DriverBinding = NULL;
     DriverFound = FALSE;
     for (Index = 0; (Index < NumberOfSortedDriverBindingProtocols) && !DriverFound; Index++) {
       if (SortedDriverBindingProtocols[Index] != NULL) {
         DriverBinding = SortedDriverBindingProtocols[Index];
-        PERF_START (DriverBinding->DriverBindingHandle, "DB:Support:", NULL, 0);
+        PERF_DRIVER_BINDING_SUPPORT_BEGIN (DriverBinding->DriverBindingHandle, ControllerHandle);
         Status = DriverBinding->Supported(
                                   DriverBinding,
                                   ControllerHandle,
                                   RemainingDevicePath
                                   );
-        PERF_END (DriverBinding->DriverBindingHandle, "DB:Support:", NULL, 0);
+        PERF_DRIVER_BINDING_SUPPORT_END (DriverBinding->DriverBindingHandle, ControllerHandle);
         if (!EFI_ERROR (Status)) {
           SortedDriverBindingProtocols[Index] = NULL;
           DriverFound = TRUE;
 
           //
           // A driver was found that supports ControllerHandle, so attempt to start the driver
           // on ControllerHandle.
           //
-          PERF_START (DriverBinding->DriverBindingHandle, "DB:Start:", NULL, 0);
+          PERF_DRIVER_BINDING_START_BEGIN (DriverBinding->DriverBindingHandle, ControllerHandle);
           Status = DriverBinding->Start (
                                     DriverBinding,
                                     ControllerHandle,
                                     RemainingDevicePath
                                     );
-          PERF_END (DriverBinding->DriverBindingHandle, "DB:Start:", NULL, 0);
+          PERF_DRIVER_BINDING_START_END (DriverBinding->DriverBindingHandle, ControllerHandle);
 
           if (!EFI_ERROR (Status)) {
             //
             // The driver was successfully started on ControllerHandle, so set a flag
             //
diff --git a/MdeModulePkg/Core/Dxe/Image/Image.c b/MdeModulePkg/Core/Dxe/Image/Image.c
index c49ddfcc81d..adeb4bf313a 100644
--- a/MdeModulePkg/Core/Dxe/Image/Image.c
+++ b/MdeModulePkg/Core/Dxe/Image/Image.c
@@ -1434,17 +1434,13 @@ CoreLoadImage (
   IN UINTN                      SourceSize,
   OUT EFI_HANDLE                *ImageHandle
   )
 {
   EFI_STATUS    Status;
-  UINT64        Tick;
   EFI_HANDLE    Handle;
 
-  Tick = 0;
-  PERF_CODE (
-    Tick = GetPerformanceCounter ();
-  );
+  PERF_LOAD_IMAGE_BEGIN (NULL);
 
   Status = CoreLoadImageCommon (
              BootPolicy,
              ParentImageHandle,
              FilePath,
@@ -1463,12 +1459,11 @@ CoreLoadImage (
     // ImageHandle will be valid only Status is success. 
     //
     Handle = *ImageHandle;
   }
 
-  PERF_START (Handle, "LoadImage:", NULL, Tick);
-  PERF_END (Handle, "LoadImage:", NULL, 0);
+  PERF_LOAD_IMAGE_END (Handle);
 
   return Status;
 }
 
 
@@ -1524,17 +1519,13 @@ CoreLoadImageEx (
   OUT EFI_PHYSICAL_ADDRESS             *EntryPoint         OPTIONAL,
   IN  UINT32                           Attribute
   )
 {
   EFI_STATUS    Status;
-  UINT64        Tick;
   EFI_HANDLE    Handle;
 
-  Tick = 0;
-  PERF_CODE (
-    Tick = GetPerformanceCounter ();
-  );
+  PERF_LOAD_IMAGE_BEGIN (NULL);
 
   Status = CoreLoadImageCommon (
            TRUE,
            ParentImageHandle,
            FilePath,
@@ -1553,12 +1544,11 @@ CoreLoadImageEx (
     // ImageHandle will be valid only Status is success. 
     //
     Handle = *ImageHandle;
   }
 
-  PERF_START (Handle, "LoadImage:", NULL, Tick);
-  PERF_END (Handle, "LoadImage:", NULL, 0);
+  PERF_LOAD_IMAGE_END (Handle);
 
   return Status;
 }
 
 
@@ -1592,14 +1582,12 @@ CoreStartImage (
   EFI_STATUS                    Status;
   LOADED_IMAGE_PRIVATE_DATA     *Image;
   LOADED_IMAGE_PRIVATE_DATA     *LastImage;
   UINT64                        HandleDatabaseKey;
   UINTN                         SetJumpFlag;
-  UINT64                        Tick;
   EFI_HANDLE                    Handle;
 
-  Tick = 0;
   Handle = ImageHandle;
 
   Image = CoreLoadedImageInfo (ImageHandle);
   if (Image == NULL  ||  Image->Started) {
     return EFI_INVALID_PARAMETER;
@@ -1619,13 +1607,11 @@ CoreStartImage (
     DEBUG ((EFI_D_ERROR, "Image type %s can't be started ", GetMachineTypeName(Image->Machine)));
     DEBUG ((EFI_D_ERROR, "on %s UEFI system.\n", GetMachineTypeName(mDxeCoreImageMachineType)));
     return EFI_UNSUPPORTED;
   }
 
-  PERF_CODE (
-    Tick = GetPerformanceCounter ();
-  );
+  PERF_START_IMAGE_BEGIN (Handle);
 
 
   //
   // Push the current start image context, and
   // link the current image to the head.   This is the
@@ -1645,12 +1631,11 @@ CoreStartImage (
   if (Image->JumpBuffer == NULL) {
     //
     // Image may be unloaded after return with failure,
     // then ImageHandle may be invalid, so use NULL handle to record perf log.
     //
-    PERF_START (NULL, "StartImage:", NULL, Tick);
-    PERF_END (NULL, "StartImage:", NULL, 0);
+    PERF_START_IMAGE_END (NULL);
 
     //
     // Pop the current start image context
     //
     mCurrentImage = LastImage;
@@ -1761,12 +1746,11 @@ CoreStartImage (
   }
 
   //
   // Done
   //
-  PERF_START (Handle, "StartImage:", NULL, Tick);
-  PERF_END (Handle, "StartImage:", NULL, 0);
+  PERF_START_IMAGE_END (Handle);
   return Status;
 }
 
 /**
   Terminates the currently loaded EFI image and returns control to boot services.
diff --git a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
index 0ac3fdde6a9..c4f629dadff 100644
--- a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
+++ b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
@@ -998,13 +998,13 @@ PeiDispatcher (
             //
             // Call the PEIM entry point
             //
             PeimEntryPoint = (EFI_PEIM_ENTRY_POINT2)(UINTN)EntryPoint;
 
-            PERF_START (PeimFileHandle, "PEIM", NULL, 0);
+            PERF_START_IMAGE_BEGIN (PeimFileHandle);
             PeimEntryPoint(PeimFileHandle, (const EFI_PEI_SERVICES **) &Private->Ps);
-            PERF_END (PeimFileHandle, "PEIM", NULL, 0);
+            PERF_START_IMAGE_END (PeimFileHandle);
           }
 
           //
           // Process the Notify list and dispatch any notifies for
           // newly installed PPIs.
@@ -1107,11 +1107,11 @@ PeiDispatcher (
               if (Status == EFI_SUCCESS) {
                 //
                 // The PEIM has its dependencies satisfied, and its entry point
                 // has been found, so invoke it.
                 //
-                PERF_START (PeimFileHandle, "PEIM", NULL, 0);
+                PERF_START_IMAGE_BEGIN (PeimFileHandle);
 
                 REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
                   EFI_PROGRESS_CODE,
                   (EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_BEGIN),
                   (VOID *)(&PeimFileHandle),
@@ -1143,11 +1143,11 @@ PeiDispatcher (
                   EFI_PROGRESS_CODE,
                   (EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_END),
                   (VOID *)(&PeimFileHandle),
                   sizeof (PeimFileHandle)
                   );
-                PERF_END (PeimFileHandle, "PEIM", NULL, 0);
+                PERF_START_IMAGE_END (PeimFileHandle);
 
               }
             }
 
             PeiCheckAndSwitchStack (SecCoreData, Private);
diff --git a/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c b/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c
index 775bf18ce93..a52e6f02017 100644
--- a/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c
+++ b/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c
@@ -350,22 +350,21 @@ PeiCore (
   
   //
   // Update performance measurements 
   //
   if (OldCoreData == NULL) {
-    PERF_START (NULL, "SEC", NULL, 1);
-    PERF_END   (NULL, "SEC", NULL, 0);
+    PERF_EVENT ("SEC"); // Means the end of SEC phase.
 
     //
     // If first pass, start performance measurement.
     //
-    PERF_START (NULL,"PEI",    NULL, 0);
-    PERF_START (NULL,"PreMem", NULL, 0);
+    PERF_CROSSMODULE_BEGIN ("PEI");
+    PERF_INMODULE_BEGIN ("PreMem");
 
   } else {
-    PERF_END   (NULL,"PreMem",  NULL, 0);
-    PERF_START (NULL,"PostMem", NULL, 0);
+    PERF_INMODULE_END ("PreMem");
+    PERF_INMODULE_BEGIN ("PostMem");
   }
 
   //
   // Complete PEI Core Service initialization
   //  
@@ -409,19 +408,19 @@ PeiCore (
     }
 
     //
     // Alert any listeners that there is permanent memory available
     //
-    PERF_START (NULL,"DisMem", NULL, 0);
+    PERF_INMODULE_BEGIN ("DisMem");
     Status = PeiServicesInstallPpi (&mMemoryDiscoveredPpi);
 
     //
     // Process the Notify list and dispatch any notifies for the Memory Discovered PPI
     //
     ProcessNotifyList (&PrivateData);
 
-    PERF_END (NULL,"DisMem", NULL, 0);
+    PERF_INMODULE_END ("DisMem");
   }
 
   //
   // Call PEIM dispatcher
   //
@@ -435,11 +434,11 @@ PeiCore (
   }
 
   //
   // Measure PEI Core execution time.
   //
-  PERF_END (NULL, "PostMem", NULL, 0);
+  PERF_INMODULE_END ("PostMem");
 
   //
   // Lookup DXE IPL PPI
   //
   Status = PeiServicesLocatePpi (
diff --git a/MdeModulePkg/Core/PiSmmCore/Dispatcher.c b/MdeModulePkg/Core/PiSmmCore/Dispatcher.c
index f32bbbd1b4b..0b3b5924d38 100644
--- a/MdeModulePkg/Core/PiSmmCore/Dispatcher.c
+++ b/MdeModulePkg/Core/PiSmmCore/Dispatcher.c
@@ -319,17 +319,13 @@ SmmLoadImage (
   EFI_DEVICE_PATH_PROTOCOL       *FilePath;
   EFI_DEVICE_PATH_PROTOCOL       *OriginalFilePath;
   EFI_DEVICE_PATH_PROTOCOL       *HandleFilePath;
   EFI_FIRMWARE_VOLUME2_PROTOCOL  *Fv;
   PE_COFF_LOADER_IMAGE_CONTEXT   ImageContext;
-  UINT64                         Tick;
 
-  Tick = 0;
-  PERF_CODE (
-    Tick = GetPerformanceCounter ();
-  );
-   
+  PERF_LOAD_IMAGE_BEGIN (DriverEntry->ImageHandle);
+
   Buffer               = NULL;
   Size                 = 0;
   Fv                   = DriverEntry->Fv;
   NameGuid             = &DriverEntry->FileName;
   FilePath             = DriverEntry->FvFileDevicePath;
@@ -639,12 +635,11 @@ SmmLoadImage (
              &gEfiLoadedImageProtocolGuid,
              EFI_NATIVE_INTERFACE,
              &DriverEntry->SmmLoadedImage
              );
 
-  PERF_START (DriverEntry->ImageHandle, "LoadImage:", NULL, Tick);
-  PERF_END (DriverEntry->ImageHandle, "LoadImage:", NULL, 0);
+  PERF_LOAD_IMAGE_END (DriverEntry->ImageHandle);
 
   //
   // Print the load address and the PDB file name if it is available
   //
 
@@ -907,13 +902,13 @@ SmmDispatcher (
 
       //
       // For each SMM driver, pass NULL as ImageHandle
       //
       RegisterSmramProfileImage (DriverEntry, TRUE);
-      PERF_START (DriverEntry->ImageHandle, "StartImage:", NULL, 0);
+      PERF_START_IMAGE_BEGIN (DriverEntry->ImageHandle);
       Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)DriverEntry->ImageEntryPoint)(DriverEntry->ImageHandle, gST);
-      PERF_END (DriverEntry->ImageHandle, "StartImage:", NULL, 0);
+      PERF_START_IMAGE_END (DriverEntry->ImageHandle);
       if (EFI_ERROR(Status)){
         UnregisterSmramProfileImage (DriverEntry, TRUE);
         SmmFreePages(DriverEntry->ImageBuffer, DriverEntry->NumberOfPage);
         //
         // Uninstall LoadedImage
diff --git a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c
index 686b9b45a55..45f40e0e60c 100644
--- a/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c
+++ b/MdeModulePkg/Core/PiSmmCore/PiSmmCore.c
@@ -642,11 +642,11 @@ SmmEntryPoint (
   BOOLEAN                     InLegacyBoot;
   BOOLEAN                     IsOverlapped;
   VOID                        *CommunicationBuffer;
   UINTN                       BufferSize;
 
-  PERF_START (NULL, "SMM", NULL, 0) ;
+  PERF_INMODULE_BEGIN ("SMM");
 
   //
   // Update SMST with contents of the SmmEntryContext structure
   //
   gSmmCoreSmst.SmmStartupThisAp      = SmmEntryContext->SmmStartupThisAp;
@@ -737,11 +737,11 @@ SmmEntryPoint (
     // Clear the InSmm flag as we are going to leave SMM
     //
     gSmmCorePrivate->InSmm = FALSE;
   }
 
-  PERF_END (NULL, "SMM", NULL, 0) ;
+  PERF_INMODULE_END ("SMM");
 }
 
 /**
   Install LoadedImage protocol for SMM Core.
 **/
diff --git a/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c b/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c
index b842d5824ae..59bd1e4c6c0 100644
--- a/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c
+++ b/MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c
@@ -43,11 +43,11 @@ BmEndOfBdsPerfCode (
   )
 {
   //
   // Record the performance data for End of BDS
   //
-  PERF_END(NULL, "BDS", NULL, 0);
+  PERF_CROSSMODULE_END("BDS");
 
   return ;
 }
 
 /**
diff --git a/MdeModulePkg/Library/UefiBootManagerLib/BmConsole.c b/MdeModulePkg/Library/UefiBootManagerLib/BmConsole.c
index 80511814eec..d85b603d64a 100644
--- a/MdeModulePkg/Library/UefiBootManagerLib/BmConsole.c
+++ b/MdeModulePkg/Library/UefiBootManagerLib/BmConsole.c
@@ -720,27 +720,24 @@ EfiBootManagerConnectAllDefaultConsoles (
 
   Status = EfiBootManagerConnectConsoleVariable (ConOut);
   if (!EFI_ERROR (Status)) {
     OneConnected = TRUE;
   }
-  PERF_START (NULL, "ConOutReady", "BDS", 1);
-  PERF_END   (NULL, "ConOutReady", "BDS", 0);
+  PERF_EVENT ("ConOutReady");
 
   
   Status = EfiBootManagerConnectConsoleVariable (ConIn);
   if (!EFI_ERROR (Status)) {
     OneConnected = TRUE;
   }
-  PERF_START (NULL, "ConInReady", "BDS", 1);
-  PERF_END   (NULL, "ConInReady", "BDS", 0);
+  PERF_EVENT ("ConInReady");
 
   Status = EfiBootManagerConnectConsoleVariable (ErrOut);
   if (!EFI_ERROR (Status)) {
     OneConnected = TRUE;
   }
-  PERF_START (NULL, "ErrOutReady", "BDS", 1);
-  PERF_END   (NULL, "ErrOutReady", "BDS", 0);
+  PERF_EVENT ("ErrOutReady");
 
   SystemTableUpdated = FALSE;
   //
   // Fill console handles in System Table if no console device assignd.
   //
diff --git a/MdeModulePkg/Universal/BdsDxe/BdsEntry.c b/MdeModulePkg/Universal/BdsDxe/BdsEntry.c
index 3191a986304..acb25abfcd4 100644
--- a/MdeModulePkg/Universal/BdsDxe/BdsEntry.c
+++ b/MdeModulePkg/Universal/BdsDxe/BdsEntry.c
@@ -723,12 +723,12 @@ BdsEntry (
   BootSuccess     = FALSE;
 
   //
   // Insert the performance probe
   //
-  PERF_END (NULL, "DXE", NULL, 0);
-  PERF_START (NULL, "BDS", NULL, 0);
+  PERF_CROSSMODULE_END("DXE");
+  PERF_CROSSMODULE_BEGIN("BDS");
   DEBUG ((EFI_D_INFO, "[Bds] Entry...\n"));
 
   //
   // Fill in FirmwareVendor and FirmwareRevision from PCDs
   //
@@ -886,13 +886,13 @@ BdsEntry (
   // > Register new Driver#### or Boot####
   // > Register new Key####: e.g.: F12 
   // > Signal ReadyToLock event
   // > Authentication action: 1. connect Auth devices; 2. Identify auto logon user.
   //
-  PERF_START (NULL, "PlatformBootManagerBeforeConsole", "BDS", 0);
+  PERF_INMODULE_BEGIN("PlatformBootManagerBeforeConsole");
   PlatformBootManagerBeforeConsole ();
-  PERF_END   (NULL, "PlatformBootManagerBeforeConsole", "BDS", 0);
+  PERF_INMODULE_END("PlatformBootManagerBeforeConsole");
 
   //
   // Initialize hotkey service
   //
   EfiBootManagerStartHotkeyService (&HotkeyTriggered);
@@ -905,21 +905,21 @@ BdsEntry (
   EfiBootManagerFreeLoadOptions (LoadOptions, LoadOptionCount);
 
   //
   // Connect consoles
   //
-  PERF_START (NULL, "EfiBootManagerConnectAllDefaultConsoles", "BDS", 0);
+  PERF_INMODULE_BEGIN("EfiBootManagerConnectAllDefaultConsoles");
   if (PcdGetBool (PcdConInConnectOnDemand)) {
     EfiBootManagerConnectConsoleVariable (ConOut);
     EfiBootManagerConnectConsoleVariable (ErrOut);
     //
     // Do not connect ConIn devices when lazy ConIn feature is ON.
     //
   } else {
     EfiBootManagerConnectAllDefaultConsoles ();
   }
-  PERF_END   (NULL, "EfiBootManagerConnectAllDefaultConsoles", "BDS", 0);
+  PERF_INMODULE_END("EfiBootManagerConnectAllDefaultConsoles");
 
   //
   // Do the platform specific action after the console is ready
   // Possible things that can be done in PlatformBootManagerAfterConsole:
   // > Console post action:
@@ -928,13 +928,13 @@ BdsEntry (
   // > Run diagnostics like memory testing
   // > Connect certain devices
   // > Dispatch aditional option roms
   // > Special boot: e.g.: USB boot, enter UI
   // 
-  PERF_START (NULL, "PlatformBootManagerAfterConsole", "BDS", 0);
+  PERF_INMODULE_BEGIN("PlatformBootManagerAfterConsole");
   PlatformBootManagerAfterConsole ();
-  PERF_END   (NULL, "PlatformBootManagerAfterConsole", "BDS", 0);
+  PERF_INMODULE_END("PlatformBootManagerAfterConsole");
   //
   // Boot to Boot Manager Menu when EFI_OS_INDICATIONS_BOOT_TO_FW_UI is set. Skip HotkeyBoot
   //
   DataSize = sizeof (UINT64);
   Status = gRT->GetVariable (
@@ -1023,14 +1023,13 @@ BdsEntry (
     EfiBootManagerFreeLoadOptions (LoadOptions, LoadOptionCount);
 
     //
     // Execute Key####
     //
-    PERF_START (NULL, "BdsWait", "BDS", 0);
+    PERF_INMODULE_BEGIN ("BdsWait");
     BdsWait (HotkeyTriggered);
-    PERF_END   (NULL, "BdsWait", "BDS", 0);
-
+    PERF_INMODULE_END ("BdsWait");
     //
     // BdsReadKeys() can be removed after all keyboard drivers invoke callback in timer callback.
     //
     BdsReadKeys ();
 
-- 
2.14.3.windows.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [patch 8/9] SecurityPkg: Use new added Perf macros
  2018-06-19  7:23 [patch 0/9] Add new Perf macros Dandan Bi
                   ` (6 preceding siblings ...)
  2018-06-19  7:24 ` [patch 7/9] MdeModulePkg: Use new added Perf macros Dandan Bi
@ 2018-06-19  7:24 ` Dandan Bi
  2018-06-19  7:24 ` [patch 9/9] UefiCpuPkg: " Dandan Bi
  8 siblings, 0 replies; 10+ messages in thread
From: Dandan Bi @ 2018-06-19  7:24 UTC (permalink / raw)
  To: edk2-devel; +Cc: Liming Gao, Chao Zhang

Replace old Perf macros with the new added ones.

Cc: Liming Gao <liming.gao@intel.com>
Cc: Chao Zhang <chao.b.zhang@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Dandan Bi <dandan.bi@intel.com>
---
 .../DxeRsa2048Sha256GuidedSectionExtractLib.c            | 16 ++++++++--------
 .../PeiRsa2048Sha256GuidedSectionExtractLib.c            | 16 ++++++++--------
 2 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/SecurityPkg/Library/DxeRsa2048Sha256GuidedSectionExtractLib/DxeRsa2048Sha256GuidedSectionExtractLib.c b/SecurityPkg/Library/DxeRsa2048Sha256GuidedSectionExtractLib/DxeRsa2048Sha256GuidedSectionExtractLib.c
index 39768fbac22..d6f4207a506 100644
--- a/SecurityPkg/Library/DxeRsa2048Sha256GuidedSectionExtractLib/DxeRsa2048Sha256GuidedSectionExtractLib.c
+++ b/SecurityPkg/Library/DxeRsa2048Sha256GuidedSectionExtractLib/DxeRsa2048Sha256GuidedSectionExtractLib.c
@@ -161,13 +161,13 @@ Rsa2048Sha256GuidedSectionHandler (
     // Get the RSA 2048 SHA 256 information.
     //
     CertBlockRsa2048Sha256 = &((RSA_2048_SHA_256_SECTION2_HEADER *) InputSection)->CertBlockRsa2048Sha256;
     OutputBufferSize       = SECTION2_SIZE (InputSection) - sizeof (RSA_2048_SHA_256_SECTION2_HEADER);
     if ((((EFI_GUID_DEFINED_SECTION *)InputSection)->Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) {
-      PERF_START (NULL, "RsaCopy", "DXE", 0);
+      PERF_INMODULE_BEGIN ("DxeRsaCopy");
       CopyMem (*OutputBuffer, (UINT8 *)InputSection + sizeof (RSA_2048_SHA_256_SECTION2_HEADER), OutputBufferSize);
-      PERF_END (NULL, "RsaCopy", "DXE", 0);
+      PERF_INMODULE_END ("DxeRsaCopy");
     } else {
       *OutputBuffer = (UINT8 *)InputSection + sizeof (RSA_2048_SHA_256_SECTION2_HEADER);
     }
 
     //
@@ -189,13 +189,13 @@ Rsa2048Sha256GuidedSectionHandler (
     // Get the RSA 2048 SHA 256 information.
     //
     CertBlockRsa2048Sha256 = &((RSA_2048_SHA_256_SECTION_HEADER *)InputSection)->CertBlockRsa2048Sha256;
     OutputBufferSize       = SECTION_SIZE (InputSection) - sizeof (RSA_2048_SHA_256_SECTION_HEADER);
     if ((((EFI_GUID_DEFINED_SECTION *)InputSection)->Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) {
-      PERF_START (NULL, "RsaCopy", "DXE", 0);
+      PERF_INMODULE_BEGIN ("DxeRsaCopy");
       CopyMem (*OutputBuffer, (UINT8 *)InputSection + sizeof (RSA_2048_SHA_256_SECTION_HEADER), OutputBufferSize);
-      PERF_END (NULL, "RsaCopy", "DXE", 0);
+      PERF_INMODULE_END ("DxeRsaCopy");
     } else {
       *OutputBuffer = (UINT8 *)InputSection + sizeof (RSA_2048_SHA_256_SECTION_HEADER);
     }
 
     //
@@ -325,13 +325,13 @@ Rsa2048Sha256GuidedSectionHandler (
   if (!CryptoStatus) {
     DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Sha256Init() failed\n"));
     *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED;
     goto Done;
   }
-  PERF_START (NULL, "RsaShaData", "DXE", 0);
+  PERF_INMODULE_BEGIN ("DxeRsaShaData");
   CryptoStatus = Sha256Update (HashContext, *OutputBuffer, OutputBufferSize);
-  PERF_END (NULL, "RsaShaData", "DXE", 0);
+  PERF_INMODULE_END ("DxeRsaShaData");
   if (!CryptoStatus) {
     DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: Sha256Update() failed\n"));
     *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED;
     goto Done;
   }
@@ -343,19 +343,19 @@ Rsa2048Sha256GuidedSectionHandler (
   }
 
   //
   // Verify the RSA 2048 SHA 256 signature.
   //
-  PERF_START (NULL, "RsaVerify", "DXE", 0);
+  PERF_INMODULE_BEGIN ("DxeRsaVerify");
   CryptoStatus = RsaPkcs1Verify (
                    Rsa, 
                    Digest, 
                    SHA256_DIGEST_SIZE, 
                    CertBlockRsa2048Sha256->Signature, 
                    sizeof (CertBlockRsa2048Sha256->Signature)
                    );
-  PERF_END (NULL, "RsaVerify", "DXE", 0);
+  PERF_INMODULE_END ("DxeRsaVerify");
   if (!CryptoStatus) {
     //
     // If RSA 2048 SHA 256 signature verification fails, AUTH tested failed bit is set.
     //
     DEBUG ((DEBUG_ERROR, "DxeRsa2048Sha256: RsaPkcs1Verify() failed\n"));
diff --git a/SecurityPkg/Library/PeiRsa2048Sha256GuidedSectionExtractLib/PeiRsa2048Sha256GuidedSectionExtractLib.c b/SecurityPkg/Library/PeiRsa2048Sha256GuidedSectionExtractLib/PeiRsa2048Sha256GuidedSectionExtractLib.c
index ba1c700ad03..2272308ddca 100644
--- a/SecurityPkg/Library/PeiRsa2048Sha256GuidedSectionExtractLib/PeiRsa2048Sha256GuidedSectionExtractLib.c
+++ b/SecurityPkg/Library/PeiRsa2048Sha256GuidedSectionExtractLib/PeiRsa2048Sha256GuidedSectionExtractLib.c
@@ -158,13 +158,13 @@ Rsa2048Sha256GuidedSectionHandler (
     // Get the RSA 2048 SHA 256 information.
     //
     CertBlockRsa2048Sha256 = &((RSA_2048_SHA_256_SECTION2_HEADER *) InputSection)->CertBlockRsa2048Sha256;
     OutputBufferSize       = SECTION2_SIZE (InputSection) - sizeof (RSA_2048_SHA_256_SECTION2_HEADER);
     if ((((EFI_GUID_DEFINED_SECTION *)InputSection)->Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) {
-      PERF_START (NULL, "RsaCopy", "PEI", 0);
+      PERF_INMODULE_BEGIN ("PeiRsaCopy");
       CopyMem (*OutputBuffer, (UINT8 *)InputSection + sizeof (RSA_2048_SHA_256_SECTION2_HEADER), OutputBufferSize);
-      PERF_END (NULL, "RsaCopy", "PEI", 0);
+      PERF_INMODULE_END ("PeiRsaCopy");
     } else {
       *OutputBuffer = (UINT8 *)InputSection + sizeof (RSA_2048_SHA_256_SECTION2_HEADER);
     }
 
     //
@@ -186,13 +186,13 @@ Rsa2048Sha256GuidedSectionHandler (
     // Get the RSA 2048 SHA 256 information.
     //
     CertBlockRsa2048Sha256 = &((RSA_2048_SHA_256_SECTION_HEADER *)InputSection)->CertBlockRsa2048Sha256;
     OutputBufferSize       = SECTION_SIZE (InputSection) - sizeof (RSA_2048_SHA_256_SECTION_HEADER);
     if ((((EFI_GUID_DEFINED_SECTION *)InputSection)->Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) != 0) {
-      PERF_START (NULL, "RsaCopy", "PEI", 0);
+      PERF_INMODULE_BEGIN ("PeiRsaCopy");
       CopyMem (*OutputBuffer, (UINT8 *)InputSection + sizeof (RSA_2048_SHA_256_SECTION_HEADER), OutputBufferSize);
-      PERF_END (NULL, "RsaCopy", "PEI", 0);
+      PERF_INMODULE_END ("PeiRsaCopy");
     } else {
       *OutputBuffer = (UINT8 *)InputSection + sizeof (RSA_2048_SHA_256_SECTION_HEADER);
     }
 
     //
@@ -309,13 +309,13 @@ Rsa2048Sha256GuidedSectionHandler (
   if (!CryptoStatus) {
     DEBUG ((DEBUG_ERROR, "PeiRsa2048Sha256: Sha256Init() failed\n"));
     *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED;
     goto Done;
   }
-  PERF_START (NULL, "RsaShaData", "PEI", 0);
+  PERF_INMODULE_BEGIN ("PeiRsaShaData");
   CryptoStatus = Sha256Update (HashContext, *OutputBuffer, OutputBufferSize);
-  PERF_END (NULL, "RsaShaData", "PEI", 0);
+  PERF_INMODULE_END ("PeiRsaShaData");
   if (!CryptoStatus) {
     DEBUG ((DEBUG_ERROR, "PeiRsa2048Sha256: Sha256Update() failed\n"));
     *AuthenticationStatus |= EFI_AUTH_STATUS_TEST_FAILED;
     goto Done;
   }
@@ -327,19 +327,19 @@ Rsa2048Sha256GuidedSectionHandler (
   }
 
   //
   // Verify the RSA 2048 SHA 256 signature.
   //
-  PERF_START (NULL, "RsaVerify", "PEI", 0);
+  PERF_INMODULE_BEGIN ("PeiRsaVerify");
   CryptoStatus = RsaPkcs1Verify (
                    Rsa, 
                    Digest, 
                    SHA256_DIGEST_SIZE, 
                    CertBlockRsa2048Sha256->Signature, 
                    sizeof (CertBlockRsa2048Sha256->Signature)
                    );
-  PERF_END (NULL, "RsaVerify", "PEI", 0);
+  PERF_INMODULE_END ("PeiRsaVerify");
   if (!CryptoStatus) {
     //
     // If RSA 2048 SHA 256 signature verification fails, AUTH tested failed bit is set.
     //
     DEBUG ((DEBUG_ERROR, "PeiRsa2048Sha256: RsaPkcs1Verify() failed\n"));
-- 
2.14.3.windows.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [patch 9/9] UefiCpuPkg: Use new added Perf macros
  2018-06-19  7:23 [patch 0/9] Add new Perf macros Dandan Bi
                   ` (7 preceding siblings ...)
  2018-06-19  7:24 ` [patch 8/9] SecurityPkg: " Dandan Bi
@ 2018-06-19  7:24 ` Dandan Bi
  8 siblings, 0 replies; 10+ messages in thread
From: Dandan Bi @ 2018-06-19  7:24 UTC (permalink / raw)
  To: edk2-devel; +Cc: Liming Gao, Eric Dong

Replace old Perf macros with the new added ones.

Cc: Liming Gao <liming.gao@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Dandan Bi <dandan.bi@intel.com>
---
 UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c b/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c
index 4ae168a2c3c..d3cb07cd2d0 100644
--- a/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c
+++ b/UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume.c
@@ -428,21 +428,21 @@ S3ResumeBootOs (
   // NOTE: Because Debug Timer interrupt and system interrupts will be disabled 
   // in BootScriptExecuteDxe, the rest code in S3ResumeBootOs() cannot be halted
   // by soft debugger.
   //
 
-  PERF_END (NULL, "ScriptExec", NULL, 0);
+  PERF_INMODULE_END ("ScriptExec");
 
   //
   // Install BootScriptDonePpi
   //
-  PERF_START_EX (NULL, "BootScriptDonePpi", NULL, 0, PERF_INMODULE_START_ID);
+  PERF_INMODULE_BEGIN ("BootScriptDonePpi");
 
   Status = PeiServicesInstallPpi (&mPpiListPostScriptTable);
   ASSERT_EFI_ERROR (Status);
 
-  PERF_END_EX (NULL, "BootScriptDonePpi", NULL, 0, PERF_INMODULE_END_ID);
+  PERF_INMODULE_END ("BootScriptDonePpi");
 
   //
   // Get ACPI Table Address
   //
   Facs = (EFI_ACPI_4_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *) ((UINTN) (AcpiS3Context->AcpiFacsTable));
@@ -462,26 +462,26 @@ S3ResumeBootOs (
   }
 
   //
   // Install EndOfPeiPpi
   //
-  PERF_START_EX (NULL, "EndOfPeiPpi", NULL, 0, PERF_INMODULE_START_ID);
+  PERF_INMODULE_BEGIN("EndOfPeiPpi");
 
   Status = PeiServicesInstallPpi (&mPpiListEndOfPeiTable);
   ASSERT_EFI_ERROR (Status);
 
-  PERF_END_EX (NULL, "EndOfPeiPpi", NULL, 0, PERF_INMODULE_END_ID);
+  PERF_INMODULE_END("EndOfPeiPpi");
 
-  PERF_START_EX (NULL, "EndOfS3Resume", NULL, 0, PERF_INMODULE_START_ID);
+  PERF_INMODULE_BEGIN("EndOfS3Resume");
 
   DEBUG ((DEBUG_INFO, "Signal EndOfS3Resume\n"));
   //
   // Signal EndOfS3Resume to SMM.
   //
   SignalToSmmByCommunication (&gEdkiiEndOfS3ResumeGuid);
 
-  PERF_END_EX (NULL, "EndOfS3Resume", NULL, 0, PERF_INMODULE_END_ID);
+  PERF_INMODULE_END ("EndOfS3Resume");
 
   //
   // report status code on S3 resume
   //
   REPORT_STATUS_CODE (EFI_PROGRESS_CODE, EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_OS_WAKE);
@@ -878,11 +878,11 @@ S3ResumeExecuteBootScript (
   //
   // Report Status Code to indicate S3 boot script execution
   //
   REPORT_STATUS_CODE (EFI_PROGRESS_CODE, EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_S3_BOOT_SCRIPT);
 
-  PERF_START (NULL, "ScriptExec", NULL, 0);
+  PERF_INMODULE_BEGIN ("ScriptExec");
 
   if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
     //
     // X64 S3 Resume
     //
-- 
2.14.3.windows.1



^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2018-06-19  7:26 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-06-19  7:23 [patch 0/9] Add new Perf macros Dandan Bi
2018-06-19  7:23 ` [patch 1/9] MdeModulePkg: Add PERFORMANCE_MEASUREMENT_PROTOCOL Dandan Bi
2018-06-19  7:23 ` [patch 2/9] MdeModulePkg: Update Performance instances to use new protocol Dandan Bi
2018-06-19  7:23 ` [patch 3/9] MdePkg/PerformanceLib.h: Add new Perf macros Dandan Bi
2018-06-19  7:24 ` [patch 4/9] MdeModulePkg/ExtendedFirmwarePerf: Remove PerfId definitions Dandan Bi
2018-06-19  7:24 ` [patch 5/9] MdeModulePkg: Update performance library instances Dandan Bi
2018-06-19  7:24 ` [patch 6/9] ShellPkg/dp: Update dp tool to parse new Perf record Dandan Bi
2018-06-19  7:24 ` [patch 7/9] MdeModulePkg: Use new added Perf macros Dandan Bi
2018-06-19  7:24 ` [patch 8/9] SecurityPkg: " Dandan Bi
2018-06-19  7:24 ` [patch 9/9] UefiCpuPkg: " Dandan Bi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox