"Token" is passed through the perf entry, it's may be NULL.
So we need to add NULL pointer check before reference it.
Cc: Liming Gao <liming.gao@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Dandan Bi <dandan.bi@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
(cherry picked from commit c9faac275b)
		
	
		
			
				
	
	
		
			695 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			695 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Performance library instance used in PEI phase.
 | 
						|
 | 
						|
  This file implements all APIs in Performance Library class in MdePkg. It creates
 | 
						|
  performance logging GUIDed HOB on the first performance logging and then logs the
 | 
						|
  performance data to the GUIDed HOB. Due to the limitation of temporary RAM, the maximum
 | 
						|
  number of performance logging entry is specified by PcdMaxPeiPerformanceLogEntries or 
 | 
						|
  PcdMaxPeiPerformanceLogEntries16.
 | 
						|
 | 
						|
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
 | 
						|
(C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>
 | 
						|
This program and the accompanying materials
 | 
						|
are licensed and made available under the terms and conditions of the BSD License
 | 
						|
which accompanies this distribution.  The full text of the license may be found at
 | 
						|
http://opensource.org/licenses/bsd-license.php
 | 
						|
 | 
						|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | 
						|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
 | 
						|
#include <PiPei.h>
 | 
						|
 | 
						|
#include <Guid/ExtendedFirmwarePerformance.h>
 | 
						|
 | 
						|
#include <Library/PerformanceLib.h>
 | 
						|
#include <Library/DebugLib.h>
 | 
						|
#include <Library/HobLib.h>
 | 
						|
#include <Library/BaseLib.h>
 | 
						|
#include <Library/TimerLib.h>
 | 
						|
#include <Library/PcdLib.h>
 | 
						|
#include <Library/BaseMemoryLib.h>
 | 
						|
 | 
						|
#define  STRING_SIZE            (FPDT_STRING_EVENT_RECORD_NAME_LENGTH * sizeof (CHAR8))
 | 
						|
#define  MAX_RECORD_SIZE        (sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD) + STRING_SIZE)
 | 
						|
 | 
						|
/**
 | 
						|
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 info.
 | 
						|
 | 
						|
  @param  IsStart                 TRUE if the performance log is start log.
 | 
						|
  @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  RecordInfo              On return, pointer to the info of the record.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS             Get record info successfully.
 | 
						|
  @retval EFI_UNSUPPORTED         No matched FPDT record.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
GetFpdtRecordInfo (
 | 
						|
  IN BOOLEAN                 IsStart,
 | 
						|
  IN CONST VOID              *Handle,
 | 
						|
  IN CONST CHAR8             *Token,
 | 
						|
  IN CONST CHAR8             *Module,
 | 
						|
  OUT FPDT_BASIC_RECORD_INFO *RecordInfo
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN     StringSize;
 | 
						|
  UINT16    RecordType;
 | 
						|
 | 
						|
  RecordType = FPDT_DYNAMIC_STRING_EVENT_TYPE;
 | 
						|
 | 
						|
  //
 | 
						|
  // Get the ProgressID based on the Token.
 | 
						|
  // When PcdEdkiiFpdtStringRecordEnableOnly is TRUE, all records are with type of FPDT_DYNAMIC_STRING_EVENT_TYPE.
 | 
						|
  //
 | 
						|
  if (Token != NULL) {
 | 
						|
    if (AsciiStrCmp (Token, LOAD_IMAGE_TOK) == 0) {               // "LoadImage:"
 | 
						|
      if (IsStart) {
 | 
						|
        RecordInfo->ProgressID = MODULE_LOADIMAGE_START_ID;
 | 
						|
      } else {
 | 
						|
        RecordInfo->ProgressID = MODULE_LOADIMAGE_END_ID;
 | 
						|
      }
 | 
						|
      if(!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
 | 
						|
        RecordType = FPDT_GUID_QWORD_EVENT_TYPE;
 | 
						|
      }
 | 
						|
    } else if (AsciiStrCmp (Token, SEC_TOK) == 0 ||               // "SEC"
 | 
						|
               AsciiStrCmp (Token, PEI_TOK) == 0) {               // "PEI"
 | 
						|
      if (IsStart) {
 | 
						|
        RecordInfo->ProgressID = PERF_CROSSMODULE_START_ID;
 | 
						|
      } else {
 | 
						|
        RecordInfo->ProgressID = PERF_CROSSMODULE_END_ID;
 | 
						|
      }
 | 
						|
    } else if (AsciiStrCmp (Token, PEIM_TOK) == 0) {              // "PEIM"
 | 
						|
      if (IsStart) {
 | 
						|
        RecordInfo->ProgressID = MODULE_START_ID;
 | 
						|
      } else {
 | 
						|
        RecordInfo->ProgressID = MODULE_END_ID;
 | 
						|
      }
 | 
						|
      if(!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
 | 
						|
        RecordType = FPDT_GUID_EVENT_TYPE;
 | 
						|
      }
 | 
						|
    } else {                                                      //Pref used in Modules.
 | 
						|
      if (IsStart) {
 | 
						|
        RecordInfo->ProgressID = PERF_INMODULE_START_ID;
 | 
						|
      } else {
 | 
						|
        RecordInfo->ProgressID = PERF_INMODULE_END_ID;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  } else if (Module != NULL || Handle != NULL) {                  //Pref used in Modules.
 | 
						|
    if (IsStart) {
 | 
						|
      RecordInfo->ProgressID = PERF_INMODULE_START_ID;
 | 
						|
    } else {
 | 
						|
      RecordInfo->ProgressID = PERF_INMODULE_END_ID;
 | 
						|
    }
 | 
						|
  } else {
 | 
						|
    return EFI_UNSUPPORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Get the Guid and string.
 | 
						|
  //
 | 
						|
  if(PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
 | 
						|
    RecordInfo->RecordSize = sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD) + STRING_SIZE;
 | 
						|
  } else {
 | 
						|
    switch (RecordType) {
 | 
						|
    case FPDT_GUID_EVENT_TYPE:
 | 
						|
      RecordInfo->RecordSize = sizeof (FPDT_GUID_EVENT_RECORD);
 | 
						|
      break;
 | 
						|
 | 
						|
    case FPDT_GUID_QWORD_EVENT_TYPE:
 | 
						|
      RecordInfo->RecordSize = sizeof (FPDT_GUID_QWORD_EVENT_RECORD);
 | 
						|
      break;
 | 
						|
 | 
						|
    case FPDT_DYNAMIC_STRING_EVENT_TYPE:
 | 
						|
      if (Token != NULL) {
 | 
						|
        StringSize = AsciiStrSize (Token);
 | 
						|
      } else if (Module != NULL) {
 | 
						|
        StringSize = AsciiStrSize (Module);
 | 
						|
      } else {
 | 
						|
        StringSize = STRING_SIZE;
 | 
						|
      }
 | 
						|
      RecordInfo->RecordSize  = (UINT8)(sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD) + StringSize);
 | 
						|
      break;
 | 
						|
 | 
						|
    default:
 | 
						|
      //
 | 
						|
      // Other type is unsupported in PEI phase yet, return EFI_UNSUPPORTED
 | 
						|
      //
 | 
						|
      return EFI_UNSUPPORTED;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  RecordInfo->Type = RecordType;
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Convert PEI performance log to FPDT String boot record.
 | 
						|
 | 
						|
  @param  IsStart                 TRUE if the performance log is start log.
 | 
						|
  @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  Ticker                  64-bit time stamp.
 | 
						|
  @param  Identifier              32-bit identifier. If the value is 0, the created record
 | 
						|
                                  is same as the one created by StartGauge of PERFORMANCE_PROTOCOL.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS              Add FPDT boot record.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES     There are not enough resources to record the measurement.
 | 
						|
  @retval EFI_UNSUPPORTED          No matched FPDT record.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
InsertPeiFpdtMeasurement (
 | 
						|
  IN BOOLEAN      IsStart,
 | 
						|
  IN CONST VOID   *Handle,  OPTIONAL
 | 
						|
  IN CONST CHAR8  *Token,   OPTIONAL
 | 
						|
  IN CONST CHAR8  *Module,  OPTIONAL
 | 
						|
  IN UINT64       Ticker,
 | 
						|
  IN UINT32       Identifier
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_HOB_GUID_TYPE                     *GuidHob;
 | 
						|
  UINTN                                 PeiPerformanceSize;
 | 
						|
  UINT8                                 *PeiFirmwarePerformance;
 | 
						|
  FPDT_PEI_EXT_PERF_HEADER              *PeiPerformanceLogHeader;
 | 
						|
  FPDT_RECORD_PTR                       FpdtRecordPtr;
 | 
						|
  FPDT_BASIC_RECORD_INFO                RecordInfo;
 | 
						|
  CONST VOID                            *ModuleGuid;
 | 
						|
  UINTN                                 DestMax;
 | 
						|
  UINTN                                 StrLength;
 | 
						|
  CONST CHAR8                           *StringPtr;
 | 
						|
  EFI_STATUS                            Status;
 | 
						|
  UINT16                                PeiPerformanceLogEntries;
 | 
						|
  UINT64                                TimeStamp;
 | 
						|
 | 
						|
  StringPtr = NULL;
 | 
						|
  FpdtRecordPtr.RecordHeader = NULL;
 | 
						|
  PeiPerformanceLogHeader = NULL;
 | 
						|
 | 
						|
  //
 | 
						|
  // Get record info (type, size, ProgressID and Module Guid).
 | 
						|
  //
 | 
						|
  Status = GetFpdtRecordInfo (IsStart, Handle, Token, Module, &RecordInfo);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // If PERF_START()/PERF_END() 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 ((Identifier != 0) && (IsKnownID (Identifier)) && (!IsKnownTokens (Token))) {
 | 
						|
    return EFI_UNSUPPORTED;
 | 
						|
  } else if ((Identifier != 0) && (!IsKnownID (Identifier)) && (!IsKnownTokens (Token))) {
 | 
						|
    if (IsStart && ((Identifier & 0x000F) != 0)) {
 | 
						|
      Identifier &= 0xFFF0;
 | 
						|
    } else if ((!IsStart) && ((Identifier & 0x000F) == 0)) {
 | 
						|
      Identifier += 1;
 | 
						|
    }
 | 
						|
    RecordInfo.ProgressID = (UINT16)Identifier;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Get the number of PeiPerformanceLogEntries form PCD.
 | 
						|
  //
 | 
						|
  PeiPerformanceLogEntries = (UINT16) (PcdGet16 (PcdMaxPeiPerformanceLogEntries16) != 0 ?
 | 
						|
                                       PcdGet16 (PcdMaxPeiPerformanceLogEntries16) :
 | 
						|
                                       PcdGet8 (PcdMaxPeiPerformanceLogEntries));
 | 
						|
 | 
						|
  //
 | 
						|
  // Create GUID HOB Data.
 | 
						|
  //
 | 
						|
  GuidHob = GetFirstGuidHob (&gEdkiiFpdtExtendedFirmwarePerformanceGuid);
 | 
						|
  PeiFirmwarePerformance = NULL;
 | 
						|
  while (GuidHob != NULL) {
 | 
						|
    //
 | 
						|
    // PEI Performance HOB was found, then return the existing one.
 | 
						|
    //
 | 
						|
    PeiFirmwarePerformance  = (UINT8*)GET_GUID_HOB_DATA (GuidHob);
 | 
						|
    PeiPerformanceLogHeader = (FPDT_PEI_EXT_PERF_HEADER *)PeiFirmwarePerformance;
 | 
						|
    if (!PeiPerformanceLogHeader->HobIsFull && PeiPerformanceLogHeader->SizeOfAllEntries + RecordInfo.RecordSize > PeiPerformanceLogEntries * MAX_RECORD_SIZE) {
 | 
						|
      PeiPerformanceLogHeader->HobIsFull = TRUE;
 | 
						|
    }
 | 
						|
    if (!PeiPerformanceLogHeader->HobIsFull && PeiPerformanceLogHeader->SizeOfAllEntries + RecordInfo.RecordSize <= PeiPerformanceLogEntries * MAX_RECORD_SIZE) {
 | 
						|
      FpdtRecordPtr.RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)(PeiFirmwarePerformance + sizeof (FPDT_PEI_EXT_PERF_HEADER) + PeiPerformanceLogHeader->SizeOfAllEntries);
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // Previous HOB is used, then find next one.
 | 
						|
    //
 | 
						|
    GuidHob = GetNextGuidHob (&gEdkiiFpdtExtendedFirmwarePerformanceGuid, GET_NEXT_HOB (GuidHob));
 | 
						|
  }
 | 
						|
 | 
						|
  if (GuidHob == NULL) {
 | 
						|
    //
 | 
						|
    // PEI Performance HOB was not found, then build one.
 | 
						|
    //
 | 
						|
    PeiPerformanceSize      = sizeof (FPDT_PEI_EXT_PERF_HEADER) +
 | 
						|
                              MAX_RECORD_SIZE * PeiPerformanceLogEntries;
 | 
						|
    PeiFirmwarePerformance  = (UINT8*)BuildGuidHob (&gEdkiiFpdtExtendedFirmwarePerformanceGuid, PeiPerformanceSize);
 | 
						|
    if (PeiFirmwarePerformance != NULL) {
 | 
						|
      ZeroMem (PeiFirmwarePerformance, PeiPerformanceSize);
 | 
						|
    }
 | 
						|
    PeiPerformanceLogHeader = (FPDT_PEI_EXT_PERF_HEADER *)PeiFirmwarePerformance;
 | 
						|
    FpdtRecordPtr.RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)(PeiFirmwarePerformance + sizeof (FPDT_PEI_EXT_PERF_HEADER));
 | 
						|
  }
 | 
						|
 | 
						|
  if (PeiFirmwarePerformance == NULL) {
 | 
						|
    //
 | 
						|
    // there is no enough resource to store performance data
 | 
						|
    //
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Get the TimeStamp.
 | 
						|
  //
 | 
						|
  if (Ticker == 0) {
 | 
						|
    Ticker    = GetPerformanceCounter ();
 | 
						|
    TimeStamp = GetTimeInNanoSecond (Ticker);
 | 
						|
  } else if (Ticker == 1) {
 | 
						|
    TimeStamp = 0;
 | 
						|
  } else {
 | 
						|
    TimeStamp = GetTimeInNanoSecond (Ticker);
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Get the ModuleGuid.
 | 
						|
  //
 | 
						|
  if (Handle != NULL) {
 | 
						|
    ModuleGuid = Handle;
 | 
						|
  } else {
 | 
						|
    ModuleGuid = &gEfiCallerIdGuid;
 | 
						|
  }
 | 
						|
 | 
						|
  switch (RecordInfo.Type) {
 | 
						|
  case FPDT_GUID_EVENT_TYPE:
 | 
						|
    FpdtRecordPtr.GuidEvent->Header.Type       = FPDT_GUID_EVENT_TYPE;
 | 
						|
    FpdtRecordPtr.GuidEvent->Header.Length     = RecordInfo.RecordSize;;
 | 
						|
    FpdtRecordPtr.GuidEvent->Header.Revision   = FPDT_RECORD_REVISION_1;
 | 
						|
    FpdtRecordPtr.GuidEvent->ProgressID        = RecordInfo.ProgressID;
 | 
						|
    FpdtRecordPtr.GuidEvent->Timestamp         = TimeStamp;
 | 
						|
    CopyMem (&FpdtRecordPtr.GuidEvent->Guid, ModuleGuid, sizeof (EFI_GUID));
 | 
						|
    PeiPerformanceLogHeader->SizeOfAllEntries += RecordInfo.RecordSize;
 | 
						|
    break;
 | 
						|
 | 
						|
  case FPDT_GUID_QWORD_EVENT_TYPE:
 | 
						|
    FpdtRecordPtr.GuidQwordEvent->Header.Type     = FPDT_GUID_QWORD_EVENT_TYPE;
 | 
						|
    FpdtRecordPtr.GuidQwordEvent->Header.Length   = RecordInfo.RecordSize;;
 | 
						|
    FpdtRecordPtr.GuidQwordEvent->Header.Revision = FPDT_RECORD_REVISION_1;
 | 
						|
    FpdtRecordPtr.GuidQwordEvent->ProgressID      = RecordInfo.ProgressID;
 | 
						|
    FpdtRecordPtr.GuidQwordEvent->Timestamp       = TimeStamp;
 | 
						|
    PeiPerformanceLogHeader->LoadImageCount++;
 | 
						|
    FpdtRecordPtr.GuidQwordEvent->Qword           = PeiPerformanceLogHeader->LoadImageCount;
 | 
						|
    CopyMem (&FpdtRecordPtr.GuidQwordEvent->Guid, ModuleGuid, sizeof (EFI_GUID));
 | 
						|
    PeiPerformanceLogHeader->SizeOfAllEntries += RecordInfo.RecordSize;
 | 
						|
    break;
 | 
						|
 | 
						|
  case FPDT_DYNAMIC_STRING_EVENT_TYPE:
 | 
						|
    FpdtRecordPtr.DynamicStringEvent->Header.Type       = FPDT_DYNAMIC_STRING_EVENT_TYPE;
 | 
						|
    FpdtRecordPtr.DynamicStringEvent->Header.Length     = RecordInfo.RecordSize;
 | 
						|
    FpdtRecordPtr.DynamicStringEvent->Header.Revision   = FPDT_RECORD_REVISION_1;
 | 
						|
    FpdtRecordPtr.DynamicStringEvent->ProgressID        = RecordInfo.ProgressID;
 | 
						|
    FpdtRecordPtr.DynamicStringEvent->Timestamp         = TimeStamp;
 | 
						|
    CopyMem (&FpdtRecordPtr.DynamicStringEvent->Guid, ModuleGuid, sizeof (EFI_GUID));
 | 
						|
    PeiPerformanceLogHeader->SizeOfAllEntries += RecordInfo.RecordSize;
 | 
						|
 | 
						|
    if (Token != NULL) {
 | 
						|
      StringPtr                     = Token;
 | 
						|
    } else if (Module != NULL) {
 | 
						|
      StringPtr                     = Module;
 | 
						|
    }
 | 
						|
    if (StringPtr != NULL && AsciiStrLen (StringPtr) != 0) {
 | 
						|
      DestMax                       = (RecordInfo.RecordSize - sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD)) / sizeof (CHAR8);
 | 
						|
      StrLength                     = AsciiStrLen (StringPtr);
 | 
						|
      if (StrLength >= DestMax) {
 | 
						|
        StrLength                   = DestMax -1;
 | 
						|
      }
 | 
						|
      AsciiStrnCpyS (FpdtRecordPtr.DynamicStringEvent->String, DestMax, StringPtr, StrLength);
 | 
						|
    } else {
 | 
						|
      AsciiStrCpyS (FpdtRecordPtr.DynamicStringEvent->String, FPDT_STRING_EVENT_RECORD_NAME_LENGTH, "unknown name");
 | 
						|
    }
 | 
						|
    break;
 | 
						|
 | 
						|
  default:
 | 
						|
    //
 | 
						|
    // Record is not supported in current PEI phase, return EFI_ABORTED
 | 
						|
    //
 | 
						|
    return EFI_UNSUPPORTED;
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Creates a record for the beginning of a performance measurement.
 | 
						|
 | 
						|
  If TimeStamp is zero, then this function reads the current time stamp
 | 
						|
  and adds that time stamp value to the record as the start time.
 | 
						|
 | 
						|
  If TimeStamp is one, then this function reads 0 as the start time.
 | 
						|
 | 
						|
  If TimeStamp is other value, then TimeStamp is added to the record as the start time.
 | 
						|
 | 
						|
  @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
 | 
						|
  )
 | 
						|
{
 | 
						|
  return InsertPeiFpdtMeasurement (TRUE, Handle, Token, Module, TimeStamp, Identifier);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 | 
						|
  Creates a record for the end of a performance measurement.
 | 
						|
 | 
						|
  If the TimeStamp is not zero or one, then TimeStamp is added to the record as the end time.
 | 
						|
  If the TimeStamp is zero, then this function reads the current time stamp and adds that time stamp value to the record as the end time.
 | 
						|
  If the TimeStamp is one, then this function reads 0 as the end time.
 | 
						|
 | 
						|
  @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
 | 
						|
  )
 | 
						|
{
 | 
						|
  return InsertPeiFpdtMeasurement (FALSE, Handle, Token, Module, TimeStamp, Identifier);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  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.
 | 
						|
 | 
						|
  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().
 | 
						|
 | 
						|
  !!!NOT Support yet!!!
 | 
						|
 | 
						|
  @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 of entry 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;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Creates a record for the beginning of a performance measurement.
 | 
						|
 | 
						|
  If TimeStamp is zero, then this function reads the current time stamp
 | 
						|
  and adds that time stamp value to the record as the start time.
 | 
						|
 | 
						|
  If TimeStamp is one, then this function reads 0 as the start time.
 | 
						|
 | 
						|
  If TimeStamp is other value, then TimeStamp is added to the record as the start time.
 | 
						|
 | 
						|
 | 
						|
  @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 InsertPeiFpdtMeasurement (TRUE, Handle, Token, Module, TimeStamp, 0);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 | 
						|
  Creates a record for the end of a performance measurement.
 | 
						|
 | 
						|
  If the TimeStamp is not zero or one, then TimeStamp is added to the record as the end time.
 | 
						|
  If the TimeStamp is zero, then this function reads the current time stamp and adds that time stamp value to the record as the end time.
 | 
						|
  If the TimeStamp is one, then this function reads 0 as the end time.
 | 
						|
 | 
						|
  @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 InsertPeiFpdtMeasurement (FALSE, 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.
 | 
						|
 | 
						|
  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().
 | 
						|
 | 
						|
  NOT Support yet.
 | 
						|
 | 
						|
  @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 of entry 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);
 | 
						|
}
 |