]> git.proxmox.com Git - mirror_edk2.git/blob - PerformancePkg/Dp_App/Dp.c
0f61b9daaaab7f27cbf2903a82379fc9976e0393
[mirror_edk2.git] / PerformancePkg / Dp_App / Dp.c
1 /** @file
2 Shell application for Displaying Performance Metrics.
3
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.
7
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.
15
16 Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
17 (C) Copyright 2015 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
22
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.
25 **/
26
27 #include <Library/UefiApplicationEntryPoint.h>
28 #include <Library/ShellLib.h>
29 #include <Library/BaseLib.h>
30 #include <Library/MemoryAllocationLib.h>
31 #include <Library/DebugLib.h>
32 #include <Library/TimerLib.h>
33 #include <Library/UefiLib.h>
34 #include <Library/HiiLib.h>
35 #include <Library/PcdLib.h>
36
37 #include <Guid/Performance.h>
38
39 #include <PerformanceTokens.h>
40 #include "Dp.h"
41 #include "Literals.h"
42 #include "DpInternal.h"
43
44 //
45 /// Module-Global Variables
46 ///@{
47 EFI_HII_HANDLE gHiiHandle;
48 SHELL_PARAM_ITEM *DpParamList = NULL;
49 CHAR16 *mPrintTokenBuffer = NULL;
50 CHAR16 mGaugeString[DP_GAUGE_STRING_LENGTH + 1];
51 CHAR16 mUnicodeToken[DXE_PERFORMANCE_STRING_SIZE];
52 UINT64 mInterestThreshold;
53 BOOLEAN mShowId = FALSE;
54
55 PERF_SUMMARY_DATA SummaryData = { 0 }; ///< Create the SummaryData structure and init. to ZERO.
56
57 /// Timer Specific Information.
58 TIMER_INFO TimerInfo;
59
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)
66 };
67
68 /// Number of items for which we are gathering cumulative statistics.
69 UINT32 const NumCum = sizeof(CumData) / sizeof(PERF_CUM_DATA);
70
71 PARAM_ITEM_LIST ParamList[] = {
72 {STRING_TOKEN (STR_DP_OPTION_QH), TypeFlag}, // -? Help
73 {STRING_TOKEN (STR_DP_OPTION_LH), TypeFlag}, // -h Help
74 {STRING_TOKEN (STR_DP_OPTION_UH), TypeFlag}, // -H Help
75 {STRING_TOKEN (STR_DP_OPTION_LV), TypeFlag}, // -v Verbose Mode
76 {STRING_TOKEN (STR_DP_OPTION_UA), TypeFlag}, // -A All, Cooked
77 {STRING_TOKEN (STR_DP_OPTION_UR), TypeFlag}, // -R RAW All
78 {STRING_TOKEN (STR_DP_OPTION_LS), TypeFlag}, // -s Summary
79 #if PROFILING_IMPLEMENTED
80 {STRING_TOKEN (STR_DP_OPTION_UP), TypeFlag}, // -P Dump Profile Data
81 {STRING_TOKEN (STR_DP_OPTION_UT), TypeFlag}, // -T Dump Trace Data
82 #endif
83 {STRING_TOKEN (STR_DP_OPTION_LX), TypeFlag}, // -x eXclude Cumulative Items
84 {STRING_TOKEN (STR_DP_OPTION_LI), TypeFlag}, // -i Display Identifier
85 {STRING_TOKEN (STR_DP_OPTION_LC), TypeValue}, // -c Display cumulative data.
86 {STRING_TOKEN (STR_DP_OPTION_LN), TypeValue}, // -n # Number of records to display for A and R
87 {STRING_TOKEN (STR_DP_OPTION_LT), TypeValue} // -t # Threshold of interest
88 };
89
90 ///@}
91
92 /**
93 Transfer the param list value and get the command line parse.
94
95 **/
96 VOID
97 InitialShellParamList( void )
98 {
99 UINT32 ListIndex;
100 UINT32 ListLength;
101
102 //
103 // Allocate one more for the end tag.
104 //
105 ListLength = sizeof (ParamList) / sizeof (ParamList[0]) + 1;
106 DpParamList = AllocatePool (sizeof (SHELL_PARAM_ITEM) * ListLength);
107 ASSERT (DpParamList != NULL);
108
109 for (ListIndex = 0; ListIndex < ListLength - 1; ListIndex ++)
110 {
111 DpParamList[ListIndex].Name = HiiGetString (gHiiHandle, ParamList[ListIndex].Token, NULL);
112 DpParamList[ListIndex].Type = ParamList[ListIndex].Type;
113 }
114 DpParamList[ListIndex].Name = NULL;
115 DpParamList[ListIndex].Type = TypeMax;
116 }
117
118 /**
119 Display Usage and Help information.
120 **/
121 VOID
122 ShowHelp( void )
123 {
124 PrintToken (STRING_TOKEN (STR_DP_HELP_HEAD));
125 #if PROFILING_IMPLEMENTED
126 PrintToken (STRING_TOKEN (STR_DP_HELP_FLAGS));
127 #else
128 PrintToken (STRING_TOKEN (STR_DP_HELP_FLAGS_2));
129 #endif // PROFILING_IMPLEMENTED
130 PrintToken (STRING_TOKEN (STR_DP_HELP_PAGINATE));
131 PrintToken (STRING_TOKEN (STR_DP_HELP_VERBOSE));
132 PrintToken (STRING_TOKEN (STR_DP_HELP_EXCLUDE));
133 PrintToken (STRING_TOKEN (STR_DP_HELP_STAT));
134 PrintToken (STRING_TOKEN (STR_DP_HELP_ALL));
135 PrintToken (STRING_TOKEN (STR_DP_HELP_RAW));
136 #if PROFILING_IMPLEMENTED
137 PrintToken (STRING_TOKEN (STR_DP_HELP_TRACE));
138 PrintToken (STRING_TOKEN (STR_DP_HELP_PROFILE));
139 #endif // PROFILING_IMPLEMENTED
140 PrintToken (STRING_TOKEN (STR_DP_HELP_THRESHOLD));
141 PrintToken (STRING_TOKEN (STR_DP_HELP_COUNT));
142 PrintToken (STRING_TOKEN (STR_DP_HELP_ID));
143 PrintToken (STRING_TOKEN (STR_DP_HELP_CUM_DATA));
144 PrintToken (STRING_TOKEN (STR_DP_HELP_HELP));
145 Print(L"\n");
146 }
147
148 /**
149 Display the trailing Verbose information.
150 **/
151 VOID
152 DumpStatistics( void )
153 {
154 EFI_STRING StringPtr;
155 EFI_STRING StringPtrUnknown;
156 StringPtr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_STATISTICS), NULL);
157 StringPtrUnknown = HiiGetString (gHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
158 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),
159 (StringPtr == NULL) ? StringPtrUnknown : StringPtr);
160
161 PrintToken( STRING_TOKEN (STR_DP_STATS_NUMTRACE), SummaryData.NumTrace);
162 PrintToken( STRING_TOKEN (STR_DP_STATS_NUMINCOMPLETE), SummaryData.NumIncomplete);
163 PrintToken( STRING_TOKEN (STR_DP_STATS_NUMPHASES), SummaryData.NumSummary);
164 PrintToken( STRING_TOKEN (STR_DP_STATS_NUMHANDLES), SummaryData.NumHandles, SummaryData.NumTrace - SummaryData.NumHandles);
165 PrintToken( STRING_TOKEN (STR_DP_STATS_NUMPEIMS), SummaryData.NumPEIMs);
166 PrintToken( STRING_TOKEN (STR_DP_STATS_NUMGLOBALS), SummaryData.NumGlobal);
167 #if PROFILING_IMPLEMENTED
168 PrintToken( STRING_TOKEN (STR_DP_STATS_NUMPROFILE), SummaryData.NumProfile);
169 #endif // PROFILING_IMPLEMENTED
170 FreePool (StringPtr);
171 FreePool (StringPtrUnknown);
172 }
173
174 /**
175 Initialize the cumulative data.
176
177 **/
178 VOID
179 InitCumulativeData (
180 VOID
181 )
182 {
183 UINTN Index;
184
185 for (Index = 0; Index < NumCum; ++Index) {
186 CumData[Index].Count = 0;
187 CumData[Index].MinDur = PERF_MAXDUR;
188 CumData[Index].MaxDur = 0;
189 CumData[Index].Duration = 0;
190 }
191 }
192
193 /**
194 Dump performance data.
195
196 @param[in] ImageHandle The image handle.
197 @param[in] SystemTable The system table.
198
199 @retval EFI_SUCCESS Command completed successfully.
200 @retval EFI_INVALID_PARAMETER Command usage error.
201 @retval value Unknown error.
202
203 **/
204 EFI_STATUS
205 EFIAPI
206 InitializeDp (
207 IN EFI_HANDLE ImageHandle,
208 IN EFI_SYSTEM_TABLE *SystemTable
209 )
210 {
211 UINT64 Freq;
212 UINT64 Ticker;
213 UINT32 ListIndex;
214
215 LIST_ENTRY *ParamPackage;
216 CONST CHAR16 *CmdLineArg;
217 EFI_STRING StringPtr;
218 UINTN Number2Display;
219
220 EFI_STATUS Status;
221 BOOLEAN SummaryMode;
222 BOOLEAN VerboseMode;
223 BOOLEAN AllMode;
224 BOOLEAN RawMode;
225 BOOLEAN TraceMode;
226 BOOLEAN ProfileMode;
227 BOOLEAN ExcludeMode;
228 BOOLEAN CumulativeMode;
229 CONST CHAR16 *CustomCumulativeToken;
230 PERF_CUM_DATA *CustomCumulativeData;
231
232 EFI_STRING StringDpOptionQh;
233 EFI_STRING StringDpOptionLh;
234 EFI_STRING StringDpOptionUh;
235 EFI_STRING StringDpOptionLv;
236 EFI_STRING StringDpOptionUs;
237 EFI_STRING StringDpOptionLs;
238 EFI_STRING StringDpOptionUa;
239 EFI_STRING StringDpOptionUr;
240 EFI_STRING StringDpOptionUt;
241 EFI_STRING StringDpOptionUp;
242 EFI_STRING StringDpOptionLx;
243 EFI_STRING StringDpOptionLn;
244 EFI_STRING StringDpOptionLt;
245 EFI_STRING StringDpOptionLi;
246 EFI_STRING StringDpOptionLc;
247
248 SummaryMode = FALSE;
249 VerboseMode = FALSE;
250 AllMode = FALSE;
251 RawMode = FALSE;
252 TraceMode = FALSE;
253 ProfileMode = FALSE;
254 ExcludeMode = FALSE;
255 CumulativeMode = FALSE;
256 CustomCumulativeData = NULL;
257
258 StringDpOptionQh = NULL;
259 StringDpOptionLh = NULL;
260 StringDpOptionUh = NULL;
261 StringDpOptionLv = NULL;
262 StringDpOptionUs = NULL;
263 StringDpOptionLs = NULL;
264 StringDpOptionUa = NULL;
265 StringDpOptionUr = NULL;
266 StringDpOptionUt = NULL;
267 StringDpOptionUp = NULL;
268 StringDpOptionLx = NULL;
269 StringDpOptionLn = NULL;
270 StringDpOptionLt = NULL;
271 StringDpOptionLi = NULL;
272 StringDpOptionLc = NULL;
273 StringPtr = NULL;
274
275 // Get DP's entry time as soon as possible.
276 // This is used as the Shell-Phase end time.
277 //
278 Ticker = GetPerformanceCounter ();
279
280 // Register our string package with HII and return the handle to it.
281 //
282 gHiiHandle = HiiAddPackages (&gEfiCallerIdGuid, ImageHandle, DPStrings, NULL);
283 ASSERT (gHiiHandle != NULL);
284
285 // Initial the command list
286 //
287 InitialShellParamList ();
288
289 /****************************************************************************
290 **** Process Command Line arguments ****
291 ****************************************************************************/
292 Status = ShellCommandLineParse (DpParamList, &ParamPackage, NULL, TRUE);
293
294 if (EFI_ERROR(Status)) {
295 PrintToken (STRING_TOKEN (STR_DP_INVALID_ARG));
296 ShowHelp();
297 }
298 else {
299 StringDpOptionQh = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_QH), NULL);
300 StringDpOptionLh = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_LH), NULL);
301 StringDpOptionUh = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_UH), NULL);
302
303 if (ShellCommandLineGetFlag (ParamPackage, StringDpOptionQh) ||
304 ShellCommandLineGetFlag (ParamPackage, StringDpOptionLh) ||
305 ShellCommandLineGetFlag (ParamPackage, StringDpOptionUh))
306 {
307 ShowHelp();
308 }
309 else {
310 StringDpOptionLv = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_LV), NULL);
311 StringDpOptionUs = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_US), NULL);
312 StringDpOptionLs = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_LS), NULL);
313 StringDpOptionUa = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_UA), NULL);
314 StringDpOptionUr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_UR), NULL);
315 StringDpOptionUt = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_UT), NULL);
316 StringDpOptionUp = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_UP), NULL);
317 StringDpOptionLx = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_LX), NULL);
318 StringDpOptionLn = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_LN), NULL);
319 StringDpOptionLt = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_LT), NULL);
320 StringDpOptionLi = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_LI), NULL);
321 StringDpOptionLc = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_OPTION_LC), NULL);
322
323 // Boolean Options
324 //
325 VerboseMode = ShellCommandLineGetFlag (ParamPackage, StringDpOptionLv);
326 SummaryMode = (BOOLEAN) (ShellCommandLineGetFlag (ParamPackage, StringDpOptionUs) ||
327 ShellCommandLineGetFlag (ParamPackage, StringDpOptionLs));
328 AllMode = ShellCommandLineGetFlag (ParamPackage, StringDpOptionUa);
329 RawMode = ShellCommandLineGetFlag (ParamPackage, StringDpOptionUr);
330 #if PROFILING_IMPLEMENTED
331 TraceMode = ShellCommandLineGetFlag (ParamPackage, StringDpOptionUt);
332 ProfileMode = ShellCommandLineGetFlag (ParamPackage, StringDpOptionUp);
333 #endif // PROFILING_IMPLEMENTED
334 ExcludeMode = ShellCommandLineGetFlag (ParamPackage, StringDpOptionLx);
335 mShowId = ShellCommandLineGetFlag (ParamPackage, StringDpOptionLi);
336 CumulativeMode = ShellCommandLineGetFlag (ParamPackage, StringDpOptionLc);
337
338 // Options with Values
339 CmdLineArg = ShellCommandLineGetValue (ParamPackage, StringDpOptionLn);
340 if (CmdLineArg == NULL) {
341 Number2Display = DEFAULT_DISPLAYCOUNT;
342 }
343 else {
344 Number2Display = StrDecimalToUintn(CmdLineArg);
345 if (Number2Display == 0) {
346 Number2Display = MAXIMUM_DISPLAYCOUNT;
347 }
348 }
349 CmdLineArg = ShellCommandLineGetValue (ParamPackage, StringDpOptionLt);
350 if (CmdLineArg == NULL) {
351 mInterestThreshold = DEFAULT_THRESHOLD; // 1ms := 1,000 us
352 }
353 else {
354 mInterestThreshold = StrDecimalToUint64(CmdLineArg);
355 }
356 // Handle Flag combinations and default behaviors
357 // If both TraceMode and ProfileMode are FALSE, set them both to TRUE
358 if ((! TraceMode) && (! ProfileMode)) {
359 TraceMode = TRUE;
360 #if PROFILING_IMPLEMENTED
361 ProfileMode = TRUE;
362 #endif // PROFILING_IMPLEMENTED
363 }
364
365 //
366 // Init the custom cumulative data.
367 //
368 CustomCumulativeToken = ShellCommandLineGetValue (ParamPackage, StringDpOptionLc);
369 if (CustomCumulativeToken != NULL) {
370 CustomCumulativeData = AllocateZeroPool (sizeof (PERF_CUM_DATA));
371 CustomCumulativeData->MinDur = 0;
372 CustomCumulativeData->MaxDur = 0;
373 CustomCumulativeData->Count = 0;
374 CustomCumulativeData->Duration = 0;
375 CustomCumulativeData->Name = AllocateZeroPool (StrLen (CustomCumulativeToken) + 1);
376 UnicodeStrToAsciiStr (CustomCumulativeToken, CustomCumulativeData->Name);
377 }
378
379 /****************************************************************************
380 **** Timer specific processing ****
381 ****************************************************************************/
382 // Get the Performance counter characteristics:
383 // Freq = Frequency in Hz
384 // StartCount = Value loaded into the counter when it starts counting
385 // EndCount = Value counter counts to before it needs to be reset
386 //
387 Freq = GetPerformanceCounterProperties (&TimerInfo.StartCount, &TimerInfo.EndCount);
388
389 // Convert the Frequency from Hz to KHz
390 TimerInfo.Frequency = (UINT32)DivU64x32 (Freq, 1000);
391
392 // Determine in which direction the performance counter counts.
393 TimerInfo.CountUp = (BOOLEAN) (TimerInfo.EndCount >= TimerInfo.StartCount);
394
395 /****************************************************************************
396 **** Print heading ****
397 ****************************************************************************/
398 // print DP's build version
399 PrintToken (STRING_TOKEN (STR_DP_BUILD_REVISION), DP_MAJOR_VERSION, DP_MINOR_VERSION);
400
401 // print performance timer characteristics
402 PrintToken (STRING_TOKEN (STR_DP_KHZ), TimerInfo.Frequency); // Print Timer frequency in KHz
403
404 if ((VerboseMode) &&
405 (! RawMode)
406 ) {
407 StringPtr = HiiGetString (gHiiHandle,
408 (EFI_STRING_ID) (TimerInfo.CountUp ? STRING_TOKEN (STR_DP_UP) : STRING_TOKEN (STR_DP_DOWN)),
409 NULL);
410 ASSERT (StringPtr != NULL);
411 PrintToken (STRING_TOKEN (STR_DP_TIMER_PROPERTIES), // Print Timer count range and direction
412 StringPtr,
413 TimerInfo.StartCount,
414 TimerInfo.EndCount
415 );
416 PrintToken (STRING_TOKEN (STR_DP_VERBOSE_THRESHOLD), mInterestThreshold);
417 }
418
419 /* **************************************************************************
420 **** Print Sections based on command line options
421 ****
422 **** Option modes have the following priority:
423 **** v Verbose -- Valid in combination with any other options
424 **** t Threshold -- Modifies All, Raw, and Cooked output
425 **** Default is 0 for All and Raw mode
426 **** Default is DEFAULT_THRESHOLD for "Cooked" mode
427 **** n Number2Display Used by All and Raw mode. Otherwise ignored.
428 **** A All -- R and S options are ignored
429 **** R Raw -- S option is ignored
430 **** s Summary -- Modifies "Cooked" output only
431 **** Cooked (Default)
432 ****
433 **** The All, Raw, and Cooked modes are modified by the Trace and Profile
434 **** options.
435 **** !T && !P := (0) Default, Both are displayed
436 **** T && !P := (1) Only Trace records are displayed
437 **** !T && P := (2) Only Profile records are displayed
438 **** T && P := (3) Same as Default, both are displayed
439 ****************************************************************************/
440 GatherStatistics (CustomCumulativeData);
441 if (CumulativeMode) {
442 ProcessCumulative (CustomCumulativeData);
443 } else if (AllMode) {
444 if (TraceMode) {
445 DumpAllTrace( Number2Display, ExcludeMode);
446 }
447 if (ProfileMode) {
448 DumpAllProfile( Number2Display, ExcludeMode);
449 }
450 }
451 else if (RawMode) {
452 if (TraceMode) {
453 DumpRawTrace( Number2Display, ExcludeMode);
454 }
455 if (ProfileMode) {
456 DumpRawProfile( Number2Display, ExcludeMode);
457 }
458 }
459 else {
460 //------------- Begin Cooked Mode Processing
461 if (TraceMode) {
462 ProcessPhases ( Ticker );
463 if ( ! SummaryMode) {
464 Status = ProcessHandles ( ExcludeMode);
465 if ( ! EFI_ERROR( Status)) {
466 ProcessPeims ( );
467 ProcessGlobal ( );
468 ProcessCumulative (NULL);
469 }
470 }
471 }
472 if (ProfileMode) {
473 DumpAllProfile( Number2Display, ExcludeMode);
474 }
475 } //------------- End of Cooked Mode Processing
476 if ( VerboseMode || SummaryMode) {
477 DumpStatistics();
478 }
479 }
480 }
481
482 //
483 // Free the memory allocate from HiiGetString
484 //
485 ListIndex = 0;
486 while (DpParamList[ListIndex].Name != NULL) {
487 FreePool (DpParamList[ListIndex].Name);
488 ListIndex ++;
489 }
490 FreePool (DpParamList);
491
492 SafeFreePool (StringDpOptionQh);
493 SafeFreePool (StringDpOptionLh);
494 SafeFreePool (StringDpOptionUh);
495 SafeFreePool (StringDpOptionLv);
496 SafeFreePool (StringDpOptionUs);
497 SafeFreePool (StringDpOptionLs);
498 SafeFreePool (StringDpOptionUa);
499 SafeFreePool (StringDpOptionUr);
500 SafeFreePool (StringDpOptionUt);
501 SafeFreePool (StringDpOptionUp);
502 SafeFreePool (StringDpOptionLx);
503 SafeFreePool (StringDpOptionLn);
504 SafeFreePool (StringDpOptionLt);
505 SafeFreePool (StringDpOptionLi);
506 SafeFreePool (StringDpOptionLc);
507 SafeFreePool (StringPtr);
508 SafeFreePool (mPrintTokenBuffer);
509
510 if (CustomCumulativeData != NULL) {
511 SafeFreePool (CustomCumulativeData->Name);
512 }
513 SafeFreePool (CustomCumulativeData);
514
515 HiiRemovePackages (gHiiHandle);
516 return Status;
517 }