/** @file
  Performance library instance used by SMM Core.

  This library provides the performance measurement interfaces and initializes performance
  logging for the SMM phase.
  It initializes SMM phase performance logging by publishing the SMM Performance and PerformanceEx Protocol,
  which is consumed by SmmPerformanceLib to logging performance data in SMM phase.

  This library is mainly used by SMM Core to start performance logging to ensure that
  SMM Performance and PerformanceEx Protocol are installed at the very beginning of SMM phase.

 Caution: This module requires additional review when modified.
 This driver will have external input - performance data and communicate buffer in SMM mode.
 This external input must be validated carefully to avoid security issue like
 buffer overflow, integer overflow.

 SmmPerformanceHandlerEx(), SmmPerformanceHandler() will receive untrusted input and do basic validation.

Copyright (c) 2011 - 2023, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "SmmCorePerformanceLibInternal.h"

#define STRING_SIZE              (FPDT_STRING_EVENT_RECORD_NAME_LENGTH * sizeof (CHAR8))
#define FIRMWARE_RECORD_BUFFER   0x1000
#define CACHE_HANDLE_GUID_COUNT  0x100

SMM_BOOT_PERFORMANCE_TABLE  *mSmmBootPerformanceTable = NULL;

typedef struct {
  EFI_HANDLE    Handle;
  CHAR8         NameString[FPDT_STRING_EVENT_RECORD_NAME_LENGTH];
  EFI_GUID      ModuleGuid;
} HANDLE_GUID_MAP;

HANDLE_GUID_MAP  mCacheHandleGuidTable[CACHE_HANDLE_GUID_COUNT];
UINTN            mCachePairCount = 0;

UINT32                mPerformanceLength    = sizeof (SMM_BOOT_PERFORMANCE_TABLE);
UINT32                mMaxPerformanceLength = 0;
UINT32                mLoadImageCount       = 0;
BOOLEAN               mFpdtDataIsReported   = FALSE;
BOOLEAN               mLackSpaceIsReport    = FALSE;
CHAR8                 *mPlatformLanguage    = NULL;
SPIN_LOCK             mSmmFpdtLock;
PERFORMANCE_PROPERTY  mPerformanceProperty;
UINT32                mCachedLength   = 0;
UINT32                mBootRecordSize = 0;
BOOLEAN               mPerformanceMeasurementEnabled;

//
// 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 + RecordSize + FIRMWARE_RECORD_BUFFER,
                                   mSmmBootPerformanceTable
                                   );

      if (mSmmBootPerformanceTable == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }

      mSmmBootPerformanceTable->Header.Length = mPerformanceLength;
      mMaxPerformanceLength                   = mPerformanceLength + 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

@retval TRUE       Is a known one used by core.
@retval FALSE      Not a known one.

**/
BOOLEAN
IsKnownTokens (
  IN CONST CHAR8  *Token
  )
{
  if (Token == NULL) {
    return FALSE;
  }

  if ((AsciiStrCmp (Token, SEC_TOK) == 0) ||
      (AsciiStrCmp (Token, PEI_TOK) == 0) ||
      (AsciiStrCmp (Token, DXE_TOK) == 0) ||
      (AsciiStrCmp (Token, BDS_TOK) == 0) ||
      (AsciiStrCmp (Token, DRIVERBINDING_START_TOK) == 0) ||
      (AsciiStrCmp (Token, DRIVERBINDING_SUPPORT_TOK) == 0) ||
      (AsciiStrCmp (Token, DRIVERBINDING_STOP_TOK) == 0) ||
      (AsciiStrCmp (Token, LOAD_IMAGE_TOK) == 0) ||
      (AsciiStrCmp (Token, START_IMAGE_TOK) == 0) ||
      (AsciiStrCmp (Token, PEIM_TOK) == 0))
  {
    return TRUE;
  } else {
    return FALSE;
  }
}

/**
Check whether the ID is a known one which map to the known Token.

@param  Identifier  32-bit identifier.

@retval TRUE        Is a known one used by core.
@retval FALSE       Not a known one.

**/
BOOLEAN
IsKnownID (
  IN UINT32  Identifier
  )
{
  if ((Identifier == MODULE_START_ID) ||
      (Identifier == MODULE_END_ID) ||
      (Identifier == MODULE_LOADIMAGE_START_ID) ||
      (Identifier == MODULE_LOADIMAGE_END_ID) ||
      (Identifier == MODULE_DB_START_ID) ||
      (Identifier == MODULE_DB_END_ID) ||
      (Identifier == MODULE_DB_SUPPORT_START_ID) ||
      (Identifier == MODULE_DB_SUPPORT_END_ID) ||
      (Identifier == MODULE_DB_STOP_START_ID) ||
      (Identifier == MODULE_DB_STOP_END_ID))
  {
    return TRUE;
  } else {
    return FALSE;
  }
}

/**
  Get the FPDT record identifier.

  @param Attribute                The attribute of the Record.
                                  PerfStartEntry: Start Record.
                                  PerfEndEntry: End Record.
  @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  ProgressID              On return, pointer to the ProgressID.

  @retval EFI_SUCCESS              Get record info successfully.
  @retval EFI_INVALID_PARAMETER    No matched FPDT record.

**/
EFI_STATUS
GetFpdtRecordId (
  IN       PERF_MEASUREMENT_ATTRIBUTE  Attribute,
  IN CONST VOID                        *Handle,
  IN CONST CHAR8                       *String,
  OUT UINT16                           *ProgressID
  )
{
  //
  // Token to Id.
  //
  if (String != NULL) {
    if (AsciiStrCmp (String, START_IMAGE_TOK) == 0) {
      // "StartImage:"
      if (Attribute == PerfStartEntry) {
        *ProgressID = MODULE_START_ID;
      } else {
        *ProgressID = MODULE_END_ID;
      }
    } else if (AsciiStrCmp (String, LOAD_IMAGE_TOK) == 0) {
      // "LoadImage:"
      if (Attribute == PerfStartEntry) {
        *ProgressID = MODULE_LOADIMAGE_START_ID;
      } else {
        *ProgressID = MODULE_LOADIMAGE_END_ID;
      }
    } else {
      // Pref used in Modules
      if (Attribute == PerfStartEntry) {
        *ProgressID = PERF_INMODULE_START_ID;
      } else {
        *ProgressID = PERF_INMODULE_END_ID;
      }
    }
  } else if (Handle != NULL) {
    // Pref used in Modules
    if (Attribute == PerfStartEntry) {
      *ProgressID = PERF_INMODULE_START_ID;
    } else {
      *ProgressID = PERF_INMODULE_END_ID;
    }
  } else {
    return EFI_UNSUPPORTED;
  }

  return EFI_SUCCESS;
}

/**
  Get a human readable module name and module guid for the given image handle.
  If module name can't be found, "" string will return.
  If module guid can't be found, Zero Guid will return.

  @param    Handle        Image handle or Controller handle.
  @param    NameString    The ascii string will be filled into it. If not found, null string will return.
  @param    BufferSize    Size of the input NameString buffer.
  @param    ModuleGuid    Point to the guid buffer to store the got module guid value.

  @retval EFI_SUCCESS     Successfully get module name and guid.
  @retval EFI_INVALID_PARAMETER  The input parameter NameString is NULL.
  @retval other value  Module Name can't be got.
**/
EFI_STATUS
EFIAPI
GetModuleInfoFromHandle (
  IN EFI_HANDLE  Handle,
  OUT CHAR8      *NameString,
  IN UINTN       BufferSize,
  OUT EFI_GUID   *ModuleGuid OPTIONAL
  )
{
  EFI_STATUS                         Status;
  EFI_LOADED_IMAGE_PROTOCOL          *LoadedImage;
  EFI_DRIVER_BINDING_PROTOCOL        *DriverBinding;
  CHAR8                              *PdbFileName;
  EFI_GUID                           *TempGuid;
  UINTN                              StartIndex;
  UINTN                              Index;
  INTN                               Count;
  BOOLEAN                            ModuleGuidIsGet;
  UINTN                              StringSize;
  CHAR16                             *StringPtr;
  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH  *FvFilePath;

  if ((NameString == NULL) || (BufferSize == 0)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Try to get the ModuleGuid and name string form the caached array.
  //
  if (mCachePairCount > 0) {
    for (Count = mCachePairCount - 1; Count >= 0; Count--) {
      if (Handle == mCacheHandleGuidTable[Count].Handle) {
        CopyGuid (ModuleGuid, &mCacheHandleGuidTable[Count].ModuleGuid);
        AsciiStrCpyS (NameString, FPDT_STRING_EVENT_RECORD_NAME_LENGTH, mCacheHandleGuidTable[Count].NameString);
        return EFI_SUCCESS;
      }
    }
  }

  Status          = EFI_INVALID_PARAMETER;
  LoadedImage     = NULL;
  ModuleGuidIsGet = FALSE;

  //
  // Initialize GUID as zero value.
  //
  TempGuid = &gZeroGuid;
  //
  // Initialize it as "" string.
  //
  NameString[0] = 0;

  if (Handle != NULL) {
    //
    // Try Handle as ImageHandle.
    //
    Status = gBS->HandleProtocol (
                    Handle,
                    &gEfiLoadedImageProtocolGuid,
                    (VOID **)&LoadedImage
                    );

    if (EFI_ERROR (Status)) {
      //
      // Try Handle as Controller Handle
      //
      Status = gBS->OpenProtocol (
                      Handle,
                      &gEfiDriverBindingProtocolGuid,
                      (VOID **)&DriverBinding,
                      NULL,
                      NULL,
                      EFI_OPEN_PROTOCOL_GET_PROTOCOL
                      );
      if (!EFI_ERROR (Status)) {
        //
        // Get Image protocol from ImageHandle
        //
        Status = gBS->HandleProtocol (
                        DriverBinding->ImageHandle,
                        &gEfiLoadedImageProtocolGuid,
                        (VOID **)&LoadedImage
                        );
      }
    }
  }

  if (!EFI_ERROR (Status) && (LoadedImage != NULL)) {
    //
    // Get Module Guid from DevicePath.
    //
    if ((LoadedImage->FilePath != NULL) &&
        (LoadedImage->FilePath->Type == MEDIA_DEVICE_PATH) &&
        (LoadedImage->FilePath->SubType == MEDIA_PIWG_FW_FILE_DP)
        )
    {
      //
      // Determine GUID associated with module logging performance
      //
      ModuleGuidIsGet = TRUE;
      FvFilePath      = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)LoadedImage->FilePath;
      TempGuid        = &FvFilePath->FvFileName;
    }

    //
    // Method 1 Get Module Name from PDB string.
    //
    PdbFileName = PeCoffLoaderGetPdbPointer (LoadedImage->ImageBase);
    if ((PdbFileName != NULL) && (BufferSize > 0)) {
      StartIndex = 0;
      for (Index = 0; PdbFileName[Index] != 0; Index++) {
        if ((PdbFileName[Index] == '\\') || (PdbFileName[Index] == '/')) {
          StartIndex = Index + 1;
        }
      }

      //
      // Copy the PDB file name to our temporary string.
      // If the length is bigger than BufferSize, trim the redudant characters to avoid overflow in array boundary.
      //
      for (Index = 0; Index < BufferSize - 1; Index++) {
        NameString[Index] = PdbFileName[Index + StartIndex];
        if ((NameString[Index] == 0) || (NameString[Index] == '.')) {
          NameString[Index] = 0;
          break;
        }
      }

      if (Index == BufferSize - 1) {
        NameString[Index] = 0;
      }

      //
      // Module Name is got.
      //
      goto Done;
    }
  }

  if (ModuleGuidIsGet) {
    //
    // Method 2 Try to get the image's FFS UI section by image GUID
    //
    StringPtr  = NULL;
    StringSize = 0;
    Status     = GetSectionFromAnyFv (
                   TempGuid,
                   EFI_SECTION_USER_INTERFACE,
                   0,
                   (VOID **)&StringPtr,
                   &StringSize
                   );

    if (!EFI_ERROR (Status)) {
      //
      // Method 3. Get the name string from FFS UI section
      //
      for (Index = 0; Index < BufferSize - 1 && StringPtr[Index] != 0; Index++) {
        NameString[Index] = (CHAR8)StringPtr[Index];
      }

      NameString[Index] = 0;
      FreePool (StringPtr);
    }
  }

Done:
  //
  // Copy Module Guid
  //
  if (ModuleGuid != NULL) {
    CopyGuid (ModuleGuid, TempGuid);
    if (IsZeroGuid (TempGuid) && (Handle != NULL) && !ModuleGuidIsGet) {
      // Handle is GUID
      CopyGuid (ModuleGuid, (EFI_GUID *)Handle);
    }
  }

  //
  // Cache the Handle and Guid pairs.
  //
  if (mCachePairCount < CACHE_HANDLE_GUID_COUNT) {
    mCacheHandleGuidTable[mCachePairCount].Handle = Handle;
    CopyGuid (&mCacheHandleGuidTable[mCachePairCount].ModuleGuid, ModuleGuid);
    AsciiStrCpyS (mCacheHandleGuidTable[mCachePairCount].NameString, FPDT_STRING_EVENT_RECORD_NAME_LENGTH, NameString);
    mCachePairCount++;
  }

  return Status;
}

/**
  Copies the string from Source into Destination and updates Length with the
  size of the string.

  @param Destination - destination of the string copy
  @param Source      - pointer to the source string which will get copied
  @param Length      - pointer to a length variable to be updated

**/
VOID
CopyStringIntoPerfRecordAndUpdateLength (
  IN OUT CHAR8        *Destination,
  IN     CONST CHAR8  *Source,
  IN OUT UINT8        *Length
  )
{
  UINTN  StringLen;
  UINTN  DestMax;

  ASSERT (Source != NULL);

  if (PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
    DestMax = STRING_SIZE;
  } else {
    DestMax = AsciiStrSize (Source);
    if (DestMax > STRING_SIZE) {
      DestMax = STRING_SIZE;
    }
  }

  StringLen = AsciiStrLen (Source);
  if (StringLen >= DestMax) {
    StringLen = DestMax -1;
  }

  AsciiStrnCpyS (Destination, DestMax, Source, StringLen);
  *Length += (UINT8)DestMax;

  return;
}

/**
  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 Ticker            - 64-bit time stamp.
  @param Address           - Pointer to a location in memory relevant to the measurement.
  @param PerfId            - 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.

  @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                      Ticker,
  IN       UINT64                      Address   OPTIONAL,
  IN       UINT16                      PerfId,
  IN       PERF_MEASUREMENT_ATTRIBUTE  Attribute
  )

{
  EFI_STATUS       Status;
  EFI_GUID         ModuleGuid;
  CHAR8            ModuleName[FPDT_STRING_EVENT_RECORD_NAME_LENGTH];
  FPDT_RECORD_PTR  FpdtRecordPtr;
  FPDT_RECORD_PTR  CachedFpdtRecordPtr;
  UINT64           TimeStamp;
  CONST CHAR8      *StringPtr;
  UINTN            DestMax;
  UINTN            StringLen;
  UINT16           ProgressId;

  StringPtr = NULL;
  ZeroMem (ModuleName, sizeof (ModuleName));

  //
  // 1. Get the Perf Id for records from PERF_START/PERF_END, PERF_START_EX/PERF_END_EX.
  //    notes: For other Perf macros (Attribute == PerfEntry), their Id is known.
  //
  if (Attribute != PerfEntry) {
    //
    // If PERF_START_EX()/PERF_END_EX() have specified the ProgressID,it has high priority.
    // !!! Note: If the Perf is not the known Token used in the core but have same
    // ID with the core Token, this case will not be supported.
    // And in currtnt usage mode, for the unkown ID, there is a general rule:
    // 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 ((PerfId != 0) && (IsKnownID (PerfId)) && (!IsKnownTokens (String))) {
      return EFI_INVALID_PARAMETER;
    } else if ((PerfId != 0) && (!IsKnownID (PerfId)) && (!IsKnownTokens (String))) {
      if ((Attribute == PerfStartEntry) && ((PerfId & 0x000F) != 0)) {
        PerfId &= 0xFFF0;
      } else if ((Attribute == PerfEndEntry) && ((PerfId & 0x000F) == 0)) {
        PerfId += 1;
      }
    }

    if (PerfId == 0) {
      //
      // Get ProgressID form the String Token.
      //
      Status = GetFpdtRecordId (Attribute, CallerIdentifier, String, &ProgressId);
      if (EFI_ERROR (Status)) {
        return Status;
      }

      PerfId = ProgressId;
    }
  }

  //
  // 2. Get the buffer to store the FPDT record.
  //
  Status = GetFpdtRecordPtr (FPDT_MAX_PERF_RECORD_SIZE, &FpdtRecordPtr);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // 3. Get the TimeStamp.
  //
  if (Ticker == 0) {
    Ticker    = GetPerformanceCounter ();
    TimeStamp = GetTimeInNanoSecond (Ticker);
  } else if (Ticker == 1) {
    TimeStamp = 0;
  } else {
    TimeStamp = GetTimeInNanoSecond (Ticker);
  }

  //
  // 4. Fill in the FPDT record according to different Performance Identifier.
  //
  switch (PerfId) {
    case MODULE_START_ID:
    case MODULE_END_ID:
      GetModuleInfoFromHandle ((EFI_HANDLE)CallerIdentifier, ModuleName, sizeof (ModuleName), &ModuleGuid);
      StringPtr = ModuleName;
      //
      // Cache the offset of start image start record and use to update the start image end record if needed.
      //
      if ((PerfId == MODULE_START_ID) && (Attribute == PerfEntry)) {
        mCachedLength = mSmmBootPerformanceTable->Header.Length;
      }

      if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
        FpdtRecordPtr.GuidEvent->Header.Type     = FPDT_GUID_EVENT_TYPE;
        FpdtRecordPtr.GuidEvent->Header.Length   = sizeof (FPDT_GUID_EVENT_RECORD);
        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 ((CallerIdentifier == NULL) && (PerfId == MODULE_END_ID) && (mCachedLength != 0)) {
          CachedFpdtRecordPtr.RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)((UINT8 *)mSmmBootPerformanceTable + mCachedLength);
          CopyMem (&FpdtRecordPtr.GuidEvent->Guid, &CachedFpdtRecordPtr.GuidEvent->Guid, sizeof (FpdtRecordPtr.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++;
        //
        // Cache the offset of load image start record and use to be updated by the load image end record if needed.
        //
        if ((CallerIdentifier == NULL) && (Attribute == PerfEntry)) {
          mCachedLength = mSmmBootPerformanceTable->Header.Length;
        }
      }

      if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
        FpdtRecordPtr.GuidQwordEvent->Header.Type     = FPDT_GUID_QWORD_EVENT_TYPE;
        FpdtRecordPtr.GuidQwordEvent->Header.Length   = sizeof (FPDT_GUID_QWORD_EVENT_RECORD);
        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 ((String == NULL) || (Guid == NULL)) {
        return EFI_INVALID_PARAMETER;
      }

      StringPtr = String;
      if (AsciiStrLen (String) == 0) {
        StringPtr = "unknown name";
      }

      if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
        FpdtRecordPtr.DualGuidStringEvent->Header.Type     = FPDT_DUAL_GUID_STRING_EVENT_TYPE;
        FpdtRecordPtr.DualGuidStringEvent->Header.Length   = sizeof (FPDT_DUAL_GUID_STRING_EVENT_RECORD);
        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));
        CopyStringIntoPerfRecordAndUpdateLength (FpdtRecordPtr.DualGuidStringEvent->String, StringPtr, &FpdtRecordPtr.DualGuidStringEvent->Header.Length);
      }

      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:
      GetModuleInfoFromHandle ((EFI_HANDLE)CallerIdentifier, ModuleName, sizeof (ModuleName), &ModuleGuid);
      if (String != NULL) {
        StringPtr = String;
      } else {
        StringPtr = ModuleName;
      }

      if (AsciiStrLen (StringPtr) == 0) {
        StringPtr = "unknown name";
      }

      if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
        FpdtRecordPtr.DynamicStringEvent->Header.Type     = FPDT_DYNAMIC_STRING_EVENT_TYPE;
        FpdtRecordPtr.DynamicStringEvent->Header.Length   = sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD);
        FpdtRecordPtr.DynamicStringEvent->Header.Revision = FPDT_RECORD_REVISION_1;
        FpdtRecordPtr.DynamicStringEvent->ProgressID      = PerfId;
        FpdtRecordPtr.DynamicStringEvent->Timestamp       = TimeStamp;
        CopyMem (&FpdtRecordPtr.DynamicStringEvent->Guid, &ModuleGuid, sizeof (FpdtRecordPtr.DynamicStringEvent->Guid));
        CopyStringIntoPerfRecordAndUpdateLength (FpdtRecordPtr.DynamicStringEvent->String, StringPtr, &FpdtRecordPtr.DynamicStringEvent->Header.Length);
      }

      break;

    default:
      if (Attribute != PerfEntry) {
        GetModuleInfoFromHandle ((EFI_HANDLE)CallerIdentifier, ModuleName, sizeof (ModuleName), &ModuleGuid);
        if (String != NULL) {
          StringPtr = String;
        } else {
          StringPtr = ModuleName;
        }

        if (AsciiStrLen (StringPtr) == 0) {
          StringPtr = "unknown name";
        }

        if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
          FpdtRecordPtr.DynamicStringEvent->Header.Type     = FPDT_DYNAMIC_STRING_EVENT_TYPE;
          FpdtRecordPtr.DynamicStringEvent->Header.Length   = sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD);
          FpdtRecordPtr.DynamicStringEvent->Header.Revision = FPDT_RECORD_REVISION_1;
          FpdtRecordPtr.DynamicStringEvent->ProgressID      = PerfId;
          FpdtRecordPtr.DynamicStringEvent->Timestamp       = TimeStamp;
          CopyMem (&FpdtRecordPtr.DynamicStringEvent->Guid, &ModuleGuid, sizeof (FpdtRecordPtr.DynamicStringEvent->Guid));
          CopyStringIntoPerfRecordAndUpdateLength (FpdtRecordPtr.DynamicStringEvent->String, StringPtr, &FpdtRecordPtr.DynamicStringEvent->Header.Length);
        }
      } else {
        return EFI_INVALID_PARAMETER;
      }

      break;
  }

  //
  // 4.2 When PcdEdkiiFpdtStringRecordEnableOnly==TRUE, create string record for all Perf entries.
  //
  if (PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
    if (StringPtr == NULL) {
      return EFI_INVALID_PARAMETER;
    }

    FpdtRecordPtr.DynamicStringEvent->Header.Type     = FPDT_DYNAMIC_STRING_EVENT_TYPE;
    FpdtRecordPtr.DynamicStringEvent->Header.Length   = sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD);
    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 (FpdtRecordPtr.DynamicStringEvent->Guid));
    } else {
      CopyMem (&FpdtRecordPtr.DynamicStringEvent->Guid, &ModuleGuid, sizeof (FpdtRecordPtr.DynamicStringEvent->Guid));
    }

    if (AsciiStrLen (StringPtr) == 0) {
      StringPtr = "unknown name";
    }

    CopyStringIntoPerfRecordAndUpdateLength (FpdtRecordPtr.DynamicStringEvent->String, StringPtr, &FpdtRecordPtr.DynamicStringEvent->Header.Length);

    if ((PerfId == MODULE_LOADIMAGE_START_ID) || (PerfId == MODULE_END_ID)) {
      FpdtRecordPtr.DynamicStringEvent->Header.Length = (UINT8)(sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD)+ STRING_SIZE);
    }

    if (((PerfId == MODULE_LOADIMAGE_END_ID) || (PerfId == MODULE_END_ID)) && (mCachedLength != 0)) {
      CachedFpdtRecordPtr.RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)((UINT8 *)mSmmBootPerformanceTable + mCachedLength);
      if (PerfId == MODULE_LOADIMAGE_END_ID) {
        DestMax   = CachedFpdtRecordPtr.DynamicStringEvent->Header.Length - sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD);
        StringLen = AsciiStrLen (StringPtr);
        if (StringLen >= DestMax) {
          StringLen = DestMax -1;
        }

        CopyMem (&CachedFpdtRecordPtr.DynamicStringEvent->Guid, &ModuleGuid, sizeof (CachedFpdtRecordPtr.DynamicStringEvent->Guid));
        AsciiStrnCpyS (CachedFpdtRecordPtr.DynamicStringEvent->String, DestMax, StringPtr, StringLen);
      } else if (PerfId == MODULE_END_ID) {
        DestMax   = FpdtRecordPtr.DynamicStringEvent->Header.Length - sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD);
        StringLen = AsciiStrLen (CachedFpdtRecordPtr.DynamicStringEvent->String);
        if (StringLen >= DestMax) {
          StringLen = DestMax -1;
        }

        CopyMem (&FpdtRecordPtr.DynamicStringEvent->Guid, &CachedFpdtRecordPtr.DynamicStringEvent->Guid, sizeof (CachedFpdtRecordPtr.DynamicStringEvent->Guid));
        AsciiStrnCpyS (FpdtRecordPtr.DynamicStringEvent->String, DestMax, CachedFpdtRecordPtr.DynamicStringEvent->String, StringLen);
      }

      mCachedLength = 0;
    }
  }

  //
  // 5. Update the length of the used buffer after fill in the record.
  //
  mPerformanceLength                      += FpdtRecordPtr.RecordHeader->Length;
  mSmmBootPerformanceTable->Header.Length += FpdtRecordPtr.RecordHeader->Length;

  return EFI_SUCCESS;
}

/**
  Communication service SMI Handler entry.

  This SMI handler provides services for report MM boot records.

  Caution: This function may receive untrusted input.
  Communicate buffer and buffer size are external input, so this function will do basic validation.

  @param[in]     DispatchHandle  The unique handle assigned to this handler by SmiHandlerRegister().
  @param[in]     RegisterContext Points to an optional handler context which was specified when the
                                 handler was registered.
  @param[in, out] CommBuffer     A pointer to a collection of data in memory that will
                                 be conveyed from a non-MM environment into an MM environment.
  @param[in, out] CommBufferSize The size of the CommBuffer.

  @retval EFI_SUCCESS                         The interrupt was handled and quiesced. No other handlers
                                              should still be called.
  @retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED  The interrupt has been quiesced but other handlers should
                                              still be called.
  @retval EFI_WARN_INTERRUPT_SOURCE_PENDING   The interrupt is still pending and other handlers should still
                                              be called.
  @retval EFI_INTERRUPT_PENDING               The interrupt could not be quiesced.

**/
EFI_STATUS
EFIAPI
FpdtSmiHandler (
  IN     EFI_HANDLE  DispatchHandle,
  IN     CONST VOID  *RegisterContext,
  IN OUT VOID        *CommBuffer,
  IN OUT UINTN       *CommBufferSize
  )
{
  EFI_STATUS                   Status;
  SMM_BOOT_RECORD_COMMUNICATE  *SmmCommData;
  UINTN                        BootRecordOffset;
  UINTN                        BootRecordSize;
  VOID                         *BootRecordData;
  UINTN                        TempCommBufferSize;
  UINT8                        *BootRecordBuffer;

  //
  // If input is invalid, stop processing this SMI
  //
  if ((CommBuffer == NULL) || (CommBufferSize == NULL)) {
    return EFI_SUCCESS;
  }

  TempCommBufferSize = *CommBufferSize;

  if (TempCommBufferSize < sizeof (SMM_BOOT_RECORD_COMMUNICATE)) {
    return EFI_SUCCESS;
  }

  if (!SmmIsBufferOutsideSmmValid ((UINTN)CommBuffer, TempCommBufferSize)) {
    DEBUG ((DEBUG_ERROR, "FpdtSmiHandler: MM communication data buffer in MMRAM or overflow!\n"));
    return EFI_SUCCESS;
  }

  SmmCommData = (SMM_BOOT_RECORD_COMMUNICATE *)CommBuffer;

  Status = EFI_SUCCESS;

  switch (SmmCommData->Function) {
    case SMM_FPDT_FUNCTION_GET_BOOT_RECORD_SIZE:
      if (mSmmBootPerformanceTable != NULL) {
        mBootRecordSize = mSmmBootPerformanceTable->Header.Length - sizeof (SMM_BOOT_PERFORMANCE_TABLE);
      }

      SmmCommData->BootRecordSize = mBootRecordSize;
      break;

    case SMM_FPDT_FUNCTION_GET_BOOT_RECORD_DATA:
      Status = EFI_UNSUPPORTED;
      break;

    case SMM_FPDT_FUNCTION_GET_BOOT_RECORD_DATA_BY_OFFSET:
      BootRecordOffset = SmmCommData->BootRecordOffset;
      BootRecordData   = SmmCommData->BootRecordData;
      BootRecordSize   = SmmCommData->BootRecordSize;
      if ((BootRecordData == NULL) || (BootRecordOffset >= mBootRecordSize)) {
        Status = EFI_INVALID_PARAMETER;
        break;
      }

      //
      // Sanity check
      //
      if (BootRecordSize > mBootRecordSize - BootRecordOffset) {
        BootRecordSize = mBootRecordSize - BootRecordOffset;
      }

      SmmCommData->BootRecordSize = BootRecordSize;
      if (!SmmIsBufferOutsideSmmValid ((UINTN)BootRecordData, BootRecordSize)) {
        DEBUG ((DEBUG_ERROR, "FpdtSmiHandler: MM Data buffer in MMRAM or overflow!\n"));
        Status = EFI_ACCESS_DENIED;
        break;
      }

      BootRecordBuffer = ((UINT8 *)(mSmmBootPerformanceTable)) + sizeof (SMM_BOOT_PERFORMANCE_TABLE);
      CopyMem (
        (UINT8 *)BootRecordData,
        BootRecordBuffer + BootRecordOffset,
        BootRecordSize
        );
      mFpdtDataIsReported = TRUE;
      break;

    default:
      Status = EFI_UNSUPPORTED;
  }

  SmmCommData->ReturnStatus = Status;

  return EFI_SUCCESS;
}

/**
  This is the Event call back function is triggered in SMM to notify the Library
  the system is entering runtime phase.

  @param[in] Protocol   Points to the protocol's unique identifier
  @param[in] Interface  Points to the interface instance
  @param[in] Handle     The handle on which the interface was installed

  @retval EFI_SUCCESS SmmAtRuntimeCallBack runs successfully
 **/
EFI_STATUS
EFIAPI
SmmCorePerformanceLibExitBootServicesCallback (
  IN CONST EFI_GUID  *Protocol,
  IN VOID            *Interface,
  IN EFI_HANDLE      Handle
  )
{
  //
  // Disable performance measurement after ExitBootServices because
  // 1. Performance measurement might impact SMI latency at runtime;
  // 2. Performance log is copied to non SMRAM at ReadyToBoot so runtime performance
  //    log is not useful.
  //
  mPerformanceMeasurementEnabled = FALSE;

  return EFI_SUCCESS;
}

/**
  SmmBase2 protocol notify callback function, when SMST and SMM memory service get initialized
  this function is callbacked to initialize the Smm Performance Lib

  @param  Event    The event of notify protocol.
  @param  Context  Notify event context.

**/
VOID
EFIAPI
InitializeSmmCorePerformanceLib (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  EFI_HANDLE            Handle;
  EFI_HANDLE            SmiHandle;
  EFI_STATUS            Status;
  PERFORMANCE_PROPERTY  *PerformanceProperty;
  VOID                  *Registration;

  //
  // Initialize spin lock
  //
  InitializeSpinLock (&mSmmFpdtLock);

  //
  // Install the protocol interfaces for SMM performance library instance.
  //
  Handle = NULL;
  Status = gSmst->SmmInstallProtocolInterface (
                    &Handle,
                    &gEdkiiSmmPerformanceMeasurementProtocolGuid,
                    EFI_NATIVE_INTERFACE,
                    &mPerformanceMeasurementInterface
                    );
  ASSERT_EFI_ERROR (Status);

  //
  // Register SMI handler.
  //
  SmiHandle = NULL;
  Status    = gSmst->SmiHandlerRegister (FpdtSmiHandler, &gEfiFirmwarePerformanceGuid, &SmiHandle);
  ASSERT_EFI_ERROR (Status);

  Status = EfiGetSystemConfigurationTable (&gPerformanceProtocolGuid, (VOID **)&PerformanceProperty);
  if (EFI_ERROR (Status)) {
    //
    // Install configuration table for performance property.
    //
    mPerformanceProperty.Revision  = PERFORMANCE_PROPERTY_REVISION;
    mPerformanceProperty.Reserved  = 0;
    mPerformanceProperty.Frequency = GetPerformanceCounterProperties (
                                       &mPerformanceProperty.TimerStartValue,
                                       &mPerformanceProperty.TimerEndValue
                                       );
    Status = gBS->InstallConfigurationTable (&gPerformanceProtocolGuid, &mPerformanceProperty);
    ASSERT_EFI_ERROR (Status);
  }

  //
  // Register callback function for ExitBootServices event.
  //
  Status = gSmst->SmmRegisterProtocolNotify (
                    &gEdkiiSmmExitBootServicesProtocolGuid,
                    SmmCorePerformanceLibExitBootServicesCallback,
                    &Registration
                    );
  ASSERT_EFI_ERROR (Status);
}

/**
  The constructor function initializes the Performance Measurement Enable flag and
  registers SmmBase2 protocol notify callback.
  It will ASSERT() if one of these operations fails and it will always return EFI_SUCCESS.

  @param  ImageHandle   The firmware allocated handle for the EFI image.
  @param  SystemTable   A pointer to the EFI System Table.

  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.

**/
EFI_STATUS
EFIAPI
SmmCorePerformanceLibConstructor (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS  Status;
  EFI_EVENT   Event;
  VOID        *Registration;

  mPerformanceMeasurementEnabled =  (BOOLEAN)((PcdGet8 (PcdPerformanceLibraryPropertyMask) & PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED) != 0);

  if (!PerformanceMeasurementEnabled ()) {
    //
    // Do not initialize performance infrastructure if not required.
    //
    return EFI_SUCCESS;
  }

  //
  // Create the events to do the library init.
  //
  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  InitializeSmmCorePerformanceLib,
                  NULL,
                  &Event
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // Register for protocol notifications on this event
  //
  Status = gBS->RegisterProtocolNotify (
                  &gEfiSmmBase2ProtocolGuid,
                  Event,
                  &Registration
                  );

  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;

  Status = EFI_SUCCESS;

  AcquireSpinLock (&mSmmFpdtLock);
  Status = InsertFpdtRecord (CallerIdentifier, Guid, String, TimeStamp, Address, (UINT16)Identifier, Attribute);
  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
  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 StartPerformanceMeasurement.

  @retval RETURN_SUCCESS          The start of the measurement was recorded.
  @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.

**/
RETURN_STATUS
EFIAPI
StartPerformanceMeasurementEx (
  IN CONST VOID   *Handle   OPTIONAL,
  IN CONST CHAR8  *Token    OPTIONAL,
  IN CONST CHAR8  *Module   OPTIONAL,
  IN UINT64       TimeStamp,
  IN UINT32       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.

  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 RETURN_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 EndPerformanceMeasurement.

  @retval RETURN_SUCCESS          The end of  the measurement was recorded.
  @retval RETURN_NOT_FOUND        The specified measurement record could not be found.

**/
RETURN_STATUS
EFIAPI
EndPerformanceMeasurementEx (
  IN CONST VOID   *Handle   OPTIONAL,
  IN CONST CHAR8  *Token    OPTIONAL,
  IN CONST CHAR8  *Module   OPTIONAL,
  IN UINT64       TimeStamp,
  IN UINT32       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,
  and then assign the Identifier with 0.

  !!! Not Support!!!

  Attempts to retrieve the performance log entry specified by LogEntryKey.  If LogEntryKey is
  zero on entry, then an attempt is made to retrieve the first entry from the performance log,
  and the key for the second entry in the log is returned.  If the performance log is empty,
  then no entry is retrieved and zero is returned.  If LogEntryKey is not zero, then the performance
  log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is
  returned.  If LogEntryKey is the key for the last entry in the log, then the last log entry is
  retrieved and an implementation specific non-zero key value that specifies the end of the performance
  log is returned.  If LogEntryKey is equal this implementation specific non-zero key value, then no entry
  is retrieved and zero is returned.  In the cases where a performance log entry can be returned,
  the log entry is returned in Handle, Token, Module, StartTimeStamp, EndTimeStamp and Identifier.
  If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().
  If Handle is NULL, then ASSERT().
  If Token is NULL, then ASSERT().
  If Module is NULL, then ASSERT().
  If StartTimeStamp is NULL, then ASSERT().
  If EndTimeStamp is NULL, then ASSERT().
  If Identifier is NULL, then ASSERT().

  @param  LogEntryKey             On entry, the key of the performance measurement log entry to retrieve.
                                  0, then the first performance measurement log entry is retrieved.
                                  On exit, the key of the next performance log entry.
  @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  StartTimeStamp          Pointer to the 64-bit time stamp that was recorded when the measurement
                                  was started.
  @param  EndTimeStamp            Pointer to the 64-bit time stamp that was recorded when the measurement
                                  was ended.
  @param  Identifier              Pointer to the 32-bit identifier that was recorded.

  @return The key for the next performance log entry (in general case).

**/
UINTN
EFIAPI
GetPerformanceMeasurementEx (
  IN  UINTN        LogEntryKey,
  OUT CONST VOID   **Handle,
  OUT CONST CHAR8  **Token,
  OUT CONST CHAR8  **Module,
  OUT UINT64       *StartTimeStamp,
  OUT UINT64       *EndTimeStamp,
  OUT UINT32       *Identifier
  )
{
  return 0;
}

/**
  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 RETURN_SUCCESS          The start of the measurement was recorded.
  @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.

**/
RETURN_STATUS
EFIAPI
StartPerformanceMeasurement (
  IN CONST VOID   *Handle   OPTIONAL,
  IN CONST CHAR8  *Token    OPTIONAL,
  IN CONST CHAR8  *Module   OPTIONAL,
  IN UINT64       TimeStamp
  )
{
  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.

  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 RETURN_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 RETURN_SUCCESS          The end of  the measurement was recorded.
  @retval RETURN_NOT_FOUND        The specified measurement record could not be found.

**/
RETURN_STATUS
EFIAPI
EndPerformanceMeasurement (
  IN CONST VOID   *Handle   OPTIONAL,
  IN CONST CHAR8  *Token    OPTIONAL,
  IN CONST CHAR8  *Module   OPTIONAL,
  IN UINT64       TimeStamp
  )
{
  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,
  and then eliminate the Identifier.

  !!! Not Support!!!

  Attempts to retrieve the performance log entry specified by LogEntryKey.  If LogEntryKey is
  zero on entry, then an attempt is made to retrieve the first entry from the performance log,
  and the key for the second entry in the log is returned.  If the performance log is empty,
  then no entry is retrieved and zero is returned.  If LogEntryKey is not zero, then the performance
  log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is
  returned.  If LogEntryKey is the key for the last entry in the log, then the last log entry is
  retrieved and an implementation specific non-zero key value that specifies the end of the performance
  log is returned.  If LogEntryKey is equal this implementation specific non-zero key value, then no entry
  is retrieved and zero is returned.  In the cases where a performance log entry can be returned,
  the log entry is returned in Handle, Token, Module, StartTimeStamp, and EndTimeStamp.
  If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().
  If Handle is NULL, then ASSERT().
  If Token is NULL, then ASSERT().
  If Module is NULL, then ASSERT().
  If StartTimeStamp is NULL, then ASSERT().
  If EndTimeStamp is NULL, then ASSERT().

  @param  LogEntryKey             On entry, the key of the performance measurement log entry to retrieve.
                                  0, then the first performance measurement log entry is retrieved.
                                  On exit, the key of the next performance log entry.
  @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  StartTimeStamp          Pointer to the 64-bit time stamp that was recorded when the measurement
                                  was started.
  @param  EndTimeStamp            Pointer to the 64-bit time stamp that was recorded when the measurement
                                  was ended.

  @return The key for the next performance log entry (in general case).

**/
UINTN
EFIAPI
GetPerformanceMeasurement (
  IN  UINTN        LogEntryKey,
  OUT CONST VOID   **Handle,
  OUT CONST CHAR8  **Token,
  OUT CONST CHAR8  **Module,
  OUT UINT64       *StartTimeStamp,
  OUT UINT64       *EndTimeStamp
  )
{
  return 0;
}

/**
  Returns TRUE if the performance measurement macros are enabled.

  This function returns TRUE if the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
  PcdPerformanceLibraryPropertyMask is set.  Otherwise FALSE is returned.

  @retval TRUE                    The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
                                  PcdPerformanceLibraryPropertyMask is set.
  @retval FALSE                   The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
                                  PcdPerformanceLibraryPropertyMask is clear.

**/
BOOLEAN
EFIAPI
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
  )
{
  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;
}
