2 Shell application for Displaying Performance Metrics.
4 The Dp application 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 - 2012, Intel Corporation. All rights reserved.<BR>
17 This program and the accompanying materials
18 are licensed and made available under the terms and conditions of the BSD License
19 which accompanies this distribution. The full text of the license may be found at
20 http://opensource.org/licenses/bsd-license.php
22 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
23 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
26 #include <Library/UefiApplicationEntryPoint.h>
27 #include <Library/ShellLib.h>
28 #include <Library/BaseLib.h>
29 #include <Library/MemoryAllocationLib.h>
30 #include <Library/DebugLib.h>
31 #include <Library/TimerLib.h>
32 #include <Library/UefiLib.h>
33 #include <Library/HiiLib.h>
34 #include <Library/PcdLib.h>
36 #include <Guid/Performance.h>
38 #include <PerformanceTokens.h>
41 #include "DpInternal.h"
44 /// Module-Global Variables
46 EFI_HII_HANDLE gHiiHandle
;
47 SHELL_PARAM_ITEM
*DpParamList
= NULL
;
48 CHAR16
*mPrintTokenBuffer
= NULL
;
49 CHAR16 mGaugeString
[DP_GAUGE_STRING_LENGTH
+ 1];
50 CHAR16 mUnicodeToken
[DXE_PERFORMANCE_STRING_SIZE
];
51 UINT64 mInterestThreshold
;
52 BOOLEAN mShowId
= FALSE
;
54 PERF_SUMMARY_DATA SummaryData
= { 0 }; ///< Create the SummaryData structure and init. to ZERO.
56 /// Timer Specific Information.
59 /// Items for which to gather cumulative statistics.
60 PERF_CUM_DATA CumData
[] = {
61 PERF_INIT_CUM_DATA (LOAD_IMAGE_TOK
),
62 PERF_INIT_CUM_DATA (START_IMAGE_TOK
),
63 PERF_INIT_CUM_DATA (DRIVERBINDING_START_TOK
),
64 PERF_INIT_CUM_DATA (DRIVERBINDING_SUPPORT_TOK
)
67 /// Number of items for which we are gathering cumulative statistics.
68 UINT32
const NumCum
= sizeof(CumData
) / sizeof(PERF_CUM_DATA
);
70 PARAM_ITEM_LIST ParamList
[] = {
71 {STRING_TOKEN (STR_DP_OPTION_QH
), TypeFlag
}, // -? Help
72 {STRING_TOKEN (STR_DP_OPTION_LH
), TypeFlag
}, // -h Help
73 {STRING_TOKEN (STR_DP_OPTION_UH
), TypeFlag
}, // -H Help
74 {STRING_TOKEN (STR_DP_OPTION_LV
), TypeFlag
}, // -v Verbose Mode
75 {STRING_TOKEN (STR_DP_OPTION_UA
), TypeFlag
}, // -A All, Cooked
76 {STRING_TOKEN (STR_DP_OPTION_UR
), TypeFlag
}, // -R RAW All
77 {STRING_TOKEN (STR_DP_OPTION_LS
), TypeFlag
}, // -s Summary
78 #if PROFILING_IMPLEMENTED
79 {STRING_TOKEN (STR_DP_OPTION_UP
), TypeFlag
}, // -P Dump Profile Data
80 {STRING_TOKEN (STR_DP_OPTION_UT
), TypeFlag
}, // -T Dump Trace Data
82 {STRING_TOKEN (STR_DP_OPTION_LX
), TypeFlag
}, // -x eXclude Cumulative Items
83 {STRING_TOKEN (STR_DP_OPTION_LI
), TypeFlag
}, // -i Display Identifier
84 {STRING_TOKEN (STR_DP_OPTION_LN
), TypeValue
}, // -n # Number of records to display for A and R
85 {STRING_TOKEN (STR_DP_OPTION_LT
), TypeValue
} // -t # Threshold of interest
91 Transfer the param list value and get the command line parse.
95 InitialShellParamList( void )
101 // Allocate one more for the end tag.
103 ListLength
= sizeof (ParamList
) / sizeof (ParamList
[0]) + 1;
104 DpParamList
= AllocatePool (sizeof (SHELL_PARAM_ITEM
) * ListLength
);
105 ASSERT (DpParamList
!= NULL
);
107 for (ListIndex
= 0; ListIndex
< ListLength
- 1; ListIndex
++)
109 DpParamList
[ListIndex
].Name
= HiiGetString (gHiiHandle
, ParamList
[ListIndex
].Token
, NULL
);
110 DpParamList
[ListIndex
].Type
= ParamList
[ListIndex
].Type
;
112 DpParamList
[ListIndex
].Name
= NULL
;
113 DpParamList
[ListIndex
].Type
= TypeMax
;
117 Display Usage and Help information.
122 PrintToken (STRING_TOKEN (STR_DP_HELP_HEAD
));
123 #if PROFILING_IMPLEMENTED
124 PrintToken (STRING_TOKEN (STR_DP_HELP_FLAGS
));
126 PrintToken (STRING_TOKEN (STR_DP_HELP_FLAGS_2
));
127 #endif // PROFILING_IMPLEMENTED
128 PrintToken (STRING_TOKEN (STR_DP_HELP_PAGINATE
));
129 PrintToken (STRING_TOKEN (STR_DP_HELP_VERBOSE
));
130 PrintToken (STRING_TOKEN (STR_DP_HELP_EXCLUDE
));
131 PrintToken (STRING_TOKEN (STR_DP_HELP_STAT
));
132 PrintToken (STRING_TOKEN (STR_DP_HELP_ALL
));
133 PrintToken (STRING_TOKEN (STR_DP_HELP_RAW
));
134 #if PROFILING_IMPLEMENTED
135 PrintToken (STRING_TOKEN (STR_DP_HELP_TRACE
));
136 PrintToken (STRING_TOKEN (STR_DP_HELP_PROFILE
));
137 #endif // PROFILING_IMPLEMENTED
138 PrintToken (STRING_TOKEN (STR_DP_HELP_THRESHOLD
));
139 PrintToken (STRING_TOKEN (STR_DP_HELP_COUNT
));
140 PrintToken (STRING_TOKEN (STR_DP_HELP_ID
));
141 PrintToken (STRING_TOKEN (STR_DP_HELP_HELP
));
146 Display the trailing Verbose information.
149 DumpStatistics( void )
151 EFI_STRING StringPtr
;
152 EFI_STRING StringPtrUnknown
;
153 StringPtr
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_SECTION_STATISTICS
), NULL
);
154 StringPtrUnknown
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_ALIT_UNKNOWN
), NULL
);
155 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER
),
156 (StringPtr
== NULL
) ? StringPtrUnknown
: StringPtr
);
158 PrintToken( STRING_TOKEN (STR_DP_STATS_NUMTRACE
), SummaryData
.NumTrace
);
159 PrintToken( STRING_TOKEN (STR_DP_STATS_NUMINCOMPLETE
), SummaryData
.NumIncomplete
);
160 PrintToken( STRING_TOKEN (STR_DP_STATS_NUMPHASES
), SummaryData
.NumSummary
);
161 PrintToken( STRING_TOKEN (STR_DP_STATS_NUMHANDLES
), SummaryData
.NumHandles
, SummaryData
.NumTrace
- SummaryData
.NumHandles
);
162 PrintToken( STRING_TOKEN (STR_DP_STATS_NUMPEIMS
), SummaryData
.NumPEIMs
);
163 PrintToken( STRING_TOKEN (STR_DP_STATS_NUMGLOBALS
), SummaryData
.NumGlobal
);
164 #if PROFILING_IMPLEMENTED
165 PrintToken( STRING_TOKEN (STR_DP_STATS_NUMPROFILE
), SummaryData
.NumProfile
);
166 #endif // PROFILING_IMPLEMENTED
167 FreePool (StringPtr
);
168 FreePool (StringPtrUnknown
);
172 Dump performance data.
174 @param[in] ImageHandle The image handle.
175 @param[in] SystemTable The system table.
177 @retval EFI_SUCCESS Command completed successfully.
178 @retval EFI_INVALID_PARAMETER Command usage error.
179 @retval value Unknown error.
185 IN EFI_HANDLE ImageHandle
,
186 IN EFI_SYSTEM_TABLE
*SystemTable
193 LIST_ENTRY
*ParamPackage
;
194 CONST CHAR16
*CmdLineArg
;
195 EFI_STRING StringPtr
;
196 UINTN Number2Display
;
207 EFI_STRING StringDpOptionQh
;
208 EFI_STRING StringDpOptionLh
;
209 EFI_STRING StringDpOptionUh
;
210 EFI_STRING StringDpOptionLv
;
211 EFI_STRING StringDpOptionUs
;
212 EFI_STRING StringDpOptionLs
;
213 EFI_STRING StringDpOptionUa
;
214 EFI_STRING StringDpOptionUr
;
215 EFI_STRING StringDpOptionUt
;
216 EFI_STRING StringDpOptionUp
;
217 EFI_STRING StringDpOptionLx
;
218 EFI_STRING StringDpOptionLn
;
219 EFI_STRING StringDpOptionLt
;
220 EFI_STRING StringDpOptionLi
;
230 StringDpOptionQh
= NULL
;
231 StringDpOptionLh
= NULL
;
232 StringDpOptionUh
= NULL
;
233 StringDpOptionLv
= NULL
;
234 StringDpOptionUs
= NULL
;
235 StringDpOptionLs
= NULL
;
236 StringDpOptionUa
= NULL
;
237 StringDpOptionUr
= NULL
;
238 StringDpOptionUt
= NULL
;
239 StringDpOptionUp
= NULL
;
240 StringDpOptionLx
= NULL
;
241 StringDpOptionLn
= NULL
;
242 StringDpOptionLt
= NULL
;
243 StringDpOptionLi
= NULL
;
246 // Get DP's entry time as soon as possible.
247 // This is used as the Shell-Phase end time.
249 Ticker
= GetPerformanceCounter ();
251 // Register our string package with HII and return the handle to it.
253 gHiiHandle
= HiiAddPackages (&gEfiCallerIdGuid
, ImageHandle
, DPStrings
, NULL
);
254 ASSERT (gHiiHandle
!= NULL
);
256 // Initial the command list
258 InitialShellParamList ();
260 /****************************************************************************
261 **** Process Command Line arguments ****
262 ****************************************************************************/
263 Status
= ShellCommandLineParse (DpParamList
, &ParamPackage
, NULL
, TRUE
);
265 if (EFI_ERROR(Status
)) {
266 PrintToken (STRING_TOKEN (STR_DP_INVALID_ARG
));
270 StringDpOptionQh
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_OPTION_QH
), NULL
);
271 StringDpOptionLh
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_OPTION_LH
), NULL
);
272 StringDpOptionUh
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_OPTION_UH
), NULL
);
274 if (ShellCommandLineGetFlag (ParamPackage
, StringDpOptionQh
) ||
275 ShellCommandLineGetFlag (ParamPackage
, StringDpOptionLh
) ||
276 ShellCommandLineGetFlag (ParamPackage
, StringDpOptionUh
))
281 StringDpOptionLv
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_OPTION_LV
), NULL
);
282 StringDpOptionUs
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_OPTION_US
), NULL
);
283 StringDpOptionLs
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_OPTION_LS
), NULL
);
284 StringDpOptionUa
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_OPTION_UA
), NULL
);
285 StringDpOptionUr
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_OPTION_UR
), NULL
);
286 StringDpOptionUt
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_OPTION_UT
), NULL
);
287 StringDpOptionUp
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_OPTION_UP
), NULL
);
288 StringDpOptionLx
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_OPTION_LX
), NULL
);
289 StringDpOptionLn
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_OPTION_LN
), NULL
);
290 StringDpOptionLt
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_OPTION_LT
), NULL
);
291 StringDpOptionLi
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_OPTION_LI
), NULL
);
295 VerboseMode
= ShellCommandLineGetFlag (ParamPackage
, StringDpOptionLv
);
296 SummaryMode
= (BOOLEAN
) (ShellCommandLineGetFlag (ParamPackage
, StringDpOptionUs
) ||
297 ShellCommandLineGetFlag (ParamPackage
, StringDpOptionLs
));
298 AllMode
= ShellCommandLineGetFlag (ParamPackage
, StringDpOptionUa
);
299 RawMode
= ShellCommandLineGetFlag (ParamPackage
, StringDpOptionUr
);
300 #if PROFILING_IMPLEMENTED
301 TraceMode
= ShellCommandLineGetFlag (ParamPackage
, StringDpOptionUt
);
302 ProfileMode
= ShellCommandLineGetFlag (ParamPackage
, StringDpOptionUp
);
303 #endif // PROFILING_IMPLEMENTED
304 ExcludeMode
= ShellCommandLineGetFlag (ParamPackage
, StringDpOptionLx
);
305 mShowId
= ShellCommandLineGetFlag (ParamPackage
, StringDpOptionLi
);
307 // Options with Values
308 CmdLineArg
= ShellCommandLineGetValue (ParamPackage
, StringDpOptionLn
);
309 if (CmdLineArg
== NULL
) {
310 Number2Display
= DEFAULT_DISPLAYCOUNT
;
313 Number2Display
= StrDecimalToUintn(CmdLineArg
);
314 if (Number2Display
== 0) {
315 Number2Display
= MAXIMUM_DISPLAYCOUNT
;
318 CmdLineArg
= ShellCommandLineGetValue (ParamPackage
, StringDpOptionLt
);
319 if (CmdLineArg
== NULL
) {
320 mInterestThreshold
= DEFAULT_THRESHOLD
; // 1ms := 1,000 us
323 mInterestThreshold
= StrDecimalToUint64(CmdLineArg
);
325 // Handle Flag combinations and default behaviors
326 // If both TraceMode and ProfileMode are FALSE, set them both to TRUE
327 if ((! TraceMode
) && (! ProfileMode
)) {
329 #if PROFILING_IMPLEMENTED
331 #endif // PROFILING_IMPLEMENTED
334 /****************************************************************************
335 **** Timer specific processing ****
336 ****************************************************************************/
337 // Get the Performance counter characteristics:
338 // Freq = Frequency in Hz
339 // StartCount = Value loaded into the counter when it starts counting
340 // EndCount = Value counter counts to before it needs to be reset
342 Freq
= GetPerformanceCounterProperties (&TimerInfo
.StartCount
, &TimerInfo
.EndCount
);
344 // Convert the Frequency from Hz to KHz
345 TimerInfo
.Frequency
= (UINT32
)DivU64x32 (Freq
, 1000);
347 // Determine in which direction the performance counter counts.
348 TimerInfo
.CountUp
= (BOOLEAN
) (TimerInfo
.EndCount
>= TimerInfo
.StartCount
);
350 /****************************************************************************
351 **** Print heading ****
352 ****************************************************************************/
353 // print DP's build version
354 PrintToken (STRING_TOKEN (STR_DP_BUILD_REVISION
), DP_MAJOR_VERSION
, DP_MINOR_VERSION
);
356 // print performance timer characteristics
357 PrintToken (STRING_TOKEN (STR_DP_KHZ
), TimerInfo
.Frequency
); // Print Timer frequency in KHz
362 StringPtr
= HiiGetString (gHiiHandle
,
363 (EFI_STRING_ID
) (TimerInfo
.CountUp
? STRING_TOKEN (STR_DP_UP
) : STRING_TOKEN (STR_DP_DOWN
)),
365 ASSERT (StringPtr
!= NULL
);
366 PrintToken (STRING_TOKEN (STR_DP_TIMER_PROPERTIES
), // Print Timer count range and direction
368 TimerInfo
.StartCount
,
371 PrintToken (STRING_TOKEN (STR_DP_VERBOSE_THRESHOLD
), mInterestThreshold
);
374 /* **************************************************************************
375 **** Print Sections based on command line options
377 **** Option modes have the following priority:
378 **** v Verbose -- Valid in combination with any other options
379 **** t Threshold -- Modifies All, Raw, and Cooked output
380 **** Default is 0 for All and Raw mode
381 **** Default is DEFAULT_THRESHOLD for "Cooked" mode
382 **** n Number2Display Used by All and Raw mode. Otherwise ignored.
383 **** A All -- R and S options are ignored
384 **** R Raw -- S option is ignored
385 **** s Summary -- Modifies "Cooked" output only
386 **** Cooked (Default)
388 **** The All, Raw, and Cooked modes are modified by the Trace and Profile
390 **** !T && !P := (0) Default, Both are displayed
391 **** T && !P := (1) Only Trace records are displayed
392 **** !T && P := (2) Only Profile records are displayed
393 **** T && P := (3) Same as Default, both are displayed
394 ****************************************************************************/
398 DumpAllTrace( Number2Display
, ExcludeMode
);
401 DumpAllProfile( Number2Display
, ExcludeMode
);
406 DumpRawTrace( Number2Display
, ExcludeMode
);
409 DumpRawProfile( Number2Display
, ExcludeMode
);
413 //------------- Begin Cooked Mode Processing
415 ProcessPhases ( Ticker
);
416 if ( ! SummaryMode
) {
417 Status
= ProcessHandles ( ExcludeMode
);
418 if ( ! EFI_ERROR( Status
)) {
421 ProcessCumulative ();
426 DumpAllProfile( Number2Display
, ExcludeMode
);
428 } //------------- End of Cooked Mode Processing
429 if ( VerboseMode
|| SummaryMode
) {
435 // Free the memory allocate from HiiGetString
438 while (DpParamList
[ListIndex
].Name
!= NULL
) {
439 FreePool (DpParamList
[ListIndex
].Name
);
442 FreePool (DpParamList
);
444 SafeFreePool (StringDpOptionQh
);
445 SafeFreePool (StringDpOptionLh
);
446 SafeFreePool (StringDpOptionUh
);
447 SafeFreePool (StringDpOptionLv
);
448 SafeFreePool (StringDpOptionUs
);
449 SafeFreePool (StringDpOptionLs
);
450 SafeFreePool (StringDpOptionUa
);
451 SafeFreePool (StringDpOptionUr
);
452 SafeFreePool (StringDpOptionUt
);
453 SafeFreePool (StringDpOptionUp
);
454 SafeFreePool (StringDpOptionLx
);
455 SafeFreePool (StringDpOptionLn
);
456 SafeFreePool (StringDpOptionLt
);
457 SafeFreePool (StringDpOptionLi
);
458 SafeFreePool (StringPtr
);
459 SafeFreePool (mPrintTokenBuffer
);
461 HiiRemovePackages (gHiiHandle
);