New added checkers includes: 1. Too many invalid parameters 2. Too few parameter 3. Invalid number parameter for -n and -t flag 4. Conflict parameter of -A and -R. Cc: Liming Gao <liming.gao@intel.com> Cc: Ruiyu Ni <ruiyu.ni@intel.com> Cc: Jaben Carsey <jaben.carsey@intel.com> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Dandan Bi <dandan.bi@intel.com> Reviewed-by: Jaben Carsey <jaben.carsey@intel.com>
		
			
				
	
	
		
			1102 lines
		
	
	
		
			37 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1102 lines
		
	
	
		
			37 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Shell command for Displaying Performance Metrics.
 | 
						|
 | 
						|
  The Dp command reads performance data and presents it in several
 | 
						|
  different formats depending upon the needs of the user.  Both
 | 
						|
  Trace and Measured Profiling information is processed and presented.
 | 
						|
 | 
						|
  Dp uses the "PerformanceLib" to read the measurement records.
 | 
						|
  The "TimerLib" provides information about the timer, such as frequency,
 | 
						|
  beginning, and ending counter values.
 | 
						|
  Measurement records contain identifying information (Handle, Token, Module)
 | 
						|
  and start and end time values.
 | 
						|
  Dp uses this information to group records in different ways.  It also uses
 | 
						|
  timer information to calculate elapsed time for each measurement.
 | 
						|
 | 
						|
  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
 | 
						|
  (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 "Dp.h"
 | 
						|
#include "Literals.h"
 | 
						|
#include "DpInternal.h"
 | 
						|
 | 
						|
#pragma pack(1)
 | 
						|
 | 
						|
typedef struct {
 | 
						|
  EFI_ACPI_DESCRIPTION_HEADER  Header;
 | 
						|
  UINT32                       Entry;
 | 
						|
} RSDT_TABLE;
 | 
						|
 | 
						|
typedef struct {
 | 
						|
  EFI_ACPI_DESCRIPTION_HEADER  Header;
 | 
						|
  UINT64                       Entry;
 | 
						|
} XSDT_TABLE;
 | 
						|
 | 
						|
#pragma pack()
 | 
						|
 | 
						|
EFI_HANDLE   mDpHiiHandle;
 | 
						|
 | 
						|
typedef struct {
 | 
						|
  EFI_HANDLE    Handle;
 | 
						|
  EFI_GUID      ModuleGuid;
 | 
						|
} HANDLE_GUID_MAP;
 | 
						|
 | 
						|
HANDLE_GUID_MAP  *mCacheHandleGuidTable;
 | 
						|
UINTN            mCachePairCount = 0;
 | 
						|
 | 
						|
//
 | 
						|
/// Module-Global Variables
 | 
						|
///@{
 | 
						|
CHAR16           mGaugeString[DP_GAUGE_STRING_LENGTH + 1];
 | 
						|
CHAR16           mUnicodeToken[DXE_PERFORMANCE_STRING_SIZE];
 | 
						|
UINT64           mInterestThreshold;
 | 
						|
BOOLEAN          mShowId = FALSE;
 | 
						|
UINT8            *mBootPerformanceTable;
 | 
						|
UINTN            mBootPerformanceTableSize;
 | 
						|
BOOLEAN          mPeiPhase = FALSE;
 | 
						|
BOOLEAN          mDxePhase = FALSE;
 | 
						|
 | 
						|
PERF_SUMMARY_DATA SummaryData = { 0 };    ///< Create the SummaryData structure and init. to ZERO.
 | 
						|
MEASUREMENT_RECORD  *mMeasurementList = NULL;
 | 
						|
UINTN               mMeasurementNum    = 0;
 | 
						|
 | 
						|
/// Items for which to gather cumulative statistics.
 | 
						|
PERF_CUM_DATA CumData[] = {
 | 
						|
  PERF_INIT_CUM_DATA (LOAD_IMAGE_TOK),
 | 
						|
  PERF_INIT_CUM_DATA (START_IMAGE_TOK),
 | 
						|
  PERF_INIT_CUM_DATA (DRIVERBINDING_START_TOK),
 | 
						|
  PERF_INIT_CUM_DATA (DRIVERBINDING_SUPPORT_TOK)
 | 
						|
};
 | 
						|
 | 
						|
/// Number of items for which we are gathering cumulative statistics.
 | 
						|
UINT32 const      NumCum = sizeof(CumData) / sizeof(PERF_CUM_DATA);
 | 
						|
 | 
						|
STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
 | 
						|
  {L"-v", TypeFlag},   // -v   Verbose Mode
 | 
						|
  {L"-A", TypeFlag},   // -A   All, Cooked
 | 
						|
  {L"-R", TypeFlag},   // -R   RAW All
 | 
						|
  {L"-s", TypeFlag},   // -s   Summary
 | 
						|
  {L"-x", TypeFlag},   // -x   eXclude Cumulative Items
 | 
						|
  {L"-i", TypeFlag},   // -i   Display Identifier
 | 
						|
  {L"-c", TypeValue},  // -c   Display cumulative data.
 | 
						|
  {L"-n", TypeValue},  // -n # Number of records to display for A and R
 | 
						|
  {L"-t", TypeValue},  // -t # Threshold of interest
 | 
						|
  {NULL, TypeMax}
 | 
						|
  };
 | 
						|
 | 
						|
///@}
 | 
						|
 | 
						|
/**
 | 
						|
   Display the trailing Verbose information.
 | 
						|
**/
 | 
						|
VOID
 | 
						|
DumpStatistics( void )
 | 
						|
{
 | 
						|
  EFI_STRING                StringPtr;
 | 
						|
  EFI_STRING                StringPtrUnknown;
 | 
						|
  StringPtr        = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_STATISTICS), NULL);
 | 
						|
  StringPtrUnknown = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
 | 
						|
  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), mDpHiiHandle,
 | 
						|
              (StringPtr == NULL) ? StringPtrUnknown : StringPtr);
 | 
						|
  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMTRACE), mDpHiiHandle,      SummaryData.NumTrace);
 | 
						|
  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMINCOMPLETE), mDpHiiHandle, SummaryData.NumIncomplete);
 | 
						|
  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMPHASES), mDpHiiHandle,     SummaryData.NumSummary);
 | 
						|
  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMHANDLES), mDpHiiHandle,    SummaryData.NumHandles, SummaryData.NumTrace - SummaryData.NumHandles);
 | 
						|
  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMPEIMS), mDpHiiHandle,      SummaryData.NumPEIMs);
 | 
						|
  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMGLOBALS), mDpHiiHandle,    SummaryData.NumGlobal);
 | 
						|
  SHELL_FREE_NON_NULL (StringPtr);
 | 
						|
  SHELL_FREE_NON_NULL (StringPtrUnknown);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  This function scan ACPI table in RSDT.
 | 
						|
 | 
						|
  @param  Rsdt        ACPI RSDT
 | 
						|
  @param  Signature   ACPI table signature
 | 
						|
 | 
						|
  @return ACPI table
 | 
						|
**/
 | 
						|
VOID *
 | 
						|
ScanTableInRSDT (
 | 
						|
  IN RSDT_TABLE                   *Rsdt,
 | 
						|
  IN UINT32                       Signature
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN                         Index;
 | 
						|
  UINT32                        EntryCount;
 | 
						|
  UINT32                        *EntryPtr;
 | 
						|
  EFI_ACPI_DESCRIPTION_HEADER   *Table;
 | 
						|
 | 
						|
  EntryCount = (Rsdt->Header.Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof(UINT32);
 | 
						|
 | 
						|
  EntryPtr = &Rsdt->Entry;
 | 
						|
  for (Index = 0; Index < EntryCount; Index ++, EntryPtr ++) {
 | 
						|
    Table = (EFI_ACPI_DESCRIPTION_HEADER*)((UINTN)(*EntryPtr));
 | 
						|
    if (Table->Signature == Signature) {
 | 
						|
      return Table;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  This function scan ACPI table in XSDT.
 | 
						|
 | 
						|
  @param  Xsdt       ACPI XSDT
 | 
						|
  @param  Signature  ACPI table signature
 | 
						|
 | 
						|
  @return ACPI table
 | 
						|
**/
 | 
						|
VOID *
 | 
						|
ScanTableInXSDT (
 | 
						|
  IN XSDT_TABLE                   *Xsdt,
 | 
						|
  IN UINT32                       Signature
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN                        Index;
 | 
						|
  UINT32                       EntryCount;
 | 
						|
  UINT64                       EntryPtr;
 | 
						|
  UINTN                        BasePtr;
 | 
						|
  EFI_ACPI_DESCRIPTION_HEADER  *Table;
 | 
						|
 | 
						|
  EntryCount = (Xsdt->Header.Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof(UINT64);
 | 
						|
 | 
						|
  BasePtr = (UINTN)(&(Xsdt->Entry));
 | 
						|
  for (Index = 0; Index < EntryCount; Index ++) {
 | 
						|
    CopyMem (&EntryPtr, (VOID *)(BasePtr + Index * sizeof(UINT64)), sizeof(UINT64));
 | 
						|
    Table = (EFI_ACPI_DESCRIPTION_HEADER*)((UINTN)(EntryPtr));
 | 
						|
    if (Table->Signature == Signature) {
 | 
						|
      return Table;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  This function scan ACPI table in RSDP.
 | 
						|
 | 
						|
  @param  Rsdp       ACPI RSDP
 | 
						|
  @param  Signature  ACPI table signature
 | 
						|
 | 
						|
  @return ACPI table
 | 
						|
**/
 | 
						|
VOID *
 | 
						|
FindAcpiPtr (
 | 
						|
  IN EFI_ACPI_5_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp,
 | 
						|
  IN UINT32                                       Signature
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_ACPI_DESCRIPTION_HEADER                    *AcpiTable;
 | 
						|
  RSDT_TABLE                                     *Rsdt;
 | 
						|
  XSDT_TABLE                                     *Xsdt;
 | 
						|
 | 
						|
  AcpiTable = NULL;
 | 
						|
 | 
						|
  //
 | 
						|
  // Check ACPI2.0 table
 | 
						|
  //
 | 
						|
  Rsdt = (RSDT_TABLE *)(UINTN)Rsdp->RsdtAddress;
 | 
						|
  Xsdt = NULL;
 | 
						|
  if ((Rsdp->Revision >= 2) && (Rsdp->XsdtAddress < (UINT64)(UINTN)-1)) {
 | 
						|
    Xsdt = (XSDT_TABLE *)(UINTN)Rsdp->XsdtAddress;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Check Xsdt
 | 
						|
  //
 | 
						|
  if (Xsdt != NULL) {
 | 
						|
    AcpiTable = ScanTableInXSDT (Xsdt, Signature);
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Check Rsdt
 | 
						|
  //
 | 
						|
  if ((AcpiTable == NULL) && (Rsdt != NULL)) {
 | 
						|
    AcpiTable = ScanTableInRSDT (Rsdt, Signature);
 | 
						|
  }
 | 
						|
 | 
						|
  return AcpiTable;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Get Boot performance table form Acpi table.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
GetBootPerformanceTable (
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                  Status;
 | 
						|
  VOID                        *AcpiTable;
 | 
						|
  FIRMWARE_PERFORMANCE_TABLE  *FirmwarePerformanceTable;
 | 
						|
 | 
						|
  AcpiTable = NULL;
 | 
						|
 | 
						|
  Status = EfiGetSystemConfigurationTable (
 | 
						|
             &gEfiAcpi20TableGuid,
 | 
						|
             &AcpiTable
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    Status = EfiGetSystemConfigurationTable (
 | 
						|
               &gEfiAcpi10TableGuid,
 | 
						|
               &AcpiTable
 | 
						|
                 );
 | 
						|
  }
 | 
						|
  if (EFI_ERROR(Status) || AcpiTable == NULL) {
 | 
						|
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GET_ACPI_TABLE_FAIL), mDpHiiHandle);
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  FirmwarePerformanceTable = FindAcpiPtr (
 | 
						|
                      (EFI_ACPI_5_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)AcpiTable,
 | 
						|
                      EFI_ACPI_5_0_FIRMWARE_PERFORMANCE_DATA_TABLE_SIGNATURE
 | 
						|
                      );
 | 
						|
  if (FirmwarePerformanceTable == NULL) {
 | 
						|
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GET_ACPI_FPDT_FAIL), mDpHiiHandle);
 | 
						|
    return EFI_NOT_FOUND;
 | 
						|
  }
 | 
						|
 | 
						|
  mBootPerformanceTable = (UINT8*) (UINTN)FirmwarePerformanceTable->BootPointerRecord.BootPerformanceTablePointer;
 | 
						|
  mBootPerformanceTableSize = ((BOOT_PERFORMANCE_TABLE *) mBootPerformanceTable)->Header.Length;
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Get Handle form Module Guid.
 | 
						|
 | 
						|
  @param  ModuleGuid     Module Guid.
 | 
						|
  @param  Handle         The handle to be returned.
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
GetHandleFormModuleGuid (
 | 
						|
  IN      EFI_GUID        *ModuleGuid,
 | 
						|
  IN OUT  EFI_HANDLE      *Handle
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN                             Index;
 | 
						|
 | 
						|
  if (IsZeroGuid (ModuleGuid)) {
 | 
						|
    *Handle = NULL;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Try to get the Handle form the caached array.
 | 
						|
  //
 | 
						|
  for (Index = 0; Index < mCachePairCount; Index++) {
 | 
						|
    if (CompareGuid (ModuleGuid, &mCacheHandleGuidTable[Index].ModuleGuid)) {
 | 
						|
      *Handle = mCacheHandleGuidTable[Index].Handle;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  if (Index >= mCachePairCount) {
 | 
						|
    *Handle = NULL;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
Cache the GUID and handle mapping pairs. In order to save time for searching.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
BuildCachedGuidHandleTable (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                        Status;
 | 
						|
  EFI_HANDLE                        *HandleBuffer;
 | 
						|
  UINTN                             HandleCount;
 | 
						|
  UINTN                             Index;
 | 
						|
  EFI_LOADED_IMAGE_PROTOCOL         *LoadedImage;
 | 
						|
  EFI_DRIVER_BINDING_PROTOCOL       *DriverBinding;
 | 
						|
  EFI_GUID                          *TempGuid;
 | 
						|
  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFilePath;
 | 
						|
 | 
						|
  Status = gBS->LocateHandleBuffer (AllHandles, NULL, NULL, &HandleCount, &HandleBuffer);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLES_ERROR), mDpHiiHandle, Status);
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  mCacheHandleGuidTable = AllocateZeroPool (HandleCount * sizeof (HANDLE_GUID_MAP));
 | 
						|
  if (mCacheHandleGuidTable == NULL) {
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  for (Index = 0; Index < HandleCount; Index++) {
 | 
						|
    //
 | 
						|
    // Try Handle as ImageHandle.
 | 
						|
    //
 | 
						|
    Status = gBS->HandleProtocol (
 | 
						|
                  HandleBuffer[Index],
 | 
						|
                  &gEfiLoadedImageProtocolGuid,
 | 
						|
                  (VOID**) &LoadedImage
 | 
						|
                  );
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      //
 | 
						|
      // Try Handle as Controller Handle
 | 
						|
      //
 | 
						|
      Status = gBS->OpenProtocol (
 | 
						|
                    HandleBuffer[Index],
 | 
						|
                    &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
 | 
						|
         ) {
 | 
						|
        FvFilePath      = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) LoadedImage->FilePath;
 | 
						|
        TempGuid        = &FvFilePath->FvFileName;
 | 
						|
 | 
						|
        mCacheHandleGuidTable[mCachePairCount].Handle = HandleBuffer[Index];
 | 
						|
        CopyGuid (&mCacheHandleGuidTable[mCachePairCount].ModuleGuid, TempGuid);
 | 
						|
        mCachePairCount ++;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  if (HandleBuffer != NULL) {
 | 
						|
    FreePool (HandleBuffer);
 | 
						|
    HandleBuffer = NULL;
 | 
						|
  }
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Get Measurement form Fpdt records.
 | 
						|
 | 
						|
  @param  RecordHeader        Pointer to the start record.
 | 
						|
  @param  IsStart             Is start record or End record.
 | 
						|
  @param  Measurement         Pointer to the measurement which need to be filled.
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
GetMeasurementInfo (
 | 
						|
  IN     EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER  *RecordHeader,
 | 
						|
  IN     BOOLEAN                                      IsStart,
 | 
						|
  IN OUT MEASUREMENT_RECORD                           *Measurement
 | 
						|
  )
 | 
						|
{
 | 
						|
  VOID                                         *ModuleGuid;
 | 
						|
  EFI_HANDLE                                   StartHandle;
 | 
						|
 | 
						|
  switch (RecordHeader->Type) {
 | 
						|
  case FPDT_GUID_EVENT_TYPE:
 | 
						|
    ModuleGuid                    = &(((FPDT_GUID_EVENT_RECORD *)RecordHeader)->Guid);
 | 
						|
    Measurement->Identifier       = ((UINT32)((FPDT_GUID_EVENT_RECORD *)RecordHeader)->ProgressID);
 | 
						|
    if (IsStart) {
 | 
						|
      Measurement->StartTimeStamp = ((FPDT_GUID_EVENT_RECORD *)RecordHeader)->Timestamp;
 | 
						|
    } else {
 | 
						|
      Measurement->EndTimeStamp   = ((FPDT_GUID_EVENT_RECORD *)RecordHeader)->Timestamp;
 | 
						|
    }
 | 
						|
    switch (Measurement->Identifier) {
 | 
						|
    case MODULE_START_ID:
 | 
						|
    case MODULE_END_ID:
 | 
						|
      if (mPeiPhase) {
 | 
						|
        Measurement->Token        = ALit_PEIM;
 | 
						|
        Measurement->Module       = ALit_PEIM;
 | 
						|
      } else if (mDxePhase) {
 | 
						|
        Measurement->Token        = ALit_START_IMAGE;
 | 
						|
        Measurement->Module       = ALit_START_IMAGE;
 | 
						|
      }
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      ASSERT(FALSE);
 | 
						|
    }
 | 
						|
 | 
						|
    if (Measurement->Token != NULL && AsciiStrCmp (Measurement->Token, ALit_PEIM) == 0) {
 | 
						|
      Measurement->Handle         = &(((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Guid);
 | 
						|
    } else {
 | 
						|
      GetHandleFormModuleGuid(ModuleGuid, &StartHandle);
 | 
						|
      Measurement->Handle = StartHandle;
 | 
						|
      //
 | 
						|
      // When no perf entry to record the PEI and DXE phase,
 | 
						|
      // For start image, we need detect the PEIM and non PEIM here.
 | 
						|
      //
 | 
						|
      if (Measurement->Token == NULL) {
 | 
						|
        if (StartHandle == NULL && !IsZeroGuid (ModuleGuid)) {
 | 
						|
          Measurement->Token      = ALit_PEIM;
 | 
						|
          Measurement->Module     = ALit_PEIM;
 | 
						|
          Measurement->Handle     = ModuleGuid;
 | 
						|
        } else {
 | 
						|
          Measurement->Token      = ALit_START_IMAGE;
 | 
						|
          Measurement->Module     = ALit_START_IMAGE;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
    break;
 | 
						|
 | 
						|
  case FPDT_DYNAMIC_STRING_EVENT_TYPE:
 | 
						|
    ModuleGuid                    = &(((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Guid);
 | 
						|
    Measurement->Identifier       = ((UINT32)((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->ProgressID);
 | 
						|
    if (IsStart) {
 | 
						|
      Measurement->StartTimeStamp = ((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;
 | 
						|
    } else {
 | 
						|
      Measurement->EndTimeStamp   = ((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;
 | 
						|
    }
 | 
						|
    switch (Measurement->Identifier) {
 | 
						|
    case MODULE_START_ID:
 | 
						|
    case MODULE_END_ID:
 | 
						|
      if (mPeiPhase) {
 | 
						|
        Measurement->Token        = ALit_PEIM;
 | 
						|
      } else if (mDxePhase) {
 | 
						|
        Measurement->Token        = ALit_START_IMAGE;
 | 
						|
      }
 | 
						|
      break;
 | 
						|
 | 
						|
    case MODULE_LOADIMAGE_START_ID:
 | 
						|
    case MODULE_LOADIMAGE_END_ID:
 | 
						|
      Measurement->Token          = ALit_LOAD_IMAGE;
 | 
						|
      break;
 | 
						|
 | 
						|
    case MODULE_DB_START_ID:
 | 
						|
    case MODULE_DB_END_ID:
 | 
						|
      Measurement->Token          = ALit_DB_START;
 | 
						|
      break;
 | 
						|
 | 
						|
    case MODULE_DB_SUPPORT_START_ID:
 | 
						|
    case MODULE_DB_SUPPORT_END_ID:
 | 
						|
      Measurement->Token          = ALit_DB_SUPPORT;
 | 
						|
      break;
 | 
						|
 | 
						|
    case MODULE_DB_STOP_START_ID:
 | 
						|
    case MODULE_DB_STOP_END_ID:
 | 
						|
      Measurement->Token          = ALit_DB_STOP;
 | 
						|
      break;
 | 
						|
 | 
						|
    default:
 | 
						|
      Measurement->Token          = ((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->String;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    Measurement->Module           = ((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->String;
 | 
						|
 | 
						|
    if (Measurement->Token != NULL && AsciiStrCmp (Measurement->Token, ALit_PEIM) == 0) {
 | 
						|
      Measurement->Handle         = &(((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Guid);
 | 
						|
    } else {
 | 
						|
      GetHandleFormModuleGuid(ModuleGuid, &StartHandle);
 | 
						|
      Measurement->Handle = StartHandle;
 | 
						|
      //
 | 
						|
      // When no perf entry to record the PEI and DXE phase,
 | 
						|
      // For start image, we need detect the PEIM and non PEIM here.
 | 
						|
      //
 | 
						|
      if (Measurement->Token == NULL  && (Measurement->Identifier == MODULE_START_ID || Measurement->Identifier == MODULE_END_ID)) {
 | 
						|
        if (StartHandle == NULL && !IsZeroGuid (ModuleGuid)) {
 | 
						|
          Measurement->Token      = ALit_PEIM;
 | 
						|
          Measurement->Handle     = ModuleGuid;
 | 
						|
        } else {
 | 
						|
          Measurement->Token      = ALit_START_IMAGE;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
    break;
 | 
						|
 | 
						|
  case FPDT_GUID_QWORD_EVENT_TYPE:
 | 
						|
    ModuleGuid                    = &(((FPDT_GUID_QWORD_EVENT_RECORD *)RecordHeader)->Guid);
 | 
						|
    Measurement->Identifier       = ((UINT32)((FPDT_GUID_QWORD_EVENT_RECORD *)RecordHeader)->ProgressID);
 | 
						|
    if (IsStart) {
 | 
						|
      Measurement->StartTimeStamp = ((FPDT_GUID_QWORD_EVENT_RECORD *)RecordHeader)->Timestamp;
 | 
						|
    } else {
 | 
						|
      Measurement->EndTimeStamp   = ((FPDT_GUID_QWORD_EVENT_RECORD *)RecordHeader)->Timestamp;
 | 
						|
    }
 | 
						|
    switch (Measurement->Identifier) {
 | 
						|
    case MODULE_DB_START_ID:
 | 
						|
      Measurement->Token          = ALit_DB_START;
 | 
						|
      Measurement->Module         = ALit_DB_START;
 | 
						|
      break;
 | 
						|
 | 
						|
    case MODULE_DB_SUPPORT_START_ID:
 | 
						|
    case MODULE_DB_SUPPORT_END_ID:
 | 
						|
      Measurement->Token          = ALit_DB_SUPPORT;
 | 
						|
      Measurement->Module         = ALit_DB_SUPPORT;
 | 
						|
      break;
 | 
						|
 | 
						|
    case MODULE_DB_STOP_START_ID:
 | 
						|
    case MODULE_DB_STOP_END_ID:
 | 
						|
      Measurement->Token          = ALit_DB_STOP;
 | 
						|
      Measurement->Module         = ALit_DB_STOP;
 | 
						|
      break;
 | 
						|
 | 
						|
    case MODULE_LOADIMAGE_START_ID:
 | 
						|
    case MODULE_LOADIMAGE_END_ID:
 | 
						|
      Measurement->Token          = ALit_LOAD_IMAGE;
 | 
						|
      Measurement->Module         = ALit_LOAD_IMAGE;
 | 
						|
      break;
 | 
						|
 | 
						|
    default:
 | 
						|
      ASSERT(FALSE);
 | 
						|
    }
 | 
						|
    GetHandleFormModuleGuid(ModuleGuid, &StartHandle);
 | 
						|
    Measurement->Handle = StartHandle;
 | 
						|
    break;
 | 
						|
 | 
						|
  case  FPDT_GUID_QWORD_STRING_EVENT_TYPE:
 | 
						|
    ModuleGuid                    = &(((FPDT_GUID_QWORD_STRING_EVENT_RECORD *)RecordHeader)->Guid);
 | 
						|
    Measurement->Identifier       = ((UINT32)((FPDT_GUID_QWORD_STRING_EVENT_RECORD *)RecordHeader)->ProgressID);
 | 
						|
    if (IsStart) {
 | 
						|
      Measurement->StartTimeStamp = ((FPDT_GUID_QWORD_STRING_EVENT_RECORD*)RecordHeader)->Timestamp;
 | 
						|
    } else {
 | 
						|
      Measurement->EndTimeStamp   = ((FPDT_GUID_QWORD_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // Currently only "DB:Start:" end record with FPDT_GUID_QWORD_STRING_EVENT_TYPE.
 | 
						|
    //
 | 
						|
    switch (Measurement->Identifier) {
 | 
						|
    case MODULE_DB_END_ID:
 | 
						|
      Measurement->Token          = ALit_DB_START;
 | 
						|
      Measurement->Module         = ALit_DB_START;
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      ASSERT(FALSE);
 | 
						|
    }
 | 
						|
    GetHandleFormModuleGuid(ModuleGuid, &StartHandle);
 | 
						|
    Measurement->Handle = StartHandle;
 | 
						|
    break;
 | 
						|
 | 
						|
  case FPDT_DUAL_GUID_STRING_EVENT_TYPE:
 | 
						|
    ModuleGuid                    = &(((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->Guid1);
 | 
						|
    Measurement->Identifier       = ((UINT32)((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->ProgressID);
 | 
						|
    if (IsStart) {
 | 
						|
      Measurement->StartTimeStamp = ((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;
 | 
						|
    } else {
 | 
						|
      Measurement->EndTimeStamp   = ((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;
 | 
						|
    }
 | 
						|
    Measurement->Token            = ((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->String;
 | 
						|
    Measurement->Module           = ((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->String;
 | 
						|
    GetHandleFormModuleGuid(ModuleGuid, &StartHandle);
 | 
						|
    Measurement->Handle = StartHandle;
 | 
						|
    break;
 | 
						|
 | 
						|
  default:
 | 
						|
    break;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Search the start measurement in the mMeasurementList for the end measurement.
 | 
						|
 | 
						|
  @param  EndMeasureMent        Measurement for end record.
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
SearchMeasurement (
 | 
						|
  IN MEASUREMENT_RECORD                           *EndMeasureMent
 | 
						|
  )
 | 
						|
{
 | 
						|
  INTN                            Index;
 | 
						|
 | 
						|
  for (Index = mMeasurementNum - 1; Index >= 0; Index--) {
 | 
						|
    if (AsciiStrCmp (EndMeasureMent->Token, ALit_PEIM) == 0) {
 | 
						|
      if (mMeasurementList[Index].EndTimeStamp == 0 && EndMeasureMent->Handle!= NULL && mMeasurementList[Index].Handle != NULL&&
 | 
						|
          CompareGuid(mMeasurementList[Index].Handle, EndMeasureMent->Handle) &&
 | 
						|
          (AsciiStrCmp (mMeasurementList[Index].Token, EndMeasureMent->Token) == 0) &&
 | 
						|
          (AsciiStrCmp (mMeasurementList[Index].Module, EndMeasureMent->Module) == 0)) {
 | 
						|
        mMeasurementList[Index].EndTimeStamp = EndMeasureMent->EndTimeStamp;
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    } else if (EndMeasureMent->Identifier == PERF_CROSSMODULE_END_ID) {
 | 
						|
      if (mMeasurementList[Index].EndTimeStamp == 0 &&
 | 
						|
         (AsciiStrCmp (mMeasurementList[Index].Token, EndMeasureMent->Token) == 0) &&
 | 
						|
         (AsciiStrCmp (mMeasurementList[Index].Module, EndMeasureMent->Module) == 0) &&
 | 
						|
         mMeasurementList[Index].Identifier == PERF_CROSSMODULE_START_ID) {
 | 
						|
        mMeasurementList[Index].EndTimeStamp = EndMeasureMent->EndTimeStamp;
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    } else {
 | 
						|
      if (mMeasurementList[Index].EndTimeStamp == 0 && mMeasurementList[Index].Handle == EndMeasureMent->Handle &&
 | 
						|
         (AsciiStrCmp (mMeasurementList[Index].Token, EndMeasureMent->Token) == 0) &&
 | 
						|
         (AsciiStrCmp (mMeasurementList[Index].Module, EndMeasureMent->Module) == 0)) {
 | 
						|
        mMeasurementList[Index].EndTimeStamp = EndMeasureMent->EndTimeStamp;
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Generate the measure record array.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
BuildMeasurementList (
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER  *RecordHeader;
 | 
						|
  UINT8                                        *PerformanceTablePtr;
 | 
						|
  UINT16                                       StartProgressId;
 | 
						|
  UINTN                                        TableLength;
 | 
						|
  UINT8                                        *StartRecordEvent;
 | 
						|
  MEASUREMENT_RECORD                           MeasureMent;
 | 
						|
 | 
						|
  mMeasurementList = AllocateZeroPool (mBootPerformanceTableSize);
 | 
						|
  if (mMeasurementList == NULL) {
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  TableLength         = sizeof (BOOT_PERFORMANCE_TABLE);
 | 
						|
  PerformanceTablePtr = (mBootPerformanceTable + TableLength);
 | 
						|
 | 
						|
  while (TableLength < mBootPerformanceTableSize) {
 | 
						|
    RecordHeader      = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER*) PerformanceTablePtr;
 | 
						|
    StartRecordEvent  = (UINT8 *)RecordHeader;
 | 
						|
    StartProgressId   = ((FPDT_GUID_EVENT_RECORD *)StartRecordEvent)->ProgressID;
 | 
						|
 | 
						|
    //
 | 
						|
    // If the record with ProgressId 0, the record doesn't appear in pairs. The timestamp in the record is the EndTimeStamp, its StartTimeStamp is 0.
 | 
						|
    // If the record is the start record, fill the info to the measurement in the mMeasurementList.
 | 
						|
    // If the record is the end record, find the related start measurement in the mMeasurementList and fill the EndTimeStamp.
 | 
						|
    //
 | 
						|
    if (StartProgressId == 0) {
 | 
						|
      GetMeasurementInfo (RecordHeader, FALSE, &(mMeasurementList[mMeasurementNum]));
 | 
						|
      mMeasurementNum ++;
 | 
						|
    } else if (((StartProgressId >= PERF_EVENTSIGNAL_START_ID && ((StartProgressId & 0x000F) == 0)) ||
 | 
						|
        (StartProgressId < PERF_EVENTSIGNAL_START_ID && ((StartProgressId & 0x0001) != 0)))) {
 | 
						|
      //
 | 
						|
      // Since PEIM and StartImage has same Type and ID when PCD PcdEdkiiFpdtStringRecordEnableOnly = FALSE
 | 
						|
      // So we need to identify these two kinds of record through different phase.
 | 
						|
      //
 | 
						|
      if(StartProgressId == PERF_CROSSMODULE_START_ID ){
 | 
						|
        if (AsciiStrCmp (((FPDT_DYNAMIC_STRING_EVENT_RECORD *)StartRecordEvent)->String, ALit_PEI) == 0) {
 | 
						|
          mPeiPhase = TRUE;
 | 
						|
        } else if (AsciiStrCmp (((FPDT_DYNAMIC_STRING_EVENT_RECORD *)StartRecordEvent)->String, ALit_DXE) == 0) {
 | 
						|
          mDxePhase = TRUE;
 | 
						|
          mPeiPhase = FALSE;
 | 
						|
        }
 | 
						|
      }
 | 
						|
      // Get measurement info form the start record to the mMeasurementList.
 | 
						|
      GetMeasurementInfo (RecordHeader, TRUE, &(mMeasurementList[mMeasurementNum]));
 | 
						|
      mMeasurementNum ++;
 | 
						|
    } else {
 | 
						|
      ZeroMem(&MeasureMent, sizeof(MEASUREMENT_RECORD));
 | 
						|
      GetMeasurementInfo (RecordHeader, FALSE, &MeasureMent);
 | 
						|
      SearchMeasurement (&MeasureMent);
 | 
						|
    }
 | 
						|
    TableLength         += RecordHeader->Length;
 | 
						|
    PerformanceTablePtr += RecordHeader->Length;
 | 
						|
  }
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Initialize the cumulative data.
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
InitCumulativeData (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN                             Index;
 | 
						|
 | 
						|
  for (Index = 0; Index < NumCum; ++Index) {
 | 
						|
    CumData[Index].Count = 0;
 | 
						|
    CumData[Index].MinDur = PERF_MAXDUR;
 | 
						|
    CumData[Index].MaxDur = 0;
 | 
						|
    CumData[Index].Duration = 0;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Initialize the Summary data.
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
InitSummaryData (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  SummaryData.NumTrace      = 0;
 | 
						|
  SummaryData.NumIncomplete = 0;
 | 
						|
  SummaryData.NumSummary    = 0;
 | 
						|
  SummaryData.NumHandles    = 0;
 | 
						|
  SummaryData.NumPEIMs      = 0;
 | 
						|
  SummaryData.NumGlobal     = 0;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Dump performance data.
 | 
						|
 | 
						|
  @param[in]  ImageHandle     The image handle.
 | 
						|
  @param[in]  SystemTable     The system table.
 | 
						|
 | 
						|
  @retval SHELL_SUCCESS            Command completed successfully.
 | 
						|
  @retval SHELL_INVALID_PARAMETER  Command usage error.
 | 
						|
  @retval SHELL_ABORTED            The user aborts the operation.
 | 
						|
  @retval value                    Unknown error.
 | 
						|
**/
 | 
						|
SHELL_STATUS
 | 
						|
RunDp (
 | 
						|
  IN EFI_HANDLE               ImageHandle,
 | 
						|
  IN EFI_SYSTEM_TABLE         *SystemTable
 | 
						|
  )
 | 
						|
{
 | 
						|
  LIST_ENTRY                *ParamPackage;
 | 
						|
  CONST CHAR16              *CmdLineArg;
 | 
						|
  EFI_STATUS                Status;
 | 
						|
 | 
						|
  PERFORMANCE_PROPERTY      *PerformanceProperty;
 | 
						|
  UINTN                     Number2Display;
 | 
						|
 | 
						|
  EFI_STRING                StringPtr;
 | 
						|
  BOOLEAN                   SummaryMode;
 | 
						|
  BOOLEAN                   VerboseMode;
 | 
						|
  BOOLEAN                   AllMode;
 | 
						|
  BOOLEAN                   RawMode;
 | 
						|
  BOOLEAN                   ExcludeMode;
 | 
						|
  BOOLEAN                   CumulativeMode;
 | 
						|
  CONST CHAR16              *CustomCumulativeToken;
 | 
						|
  PERF_CUM_DATA             *CustomCumulativeData;
 | 
						|
  UINTN                     NameSize;
 | 
						|
  SHELL_STATUS              ShellStatus;
 | 
						|
  TIMER_INFO                TimerInfo;
 | 
						|
  UINT64                    Intermediate;
 | 
						|
 | 
						|
  StringPtr   = NULL;
 | 
						|
  SummaryMode = FALSE;
 | 
						|
  VerboseMode = FALSE;
 | 
						|
  AllMode     = FALSE;
 | 
						|
  RawMode     = FALSE;
 | 
						|
  ExcludeMode = FALSE;
 | 
						|
  CumulativeMode = FALSE;
 | 
						|
  CustomCumulativeData = NULL;
 | 
						|
  ShellStatus = SHELL_SUCCESS;
 | 
						|
 | 
						|
  //
 | 
						|
  // initialize the shell lib (we must be in non-auto-init...)
 | 
						|
  //
 | 
						|
  Status = ShellInitialize();
 | 
						|
  ASSERT_EFI_ERROR(Status);
 | 
						|
 | 
						|
  //
 | 
						|
  // Process Command Line arguments
 | 
						|
  //
 | 
						|
  Status = ShellCommandLineParse (ParamList, &ParamPackage, NULL, TRUE);
 | 
						|
  if (EFI_ERROR(Status)) {
 | 
						|
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_INVALID_ARG), mDpHiiHandle);
 | 
						|
    return SHELL_INVALID_PARAMETER;
 | 
						|
  } else if (ShellCommandLineGetCount(ParamPackage) > 1){
 | 
						|
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TOO_MANY), mDpHiiHandle);
 | 
						|
    return SHELL_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Boolean options
 | 
						|
  //
 | 
						|
  VerboseMode = ShellCommandLineGetFlag (ParamPackage, L"-v");
 | 
						|
  SummaryMode = (BOOLEAN) (ShellCommandLineGetFlag (ParamPackage, L"-S") || ShellCommandLineGetFlag (ParamPackage, L"-s"));
 | 
						|
  AllMode     = ShellCommandLineGetFlag (ParamPackage, L"-A");
 | 
						|
  RawMode     = ShellCommandLineGetFlag (ParamPackage, L"-R");
 | 
						|
  ExcludeMode = ShellCommandLineGetFlag (ParamPackage, L"-x");
 | 
						|
  mShowId     = ShellCommandLineGetFlag (ParamPackage, L"-i");
 | 
						|
  CumulativeMode = ShellCommandLineGetFlag (ParamPackage, L"-c");
 | 
						|
 | 
						|
  if (AllMode && RawMode) {
 | 
						|
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_CONFLICT_ARG), mDpHiiHandle, L"-A", L"-R");
 | 
						|
    return SHELL_INVALID_PARAMETER;
 | 
						|
  }
 | 
						|
 | 
						|
  // Options with Values
 | 
						|
  if (ShellCommandLineGetFlag (ParamPackage, L"-n")) {
 | 
						|
    CmdLineArg  = ShellCommandLineGetValue (ParamPackage, L"-n");
 | 
						|
    if (CmdLineArg == NULL) {
 | 
						|
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TOO_FEW), mDpHiiHandle);
 | 
						|
      return SHELL_INVALID_PARAMETER;
 | 
						|
    } else {
 | 
						|
      if (!(RawMode || AllMode)) {
 | 
						|
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_NO_RAW_ALL), mDpHiiHandle);
 | 
						|
        return SHELL_INVALID_PARAMETER;
 | 
						|
      }
 | 
						|
      Status = ShellConvertStringToUint64(CmdLineArg, &Intermediate, FALSE, TRUE);
 | 
						|
      if (EFI_ERROR (Status)) {
 | 
						|
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_INVALID_NUM_ARG), mDpHiiHandle, L"-n");
 | 
						|
        return SHELL_INVALID_PARAMETER;
 | 
						|
      } else {
 | 
						|
        Number2Display = (UINTN)Intermediate;
 | 
						|
        if (Number2Display == 0 || Number2Display > MAXIMUM_DISPLAYCOUNT) {
 | 
						|
          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_INVALID_RANGE), mDpHiiHandle, L"-n", 0, MAXIMUM_DISPLAYCOUNT);
 | 
						|
          return SHELL_INVALID_PARAMETER;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  } else {
 | 
						|
    Number2Display = DEFAULT_DISPLAYCOUNT;
 | 
						|
  }
 | 
						|
 | 
						|
  if (ShellCommandLineGetFlag (ParamPackage, L"-t")) {
 | 
						|
    CmdLineArg  = ShellCommandLineGetValue (ParamPackage, L"-t");
 | 
						|
    if (CmdLineArg == NULL) {
 | 
						|
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TOO_FEW), mDpHiiHandle);
 | 
						|
      return SHELL_INVALID_PARAMETER;
 | 
						|
    } else {
 | 
						|
      Status = ShellConvertStringToUint64(CmdLineArg, &Intermediate, FALSE, TRUE);
 | 
						|
      if (EFI_ERROR (Status)) {
 | 
						|
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_INVALID_NUM_ARG), mDpHiiHandle, L"-t");
 | 
						|
        return SHELL_INVALID_PARAMETER;
 | 
						|
      } else {
 | 
						|
        mInterestThreshold = Intermediate;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  } else {
 | 
						|
    mInterestThreshold = DEFAULT_THRESHOLD;  // 1ms := 1,000 us
 | 
						|
  }
 | 
						|
 | 
						|
  if (ShellCommandLineGetFlag (ParamPackage, L"-c")) {
 | 
						|
    CustomCumulativeToken = ShellCommandLineGetValue (ParamPackage, L"-c");
 | 
						|
    if (CustomCumulativeToken == NULL) {
 | 
						|
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TOO_FEW), mDpHiiHandle);
 | 
						|
      return SHELL_INVALID_PARAMETER;
 | 
						|
    } else {
 | 
						|
      CustomCumulativeData = AllocateZeroPool (sizeof (PERF_CUM_DATA));
 | 
						|
      if (CustomCumulativeData == NULL) {
 | 
						|
        ShellStatus = SHELL_OUT_OF_RESOURCES;
 | 
						|
        goto Done;
 | 
						|
      }
 | 
						|
      CustomCumulativeData->MinDur = PERF_MAXDUR;
 | 
						|
      CustomCumulativeData->MaxDur = 0;
 | 
						|
      CustomCumulativeData->Count  = 0;
 | 
						|
      CustomCumulativeData->Duration = 0;
 | 
						|
      NameSize = StrLen (CustomCumulativeToken) + 1;
 | 
						|
      CustomCumulativeData->Name   = AllocateZeroPool (NameSize);
 | 
						|
      if (CustomCumulativeData->Name == NULL) {
 | 
						|
        ShellStatus = SHELL_OUT_OF_RESOURCES;
 | 
						|
        goto Done;
 | 
						|
      }
 | 
						|
      UnicodeStrToAsciiStrS (CustomCumulativeToken, CustomCumulativeData->Name, NameSize);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // DP dump performance data by parsing FPDT table in ACPI table.
 | 
						|
  // Folloing 3 steps are to get the measurement form the FPDT table.
 | 
						|
  //
 | 
						|
 | 
						|
  //
 | 
						|
  //1. Get FPDT from ACPI table.
 | 
						|
  //
 | 
						|
  Status = GetBootPerformanceTable ();
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ShellStatus = Status;
 | 
						|
    goto Done;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  //2. Cache the ModuleGuid and hanlde mapping table.
 | 
						|
  //
 | 
						|
  Status = BuildCachedGuidHandleTable();
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ShellStatus = Status;
 | 
						|
    goto Done;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  //3. Build the measurement array form the FPDT records.
 | 
						|
  //
 | 
						|
  Status = BuildMeasurementList ();
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ShellStatus = SHELL_OUT_OF_RESOURCES;
 | 
						|
    goto Done;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Initialize the pre-defined cumulative data.
 | 
						|
  //
 | 
						|
  InitCumulativeData ();
 | 
						|
 | 
						|
  //
 | 
						|
  // Initialize the Summary data.
 | 
						|
  //
 | 
						|
  InitSummaryData ();
 | 
						|
 | 
						|
  //
 | 
						|
  // Timer specific processing
 | 
						|
  //
 | 
						|
  // Get the Performance counter characteristics:
 | 
						|
  //          Freq = Frequency in Hz
 | 
						|
  //    StartCount = Value loaded into the counter when it starts counting
 | 
						|
  //      EndCount = Value counter counts to before it needs to be reset
 | 
						|
  //
 | 
						|
  Status = EfiGetSystemConfigurationTable (&gPerformanceProtocolGuid, (VOID **) &PerformanceProperty);
 | 
						|
  if (EFI_ERROR (Status) || (PerformanceProperty == NULL)) {
 | 
						|
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PERF_PROPERTY_NOT_FOUND), mDpHiiHandle);
 | 
						|
    goto Done;
 | 
						|
  }
 | 
						|
 | 
						|
  TimerInfo.Frequency  = (UINT32)DivU64x32 (PerformanceProperty->Frequency, 1000);
 | 
						|
  TimerInfo.StartCount = 0;
 | 
						|
  TimerInfo.EndCount   = 0xFFFF;
 | 
						|
  TimerInfo.CountUp = TRUE;
 | 
						|
 | 
						|
  //
 | 
						|
  // Print header
 | 
						|
  //
 | 
						|
  // print DP's build version
 | 
						|
  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_BUILD_REVISION), mDpHiiHandle, DP_MAJOR_VERSION, DP_MINOR_VERSION);
 | 
						|
 | 
						|
  // print performance timer characteristics
 | 
						|
  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_KHZ), mDpHiiHandle, TimerInfo.Frequency);
 | 
						|
 | 
						|
  if (VerboseMode && !RawMode) {
 | 
						|
    StringPtr = HiiGetString (mDpHiiHandle,
 | 
						|
                  (EFI_STRING_ID) (TimerInfo.CountUp ? STRING_TOKEN (STR_DP_UP) : STRING_TOKEN (STR_DP_DOWN)), NULL);
 | 
						|
    ASSERT (StringPtr != NULL);
 | 
						|
    // Print Timer count range and direction
 | 
						|
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TIMER_PROPERTIES), mDpHiiHandle,
 | 
						|
                StringPtr,
 | 
						|
                TimerInfo.StartCount,
 | 
						|
                TimerInfo.EndCount
 | 
						|
                );
 | 
						|
    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_VERBOSE_THRESHOLD), mDpHiiHandle, mInterestThreshold);
 | 
						|
  }
 | 
						|
 | 
						|
/****************************************************************************
 | 
						|
****            Print Sections based on command line options
 | 
						|
****
 | 
						|
****  Option modes have the following priority:
 | 
						|
****    v Verbose     --  Valid in combination with any other options
 | 
						|
****    t Threshold   --  Modifies All, Raw, and Cooked output
 | 
						|
****                      Default is 0 for All and Raw mode
 | 
						|
****                      Default is DEFAULT_THRESHOLD for "Cooked" mode
 | 
						|
****    n Number2Display  Used by All and Raw mode.  Otherwise ignored.
 | 
						|
****    A All         --  R and S options are ignored
 | 
						|
****    R Raw         --  S option is ignored
 | 
						|
****    s Summary     --  Modifies "Cooked" output only
 | 
						|
****    Cooked (Default)
 | 
						|
****************************************************************************/
 | 
						|
  GatherStatistics (CustomCumulativeData);
 | 
						|
  if (CumulativeMode) {
 | 
						|
    ProcessCumulative (CustomCumulativeData);
 | 
						|
  } else if (AllMode) {
 | 
						|
    Status = DumpAllTrace( Number2Display, ExcludeMode);
 | 
						|
    if (Status == EFI_ABORTED) {
 | 
						|
      ShellStatus = SHELL_ABORTED;
 | 
						|
      goto Done;
 | 
						|
    }
 | 
						|
  } else if (RawMode) {
 | 
						|
    Status = DumpRawTrace( Number2Display, ExcludeMode);
 | 
						|
    if (Status == EFI_ABORTED) {
 | 
						|
      ShellStatus = SHELL_ABORTED;
 | 
						|
      goto Done;
 | 
						|
    }
 | 
						|
  } else {
 | 
						|
    //------------- Begin Cooked Mode Processing
 | 
						|
    ProcessPhases ();
 | 
						|
    if ( ! SummaryMode) {
 | 
						|
      Status = ProcessHandles ( ExcludeMode);
 | 
						|
      if (Status == EFI_ABORTED) {
 | 
						|
        ShellStatus = SHELL_ABORTED;
 | 
						|
        goto Done;
 | 
						|
      }
 | 
						|
 | 
						|
      Status = ProcessPeims ();
 | 
						|
      if (Status == EFI_ABORTED) {
 | 
						|
        ShellStatus = SHELL_ABORTED;
 | 
						|
        goto Done;
 | 
						|
      }
 | 
						|
 | 
						|
      Status = ProcessGlobal ();
 | 
						|
      if (Status == EFI_ABORTED) {
 | 
						|
        ShellStatus = SHELL_ABORTED;
 | 
						|
        goto Done;
 | 
						|
      }
 | 
						|
 | 
						|
       ProcessCumulative (NULL);
 | 
						|
    }
 | 
						|
  } //------------- End of Cooked Mode Processing
 | 
						|
  if ( VerboseMode || SummaryMode) {
 | 
						|
    DumpStatistics();
 | 
						|
  }
 | 
						|
 | 
						|
Done:
 | 
						|
  if (ParamPackage != NULL) {
 | 
						|
    ShellCommandLineFreeVarList (ParamPackage);
 | 
						|
  }
 | 
						|
  SHELL_FREE_NON_NULL (StringPtr);
 | 
						|
  if (CustomCumulativeData != NULL) {
 | 
						|
    SHELL_FREE_NON_NULL (CustomCumulativeData->Name);
 | 
						|
  }
 | 
						|
  SHELL_FREE_NON_NULL (CustomCumulativeData);
 | 
						|
 | 
						|
  SHELL_FREE_NON_NULL (mMeasurementList);
 | 
						|
 | 
						|
  SHELL_FREE_NON_NULL (mCacheHandleGuidTable);
 | 
						|
 | 
						|
  mMeasurementNum = 0;
 | 
						|
  mCachePairCount = 0;
 | 
						|
  return ShellStatus;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Retrive HII package list from ImageHandle and publish to HII database.
 | 
						|
 | 
						|
  @param ImageHandle            The image handle of the process.
 | 
						|
 | 
						|
  @return HII handle.
 | 
						|
**/
 | 
						|
EFI_HANDLE
 | 
						|
InitializeHiiPackage (
 | 
						|
  EFI_HANDLE                  ImageHandle
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                  Status;
 | 
						|
  EFI_HII_PACKAGE_LIST_HEADER *PackageList;
 | 
						|
  EFI_HANDLE                  HiiHandle;
 | 
						|
 | 
						|
  //
 | 
						|
  // Retrieve HII package list from ImageHandle
 | 
						|
  //
 | 
						|
  Status = gBS->OpenProtocol (
 | 
						|
                  ImageHandle,
 | 
						|
                  &gEfiHiiPackageListProtocolGuid,
 | 
						|
                  (VOID **)&PackageList,
 | 
						|
                  ImageHandle,
 | 
						|
                  NULL,
 | 
						|
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
 | 
						|
                  );
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Publish HII package list to HII Database.
 | 
						|
  //
 | 
						|
  Status = gHiiDatabase->NewPackageList (
 | 
						|
                           gHiiDatabase,
 | 
						|
                           PackageList,
 | 
						|
                           NULL,
 | 
						|
                           &HiiHandle
 | 
						|
                           );
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
  return HiiHandle;
 | 
						|
}
 |