ShellPkg: Add "dp" command library to ShellPkg.

This command is only included in the build with command line option "-D INCLUDE_DP".  The user must also update the DSC with appropriate library instances that match the platform for the build to succeed.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jaben Carsey <jaben.carsey@intel.com>
Reviewed-by: Erik Bjorge <erik.c.bjorge@intel.com>

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14160 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
jcarsey 2013-03-04 22:02:59 +00:00
parent 365aa98a5d
commit d41bc92c99
14 changed files with 2377 additions and 3 deletions

View File

@ -0,0 +1,310 @@
/** @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 - 2013, Intel Corporation. All rights reserved.
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 "UefiDpLib.h"
#include <Guid/GlobalVariable.h>
#include <Library/PrintLib.h>
#include <Library/HandleParsingLib.h>
#include <Library/DevicePathLib.h>
#include <Library/ShellLib.h>
#include <Library/BaseLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DebugLib.h>
#include <Library/TimerLib.h>
#include <Library/UefiLib.h>
#include <Guid/Performance.h>
#include <PerformanceTokens.h>
#include "Dp.h"
#include "Literals.h"
#include "DpInternal.h"
//
/// Module-Global Variables
///@{
CHAR16 mGaugeString[DP_GAUGE_STRING_LENGTH + 1];
CHAR16 mUnicodeToken[DXE_PERFORMANCE_STRING_SIZE];
UINT64 mInterestThreshold;
BOOLEAN mShowId = FALSE;
PERF_SUMMARY_DATA SummaryData = { 0 }; ///< Create the SummaryData structure and init. to ZERO.
/// Timer Specific Information.
TIMER_INFO TimerInfo;
/// 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
#if PROFILING_IMPLEMENTED
{L"-P", TypeFlag}, // -P Dump Profile Data
{L"-T", TypeFlag}, // -T Dump Trace Data
#endif // PROFILING_IMPLEMENTED
{L"-x", TypeFlag}, // -x eXclude Cumulative Items
{L"-i", TypeFlag}, // -i Display Identifier
{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 (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_STATISTICS), NULL);
StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,
(StringPtr == NULL) ? StringPtrUnknown : StringPtr);
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMTRACE), gDpHiiHandle, SummaryData.NumTrace);
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMINCOMPLETE), gDpHiiHandle, SummaryData.NumIncomplete);
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMPHASES), gDpHiiHandle, SummaryData.NumSummary);
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMHANDLES), gDpHiiHandle, SummaryData.NumHandles, SummaryData.NumTrace - SummaryData.NumHandles);
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMPEIMS), gDpHiiHandle, SummaryData.NumPEIMs);
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMGLOBALS), gDpHiiHandle, SummaryData.NumGlobal);
#if PROFILING_IMPLEMENTED
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMPROFILE), gDpHiiHandle, SummaryData.NumProfile);
#endif // PROFILING_IMPLEMENTED
SHELL_FREE_NON_NULL (StringPtr);
SHELL_FREE_NON_NULL (StringPtrUnknown);
}
/**
Dump performance data.
@param[in] ImageHandle The image handle.
@param[in] SystemTable The system table.
@retval EFI_SUCCESS Command completed successfully.
@retval EFI_INVALID_PARAMETER Command usage error.
@retval value Unknown error.
**/
SHELL_STATUS
EFIAPI
ShellCommandRunDp (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
LIST_ENTRY *ParamPackage;
CONST CHAR16 *CmdLineArg;
EFI_STATUS Status;
UINT64 Freq;
UINT64 Ticker;
UINTN Number2Display;
EFI_STRING StringPtr = NULL;
BOOLEAN SummaryMode = FALSE;
BOOLEAN VerboseMode = FALSE;
BOOLEAN AllMode = FALSE;
BOOLEAN RawMode = FALSE;
BOOLEAN TraceMode = FALSE;
BOOLEAN ProfileMode = FALSE;
BOOLEAN ExcludeMode = FALSE;
// Get DP's entry time as soon as possible.
// This is used as the Shell-Phase end time.
//
Ticker = GetPerformanceCounter ();
//
// initialize the shell lib (we must be in non-auto-init...)
//
Status = ShellInitialize();
ASSERT_EFI_ERROR(Status);
Status = CommandInit();
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), gDpHiiHandle);
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");
#if PROFILING_IMPLEMENTED
TraceMode = ShellCommandLineGetFlag (ParamPackage, L"-T");
ProfileMode = ShellCommandLineGetFlag (ParamPackage, L"-P");
#endif // PROFILING_IMPLEMENTED
ExcludeMode = ShellCommandLineGetFlag (ParamPackage, L"-x");
mShowId = ShellCommandLineGetFlag (ParamPackage, L"-i");
// Options with Values
CmdLineArg = ShellCommandLineGetValue (ParamPackage, L"-n");
if (CmdLineArg == NULL) {
Number2Display = DEFAULT_DISPLAYCOUNT;
} else {
Number2Display = StrDecimalToUintn(CmdLineArg);
if (Number2Display == 0) {
Number2Display = MAXIMUM_DISPLAYCOUNT;
}
}
CmdLineArg = ShellCommandLineGetValue (ParamPackage, L"-t");
if (CmdLineArg == NULL) {
mInterestThreshold = DEFAULT_THRESHOLD; // 1ms := 1,000 us
} else {
mInterestThreshold = StrDecimalToUint64(CmdLineArg);
}
// Handle Flag combinations and default behaviors
// If both TraceMode and ProfileMode are FALSE, set them both to TRUE
if ((! TraceMode) && (! ProfileMode)) {
TraceMode = TRUE;
#if PROFILING_IMPLEMENTED
ProfileMode = TRUE;
#endif // PROFILING_IMPLEMENTED
}
//
// 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
//
Freq = GetPerformanceCounterProperties (&TimerInfo.StartCount, &TimerInfo.EndCount);
// Convert the Frequency from Hz to KHz
TimerInfo.Frequency = (UINT32)DivU64x32 (Freq, 1000);
// Determine in which direction the performance counter counts.
TimerInfo.CountUp = (BOOLEAN) (TimerInfo.EndCount >= TimerInfo.StartCount);
//
// Print header
//
// print DP's build version
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_BUILD_REVISION), gDpHiiHandle, DP_MAJOR_VERSION, DP_MINOR_VERSION);
// print performance timer characteristics
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_KHZ), gDpHiiHandle, TimerInfo.Frequency);
if (VerboseMode && !RawMode) {
StringPtr = HiiGetString (gDpHiiHandle,
(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), gDpHiiHandle,
StringPtr,
TimerInfo.StartCount,
TimerInfo.EndCount
);
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_VERBOSE_THRESHOLD), gDpHiiHandle, 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)
****
**** The All, Raw, and Cooked modes are modified by the Trace and Profile
**** options.
**** !T && !P := (0) Default, Both are displayed
**** T && !P := (1) Only Trace records are displayed
**** !T && P := (2) Only Profile records are displayed
**** T && P := (3) Same as Default, both are displayed
****************************************************************************/
GatherStatistics();
if (AllMode) {
if (TraceMode) {
DumpAllTrace( Number2Display, ExcludeMode);
}
if (ProfileMode) {
DumpAllProfile( Number2Display, ExcludeMode);
}
} else if (RawMode) {
if (TraceMode) {
DumpRawTrace( Number2Display, ExcludeMode);
}
if (ProfileMode) {
DumpRawProfile( Number2Display, ExcludeMode);
}
} else {
//------------- Begin Cooked Mode Processing
if (TraceMode) {
ProcessPhases ( Ticker );
if ( ! SummaryMode) {
Status = ProcessHandles ( ExcludeMode);
if ( ! EFI_ERROR( Status)) {
ProcessPeims ();
ProcessGlobal ();
ProcessCumulative ();
}
}
}
if (ProfileMode) {
DumpAllProfile( Number2Display, ExcludeMode);
}
} //------------- End of Cooked Mode Processing
if ( VerboseMode || SummaryMode) {
DumpStatistics();
}
SHELL_FREE_NON_NULL (StringPtr);
return SHELL_SUCCESS;
}

View File

@ -0,0 +1,98 @@
/** @file
Common declarations for the Dp Performance Reporting Utility.
Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.
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.
**/
#ifndef _EFI_APP_DP_H_
#define _EFI_APP_DP_H_
#include <Library/ShellLib.h>
#include <ShellBase.h>
#define DP_MAJOR_VERSION 2
#define DP_MINOR_VERSION 4
/**
* The value assigned to DP_DEBUG controls which debug output
* is generated. Set it to ZERO to disable.
**/
#define DP_DEBUG 0
/**
* Set to 1 once Profiling has been implemented in order to enable
* profiling related options and report output.
**/
#define PROFILING_IMPLEMENTED 0
#define DEFAULT_THRESHOLD 1000 ///< One millisecond.
#define DEFAULT_DISPLAYCOUNT 50
#define MAXIMUM_DISPLAYCOUNT 999999 ///< Arbitrary maximum reasonable number.
#define PERF_MAXDUR 0xFFFFFFFFFFFFFFFFULL
/// Determine whether 0 <= C < L. If L == 0, return true regardless of C.
#define WITHIN_LIMIT( C, L) ( ((L) == 0) || ((C) < (L)) )
/// Structure for storing Timer specific information.
typedef struct {
UINT64 StartCount; ///< Value timer is initialized with.
UINT64 EndCount; ///< Value timer has just before it wraps.
UINT32 Frequency; ///< Timer count frequency in KHz.
BOOLEAN CountUp; ///< TRUE if the counter counts up.
} TIMER_INFO;
/** Initialize one PERF_CUM_DATA structure instance for token t.
*
* This parameterized macro takes a single argument, t, which is expected
* to resolve to a pointer to an ASCII string literal. This parameter may
* take any one of the following forms:
* - PERF_INIT_CUM_DATA("Token") A string literal
* - PERF_INIT_CUM_DATA(pointer) A pointer -- CHAR8 *pointer;
* - PERF_INIT_CUM_DATA(array) Address of an array -- CHAR8 array[N];
**/
#define PERF_INIT_CUM_DATA(t) { 0ULL, PERF_MAXDUR, 0ULL, (t), 0U }
typedef struct {
UINT64 Duration; ///< Cumulative duration for this item.
UINT64 MinDur; ///< Smallest duration encountered.
UINT64 MaxDur; ///< Largest duration encountered.
CHAR8 *Name; ///< ASCII name of this item.
UINT32 Count; ///< Total number of measurements accumulated.
} PERF_CUM_DATA;
typedef struct {
UINT32 NumTrace; ///< Number of recorded TRACE performance measurements.
UINT32 NumProfile; ///< Number of recorded PROFILE performance measurements.
UINT32 NumIncomplete; ///< Number of measurements with no END value.
UINT32 NumSummary; ///< Number of summary section measurements.
UINT32 NumHandles; ///< Number of measurements with handles.
UINT32 NumPEIMs; ///< Number of measurements of PEIMs.
UINT32 NumGlobal; ///< Number of measurements with END value and NULL handle.
} PERF_SUMMARY_DATA;
typedef struct {
CONST VOID *Handle;
CONST CHAR8 *Token; ///< Measured token string name.
CONST CHAR8 *Module; ///< Module string name.
UINT64 StartTimeStamp; ///< Start time point.
UINT64 EndTimeStamp; ///< End time point.
UINT32 Identifier; ///< Identifier.
} MEASUREMENT_RECORD;
typedef struct {
CHAR8 *Name; ///< Measured token string name.
UINT64 CumulativeTime; ///< Accumulated Elapsed Time.
UINT64 MinTime; ///< Minimum Elapsed Time.
UINT64 MaxTime; ///< Maximum Elapsed Time.
UINT32 Count; ///< Number of measurements accumulated.
} PROFILE_RECORD;
#endif // _EFI_APP_DP_H_

View File

@ -0,0 +1,340 @@
/** @file
Declarations of objects defined internally to the Dp Application.
Declarations of data and functions which are private to the Dp application.
This file should never be referenced by anything other than components of the
Dp application. In addition to global data, function declarations for
DpUtilities.c, DpTrace.c, and DpProfile.c are included here.
Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.
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.
**/
#ifndef _DP_INTELNAL_H_
#define _DP_INTELNAL_H_
#define DP_GAUGE_STRING_LENGTH 36
//
/// Module-Global Variables
///@{
extern EFI_HII_HANDLE gDpHiiHandle;
extern CHAR16 mGaugeString[DP_GAUGE_STRING_LENGTH + 1];
extern CHAR16 mUnicodeToken[DXE_PERFORMANCE_STRING_SIZE];
extern UINT64 mInterestThreshold;
extern BOOLEAN mShowId;
extern PERF_SUMMARY_DATA SummaryData; ///< Create the SummaryData structure and init. to ZERO.
/// Timer Specific Information.
extern TIMER_INFO TimerInfo;
/// Items for which to gather cumulative statistics.
extern PERF_CUM_DATA CumData[];
/// Number of items for which we are gathering cumulative statistics.
extern UINT32 const NumCum;
///@}
/**
Calculate an event's duration in timer ticks.
Given the count direction and the event's start and end timer values,
calculate the duration of the event in timer ticks. Information for
the current measurement is pointed to by the parameter.
If the measurement's start time is 1, it indicates that the developer
is indicating that the measurement began at the release of reset.
The start time is adjusted to the timer's starting count before performing
the elapsed time calculation.
The calculated duration, in ticks, is the absolute difference between
the measurement's ending and starting counts.
@param Measurement Pointer to a MEASUREMENT_RECORD structure containing
data for the current measurement.
@return The 64-bit duration of the event.
**/
UINT64
GetDuration (
IN OUT MEASUREMENT_RECORD *Measurement
);
/**
Determine whether the Measurement record is for an EFI Phase.
The Token and Module members of the measurement record are checked.
Module must be empty and Token must be one of SEC, PEI, DXE, BDS, or SHELL.
@param[in] Measurement A pointer to the Measurement record to test.
@retval TRUE The measurement record is for an EFI Phase.
@retval FALSE The measurement record is NOT for an EFI Phase.
**/
BOOLEAN
IsPhase(
IN MEASUREMENT_RECORD *Measurement
);
/**
Get the file name portion of the Pdb File Name.
The portion of the Pdb File Name between the last backslash and
either a following period or the end of the string is converted
to Unicode and copied into UnicodeBuffer. The name is truncated,
if necessary, to ensure that UnicodeBuffer is not overrun.
@param[in] PdbFileName Pdb file name.
@param[out] UnicodeBuffer The resultant Unicode File Name.
**/
VOID
GetShortPdbFileName (
IN CHAR8 *PdbFileName,
OUT CHAR16 *UnicodeBuffer
);
/**
Get a human readable name for an image handle.
The following methods will be tried orderly:
1. Image PDB
2. ComponentName2 protocol
3. FFS UI section
4. Image GUID
5. Image DevicePath
6. Unknown Driver Name
@param[in] Handle
@post The resulting Unicode name string is stored in the
mGaugeString global array.
**/
VOID
GetNameFromHandle (
IN EFI_HANDLE Handle
);
/**
Calculate the Duration in microseconds.
Duration is multiplied by 1000, instead of Frequency being divided by 1000 or
multiplying the result by 1000, in order to maintain precision. Since Duration is
a 64-bit value, multiplying it by 1000 is unlikely to produce an overflow.
The time is calculated as (Duration * 1000) / Timer_Frequency.
@param[in] Duration The event duration in timer ticks.
@return A 64-bit value which is the Elapsed time in microseconds.
**/
UINT64
DurationInMicroSeconds (
IN UINT64 Duration
);
/**
Get index of Measurement Record's match in the CumData array.
If the Measurement's Token value matches a Token in one of the CumData
records, the index of the matching record is returned. The returned
index is a signed value so that negative values can indicate that
the Measurement didn't match any entry in the CumData array.
@param[in] Measurement A pointer to a Measurement Record to match against the CumData array.
@retval <0 Token is not in the CumData array.
@retval >=0 Return value is the index into CumData where Token is found.
**/
INTN
GetCumulativeItem(
IN MEASUREMENT_RECORD *Measurement
);
/**
Collect verbose statistics about the logged performance measurements.
General Summary information for all Trace measurements is gathered and
stored within the SummaryData structure. This information is both
used internally by subsequent reporting functions, and displayed
at the end of verbose reports.
@pre The SummaryData and CumData structures must be initialized
prior to calling this function.
@post The SummaryData and CumData structures contain statistics for the
current performance logs.
**/
VOID
GatherStatistics(
VOID
);
/**
Gather and print ALL Trace Records.
Displays all "interesting" Trace measurements in order.<BR>
The number of records displayed is controlled by:
- records with a duration less than mInterestThreshold microseconds are not displayed.
- No more than Limit records are displayed. A Limit of zero will not limit the output.
- If the ExcludeFlag is TRUE, records matching entries in the CumData array are not
displayed.
@pre The mInterestThreshold global variable is set to the shortest duration to be printed.
The mGaugeString and mUnicodeToken global arrays are used for temporary string storage.
They must not be in use by a calling function.
@param[in] Limit The number of records to print. Zero is ALL.
@param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.
**/
VOID
DumpAllTrace(
IN UINTN Limit,
IN BOOLEAN ExcludeFlag
);
/**
Gather and print Raw Trace Records.
All Trace measurements with a duration greater than or equal to
mInterestThreshold are printed without interpretation.
The number of records displayed is controlled by:
- records with a duration less than mInterestThreshold microseconds are not displayed.
- No more than Limit records are displayed. A Limit of zero will not limit the output.
- If the ExcludeFlag is TRUE, records matching entries in the CumData array are not
displayed.
@pre The mInterestThreshold global variable is set to the shortest duration to be printed.
@param[in] Limit The number of records to print. Zero is ALL.
@param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.
**/
VOID
DumpRawTrace(
IN UINTN Limit,
IN BOOLEAN ExcludeFlag
);
/**
Gather and print Major Phase metrics.
@param[in] Ticker The timer value for the END of Shell phase
**/
VOID
ProcessPhases(
IN UINT64 Ticker
);
/**
Gather and print Handle data.
@param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.
@return Status from a call to gBS->LocateHandle().
**/
EFI_STATUS
ProcessHandles(
IN BOOLEAN ExcludeFlag
);
/**
Gather and print PEIM data.
Only prints complete PEIM records
**/
VOID
ProcessPeims(
VOID
);
/**
Gather and print global data.
Strips out incomplete or "Execution Phase" records
Only prints records where Handle is NULL
Increment TIndex for every record, even skipped ones, so that we have an
indication of every measurement record taken.
**/
VOID
ProcessGlobal(
VOID
);
/**
Gather and print cumulative data.
Traverse the measurement records and:<BR>
For each record with a Token listed in the CumData array:<BR>
- Update the instance count and the total, minimum, and maximum durations.
Finally, print the gathered cumulative statistics.
**/
VOID
ProcessCumulative(
VOID
);
/**
Gather and print ALL Profiling Records.
Displays all "interesting" Profile measurements in order.
The number of records displayed is controlled by:
- records with a duration less than mInterestThreshold microseconds are not displayed.
- No more than Limit records are displayed. A Limit of zero will not limit the output.
- If the ExcludeFlag is TRUE, records matching entries in the CumData array are not
displayed.
@pre The mInterestThreshold global variable is set to the shortest duration to be printed.
The mGaugeString and mUnicodeToken global arrays are used for temporary string storage.
They must not be in use by a calling function.
@param[in] Limit The number of records to print. Zero is ALL.
@param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.
**/
VOID
DumpAllProfile(
IN UINTN Limit,
IN BOOLEAN ExcludeFlag
);
/**
Gather and print Raw Profile Records.
All Profile measurements with a duration greater than or equal to
mInterestThreshold are printed without interpretation.
The number of records displayed is controlled by:
- records with a duration less than mInterestThreshold microseconds are not displayed.
- No more than Limit records are displayed. A Limit of zero will not limit the output.
- If the ExcludeFlag is TRUE, records matching entries in the CumData array are not
displayed.
@pre The mInterestThreshold global variable is set to the shortest duration to be printed.
@param[in] Limit The number of records to print. Zero is ALL.
@param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.
**/
VOID
DumpRawProfile(
IN UINTN Limit,
IN BOOLEAN ExcludeFlag
);
#endif

View File

@ -0,0 +1,101 @@
/** @file
Measured Profiling reporting for the Dp utility.
Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.
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 <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/TimerLib.h>
#include <Library/PeCoffGetEntryPointLib.h>
#include <Library/PerformanceLib.h>
#include <Library/PrintLib.h>
#include <Library/HiiLib.h>
#include <Library/PcdLib.h>
#include <Guid/Performance.h>
#include "Dp.h"
#include "Literals.h"
#include "DpInternal.h"
/**
Gather and print ALL Profiling Records.
Displays all "interesting" Profile measurements in order.
The number of records displayed is controlled by:
- records with a duration less than mInterestThreshold microseconds are not displayed.
- No more than Limit records are displayed. A Limit of zero will not limit the output.
- If the ExcludeFlag is TRUE, records matching entries in the CumData array are not
displayed.
@pre The mInterestThreshold global variable is set to the shortest duration to be printed.
The mGaugeString and mUnicodeToken global arrays are used for temporary string storage.
They must not be in use by a calling function.
@param[in] Limit The number of records to print. Zero is ALL.
@param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.
**/
VOID
DumpAllProfile(
IN UINTN Limit,
IN BOOLEAN ExcludeFlag
)
{
EFI_STRING StringPtr;
EFI_STRING StringPtrUnknown;
StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_PROFILE), NULL);
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,
(StringPtr == NULL) ? StringPtrUnknown: StringPtr);
FreePool (StringPtr);
FreePool (StringPtrUnknown);
}
/**
Gather and print Raw Profile Records.
All Profile measurements with a duration greater than or equal to
mInterestThreshold are printed without interpretation.
The number of records displayed is controlled by:
- records with a duration less than mInterestThreshold microseconds are not displayed.
- No more than Limit records are displayed. A Limit of zero will not limit the output.
- If the ExcludeFlag is TRUE, records matching entries in the CumData array are not
displayed.
@pre The mInterestThreshold global variable is set to the shortest duration to be printed.
@param[in] Limit The number of records to print. Zero is ALL.
@param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.
**/
VOID
DumpRawProfile(
IN UINTN Limit,
IN BOOLEAN ExcludeFlag
)
{
EFI_STRING StringPtr;
EFI_STRING StringPtrUnknown;
StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_RAWPROFILE), NULL);
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,
(StringPtr == NULL) ? StringPtrUnknown: StringPtr);
FreePool (StringPtr);
FreePool (StringPtrUnknown);
}

View File

@ -0,0 +1,828 @@
/** @file
Trace reporting for the Dp utility.
Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.
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 <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/TimerLib.h>
#include <Library/PeCoffGetEntryPointLib.h>
#include <Library/PerformanceLib.h>
#include <Library/PrintLib.h>
#include <Library/HiiLib.h>
#include <Library/PcdLib.h>
#include <Guid/Performance.h>
#include "Dp.h"
#include "Literals.h"
#include "DpInternal.h"
/**
Collect verbose statistics about the logged performance measurements.
General Summary information for all Trace measurements is gathered and
stored within the SummaryData structure. This information is both
used internally by subsequent reporting functions, and displayed
at the end of verbose reports.
@pre The SummaryData and CumData structures must be initialized
prior to calling this function.
@post The SummaryData and CumData structures contain statistics for the
current performance logs.
**/
VOID
GatherStatistics(
VOID
)
{
MEASUREMENT_RECORD Measurement;
UINT64 Duration;
UINTN LogEntryKey;
INTN TIndex;
LogEntryKey = 0;
while ((LogEntryKey = GetPerformanceMeasurementEx (
LogEntryKey,
&Measurement.Handle,
&Measurement.Token,
&Measurement.Module,
&Measurement.StartTimeStamp,
&Measurement.EndTimeStamp,
&Measurement.Identifier)) != 0)
{
++SummaryData.NumTrace; // Count the number of TRACE Measurement records
if (Measurement.EndTimeStamp == 0) {
++SummaryData.NumIncomplete; // Count the incomplete records
continue;
}
if (Measurement.Handle != NULL) {
++SummaryData.NumHandles; // Count the number of measurements with non-NULL handles
}
if (IsPhase( &Measurement)) {
++SummaryData.NumSummary; // Count the number of major phases
}
else { // !IsPhase(...
if(Measurement.Handle == NULL) {
++SummaryData.NumGlobal;
}
}
if (AsciiStrnCmp (Measurement.Token, ALit_PEIM, PERF_TOKEN_LENGTH) == 0) {
++SummaryData.NumPEIMs; // Count PEIM measurements
}
Duration = GetDuration (&Measurement);
TIndex = GetCumulativeItem (&Measurement);
if (TIndex >= 0) {
CumData[TIndex].Duration += Duration;
CumData[TIndex].Count++;
if ( Duration < CumData[TIndex].MinDur ) {
CumData[TIndex].MinDur = Duration;
}
if ( Duration > CumData[TIndex].MaxDur ) {
CumData[TIndex].MaxDur = Duration;
}
}
}
}
/**
Gather and print ALL Trace Records.
Displays all "interesting" Trace measurements in order.<BR>
The number of records displayed is controlled by:
- records with a duration less than mInterestThreshold microseconds are not displayed.
- No more than Limit records are displayed. A Limit of zero will not limit the output.
- If the ExcludeFlag is TRUE, records matching entries in the CumData array are not
displayed.
@pre The mInterestThreshold global variable is set to the shortest duration to be printed.
The mGaugeString and mUnicodeToken global arrays are used for temporary string storage.
They must not be in use by a calling function.
@param[in] Limit The number of records to print. Zero is ALL.
@param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.
**/
VOID
DumpAllTrace(
IN UINTN Limit,
IN BOOLEAN ExcludeFlag
)
{
MEASUREMENT_RECORD Measurement;
UINT64 ElapsedTime;
UINT64 Duration;
CHAR16 *IncFlag;
UINTN LogEntryKey;
UINTN Count;
UINTN Index;
UINTN TIndex;
EFI_HANDLE *HandleBuffer;
UINTN Size;
EFI_HANDLE TempHandle;
EFI_STATUS Status;
EFI_STRING StringPtrUnknown;
StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
IncFlag = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_ALL), NULL);
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,
(IncFlag == NULL) ? StringPtrUnknown : IncFlag);
FreePool (StringPtrUnknown);
// Get Handle information
//
Size = 0;
HandleBuffer = &TempHandle;
Status = gBS->LocateHandle (AllHandles, NULL, NULL, &Size, &TempHandle);
if (Status == EFI_BUFFER_TOO_SMALL) {
HandleBuffer = AllocatePool (Size);
ASSERT (HandleBuffer != NULL);
if (HandleBuffer == NULL) {
return;
}
Status = gBS->LocateHandle (AllHandles, NULL, NULL, &Size, HandleBuffer);
}
if (EFI_ERROR (Status)) {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLES_ERROR), gDpHiiHandle, Status);
}
else {
// We have successfully populated the HandleBuffer
// Display ALL Measurement Records
// Up to Limit lines displayed
// Display only records with Elapsed times >= mInterestThreshold
// Display driver names in Module field for records with Handles.
//
if (mShowId) {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_ALL_HEADR2), gDpHiiHandle);
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_ALL_DASHES2), gDpHiiHandle);
} else {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_ALL_HEADR), gDpHiiHandle);
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), gDpHiiHandle);
}
LogEntryKey = 0;
Count = 0;
Index = 0;
while ( WITHIN_LIMIT(Count, Limit) &&
((LogEntryKey = GetPerformanceMeasurementEx (
LogEntryKey,
&Measurement.Handle,
&Measurement.Token,
&Measurement.Module,
&Measurement.StartTimeStamp,
&Measurement.EndTimeStamp,
&Measurement.Identifier)) != 0)
)
{
++Index; // Count every record. First record is 1.
ElapsedTime = 0;
SHELL_FREE_NON_NULL (IncFlag);
if (Measurement.EndTimeStamp != 0) {
Duration = GetDuration (&Measurement);
ElapsedTime = DurationInMicroSeconds ( Duration );
IncFlag = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_COMPLETE), NULL);
}
else {
IncFlag = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_INCOMPLETE), NULL); // Mark incomplete records
}
if (((Measurement.EndTimeStamp != 0) && (ElapsedTime < mInterestThreshold)) ||
((ExcludeFlag) && (GetCumulativeItem(&Measurement) >= 0))
) { // Ignore "uninteresting" or excluded records
continue;
}
++Count; // Count the number of records printed
// If Handle is non-zero, see if we can determine a name for the driver
AsciiStrToUnicodeStr (Measurement.Module, mGaugeString); // Use Module by default
AsciiStrToUnicodeStr (Measurement.Token, mUnicodeToken);
if (Measurement.Handle != NULL) {
// See if the Handle is in the HandleBuffer
for (TIndex = 0; TIndex < (Size / sizeof(HandleBuffer[0])); TIndex++) {
if (Measurement.Handle == HandleBuffer[TIndex]) {
GetNameFromHandle (HandleBuffer[TIndex]);
break;
}
}
}
if (AsciiStrnCmp (Measurement.Token, ALit_PEIM, PERF_TOKEN_LENGTH) == 0) {
UnicodeSPrint (mGaugeString, sizeof (mGaugeString), L"%g", Measurement.Handle);
}
// Ensure that the argument strings are not too long.
mGaugeString[DP_GAUGE_STRING_LENGTH] = 0;
mUnicodeToken[13] = 0;
if (mShowId) {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_ALL_VARS2), gDpHiiHandle,
Index, // 1 based, Which measurement record is being printed
IncFlag,
Measurement.Handle,
mGaugeString,
mUnicodeToken,
ElapsedTime,
Measurement.Identifier
);
} else {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_ALL_VARS), gDpHiiHandle,
Index, // 1 based, Which measurement record is being printed
IncFlag,
Measurement.Handle,
mGaugeString,
mUnicodeToken,
ElapsedTime
);
}
}
}
if (HandleBuffer != &TempHandle) {
FreePool (HandleBuffer);
}
SHELL_FREE_NON_NULL (IncFlag);
}
/**
Gather and print Raw Trace Records.
All Trace measurements with a duration greater than or equal to
mInterestThreshold are printed without interpretation.
The number of records displayed is controlled by:
- records with a duration less than mInterestThreshold microseconds are not displayed.
- No more than Limit records are displayed. A Limit of zero will not limit the output.
- If the ExcludeFlag is TRUE, records matching entries in the CumData array are not
displayed.
@pre The mInterestThreshold global variable is set to the shortest duration to be printed.
@param[in] Limit The number of records to print. Zero is ALL.
@param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.
**/
VOID
DumpRawTrace(
IN UINTN Limit,
IN BOOLEAN ExcludeFlag
)
{
MEASUREMENT_RECORD Measurement;
UINT64 ElapsedTime;
UINT64 Duration;
UINTN LogEntryKey;
UINTN Count;
UINTN Index;
EFI_STRING StringPtr;
EFI_STRING StringPtrUnknown;
StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_RAWTRACE), NULL);
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,
(StringPtr == NULL) ? StringPtrUnknown : StringPtr);
FreePool (StringPtr);
FreePool (StringPtrUnknown);
if (mShowId) {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_HEADR2), gDpHiiHandle);
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_DASHES2), gDpHiiHandle);
} else {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_HEADR), gDpHiiHandle);
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_DASHES), gDpHiiHandle);
}
LogEntryKey = 0;
Count = 0;
Index = 0;
while ( WITHIN_LIMIT(Count, Limit) &&
((LogEntryKey = GetPerformanceMeasurementEx (
LogEntryKey,
&Measurement.Handle,
&Measurement.Token,
&Measurement.Module,
&Measurement.StartTimeStamp,
&Measurement.EndTimeStamp,
&Measurement.Identifier)) != 0)
)
{
++Index; // Count every record. First record is 1.
ElapsedTime = 0;
if (Measurement.EndTimeStamp != 0) {
Duration = GetDuration (&Measurement);
ElapsedTime = DurationInMicroSeconds ( Duration );
}
if ((ElapsedTime < mInterestThreshold) ||
((ExcludeFlag) && (GetCumulativeItem(&Measurement) >= 0))
) { // Ignore "uninteresting" or Excluded records
continue;
}
++Count; // Count the number of records printed
if (mShowId) {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_VARS2), gDpHiiHandle,
Index, // 1 based, Which measurement record is being printed
Measurement.Handle,
Measurement.StartTimeStamp,
Measurement.EndTimeStamp,
Measurement.Token,
Measurement.Module,
Measurement.Identifier
);
} else {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_VARS), gDpHiiHandle,
Index, // 1 based, Which measurement record is being printed
Measurement.Handle,
Measurement.StartTimeStamp,
Measurement.EndTimeStamp,
Measurement.Token,
Measurement.Module
);
}
}
}
/**
Gather and print Major Phase metrics.
@param[in] Ticker The timer value for the END of Shell phase
**/
VOID
ProcessPhases(
IN UINT64 Ticker
)
{
MEASUREMENT_RECORD Measurement;
UINT64 BdsTimeoutValue;
UINT64 SecTime;
UINT64 PeiTime;
UINT64 DxeTime;
UINT64 BdsTime;
UINT64 ShellTime;
UINT64 ElapsedTime;
UINT64 Duration;
UINT64 Total;
EFI_STRING StringPtr;
UINTN LogEntryKey;
EFI_STRING StringPtrUnknown;
BdsTimeoutValue = 0;
SecTime = 0;
PeiTime = 0;
DxeTime = 0;
BdsTime = 0;
ShellTime = 0;
//
// Get Execution Phase Statistics
//
StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_PHASES), NULL);
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,
(StringPtr == NULL) ? StringPtrUnknown : StringPtr);
FreePool (StringPtr);
FreePool (StringPtrUnknown);
LogEntryKey = 0;
while ((LogEntryKey = GetPerformanceMeasurementEx (
LogEntryKey,
&Measurement.Handle,
&Measurement.Token,
&Measurement.Module,
&Measurement.StartTimeStamp,
&Measurement.EndTimeStamp,
&Measurement.Identifier)) != 0)
{
if (AsciiStrnCmp (Measurement.Token, ALit_SHELL, PERF_TOKEN_LENGTH) == 0) {
Measurement.EndTimeStamp = Ticker;
}
if (Measurement.EndTimeStamp == 0) { // Skip "incomplete" records
continue;
}
Duration = GetDuration (&Measurement);
if ( Measurement.Handle != NULL
&& (AsciiStrnCmp (Measurement.Token, ALit_BdsTO, PERF_TOKEN_LENGTH) == 0)
)
{
BdsTimeoutValue = Duration;
} else if (AsciiStrnCmp (Measurement.Token, ALit_SEC, PERF_TOKEN_LENGTH) == 0) {
SecTime = Duration;
} else if (AsciiStrnCmp (Measurement.Token, ALit_PEI, PERF_TOKEN_LENGTH) == 0) {
PeiTime = Duration;
} else if (AsciiStrnCmp (Measurement.Token, ALit_DXE, PERF_TOKEN_LENGTH) == 0) {
DxeTime = Duration;
} else if (AsciiStrnCmp (Measurement.Token, ALit_BDS, PERF_TOKEN_LENGTH) == 0) {
BdsTime = Duration;
} else if (AsciiStrnCmp (Measurement.Token, ALit_SHELL, PERF_TOKEN_LENGTH) == 0) {
ShellTime = Duration;
}
}
Total = 0;
// print SEC phase duration time
//
if (SecTime > 0) {
ElapsedTime = DurationInMicroSeconds ( SecTime ); // Calculate elapsed time in microseconds
Total += DivU64x32 (ElapsedTime, 1000); // Accumulate time in milliseconds
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SEC_PHASE), gDpHiiHandle, ElapsedTime);
}
// print PEI phase duration time
//
if (PeiTime > 0) {
ElapsedTime = DivU64x32 (
PeiTime,
(UINT32)TimerInfo.Frequency
);
Total += ElapsedTime;
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PHASE_DURATION), gDpHiiHandle, ALit_PEI, ElapsedTime);
}
// print DXE phase duration time
//
if (DxeTime > 0) {
ElapsedTime = DivU64x32 (
DxeTime,
(UINT32)TimerInfo.Frequency
);
Total += ElapsedTime;
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PHASE_DURATION), gDpHiiHandle, ALit_DXE, ElapsedTime);
}
// print BDS phase duration time
//
if (BdsTime > 0) {
ElapsedTime = DivU64x32 (
BdsTime,
(UINT32)TimerInfo.Frequency
);
Total += ElapsedTime;
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PHASE_DURATION), gDpHiiHandle, ALit_BDS, ElapsedTime);
}
if (BdsTimeoutValue > 0) {
ElapsedTime = DivU64x32 (
BdsTimeoutValue,
(UINT32)TimerInfo.Frequency
);
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PHASE_BDSTO), gDpHiiHandle, ALit_BdsTO, ElapsedTime);
}
// print SHELL phase duration time
//
if (ShellTime > 0) {
ElapsedTime = DivU64x32 (
ShellTime,
(UINT32)TimerInfo.Frequency
);
Total += ElapsedTime;
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PHASE_DURATION), gDpHiiHandle, ALit_SHELL, ElapsedTime);
}
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TOTAL_DURATION), gDpHiiHandle, Total);
}
/**
Gather and print Handle data.
@param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.
@return Status from a call to gBS->LocateHandle().
**/
EFI_STATUS
ProcessHandles(
IN BOOLEAN ExcludeFlag
)
{
MEASUREMENT_RECORD Measurement;
UINT64 ElapsedTime;
UINT64 Duration;
EFI_HANDLE *HandleBuffer;
EFI_STRING StringPtr;
UINTN Index;
UINTN LogEntryKey;
UINTN Count;
UINTN Size;
EFI_HANDLE TempHandle;
EFI_STATUS Status;
EFI_STRING StringPtrUnknown;
StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_DRIVERS), NULL);
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,
(StringPtr == NULL) ? StringPtrUnknown : StringPtr);
FreePool (StringPtr);
FreePool (StringPtrUnknown);
Size = 0;
HandleBuffer = &TempHandle;
Status = gBS->LocateHandle (AllHandles, NULL, NULL, &Size, &TempHandle);
if (Status == EFI_BUFFER_TOO_SMALL) {
HandleBuffer = AllocatePool (Size);
ASSERT (HandleBuffer != NULL);
if (HandleBuffer == NULL) {
return Status;
}
Status = gBS->LocateHandle (AllHandles, NULL, NULL, &Size, HandleBuffer);
}
if (EFI_ERROR (Status)) {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLES_ERROR), gDpHiiHandle, Status);
}
else {
#if DP_DEBUG == 2
Print (L"There are %,d Handles defined.\n", (Size / sizeof(HandleBuffer[0])));
#endif
if (mShowId) {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLE_SECTION2), gDpHiiHandle);
} else {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLE_SECTION), gDpHiiHandle);
}
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), gDpHiiHandle);
LogEntryKey = 0;
Count = 0;
while ((LogEntryKey = GetPerformanceMeasurementEx (
LogEntryKey,
&Measurement.Handle,
&Measurement.Token,
&Measurement.Module,
&Measurement.StartTimeStamp,
&Measurement.EndTimeStamp,
&Measurement.Identifier)) != 0)
{
Count++;
Duration = GetDuration (&Measurement);
ElapsedTime = DurationInMicroSeconds ( Duration );
if ((ElapsedTime < mInterestThreshold) ||
(Measurement.EndTimeStamp == 0) ||
(Measurement.Handle == NULL) ||
((ExcludeFlag) && (GetCumulativeItem(&Measurement) >= 0))
) { // Ignore "uninteresting" or excluded records
continue;
}
mGaugeString[0] = 0; // Empty driver name by default
AsciiStrToUnicodeStr (Measurement.Token, mUnicodeToken);
// See if the Handle is in the HandleBuffer
for (Index = 0; Index < (Size / sizeof(HandleBuffer[0])); Index++) {
if (Measurement.Handle == HandleBuffer[Index]) {
GetNameFromHandle (HandleBuffer[Index]); // Name is put into mGaugeString
break;
}
}
// Ensure that the argument strings are not too long.
mGaugeString[DP_GAUGE_STRING_LENGTH] = 0;
mUnicodeToken[11] = 0;
if (mGaugeString[0] != 0) {
// Display the record if it has a valid handle.
if (mShowId) {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLE_VARS2), gDpHiiHandle,
Count, // 1 based, Which measurement record is being printed
Index + 1, // 1 based, Which handle is being printed
mGaugeString,
mUnicodeToken,
ElapsedTime,
Measurement.Identifier
);
} else {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLE_VARS), gDpHiiHandle,
Count, // 1 based, Which measurement record is being printed
Index + 1, // 1 based, Which handle is being printed
mGaugeString,
mUnicodeToken,
ElapsedTime
);
}
}
}
}
if (HandleBuffer != &TempHandle) {
FreePool (HandleBuffer);
}
return Status;
}
/**
Gather and print PEIM data.
Only prints complete PEIM records
**/
VOID
ProcessPeims(
VOID
)
{
MEASUREMENT_RECORD Measurement;
UINT64 Duration;
UINT64 ElapsedTime;
EFI_STRING StringPtr;
UINTN LogEntryKey;
UINTN TIndex;
EFI_STRING StringPtrUnknown;
StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_PEIMS), NULL);
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,
(StringPtr == NULL) ? StringPtrUnknown : StringPtr);
FreePool (StringPtr);
FreePool (StringPtrUnknown);
if (mShowId) {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PEIM_SECTION2), gDpHiiHandle);
} else {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PEIM_SECTION), gDpHiiHandle);
}
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), gDpHiiHandle);
TIndex = 0;
LogEntryKey = 0;
while ((LogEntryKey = GetPerformanceMeasurementEx (
LogEntryKey,
&Measurement.Handle,
&Measurement.Token,
&Measurement.Module,
&Measurement.StartTimeStamp,
&Measurement.EndTimeStamp,
&Measurement.Identifier)) != 0)
{
TIndex++;
if ((Measurement.EndTimeStamp == 0) ||
(AsciiStrnCmp (Measurement.Token, ALit_PEIM, PERF_TOKEN_LENGTH) != 0)
) {
continue;
}
Duration = GetDuration (&Measurement);
ElapsedTime = DurationInMicroSeconds ( Duration ); // Calculate elapsed time in microseconds
if (ElapsedTime >= mInterestThreshold) {
// PEIM FILE Handle is the start address of its FFS file that contains its file guid.
if (mShowId) {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PEIM_VARS2), gDpHiiHandle,
TIndex, // 1 based, Which measurement record is being printed
Measurement.Handle, // base address
Measurement.Handle, // file guid
ElapsedTime,
Measurement.Identifier
);
} else {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PEIM_VARS), gDpHiiHandle,
TIndex, // 1 based, Which measurement record is being printed
Measurement.Handle, // base address
Measurement.Handle, // file guid
ElapsedTime
);
}
}
}
}
/**
Gather and print global data.
Strips out incomplete or "Execution Phase" records
Only prints records where Handle is NULL
Increment TIndex for every record, even skipped ones, so that we have an
indication of every measurement record taken.
**/
VOID
ProcessGlobal(
VOID
)
{
MEASUREMENT_RECORD Measurement;
UINT64 Duration;
UINT64 ElapsedTime;
EFI_STRING StringPtr;
UINTN LogEntryKey;
UINTN Index; // Index, or number, of the measurement record being processed
EFI_STRING StringPtrUnknown;
StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_GENERAL), NULL);
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,
(StringPtr == NULL) ? StringPtrUnknown: StringPtr);
FreePool (StringPtr);
FreePool (StringPtrUnknown);
if (mShowId) {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GLOBAL_SECTION2), gDpHiiHandle);
} else {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GLOBAL_SECTION), gDpHiiHandle);
}
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), gDpHiiHandle);
Index = 1;
LogEntryKey = 0;
while ((LogEntryKey = GetPerformanceMeasurementEx (
LogEntryKey,
&Measurement.Handle,
&Measurement.Token,
&Measurement.Module,
&Measurement.StartTimeStamp,
&Measurement.EndTimeStamp,
&Measurement.Identifier)) != 0)
{
AsciiStrToUnicodeStr (Measurement.Module, mGaugeString);
AsciiStrToUnicodeStr (Measurement.Token, mUnicodeToken);
mGaugeString[25] = 0;
mUnicodeToken[31] = 0;
if ( ! ( IsPhase( &Measurement) ||
(Measurement.Handle != NULL) ||
(Measurement.EndTimeStamp == 0)
))
{
Duration = GetDuration (&Measurement);
ElapsedTime = DurationInMicroSeconds ( Duration );
if (ElapsedTime >= mInterestThreshold) {
if (mShowId) {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GLOBAL_VARS2), gDpHiiHandle,
Index,
mGaugeString,
mUnicodeToken,
ElapsedTime,
Measurement.Identifier
);
} else {
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GLOBAL_VARS), gDpHiiHandle,
Index,
mGaugeString,
mUnicodeToken,
ElapsedTime
);
}
}
}
Index++;
}
}
/**
Gather and print cumulative data.
Traverse the measurement records and:<BR>
For each record with a Token listed in the CumData array:<BR>
- Update the instance count and the total, minimum, and maximum durations.
Finally, print the gathered cumulative statistics.
**/
VOID
ProcessCumulative(
VOID
)
{
UINT64 AvgDur; // the computed average duration
UINT64 Dur;
UINT64 MinDur;
UINT64 MaxDur;
EFI_STRING StringPtr;
UINTN TIndex;
EFI_STRING StringPtrUnknown;
StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_CUMULATIVE), NULL);
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,
(StringPtr == NULL) ? StringPtrUnknown: StringPtr);
FreePool (StringPtr);
FreePool (StringPtrUnknown);
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_CUMULATIVE_SECT_1), gDpHiiHandle);
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_CUMULATIVE_SECT_2), gDpHiiHandle);
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), gDpHiiHandle);
for ( TIndex = 0; TIndex < NumCum; ++TIndex) {
if (CumData[TIndex].Count != 0) {
AvgDur = DivU64x32 (CumData[TIndex].Duration, CumData[TIndex].Count);
AvgDur = DurationInMicroSeconds(AvgDur);
Dur = DurationInMicroSeconds(CumData[TIndex].Duration);
MaxDur = DurationInMicroSeconds(CumData[TIndex].MaxDur);
MinDur = DurationInMicroSeconds(CumData[TIndex].MinDur);
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_CUMULATIVE_STATS), gDpHiiHandle,
CumData[TIndex].Name,
CumData[TIndex].Count,
Dur,
AvgDur,
MinDur,
MaxDur
);
}
}
}

View File

@ -0,0 +1,400 @@
/** @file
Utility functions used by the Dp application.
Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.
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 <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/TimerLib.h>
#include <Library/PeCoffGetEntryPointLib.h>
#include <Library/PrintLib.h>
#include <Library/HiiLib.h>
#include <Library/PcdLib.h>
#include <Library/UefiLib.h>
#include <Library/DevicePathLib.h>
#include <Pi/PiFirmwareFile.h>
#include <Library/DxeServicesLib.h>
#include <Protocol/LoadedImage.h>
#include <Protocol/DriverBinding.h>
#include <Protocol/ComponentName2.h>
#include <Protocol/DevicePath.h>
#include <Protocol/DevicePathToText.h>
#include <Guid/Performance.h>
#include "Dp.h"
#include "Literals.h"
#include "DpInternal.h"
/**
Calculate an event's duration in timer ticks.
Given the count direction and the event's start and end timer values,
calculate the duration of the event in timer ticks. Information for
the current measurement is pointed to by the parameter.
If the measurement's start time is 1, it indicates that the developer
is indicating that the measurement began at the release of reset.
The start time is adjusted to the timer's starting count before performing
the elapsed time calculation.
The calculated duration, in ticks, is the absolute difference between
the measurement's ending and starting counts.
@param Measurement Pointer to a MEASUREMENT_RECORD structure containing
data for the current measurement.
@return The 64-bit duration of the event.
**/
UINT64
GetDuration (
IN OUT MEASUREMENT_RECORD *Measurement
)
{
UINT64 Duration;
BOOLEAN Error;
// PERF_START macros are called with a value of 1 to indicate
// the beginning of time. So, adjust the start ticker value
// to the real beginning of time.
// Assumes no wraparound. Even then, there is a very low probability
// of having a valid StartTicker value of 1.
if (Measurement->StartTimeStamp == 1) {
Measurement->StartTimeStamp = TimerInfo.StartCount;
}
if (TimerInfo.CountUp) {
Duration = Measurement->EndTimeStamp - Measurement->StartTimeStamp;
Error = (BOOLEAN)(Duration > Measurement->EndTimeStamp);
}
else {
Duration = Measurement->StartTimeStamp - Measurement->EndTimeStamp;
Error = (BOOLEAN)(Duration > Measurement->StartTimeStamp);
}
if (Error) {
DEBUG ((EFI_D_ERROR, ALit_TimerLibError));
Duration = 0;
}
return Duration;
}
/**
Determine whether the Measurement record is for an EFI Phase.
The Token and Module members of the measurement record are checked.
Module must be empty and Token must be one of SEC, PEI, DXE, BDS, or SHELL.
@param[in] Measurement A pointer to the Measurement record to test.
@retval TRUE The measurement record is for an EFI Phase.
@retval FALSE The measurement record is NOT for an EFI Phase.
**/
BOOLEAN
IsPhase(
IN MEASUREMENT_RECORD *Measurement
)
{
BOOLEAN RetVal;
RetVal = (BOOLEAN)( ( *Measurement->Module == '\0') &&
((AsciiStrnCmp (Measurement->Token, ALit_SEC, PERF_TOKEN_LENGTH) == 0) ||
(AsciiStrnCmp (Measurement->Token, ALit_PEI, PERF_TOKEN_LENGTH) == 0) ||
(AsciiStrnCmp (Measurement->Token, ALit_DXE, PERF_TOKEN_LENGTH) == 0) ||
(AsciiStrnCmp (Measurement->Token, ALit_BDS, PERF_TOKEN_LENGTH) == 0))
);
return RetVal;
}
/**
Get the file name portion of the Pdb File Name.
The portion of the Pdb File Name between the last backslash and
either a following period or the end of the string is converted
to Unicode and copied into UnicodeBuffer. The name is truncated,
if necessary, to ensure that UnicodeBuffer is not overrun.
@param[in] PdbFileName Pdb file name.
@param[out] UnicodeBuffer The resultant Unicode File Name.
**/
VOID
GetShortPdbFileName (
IN CHAR8 *PdbFileName,
OUT CHAR16 *UnicodeBuffer
)
{
UINTN IndexA; // Current work location within an ASCII string.
UINTN IndexU; // Current work location within a Unicode string.
UINTN StartIndex;
UINTN EndIndex;
ZeroMem (UnicodeBuffer, DXE_PERFORMANCE_STRING_LENGTH * sizeof (CHAR16));
if (PdbFileName == NULL) {
StrCpy (UnicodeBuffer, L" ");
} else {
StartIndex = 0;
for (EndIndex = 0; PdbFileName[EndIndex] != 0; EndIndex++)
;
for (IndexA = 0; PdbFileName[IndexA] != 0; IndexA++) {
if (PdbFileName[IndexA] == '\\') {
StartIndex = IndexA + 1;
}
if (PdbFileName[IndexA] == '.') {
EndIndex = IndexA;
}
}
IndexU = 0;
for (IndexA = StartIndex; IndexA < EndIndex; IndexA++) {
UnicodeBuffer[IndexU] = (CHAR16) PdbFileName[IndexA];
IndexU++;
if (IndexU >= DXE_PERFORMANCE_STRING_LENGTH) {
UnicodeBuffer[DXE_PERFORMANCE_STRING_LENGTH] = 0;
break;
}
}
}
}
/**
Get a human readable name for an image handle.
The following methods will be tried orderly:
1. Image PDB
2. ComponentName2 protocol
3. FFS UI section
4. Image GUID
5. Image DevicePath
6. Unknown Driver Name
@param[in] Handle
@post The resulting Unicode name string is stored in the
mGaugeString global array.
**/
VOID
GetNameFromHandle (
IN EFI_HANDLE Handle
)
{
EFI_STATUS Status;
EFI_LOADED_IMAGE_PROTOCOL *Image;
CHAR8 *PdbFileName;
EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
EFI_STRING StringPtr;
EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
EFI_GUID *NameGuid;
CHAR16 *NameString;
UINTN StringSize;
CHAR8 *PlatformLanguage;
EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2;
EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevicePathToText;
//
// Method 1: Get the name string from image PDB
//
Status = gBS->HandleProtocol (
Handle,
&gEfiLoadedImageProtocolGuid,
(VOID **) &Image
);
if (EFI_ERROR (Status)) {
Status = gBS->OpenProtocol (
Handle,
&gEfiDriverBindingProtocolGuid,
(VOID **) &DriverBinding,
NULL,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (!EFI_ERROR (Status)) {
Status = gBS->HandleProtocol (
DriverBinding->ImageHandle,
&gEfiLoadedImageProtocolGuid,
(VOID **) &Image
);
}
}
if (!EFI_ERROR (Status)) {
PdbFileName = PeCoffLoaderGetPdbPointer (Image->ImageBase);
if (PdbFileName != NULL) {
GetShortPdbFileName (PdbFileName, mGaugeString);
return;
}
}
//
// 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
//
GetEfiGlobalVariable2 (L"PlatformLang", (VOID**)&PlatformLanguage, NULL);
Status = ComponentName2->GetDriverName (
ComponentName2,
PlatformLanguage != NULL ? PlatformLanguage : "en-US",
&StringPtr
);
if (!EFI_ERROR (Status)) {
SHELL_FREE_NON_NULL (PlatformLanguage);
StrnCpy (mGaugeString, StringPtr, DP_GAUGE_STRING_LENGTH);
mGaugeString[DP_GAUGE_STRING_LENGTH] = 0;
return;
}
}
Status = gBS->HandleProtocol (
Handle,
&gEfiLoadedImageDevicePathProtocolGuid,
(VOID **) &LoadedImageDevicePath
);
if (!EFI_ERROR (Status) && (LoadedImageDevicePath != NULL)) {
DevicePath = LoadedImageDevicePath;
//
// Try to get image GUID from LoadedImageDevicePath protocol
//
NameGuid = NULL;
while (!IsDevicePathEndType (DevicePath)) {
NameGuid = EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) DevicePath);
if (NameGuid != NULL) {
break;
}
DevicePath = NextDevicePathNode (DevicePath);
}
if (NameGuid != NULL) {
//
// Try to get the image's FFS UI section by image GUID
//
NameString = NULL;
StringSize = 0;
Status = GetSectionFromAnyFv (
NameGuid,
EFI_SECTION_USER_INTERFACE,
0,
(VOID **) &NameString,
&StringSize
);
if (!EFI_ERROR (Status)) {
//
// Method 3. Get the name string from FFS UI section
//
StrnCpy (mGaugeString, NameString, DP_GAUGE_STRING_LENGTH);
mGaugeString[DP_GAUGE_STRING_LENGTH] = 0;
FreePool (NameString);
} else {
//
// Method 4: Get the name string from image GUID
//
UnicodeSPrint (mGaugeString, sizeof (mGaugeString), L"%g", NameGuid);
}
return;
} else {
//
// Method 5: Get the name string from image DevicePath
//
Status = gBS->LocateProtocol (
&gEfiDevicePathToTextProtocolGuid,
NULL,
(VOID **) &DevicePathToText
);
if (!EFI_ERROR (Status)) {
NameString = DevicePathToText->ConvertDevicePathToText (LoadedImageDevicePath, TRUE, FALSE);
if (NameString != NULL) {
StrnCpy (mGaugeString, NameString, DP_GAUGE_STRING_LENGTH);
mGaugeString[DP_GAUGE_STRING_LENGTH] = 0;
FreePool (NameString);
return;
}
}
}
}
//
// Method 6: Unknown Driver Name
//
StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_ERROR_NAME), NULL);
ASSERT (StringPtr != NULL);
StrCpy (mGaugeString, StringPtr);
FreePool (StringPtr);
}
/**
Calculate the Duration in microseconds.
Duration is multiplied by 1000, instead of Frequency being divided by 1000 or
multiplying the result by 1000, in order to maintain precision. Since Duration is
a 64-bit value, multiplying it by 1000 is unlikely to produce an overflow.
The time is calculated as (Duration * 1000) / Timer_Frequency.
@param[in] Duration The event duration in timer ticks.
@return A 64-bit value which is the Elapsed time in microseconds.
**/
UINT64
DurationInMicroSeconds (
IN UINT64 Duration
)
{
UINT64 Temp;
Temp = MultU64x32 (Duration, 1000);
return DivU64x32 (Temp, TimerInfo.Frequency);
}
/**
Get index of Measurement Record's match in the CumData array.
If the Measurement's Token value matches a Token in one of the CumData
records, the index of the matching record is returned. The returned
index is a signed value so that negative values can indicate that
the Measurement didn't match any entry in the CumData array.
@param[in] Measurement A pointer to a Measurement Record to match against the CumData array.
@retval <0 Token is not in the CumData array.
@retval >=0 Return value is the index into CumData where Token is found.
**/
INTN
GetCumulativeItem(
IN MEASUREMENT_RECORD *Measurement
)
{
INTN Index;
for( Index = 0; Index < (INTN)NumCum; ++Index) {
if (AsciiStrnCmp (Measurement->Token, CumData[Index].Name, PERF_TOKEN_LENGTH) == 0) {
return Index; // Exit, we found a match
}
}
// If the for loop exits, Token was not found.
return -1; // Indicate failure
}

View File

@ -0,0 +1,23 @@
/** @file
Definitions of ASCII string literals used by DP.
Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
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 <PerformanceTokens.h>
// ASCII String literals which probably don't need translation
CHAR8 const ALit_TimerLibError[] = "Timer library instance error!\n";
CHAR8 const ALit_SEC[] = SEC_TOK;
CHAR8 const ALit_DXE[] = DXE_TOK;
CHAR8 const ALit_SHELL[] = SHELL_TOK;
CHAR8 const ALit_PEI[] = PEI_TOK;
CHAR8 const ALit_BDS[] = BDS_TOK;
CHAR8 const ALit_BdsTO[] = "BdsTimeOut";
CHAR8 const ALit_PEIM[] = "PEIM";

View File

@ -0,0 +1,26 @@
/** @file
Declarations of ASCII string literals used by DP.
Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _LITERALS_H_
#define _LITERALS_H_
// ASCII String literals which probably don't need translation
extern CHAR8 const ALit_TimerLibError[];
extern CHAR8 const ALit_SEC[];
extern CHAR8 const ALit_DXE[];
extern CHAR8 const ALit_SHELL[];
extern CHAR8 const ALit_PEI[];
extern CHAR8 const ALit_BDS[];
extern CHAR8 const ALit_BdsTO[];
extern CHAR8 const ALit_PEIM[];
#endif // _LITERALS_H_

View File

@ -0,0 +1,101 @@
/** @file
Main file for NULL named library for install1 shell command functions.
Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.
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 "UefiDpLib.h"
STATIC CONST CHAR16 mFileName[] = L"ShellCommands";
EFI_HANDLE gDpHiiHandle = NULL;
#define DP_HII_GUID \
{ \
0xeb832fd9, 0x9089, 0x4898, { 0x83, 0xc9, 0x41, 0x61, 0x8f, 0x5c, 0x48, 0xb9 } \
}
EFI_GUID gDpHiiGuid = DP_HII_GUID;
/**
Function to get the filename with help context if HII will not be used.
@return The filename with help text in it.
**/
CONST CHAR16*
EFIAPI
UefiDpLibGetManFileName (
VOID
)
{
return (mFileName);
}
/**
Constructor for the Shell Level 1 Commands library.
Install the handlers for level 1 UEFI Shell 2.0 commands.
@param ImageHandle the image handle of the process
@param SystemTable the EFI System Table pointer
@retval EFI_SUCCESS the shell command handlers were installed sucessfully
@retval EFI_UNSUPPORTED the shell level required was not found.
**/
EFI_STATUS
EFIAPI
UefiDpLibConstructor (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
//
// check our bit of the profiles mask
//
if ((PcdGet8(PcdShellProfileMask) & BIT2) == 0) {
return (EFI_SUCCESS);
}
//
// 3rd parameter 'HII strings array' must be name of .uni strings file followed by 'Strings', e.g. mycommands.uni must be
// specified as 'mycommandsStrings' because the build Autogen process defines this as a string array for the strings in your
// .uni file. Examine your Build folder under your package's DEBUG folder and you will find it defined in a xxxStrDefs.h file.
//
gDpHiiHandle = HiiAddPackages (&gDpHiiGuid, gImageHandle, UefiDpLibStrings, NULL);
if (gDpHiiHandle == NULL) {
return (EFI_DEVICE_ERROR);
}
//
// install our shell command handlers that are always installed
//
ShellCommandRegisterCommandName(L"dp", ShellCommandRunDp , UefiDpLibGetManFileName, 0, L"", FALSE, gDpHiiHandle, STRING_TOKEN(STR_GET_HELP_DP));
return (EFI_SUCCESS);
}
/**
Destructor for the library. free any resources.
@param ImageHandle The image handle of the process.
@param SystemTable The EFI System Table pointer.
**/
EFI_STATUS
EFIAPI
UefiDpLibDestructor (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
if (gDpHiiHandle != NULL) {
HiiRemovePackages(gDpHiiHandle);
}
return (EFI_SUCCESS);
}

View File

@ -0,0 +1,60 @@
/** @file
Main file for NULL named library for dp command functions.
Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _UEFI_DP_LIB_H_
#define _UEFI_DP_LIB_H_
#include <Uefi.h>
#include <ShellBase.h>
extern EFI_GUID gDpHiiGuid;
#include <Protocol/EfiShell.h>
#include <Protocol/EfiShellParameters.h>
#include <Protocol/DevicePath.h>
#include <Protocol/LoadedImage.h>
#include <Protocol/UnicodeCollation.h>
#include <Protocol/DevicePathToText.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h>
#include <Library/ShellCommandLib.h>
#include <Library/ShellLib.h>
#include <Library/SortLib.h>
#include <Library/UefiLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/HiiLib.h>
#include <Library/FileHandleLib.h>
extern EFI_HANDLE gDpHiiHandle;
/**
Function for 'dp' command.
@param[in] ImageHandle Handle to the Image (NULL if Internal).
@param[in] SystemTable Pointer to the System Table (NULL if Internal).
**/
SHELL_STATUS
EFIAPI
ShellCommandRunDp (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
#endif

View File

@ -0,0 +1,75 @@
## @file
# Display Performance Application, Module information file.
#
# Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.
# 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.
#
##
[Defines]
INF_VERSION = 0x00010006
BASE_NAME = UefiDpLib
FILE_GUID = 9DF262F7-CF81-4294-B5A5-B2E3CAFE5618
MODULE_TYPE = UEFI_DRIVER
VERSION_STRING = 1.0
LIBRARY_CLASS = NULL|UEFI_APPLICATION UEFI_DRIVER
CONSTRUCTOR = UefiDpLibConstructor
DESTRUCTOR = UefiDpLibDestructor
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
[Sources.common]
UefiDpLib.c
UefiDpLib.h
UefiDpLib.uni
Dp.c
Dp.h
Literals.h
Literals.c
DpInternal.h
DpUtilities.c
DpTrace.c
DpProfile.c
[Packages]
MdePkg/MdePkg.dec
ShellPkg/ShellPkg.dec
MdeModulePkg/MdeModulePkg.dec
PerformancePkg/PerformancePkg.dec
[LibraryClasses]
TimerLib
PerformanceLib
DxeServicesLib
MemoryAllocationLib
BaseLib
BaseMemoryLib
DebugLib
ShellCommandLib
ShellLib
UefiLib
UefiRuntimeServicesTableLib
UefiBootServicesTableLib
SortLib
PrintLib
[Protocols]
gEfiLoadedImageProtocolGuid # ALWAYS_CONSUMED
gEfiDriverBindingProtocolGuid # SOMETIMES_CONSUMED
gEfiComponentName2ProtocolGuid # SOMETIMES_CONSUMED
gEfiLoadedImageDevicePathProtocolGuid # SOMETIMES_CONSUMED
gEfiDevicePathToTextProtocolGuid # SOMETIMES_CONSUMED
[Pcd]
gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize
gEfiShellPkgTokenSpaceGuid.PcdShellProfileMask # ALWAYS_CONSUMED

Binary file not shown.

View File

@ -0,0 +1,2 @@
from PerformancePkg\Dp_App
SVN 13406

View File

@ -1,7 +1,7 @@
## @file
# Shell Package
#
# Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
@ -64,7 +64,7 @@
gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|16000
!ifdef $(NO_SHELL_PROFILES)
gEfiShellPkgTokenSpaceGuid.PcdShellProfileMask|0x00
!endif
!endif #$(NO_SHELL_PROFILES)
[Components]
ShellPkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
@ -73,6 +73,13 @@
ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf
ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
ShellPkg/Library/UefiDpLib/UefiDpLib.inf {
<LibraryClasses>
TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf
PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
}
ShellPkg/Application/Shell/Shell.inf {
<LibraryClasses>
NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf
@ -83,6 +90,9 @@
NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf
NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf
NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf
!endif
!ifdef $(INCLUDE_DP)
NULL|ShellPkg/Library/UefiDpLib/UefiDpLib.inf
!endif #$(INCLUDE_DP)
!endif #$(NO_SHELL_PROFILES)
}