2 Shell command for Displaying Performance Metrics.
4 The Dp command reads performance data and presents it in several
5 different formats depending upon the needs of the user. Both
6 Trace and Measured Profiling information is processed and presented.
8 Dp uses the "PerformanceLib" to read the measurement records.
9 The "TimerLib" provides information about the timer, such as frequency,
10 beginning, and ending counter values.
11 Measurement records contain identifying information (Handle, Token, Module)
12 and start and end time values.
13 Dp uses this information to group records in different ways. It also uses
14 timer information to calculate elapsed time for each measurement.
16 Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.
17 (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>
18 This program and the accompanying materials
19 are licensed and made available under the terms and conditions of the BSD License
20 which accompanies this distribution. The full text of the license may be found at
21 http://opensource.org/licenses/bsd-license.php
23 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
24 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
27 #include "UefiDpLib.h"
28 #include <Guid/GlobalVariable.h>
29 #include <Library/PrintLib.h>
30 #include <Library/HandleParsingLib.h>
31 #include <Library/DevicePathLib.h>
33 #include <Library/ShellLib.h>
34 #include <Library/BaseLib.h>
35 #include <Library/MemoryAllocationLib.h>
36 #include <Library/DebugLib.h>
37 #include <Library/TimerLib.h>
38 #include <Library/UefiLib.h>
40 #include <Guid/Performance.h>
42 #include "PerformanceTokens.h"
45 #include "DpInternal.h"
48 /// Module-Global Variables
50 CHAR16 mGaugeString
[DP_GAUGE_STRING_LENGTH
+ 1];
51 CHAR16 mUnicodeToken
[DXE_PERFORMANCE_STRING_SIZE
];
52 UINT64 mInterestThreshold
;
53 BOOLEAN mShowId
= FALSE
;
55 PERF_SUMMARY_DATA SummaryData
= { 0 }; ///< Create the SummaryData structure and init. to ZERO.
57 /// Timer Specific Information.
60 /// Items for which to gather cumulative statistics.
61 PERF_CUM_DATA CumData
[] = {
62 PERF_INIT_CUM_DATA (LOAD_IMAGE_TOK
),
63 PERF_INIT_CUM_DATA (START_IMAGE_TOK
),
64 PERF_INIT_CUM_DATA (DRIVERBINDING_START_TOK
),
65 PERF_INIT_CUM_DATA (DRIVERBINDING_SUPPORT_TOK
)
68 /// Number of items for which we are gathering cumulative statistics.
69 UINT32
const NumCum
= sizeof(CumData
) / sizeof(PERF_CUM_DATA
);
71 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
72 {L
"-v", TypeFlag
}, // -v Verbose Mode
73 {L
"-A", TypeFlag
}, // -A All, Cooked
74 {L
"-R", TypeFlag
}, // -R RAW All
75 {L
"-s", TypeFlag
}, // -s Summary
76 #if PROFILING_IMPLEMENTED
77 {L
"-P", TypeFlag
}, // -P Dump Profile Data
78 {L
"-T", TypeFlag
}, // -T Dump Trace Data
79 #endif // PROFILING_IMPLEMENTED
80 {L
"-x", TypeFlag
}, // -x eXclude Cumulative Items
81 {L
"-i", TypeFlag
}, // -i Display Identifier
82 {L
"-c", TypeValue
}, // -c Display cumulative data.
83 {L
"-n", TypeValue
}, // -n # Number of records to display for A and R
84 {L
"-t", TypeValue
}, // -t # Threshold of interest
91 Display the trailing Verbose information.
94 DumpStatistics( void )
97 EFI_STRING StringPtrUnknown
;
98 StringPtr
= HiiGetString (gDpHiiHandle
, STRING_TOKEN (STR_DP_SECTION_STATISTICS
), NULL
);
99 StringPtrUnknown
= HiiGetString (gDpHiiHandle
, STRING_TOKEN (STR_ALIT_UNKNOWN
), NULL
);
100 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_SECTION_HEADER
), gDpHiiHandle
,
101 (StringPtr
== NULL
) ? StringPtrUnknown
: StringPtr
);
102 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_STATS_NUMTRACE
), gDpHiiHandle
, SummaryData
.NumTrace
);
103 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_STATS_NUMINCOMPLETE
), gDpHiiHandle
, SummaryData
.NumIncomplete
);
104 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_STATS_NUMPHASES
), gDpHiiHandle
, SummaryData
.NumSummary
);
105 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_STATS_NUMHANDLES
), gDpHiiHandle
, SummaryData
.NumHandles
, SummaryData
.NumTrace
- SummaryData
.NumHandles
);
106 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_STATS_NUMPEIMS
), gDpHiiHandle
, SummaryData
.NumPEIMs
);
107 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_STATS_NUMGLOBALS
), gDpHiiHandle
, SummaryData
.NumGlobal
);
108 #if PROFILING_IMPLEMENTED
109 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_STATS_NUMPROFILE
), gDpHiiHandle
, SummaryData
.NumProfile
);
110 #endif // PROFILING_IMPLEMENTED
111 SHELL_FREE_NON_NULL (StringPtr
);
112 SHELL_FREE_NON_NULL (StringPtrUnknown
);
116 Initialize the cumulative data.
126 for (Index
= 0; Index
< NumCum
; ++Index
) {
127 CumData
[Index
].Count
= 0;
128 CumData
[Index
].MinDur
= PERF_MAXDUR
;
129 CumData
[Index
].MaxDur
= 0;
130 CumData
[Index
].Duration
= 0;
135 Dump performance data.
137 @param[in] ImageHandle The image handle.
138 @param[in] SystemTable The system table.
140 @retval SHELL_SUCCESS Command completed successfully.
141 @retval SHELL_INVALID_PARAMETER Command usage error.
142 @retval SHELL_ABORTED The user aborts the operation.
143 @retval value Unknown error.
148 IN EFI_HANDLE ImageHandle
,
149 IN EFI_SYSTEM_TABLE
*SystemTable
152 LIST_ENTRY
*ParamPackage
;
153 CONST CHAR16
*CmdLineArg
;
158 UINTN Number2Display
;
160 EFI_STRING StringPtr
;
168 BOOLEAN CumulativeMode
;
169 CONST CHAR16
*CustomCumulativeToken
;
170 PERF_CUM_DATA
*CustomCumulativeData
;
172 SHELL_STATUS ShellStatus
;
182 CumulativeMode
= FALSE
;
183 CustomCumulativeData
= NULL
;
184 ShellStatus
= SHELL_SUCCESS
;
186 // Get DP's entry time as soon as possible.
187 // This is used as the Shell-Phase end time.
189 Ticker
= GetPerformanceCounter ();
192 // initialize the shell lib (we must be in non-auto-init...)
194 Status
= ShellInitialize();
195 ASSERT_EFI_ERROR(Status
);
197 Status
= CommandInit();
198 ASSERT_EFI_ERROR(Status
);
201 // Process Command Line arguments
203 Status
= ShellCommandLineParse (ParamList
, &ParamPackage
, NULL
, TRUE
);
204 if (EFI_ERROR(Status
)) {
205 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_INVALID_ARG
), gDpHiiHandle
);
206 return SHELL_INVALID_PARAMETER
;
212 VerboseMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-v");
213 SummaryMode
= (BOOLEAN
) (ShellCommandLineGetFlag (ParamPackage
, L
"-S") || ShellCommandLineGetFlag (ParamPackage
, L
"-s"));
214 AllMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-A");
215 RawMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-R");
216 #if PROFILING_IMPLEMENTED
217 TraceMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-T");
218 ProfileMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-P");
219 #endif // PROFILING_IMPLEMENTED
220 ExcludeMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-x");
221 mShowId
= ShellCommandLineGetFlag (ParamPackage
, L
"-i");
222 CumulativeMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-c");
224 // Options with Values
225 CmdLineArg
= ShellCommandLineGetValue (ParamPackage
, L
"-n");
226 if (CmdLineArg
== NULL
) {
227 Number2Display
= DEFAULT_DISPLAYCOUNT
;
229 Number2Display
= StrDecimalToUintn(CmdLineArg
);
230 if (Number2Display
== 0) {
231 Number2Display
= MAXIMUM_DISPLAYCOUNT
;
235 CmdLineArg
= ShellCommandLineGetValue (ParamPackage
, L
"-t");
236 if (CmdLineArg
== NULL
) {
237 mInterestThreshold
= DEFAULT_THRESHOLD
; // 1ms := 1,000 us
239 mInterestThreshold
= StrDecimalToUint64(CmdLineArg
);
242 // Handle Flag combinations and default behaviors
243 // If both TraceMode and ProfileMode are FALSE, set them both to TRUE
244 if ((! TraceMode
) && (! ProfileMode
)) {
246 #if PROFILING_IMPLEMENTED
248 #endif // PROFILING_IMPLEMENTED
252 // Initialize the pre-defined cumulative data.
254 InitCumulativeData ();
257 // Init the custom cumulative data.
259 CustomCumulativeToken
= ShellCommandLineGetValue (ParamPackage
, L
"-c");
260 if (CustomCumulativeToken
!= NULL
) {
261 CustomCumulativeData
= AllocateZeroPool (sizeof (PERF_CUM_DATA
));
262 if (CustomCumulativeData
== NULL
) {
263 return SHELL_OUT_OF_RESOURCES
;
265 CustomCumulativeData
->MinDur
= 0;
266 CustomCumulativeData
->MaxDur
= 0;
267 CustomCumulativeData
->Count
= 0;
268 CustomCumulativeData
->Duration
= 0;
269 NameSize
= StrLen (CustomCumulativeToken
) + 1;
270 CustomCumulativeData
->Name
= AllocateZeroPool (NameSize
);
271 if (CustomCumulativeData
->Name
== NULL
) {
272 FreePool (CustomCumulativeData
);
273 return SHELL_OUT_OF_RESOURCES
;
275 UnicodeStrToAsciiStrS (CustomCumulativeToken
, CustomCumulativeData
->Name
, NameSize
);
279 // Timer specific processing
281 // Get the Performance counter characteristics:
282 // Freq = Frequency in Hz
283 // StartCount = Value loaded into the counter when it starts counting
284 // EndCount = Value counter counts to before it needs to be reset
286 Freq
= GetPerformanceCounterProperties (&TimerInfo
.StartCount
, &TimerInfo
.EndCount
);
288 // Convert the Frequency from Hz to KHz
289 TimerInfo
.Frequency
= (UINT32
)DivU64x32 (Freq
, 1000);
291 // Determine in which direction the performance counter counts.
292 TimerInfo
.CountUp
= (BOOLEAN
) (TimerInfo
.EndCount
>= TimerInfo
.StartCount
);
297 // print DP's build version
298 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_BUILD_REVISION
), gDpHiiHandle
, DP_MAJOR_VERSION
, DP_MINOR_VERSION
);
300 // print performance timer characteristics
301 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_KHZ
), gDpHiiHandle
, TimerInfo
.Frequency
);
303 if (VerboseMode
&& !RawMode
) {
304 StringPtr
= HiiGetString (gDpHiiHandle
,
305 (EFI_STRING_ID
) (TimerInfo
.CountUp
? STRING_TOKEN (STR_DP_UP
) : STRING_TOKEN (STR_DP_DOWN
)), NULL
);
306 ASSERT (StringPtr
!= NULL
);
307 // Print Timer count range and direction
308 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_TIMER_PROPERTIES
), gDpHiiHandle
,
310 TimerInfo
.StartCount
,
313 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_VERBOSE_THRESHOLD
), gDpHiiHandle
, mInterestThreshold
);
316 /****************************************************************************
317 **** Print Sections based on command line options
319 **** Option modes have the following priority:
320 **** v Verbose -- Valid in combination with any other options
321 **** t Threshold -- Modifies All, Raw, and Cooked output
322 **** Default is 0 for All and Raw mode
323 **** Default is DEFAULT_THRESHOLD for "Cooked" mode
324 **** n Number2Display Used by All and Raw mode. Otherwise ignored.
325 **** A All -- R and S options are ignored
326 **** R Raw -- S option is ignored
327 **** s Summary -- Modifies "Cooked" output only
328 **** Cooked (Default)
330 **** The All, Raw, and Cooked modes are modified by the Trace and Profile
332 **** !T && !P := (0) Default, Both are displayed
333 **** T && !P := (1) Only Trace records are displayed
334 **** !T && P := (2) Only Profile records are displayed
335 **** T && P := (3) Same as Default, both are displayed
336 ****************************************************************************/
337 GatherStatistics (CustomCumulativeData
);
338 if (CumulativeMode
) {
339 ProcessCumulative (CustomCumulativeData
);
340 } else if (AllMode
) {
342 Status
= DumpAllTrace( Number2Display
, ExcludeMode
);
343 if (Status
== EFI_ABORTED
) {
344 ShellStatus
= SHELL_ABORTED
;
349 DumpAllProfile( Number2Display
, ExcludeMode
);
351 } else if (RawMode
) {
353 Status
= DumpRawTrace( Number2Display
, ExcludeMode
);
354 if (Status
== EFI_ABORTED
) {
355 ShellStatus
= SHELL_ABORTED
;
360 DumpRawProfile( Number2Display
, ExcludeMode
);
363 //------------- Begin Cooked Mode Processing
365 ProcessPhases ( Ticker
);
366 if ( ! SummaryMode
) {
367 Status
= ProcessHandles ( ExcludeMode
);
368 if (Status
== EFI_ABORTED
) {
369 ShellStatus
= SHELL_ABORTED
;
373 Status
= ProcessPeims ();
374 if (Status
== EFI_ABORTED
) {
375 ShellStatus
= SHELL_ABORTED
;
379 Status
= ProcessGlobal ();
380 if (Status
== EFI_ABORTED
) {
381 ShellStatus
= SHELL_ABORTED
;
385 ProcessCumulative (NULL
);
389 DumpAllProfile( Number2Display
, ExcludeMode
);
391 } //------------- End of Cooked Mode Processing
392 if ( VerboseMode
|| SummaryMode
) {
397 if (ParamPackage
!= NULL
) {
398 ShellCommandLineFreeVarList (ParamPackage
);
400 SHELL_FREE_NON_NULL (StringPtr
);
401 if (CustomCumulativeData
!= NULL
) {
402 SHELL_FREE_NON_NULL (CustomCumulativeData
->Name
);
404 SHELL_FREE_NON_NULL (CustomCumulativeData
);