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