/** @file
  Performance library instance mainly used by DxeCore.

  This library provides the performance measurement interfaces and initializes performance
  logging for DXE phase. It first initializes its private global data structure for
  performance logging and saves the performance GUIDed HOB passed from PEI phase.
  It initializes DXE phase performance logging by publishing the Performance and PerformanceEx Protocol,
  which are consumed by DxePerformanceLib to logging performance data in DXE phase.

  This library is mainly used by DxeCore to start performance logging to ensure that
  Performance Protocol is installed at the very beginning of DXE phase.

Copyright (c) 2006 - 2023, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "DxeCorePerformanceLibInternal.h"

//
// Data for FPDT performance records.
//
#define SMM_BOOT_RECORD_COMM_SIZE  (OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data) + sizeof(SMM_BOOT_RECORD_COMMUNICATE))
#define STRING_SIZE                (FPDT_STRING_EVENT_RECORD_NAME_LENGTH * sizeof (CHAR8))
#define FIRMWARE_RECORD_BUFFER     0x10000
#define CACHE_HANDLE_GUID_COUNT    0x800

BOOT_PERFORMANCE_TABLE  *mAcpiBootPerformanceTable    = NULL;
BOOT_PERFORMANCE_TABLE  mBootPerformanceTableTemplate = {
  {
    EFI_ACPI_5_0_FPDT_BOOT_PERFORMANCE_TABLE_SIGNATURE,
    sizeof (BOOT_PERFORMANCE_TABLE)
  },
  {
    {
      EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_TYPE_FIRMWARE_BASIC_BOOT,    // Type
      sizeof (EFI_ACPI_5_0_FPDT_FIRMWARE_BASIC_BOOT_RECORD),        // Length
      EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_REVISION_FIRMWARE_BASIC_BOOT // Revision
    },
    0,  // Reserved
    //
    // These values will be updated at runtime.
    //
    0,  // ResetEnd
    0,  // OsLoaderLoadImageStart
    0,  // OsLoaderStartImageStart
    0,  // ExitBootServicesEntry
    0   // ExitBootServicesExit
  }
};

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  mLoadImageCount       = 0;
UINT32  mPerformanceLength    = 0;
UINT32  mMaxPerformanceLength = 0;
UINT32  mBootRecordSize       = 0;
UINTN   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;
UINTN    mSmmBootRecordOffset  = 0;

EFI_DEVICE_PATH_TO_TEXT_PROTOCOL  *mDevicePathToText = NULL;

//
// Interfaces for PerformanceMeasurement Protocol.
//
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

@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;
  }
}

/**
  This internal function dumps all the SMM performance data and size.

  @param    SmmPerfData        Smm Performance data. The buffer contain the SMM perf data is allocated by this function and caller needs to free it.
  @param    SmmPerfDataSize    Smm Performance data size.
  @param    SkipGetPerfData    Skip to get performance data, just get the size.

**/
VOID
InternalGetSmmPerfData (
  OUT VOID     **SmmPerfData,
  OUT UINTN    *SmmPerfDataSize,
  IN  BOOLEAN  SkipGetPerfData
  )
{
  EFI_STATUS                               Status;
  UINT8                                    *SmmBootRecordCommBuffer;
  EFI_SMM_COMMUNICATE_HEADER               *SmmCommBufferHeader;
  SMM_BOOT_RECORD_COMMUNICATE              *SmmCommData;
  UINTN                                    CommSize;
  EFI_SMM_COMMUNICATION_PROTOCOL           *Communication;
  EDKII_PI_SMM_COMMUNICATION_REGION_TABLE  *SmmCommRegionTable;
  EFI_MEMORY_DESCRIPTOR                    *SmmCommMemRegion;
  UINTN                                    Index;
  VOID                                     *SmmBootRecordData;
  UINTN                                    SmmBootRecordDataSize;
  UINTN                                    ReservedMemSize;
  UINTN                                    SmmBootRecordDataRetrieved;

  //
  // Collect boot records from SMM drivers.
  //
  SmmBootRecordCommBuffer = NULL;
  SmmCommData             = NULL;
  SmmBootRecordData       = NULL;
  ReservedMemSize         = 0;
  Status                  = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **)&Communication);
  if (!EFI_ERROR (Status)) {
    //
    // Initialize communicate buffer
    // Get the prepared Reserved Memory Range
    //
    Status = EfiGetSystemConfigurationTable (
               &gEdkiiPiSmmCommunicationRegionTableGuid,
               (VOID **)&SmmCommRegionTable
               );
    if (!EFI_ERROR (Status)) {
      ASSERT (SmmCommRegionTable != NULL);
      SmmCommMemRegion = (EFI_MEMORY_DESCRIPTOR *)(SmmCommRegionTable + 1);
      for (Index = 0; Index < SmmCommRegionTable->NumberOfEntries; Index++) {
        if (SmmCommMemRegion->Type == EfiConventionalMemory) {
          break;
        }

        SmmCommMemRegion = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)SmmCommMemRegion + SmmCommRegionTable->DescriptorSize);
      }

      ASSERT (Index < SmmCommRegionTable->NumberOfEntries);
      ASSERT (SmmCommMemRegion->PhysicalStart > 0);
      ASSERT (SmmCommMemRegion->NumberOfPages > 0);
      ReservedMemSize = (UINTN)SmmCommMemRegion->NumberOfPages * EFI_PAGE_SIZE;

      //
      // Check enough reserved memory space
      //
      if (ReservedMemSize > SMM_BOOT_RECORD_COMM_SIZE) {
        SmmBootRecordCommBuffer = (VOID *)(UINTN)SmmCommMemRegion->PhysicalStart;
        SmmCommBufferHeader     = (EFI_SMM_COMMUNICATE_HEADER *)SmmBootRecordCommBuffer;
        SmmCommData             = (SMM_BOOT_RECORD_COMMUNICATE *)SmmCommBufferHeader->Data;
        ZeroMem ((UINT8 *)SmmCommData, sizeof (SMM_BOOT_RECORD_COMMUNICATE));

        CopyGuid (&SmmCommBufferHeader->HeaderGuid, &gEfiFirmwarePerformanceGuid);
        SmmCommBufferHeader->MessageLength = sizeof (SMM_BOOT_RECORD_COMMUNICATE);
        CommSize                           = SMM_BOOT_RECORD_COMM_SIZE;

        //
        // Get the size of boot records.
        //
        SmmCommData->Function       = SMM_FPDT_FUNCTION_GET_BOOT_RECORD_SIZE;
        SmmCommData->BootRecordData = NULL;
        Status                      = Communication->Communicate (Communication, SmmBootRecordCommBuffer, &CommSize);

        if (!EFI_ERROR (Status) && !EFI_ERROR (SmmCommData->ReturnStatus) && (SmmCommData->BootRecordSize != 0)) {
          if (SkipGetPerfData) {
            *SmmPerfDataSize = SmmCommData->BootRecordSize;
            return;
          }

          //
          // Get boot records starting from mSmmBootRecordOffset
          //
          SmmCommData->Function         = SMM_FPDT_FUNCTION_GET_BOOT_RECORD_DATA_BY_OFFSET;
          SmmCommData->BootRecordOffset = mSmmBootRecordOffset;
          SmmBootRecordDataSize         = SmmCommData->BootRecordSize - mSmmBootRecordOffset;
          SmmBootRecordData             = AllocateZeroPool (SmmBootRecordDataSize);
          SmmBootRecordDataRetrieved    = 0;
          ASSERT (SmmBootRecordData  != NULL);
          SmmCommData->BootRecordData = (VOID *)((UINTN)SmmCommMemRegion->PhysicalStart + SMM_BOOT_RECORD_COMM_SIZE);
          SmmCommData->BootRecordSize = ReservedMemSize - SMM_BOOT_RECORD_COMM_SIZE;
          while (SmmBootRecordDataRetrieved < SmmBootRecordDataSize) {
            Status = Communication->Communicate (Communication, SmmBootRecordCommBuffer, &CommSize);
            ASSERT_EFI_ERROR (Status);
            ASSERT_EFI_ERROR (SmmCommData->ReturnStatus);
            if (SmmBootRecordDataRetrieved + SmmCommData->BootRecordSize > SmmBootRecordDataSize) {
              CopyMem ((UINT8 *)SmmBootRecordData + SmmBootRecordDataRetrieved, SmmCommData->BootRecordData, SmmBootRecordDataSize - SmmBootRecordDataRetrieved);
            } else {
              CopyMem ((UINT8 *)SmmBootRecordData + SmmBootRecordDataRetrieved, SmmCommData->BootRecordData, SmmCommData->BootRecordSize);
            }

            SmmBootRecordDataRetrieved    += SmmCommData->BootRecordSize;
            SmmCommData->BootRecordOffset += SmmCommData->BootRecordSize;
          }

          mSmmBootRecordOffset = SmmCommData->BootRecordOffset;

          *SmmPerfData     = SmmBootRecordData;
          *SmmPerfDataSize = SmmBootRecordDataSize;
        }
      }
    }
  }
}

/**
  Allocate buffer for Boot Performance table.

  @return Status code.

**/
EFI_STATUS
AllocateBootPerformanceTable (
  VOID
  )
{
  EFI_STATUS                     Status;
  UINTN                          Size;
  UINTN                          BootPerformanceDataSize;
  UINT8                          *BootPerformanceData;
  FIRMWARE_PERFORMANCE_VARIABLE  PerformanceVariable;
  UINTN                          SmmBootRecordDataSize;

  SmmBootRecordDataSize = 0;

  //
  // Get SMM performance data size at the point of EndOfDxe in order to allocate the boot performance table.
  // Will Get all the data at ReadyToBoot.
  //
  InternalGetSmmPerfData (NULL, &SmmBootRecordDataSize, TRUE);

  //
  // Prepare memory for Boot Performance table.
  // Boot Performance table includes BasicBoot record, and one or more appended Boot Records.
  //
  BootPerformanceDataSize = sizeof (BOOT_PERFORMANCE_TABLE) + mPerformanceLength + SmmBootRecordDataSize + PcdGet32 (PcdExtFpdtBootRecordPadSize);

  //
  // Try to allocate the same runtime buffer as last time boot.
  //
  ZeroMem (&PerformanceVariable, sizeof (PerformanceVariable));
  Size   = sizeof (PerformanceVariable);
  Status = gRT->GetVariable (
                  EFI_FIRMWARE_PERFORMANCE_VARIABLE_NAME,
                  &gEfiFirmwarePerformanceGuid,
                  NULL,
                  &Size,
                  &PerformanceVariable
                  );
  if (!EFI_ERROR (Status)) {
    Status = gBS->AllocatePages (
                    AllocateAddress,
                    EfiReservedMemoryType,
                    EFI_SIZE_TO_PAGES (BootPerformanceDataSize),
                    &PerformanceVariable.BootPerformanceTablePointer
                    );
    if (!EFI_ERROR (Status)) {
      mAcpiBootPerformanceTable = (BOOT_PERFORMANCE_TABLE *)(UINTN)PerformanceVariable.BootPerformanceTablePointer;
    }
  }

  if (mAcpiBootPerformanceTable == NULL) {
    //
    // Fail to allocate at specified address, continue to allocate at any address.
    //
    mAcpiBootPerformanceTable = (BOOT_PERFORMANCE_TABLE *)AllocatePeiAccessiblePages (
                                                            EfiReservedMemoryType,
                                                            EFI_SIZE_TO_PAGES (BootPerformanceDataSize)
                                                            );
    if (mAcpiBootPerformanceTable != NULL) {
      ZeroMem (mAcpiBootPerformanceTable, BootPerformanceDataSize);
    }
  }

  DEBUG ((DEBUG_INFO, "DxeCorePerformanceLib: ACPI Boot Performance Table address = 0x%x\n", mAcpiBootPerformanceTable));

  if (mAcpiBootPerformanceTable == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Prepare Boot Performance Table.
  //
  BootPerformanceData = (UINT8 *)mAcpiBootPerformanceTable;
  //
  // Fill Basic Boot record to Boot Performance Table.
  //
  CopyMem (mAcpiBootPerformanceTable, &mBootPerformanceTableTemplate, sizeof (mBootPerformanceTableTemplate));
  BootPerformanceData = BootPerformanceData + mAcpiBootPerformanceTable->Header.Length;
  //
  // Fill Boot records from boot drivers.
  //
  if (mPerformancePointer != NULL) {
    CopyMem (BootPerformanceData, mPerformancePointer, mPerformanceLength);
    mAcpiBootPerformanceTable->Header.Length += mPerformanceLength;
    BootPerformanceData                       = BootPerformanceData + mPerformanceLength;
    FreePool (mPerformancePointer);
    mPerformancePointer   = NULL;
    mPerformanceLength    = 0;
    mMaxPerformanceLength = 0;
  }

  mBootRecordBuffer  = (UINT8 *)mAcpiBootPerformanceTable;
  mBootRecordSize    = mAcpiBootPerformanceTable->Header.Length;
  mBootRecordMaxSize = BootPerformanceDataSize;

  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
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;
  EFI_COMPONENT_NAME2_PROTOCOL       *ComponentName2;
  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;
    }
  }

  //
  // Method 2: Get the name string from ComponentName2 protocol
  //
  Status = gBS->HandleProtocol (
                  Handle,
                  &gEfiComponentName2ProtocolGuid,
                  (VOID **)&ComponentName2
                  );
  if (!EFI_ERROR (Status)) {
    //
    // Get the current platform language setting
    //
    if (mPlatformLanguage == NULL) {
      GetEfiGlobalVariable2 (L"PlatformLang", (VOID **)&mPlatformLanguage, NULL);
    }

    if (mPlatformLanguage != NULL) {
      Status = ComponentName2->GetDriverName (
                                 ComponentName2,
                                 mPlatformLanguage != NULL ? mPlatformLanguage : "en-US",
                                 &StringPtr
                                 );
      if (!EFI_ERROR (Status)) {
        for (Index = 0; Index < BufferSize - 1 && StringPtr[Index] != 0; Index++) {
          NameString[Index] = (CHAR8)StringPtr[Index];
        }

        NameString[Index] = 0;
        //
        // Module Name is got.
        //
        goto Done;
      }
    }
  }

  if (ModuleGuidIsGet) {
    //
    // Method 3 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;
}

/**
  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 PerfId.
  //
  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 if (AsciiStrCmp (String, DRIVERBINDING_START_TOK) == 0) {
      // "DB:Start:"
      if (Attribute == PerfStartEntry) {
        *ProgressID = MODULE_DB_START_ID;
      } else {
        *ProgressID = MODULE_DB_END_ID;
      }
    } else if (AsciiStrCmp (String, DRIVERBINDING_SUPPORT_TOK) == 0) {
      // "DB:Support:"
      if (PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
        return RETURN_UNSUPPORTED;
      }

      if (Attribute == PerfStartEntry) {
        *ProgressID = MODULE_DB_SUPPORT_START_ID;
      } else {
        *ProgressID = MODULE_DB_SUPPORT_END_ID;
      }
    } else if (AsciiStrCmp (String, DRIVERBINDING_STOP_TOK) == 0) {
      // "DB:Stop:"
      if (PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
        return RETURN_UNSUPPORTED;
      }

      if (Attribute == PerfStartEntry) {
        *ProgressID = MODULE_DB_STOP_START_ID;
      } else {
        *ProgressID = MODULE_DB_STOP_END_ID;
      }
    } else if ((AsciiStrCmp (String, PEI_TOK) == 0) ||                 // "PEI"
               (AsciiStrCmp (String, DXE_TOK) == 0) ||                 // "DXE"
               (AsciiStrCmp (String, BDS_TOK) == 0))                   // "BDS"
    {
      if (Attribute == PerfStartEntry) {
        *ProgressID = PERF_CROSSMODULE_START_ID;
      } else {
        *ProgressID = PERF_CROSSMODULE_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_INVALID_PARAMETER;
  }

  return EFI_SUCCESS;
}

/**
  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;
}

/**
  Get a string description for device for the given controller handle and update record
  length. 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 ComponentNameString - Pointer to a location where the string will be saved
  @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,
  OUT CHAR8      *ComponentNameString,
  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 FPDT_MAX_PERF_RECORD_SIZE worth of the record
      //
      ControllerNameStringSize = FPDT_MAX_PERF_RECORD_SIZE - (*Length) - 1;
    }

    UnicodeStrnToAsciiStrS (StringPtr, ControllerNameStringSize - 1, ComponentNameString, ControllerNameStringSize, &ControllerNameStringSize);

    //
    // Add a space in the end of the ControllerName
    //
    AsciiStringPtr  = ComponentNameString + 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 FPDT_MAX_PERF_RECORD_SIZE worth of the record
        //
        DevicePathStringSize = FPDT_MAX_PERF_RECORD_SIZE - (*Length);
      }

      if (ControllerNameStringSize != 0) {
        AsciiStringPtr = ComponentNameString + ControllerNameStringSize - 1;
      } else {
        AsciiStringPtr = ComponentNameString;
      }

      UnicodeStrnToAsciiStrS (StringPtr, DevicePathStringSize - 1, AsciiStringPtr, DevicePathStringSize, &DevicePathStringSize);
      *Length += (UINT8)DevicePathStringSize;
      return EFI_SUCCESS;
    }
  }

  return EFI_UNSUPPORTED;
}

/**
  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_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;
  EFI_STATUS       Status;
  UINT16           ProgressId;

  StringPtr  = NULL;
  ProgressId = 0;
  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;
      }
    } else 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 ((Attribute == PerfEntry) && (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   = 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)) {
          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 (&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)) {
          if (mFpdtBufferIsReported) {
            mCachedLength = mBootRecordSize;
          } else {
            mCachedLength = mPerformanceLength;
          }
        }
      }

      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)) {
          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:
      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   = 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           = Address;
        CopyMem (&FpdtRecordPtr.GuidQwordEvent->Guid, &ModuleGuid, sizeof (FpdtRecordPtr.GuidQwordEvent->Guid));
      }

      break;

    case MODULE_DB_END_ID:
      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   = sizeof (FPDT_GUID_QWORD_STRING_EVENT_RECORD);
        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));
        if (Address != 0) {
          GetDeviceInfoFromHandleAndUpdateLength (CallerIdentifier, (EFI_HANDLE)(UINTN)Address, FpdtRecordPtr.GuidQwordStringEvent->String, &FpdtRecordPtr.GuidQwordStringEvent->Header.Length);
        }
      }

      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) || (PerfId == MODULE_DB_SUPPORT_START_ID) || (PerfId == MODULE_DB_SUPPORT_END_ID)) {
      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)) {
      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);
      }

      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.
  //
  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.

  @param  HobStart      A pointer to a Guid.

  This internal function dumps all the PEI performance log to the DXE performance gauge array.
  It retrieves the optional GUID HOB for PEI performance and then saves the performance data
  to DXE performance data structures.

**/
VOID
InternalGetPeiPerformance (
  VOID  *HobStart
  )
{
  UINT8                     *FirmwarePerformanceHob;
  FPDT_PEI_EXT_PERF_HEADER  *PeiPerformanceLogHeader;
  UINT8                     *EventRec;
  EFI_HOB_GUID_TYPE         *GuidHob;

  GuidHob = GetNextGuidHob (&gEdkiiFpdtExtendedFirmwarePerformanceGuid, HobStart);
  while (GuidHob != NULL) {
    FirmwarePerformanceHob  = GET_GUID_HOB_DATA (GuidHob);
    PeiPerformanceLogHeader = (FPDT_PEI_EXT_PERF_HEADER *)FirmwarePerformanceHob;

    if (mPerformanceLength + PeiPerformanceLogHeader->SizeOfAllEntries > mMaxPerformanceLength) {
      mPerformancePointer = ReallocatePool (
                              mPerformanceLength,
                              mPerformanceLength +
                              (UINTN)PeiPerformanceLogHeader->SizeOfAllEntries +
                              FIRMWARE_RECORD_BUFFER,
                              mPerformancePointer
                              );
      ASSERT (mPerformancePointer != NULL);
      mMaxPerformanceLength = mPerformanceLength +
                              (UINTN)(PeiPerformanceLogHeader->SizeOfAllEntries) +
                              FIRMWARE_RECORD_BUFFER;
    }

    EventRec = mPerformancePointer + mPerformanceLength;
    CopyMem (EventRec, FirmwarePerformanceHob + sizeof (FPDT_PEI_EXT_PERF_HEADER), (UINTN)(PeiPerformanceLogHeader->SizeOfAllEntries));
    //
    // Update the used buffer size.
    //
    mPerformanceLength += (UINTN)(PeiPerformanceLogHeader->SizeOfAllEntries);
    mLoadImageCount    += PeiPerformanceLogHeader->LoadImageCount;

    //
    // Get next performance guid hob
    //
    GuidHob = GetNextGuidHob (&gEdkiiFpdtExtendedFirmwarePerformanceGuid, GET_NEXT_HOB (GuidHob));
  }
}

/**
  Report Boot Perforamnce table address as report status code.

  @param  Event    The event of notify protocol.
  @param  Context  Notify event context.

**/
VOID
EFIAPI
ReportFpdtRecordBuffer (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  EFI_STATUS  Status;
  UINT64      BPDTAddr;

  if (!mFpdtBufferIsReported) {
    Status = AllocateBootPerformanceTable ();
    if (!EFI_ERROR (Status)) {
      BPDTAddr = (UINT64)(UINTN)mAcpiBootPerformanceTable;
      REPORT_STATUS_CODE_EX (
        EFI_PROGRESS_CODE,
        EFI_SOFTWARE_DXE_BS_DRIVER,
        0,
        NULL,
        &gEdkiiFpdtExtendedFirmwarePerformanceGuid,
        &BPDTAddr,
        sizeof (UINT64)
        );
      Status = gBS->InstallConfigurationTable (&gEdkiiFpdtExtendedFirmwarePerformanceGuid, (VOID *)(UINTN)BPDTAddr);
      ASSERT_EFI_ERROR (Status);
    }

    //
    // Set FPDT report state to TRUE.
    //
    mFpdtBufferIsReported = TRUE;
  }
}

/**
  Update Boot Performance table.

  @param  Event    The event of notify protocol.
  @param  Context  Notify event context.

**/
VOID
EFIAPI
UpdateBootPerformanceTable (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  VOID   *SmmBootRecordData;
  UINTN  SmmBootRecordDataSize;
  UINTN  AppendSize;
  UINT8  *FirmwarePerformanceTablePtr;

  SmmBootRecordDataSize = 0;

  //
  // Get SMM performance data.
  //
  SmmBootRecordData = NULL;
  InternalGetSmmPerfData (&SmmBootRecordData, &SmmBootRecordDataSize, FALSE);

  FirmwarePerformanceTablePtr = (UINT8 *)mAcpiBootPerformanceTable + mAcpiBootPerformanceTable->Header.Length;

  if (mAcpiBootPerformanceTable->Header.Length + SmmBootRecordDataSize > mBootRecordMaxSize) {
    DEBUG ((DEBUG_INFO, "DxeCorePerformanceLib: No enough space to save all SMM boot performance data\n"));
    AppendSize = mBootRecordMaxSize - mAcpiBootPerformanceTable->Header.Length;
  } else {
    AppendSize = SmmBootRecordDataSize;
  }

  if (SmmBootRecordData != NULL) {
    CopyMem (FirmwarePerformanceTablePtr, SmmBootRecordData, AppendSize);
    mAcpiBootPerformanceTable->Header.Length += (UINT32)AppendSize;
    mBootRecordSize                          +=  (UINT32)AppendSize;
    FreePool (SmmBootRecordData);
  }
}

/**
  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.
  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
DxeCorePerformanceLibConstructor (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS            Status;
  EFI_HANDLE            Handle;
  EFI_EVENT             EndOfDxeEvent;
  EFI_EVENT             ReadyToBootEvent;
  PERFORMANCE_PROPERTY  *PerformanceProperty;

  if (!PerformanceMeasurementEnabled ()) {
    //
    // Do not initialize performance infrastructure if not required.
    //
    return EFI_SUCCESS;
  }

  //
  // Dump normal PEI performance records
  //
  InternalGetPeiPerformance (GetHobList ());

  //
  // Install the protocol interfaces for DXE performance library instance.
  //
  Handle = NULL;
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Handle,
                  &gEdkiiPerformanceMeasurementProtocolGuid,
                  &mPerformanceMeasurementInterface,
                  NULL
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // Register EndOfDxe event to allocate the boot performance table and report the table address through status code.
  //
  Status = gBS->CreateEventEx (
                  EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  ReportFpdtRecordBuffer,
                  NULL,
                  &gEfiEndOfDxeEventGroupGuid,
                  &EndOfDxeEvent
                  );

  //
  // Register ReadyToBoot event to update the boot performance table for SMM performance data.
  //
  Status = gBS->CreateEventEx (
                  EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  UpdateBootPerformanceTable,
                  NULL,
                  &gEfiEventReadyToBootGuid,
                  &ReadyToBootEvent
                  );

  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);
  }

  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;

  Status = InsertFpdtRecord (CallerIdentifier, Guid, String, TimeStamp, Address, (UINT16)Identifier, Attribute);

  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
  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 when the measurement
                                  was ended.

  @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 (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;
}
