]> git.proxmox.com Git - mirror_edk2.git/blob - PerformancePkg/Dp_App/Dp.c
MdePkg: add missing #defines for decoding PCIe 2.1 extended capability structures
[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 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
21
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.
24 **/
25
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>
35
36 #include <Guid/Performance.h>
37
38 #include <PerformanceTokens.h>
39 #include "Dp.h"
40 #include "Literals.h"
41 #include "DpInternal.h"
42
43 //
44 /// Module-Global Variables
45 ///@{
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;
53
54 PERF_SUMMARY_DATA SummaryData = { 0 }; ///< Create the SummaryData structure and init. to ZERO.
55
56 /// Timer Specific Information.
57 TIMER_INFO TimerInfo;
58
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)
65 };
66
67 /// Number of items for which we are gathering cumulative statistics.
68 UINT32 const NumCum = sizeof(CumData) / sizeof(PERF_CUM_DATA);
69
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
81 #endif
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
86 };
87
88 ///@}
89
90 /**
91 Transfer the param list value and get the command line parse.
92
93 **/
94 VOID
95 InitialShellParamList( void )
96 {
97 UINT32 ListIndex;
98 UINT32 ListLength;
99
100 //
101 // Allocate one more for the end tag.
102 //
103 ListLength = sizeof (ParamList) / sizeof (ParamList[0]) + 1;
104 DpParamList = AllocatePool (sizeof (SHELL_PARAM_ITEM) * ListLength);
105 ASSERT (DpParamList != NULL);
106
107 for (ListIndex = 0; ListIndex < ListLength - 1; ListIndex ++)
108 {
109 DpParamList[ListIndex].Name = HiiGetString (gHiiHandle, ParamList[ListIndex].Token, NULL);
110 DpParamList[ListIndex].Type = ParamList[ListIndex].Type;
111 }
112 DpParamList[ListIndex].Name = NULL;
113 DpParamList[ListIndex].Type = TypeMax;
114 }
115
116 /**
117 Display Usage and Help information.
118 **/
119 VOID
120 ShowHelp( void )
121 {
122 PrintToken (STRING_TOKEN (STR_DP_HELP_HEAD));
123 #if PROFILING_IMPLEMENTED
124 PrintToken (STRING_TOKEN (STR_DP_HELP_FLAGS));
125 #else
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));
142 Print(L"\n");
143 }
144
145 /**
146 Display the trailing Verbose information.
147 **/
148 VOID
149 DumpStatistics( void )
150 {
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);
157
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);
169 }
170
171 /**
172 Dump performance data.
173
174 @param[in] ImageHandle The image handle.
175 @param[in] SystemTable The system table.
176
177 @retval EFI_SUCCESS Command completed successfully.
178 @retval EFI_INVALID_PARAMETER Command usage error.
179 @retval value Unknown error.
180
181 **/
182 EFI_STATUS
183 EFIAPI
184 InitializeDp (
185 IN EFI_HANDLE ImageHandle,
186 IN EFI_SYSTEM_TABLE *SystemTable
187 )
188 {
189 UINT64 Freq;
190 UINT64 Ticker;
191 UINT32 ListIndex;
192
193 LIST_ENTRY *ParamPackage;
194 CONST CHAR16 *CmdLineArg;
195 EFI_STRING StringPtr;
196 UINTN Number2Display;
197
198 EFI_STATUS Status;
199 BOOLEAN SummaryMode;
200 BOOLEAN VerboseMode;
201 BOOLEAN AllMode;
202 BOOLEAN RawMode;
203 BOOLEAN TraceMode;
204 BOOLEAN ProfileMode;
205 BOOLEAN ExcludeMode;
206
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;
221
222 SummaryMode = FALSE;
223 VerboseMode = FALSE;
224 AllMode = FALSE;
225 RawMode = FALSE;
226 TraceMode = FALSE;
227 ProfileMode = FALSE;
228 ExcludeMode = FALSE;
229
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;
244 StringPtr = NULL;
245
246 // Get DP's entry time as soon as possible.
247 // This is used as the Shell-Phase end time.
248 //
249 Ticker = GetPerformanceCounter ();
250
251 // Register our string package with HII and return the handle to it.
252 //
253 gHiiHandle = HiiAddPackages (&gEfiCallerIdGuid, ImageHandle, DPStrings, NULL);
254 ASSERT (gHiiHandle != NULL);
255
256 // Initial the command list
257 //
258 InitialShellParamList ();
259
260 /****************************************************************************
261 **** Process Command Line arguments ****
262 ****************************************************************************/
263 Status = ShellCommandLineParse (DpParamList, &ParamPackage, NULL, TRUE);
264
265 if (EFI_ERROR(Status)) {
266 PrintToken (STRING_TOKEN (STR_DP_INVALID_ARG));
267 ShowHelp();
268 }
269 else {
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);
273
274 if (ShellCommandLineGetFlag (ParamPackage, StringDpOptionQh) ||
275 ShellCommandLineGetFlag (ParamPackage, StringDpOptionLh) ||
276 ShellCommandLineGetFlag (ParamPackage, StringDpOptionUh))
277 {
278 ShowHelp();
279 }
280 else {
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);
292
293 // Boolean Options
294 //
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);
306
307 // Options with Values
308 CmdLineArg = ShellCommandLineGetValue (ParamPackage, StringDpOptionLn);
309 if (CmdLineArg == NULL) {
310 Number2Display = DEFAULT_DISPLAYCOUNT;
311 }
312 else {
313 Number2Display = StrDecimalToUintn(CmdLineArg);
314 if (Number2Display == 0) {
315 Number2Display = MAXIMUM_DISPLAYCOUNT;
316 }
317 }
318 CmdLineArg = ShellCommandLineGetValue (ParamPackage, StringDpOptionLt);
319 if (CmdLineArg == NULL) {
320 mInterestThreshold = DEFAULT_THRESHOLD; // 1ms := 1,000 us
321 }
322 else {
323 mInterestThreshold = StrDecimalToUint64(CmdLineArg);
324 }
325 // Handle Flag combinations and default behaviors
326 // If both TraceMode and ProfileMode are FALSE, set them both to TRUE
327 if ((! TraceMode) && (! ProfileMode)) {
328 TraceMode = TRUE;
329 #if PROFILING_IMPLEMENTED
330 ProfileMode = TRUE;
331 #endif // PROFILING_IMPLEMENTED
332 }
333
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
341 //
342 Freq = GetPerformanceCounterProperties (&TimerInfo.StartCount, &TimerInfo.EndCount);
343
344 // Convert the Frequency from Hz to KHz
345 TimerInfo.Frequency = (UINT32)DivU64x32 (Freq, 1000);
346
347 // Determine in which direction the performance counter counts.
348 TimerInfo.CountUp = (BOOLEAN) (TimerInfo.EndCount >= TimerInfo.StartCount);
349
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);
355
356 // print performance timer characteristics
357 PrintToken (STRING_TOKEN (STR_DP_KHZ), TimerInfo.Frequency); // Print Timer frequency in KHz
358
359 if ((VerboseMode) &&
360 (! RawMode)
361 ) {
362 StringPtr = HiiGetString (gHiiHandle,
363 (EFI_STRING_ID) (TimerInfo.CountUp ? STRING_TOKEN (STR_DP_UP) : STRING_TOKEN (STR_DP_DOWN)),
364 NULL);
365 ASSERT (StringPtr != NULL);
366 PrintToken (STRING_TOKEN (STR_DP_TIMER_PROPERTIES), // Print Timer count range and direction
367 StringPtr,
368 TimerInfo.StartCount,
369 TimerInfo.EndCount
370 );
371 PrintToken (STRING_TOKEN (STR_DP_VERBOSE_THRESHOLD), mInterestThreshold);
372 }
373
374 /* **************************************************************************
375 **** Print Sections based on command line options
376 ****
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)
387 ****
388 **** The All, Raw, and Cooked modes are modified by the Trace and Profile
389 **** options.
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 ****************************************************************************/
395 GatherStatistics();
396 if (AllMode) {
397 if (TraceMode) {
398 DumpAllTrace( Number2Display, ExcludeMode);
399 }
400 if (ProfileMode) {
401 DumpAllProfile( Number2Display, ExcludeMode);
402 }
403 }
404 else if (RawMode) {
405 if (TraceMode) {
406 DumpRawTrace( Number2Display, ExcludeMode);
407 }
408 if (ProfileMode) {
409 DumpRawProfile( Number2Display, ExcludeMode);
410 }
411 }
412 else {
413 //------------- Begin Cooked Mode Processing
414 if (TraceMode) {
415 ProcessPhases ( Ticker );
416 if ( ! SummaryMode) {
417 Status = ProcessHandles ( ExcludeMode);
418 if ( ! EFI_ERROR( Status)) {
419 ProcessPeims ( );
420 ProcessGlobal ( );
421 ProcessCumulative ();
422 }
423 }
424 }
425 if (ProfileMode) {
426 DumpAllProfile( Number2Display, ExcludeMode);
427 }
428 } //------------- End of Cooked Mode Processing
429 if ( VerboseMode || SummaryMode) {
430 DumpStatistics();
431 }
432 }
433 }
434
435 // Free the memory allocate from HiiGetString
436 //
437 ListIndex = 0;
438 while (DpParamList[ListIndex].Name != NULL) {
439 FreePool (DpParamList[ListIndex].Name);
440 ListIndex ++;
441 }
442 FreePool (DpParamList);
443
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);
460
461 HiiRemovePackages (gHiiHandle);
462 return Status;
463 }