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