]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiDpLib/Dp.c
PerformancePkg Dp_App: Remove TimerLib dependency
[mirror_edk2.git] / ShellPkg / Library / UefiDpLib / Dp.c
CommitLineData
d41bc92c 1/** @file\r
2 Shell command for Displaying Performance Metrics.\r
3\r
4 The Dp command 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
46213c8e 16 Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.\r
196ccda0 17 (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>\r
d41bc92c 18 This program and the accompanying materials\r
19 are licensed and made available under the terms and conditions of the BSD License\r
20 which accompanies this distribution. The full text of the license may be found at\r
21 http://opensource.org/licenses/bsd-license.php\r
22 \r
23 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
24 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
25**/\r
26\r
27#include "UefiDpLib.h"\r
28#include <Guid/GlobalVariable.h>\r
29#include <Library/PrintLib.h>\r
30#include <Library/HandleParsingLib.h>\r
31#include <Library/DevicePathLib.h>\r
32\r
33#include <Library/ShellLib.h>\r
34#include <Library/BaseLib.h>\r
35#include <Library/MemoryAllocationLib.h>\r
36#include <Library/DebugLib.h>\r
37#include <Library/TimerLib.h>\r
38#include <Library/UefiLib.h>\r
39\r
40#include <Guid/Performance.h>\r
41\r
dd42277f 42#include "PerformanceTokens.h"\r
d41bc92c 43#include "Dp.h"\r
44#include "Literals.h"\r
45#include "DpInternal.h"\r
46\r
47//\r
48/// Module-Global Variables\r
49///@{\r
50CHAR16 mGaugeString[DP_GAUGE_STRING_LENGTH + 1];\r
51CHAR16 mUnicodeToken[DXE_PERFORMANCE_STRING_SIZE];\r
52UINT64 mInterestThreshold;\r
53BOOLEAN mShowId = FALSE;\r
54\r
55PERF_SUMMARY_DATA SummaryData = { 0 }; ///< Create the SummaryData structure and init. to ZERO.\r
56\r
57/// Timer Specific Information.\r
58TIMER_INFO TimerInfo;\r
59\r
60/// Items for which to gather cumulative statistics.\r
61PERF_CUM_DATA CumData[] = {\r
62 PERF_INIT_CUM_DATA (LOAD_IMAGE_TOK),\r
63 PERF_INIT_CUM_DATA (START_IMAGE_TOK),\r
64 PERF_INIT_CUM_DATA (DRIVERBINDING_START_TOK),\r
65 PERF_INIT_CUM_DATA (DRIVERBINDING_SUPPORT_TOK)\r
66};\r
67\r
68/// Number of items for which we are gathering cumulative statistics.\r
69UINT32 const NumCum = sizeof(CumData) / sizeof(PERF_CUM_DATA);\r
70\r
71STATIC CONST SHELL_PARAM_ITEM ParamList[] = {\r
72 {L"-v", TypeFlag}, // -v Verbose Mode\r
73 {L"-A", TypeFlag}, // -A All, Cooked\r
74 {L"-R", TypeFlag}, // -R RAW All\r
75 {L"-s", TypeFlag}, // -s Summary\r
76#if PROFILING_IMPLEMENTED\r
77 {L"-P", TypeFlag}, // -P Dump Profile Data\r
78 {L"-T", TypeFlag}, // -T Dump Trace Data\r
79#endif // PROFILING_IMPLEMENTED\r
80 {L"-x", TypeFlag}, // -x eXclude Cumulative Items\r
81 {L"-i", TypeFlag}, // -i Display Identifier\r
a06795c6 82 {L"-c", TypeValue}, // -c Display cumulative data.\r
d41bc92c 83 {L"-n", TypeValue}, // -n # Number of records to display for A and R\r
84 {L"-t", TypeValue}, // -t # Threshold of interest\r
85 {NULL, TypeMax}\r
86 };\r
87\r
88///@}\r
89\r
90/**\r
91 Display the trailing Verbose information.\r
92**/\r
93VOID\r
94DumpStatistics( void )\r
95{\r
96 EFI_STRING StringPtr;\r
97 EFI_STRING StringPtrUnknown;\r
98 StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_STATISTICS), NULL);\r
99 StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);\r
100 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,\r
101 (StringPtr == NULL) ? StringPtrUnknown : StringPtr);\r
102 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMTRACE), gDpHiiHandle, SummaryData.NumTrace);\r
103 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMINCOMPLETE), gDpHiiHandle, SummaryData.NumIncomplete);\r
104 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMPHASES), gDpHiiHandle, SummaryData.NumSummary);\r
105 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMHANDLES), gDpHiiHandle, SummaryData.NumHandles, SummaryData.NumTrace - SummaryData.NumHandles);\r
106 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMPEIMS), gDpHiiHandle, SummaryData.NumPEIMs);\r
107 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMGLOBALS), gDpHiiHandle, SummaryData.NumGlobal);\r
108#if PROFILING_IMPLEMENTED\r
109 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMPROFILE), gDpHiiHandle, SummaryData.NumProfile);\r
110#endif // PROFILING_IMPLEMENTED\r
111 SHELL_FREE_NON_NULL (StringPtr);\r
112 SHELL_FREE_NON_NULL (StringPtrUnknown);\r
113}\r
114\r
303ec9bc
CS
115/**\r
116 Initialize the cumulative data.\r
117\r
118**/\r
119VOID\r
120InitCumulativeData (\r
121 VOID\r
122 )\r
123{\r
124 UINTN Index;\r
125\r
126 for (Index = 0; Index < NumCum; ++Index) {\r
127 CumData[Index].Count = 0;\r
128 CumData[Index].MinDur = PERF_MAXDUR;\r
129 CumData[Index].MaxDur = 0;\r
130 CumData[Index].Duration = 0;\r
131 }\r
132}\r
133\r
134/**\r
d41bc92c 135 Dump performance data.\r
136 \r
137 @param[in] ImageHandle The image handle.\r
138 @param[in] SystemTable The system table.\r
139 \r
196ccda0
CS
140 @retval SHELL_SUCCESS Command completed successfully.\r
141 @retval SHELL_INVALID_PARAMETER Command usage error.\r
142 @retval SHELL_ABORTED The user aborts the operation.\r
143 @retval value Unknown error.\r
d41bc92c 144**/\r
145SHELL_STATUS\r
146EFIAPI\r
147ShellCommandRunDp (\r
148 IN EFI_HANDLE ImageHandle,\r
149 IN EFI_SYSTEM_TABLE *SystemTable\r
150 )\r
151{\r
152 LIST_ENTRY *ParamPackage;\r
153 CONST CHAR16 *CmdLineArg;\r
154 EFI_STATUS Status;\r
155\r
156 UINT64 Freq;\r
157 UINT64 Ticker;\r
158 UINTN Number2Display;\r
159\r
a9b4ff8d
ED
160 EFI_STRING StringPtr;\r
161 BOOLEAN SummaryMode;\r
162 BOOLEAN VerboseMode;\r
163 BOOLEAN AllMode;\r
164 BOOLEAN RawMode;\r
165 BOOLEAN TraceMode;\r
166 BOOLEAN ProfileMode;\r
167 BOOLEAN ExcludeMode;\r
a06795c6
CS
168 BOOLEAN CumulativeMode;\r
169 CONST CHAR16 *CustomCumulativeToken;\r
170 PERF_CUM_DATA *CustomCumulativeData;\r
46213c8e 171 UINTN NameSize;\r
196ccda0 172 SHELL_STATUS ShellStatus;\r
a9b4ff8d
ED
173\r
174 StringPtr = NULL;\r
175 SummaryMode = FALSE;\r
176 VerboseMode = FALSE;\r
177 AllMode = FALSE;\r
178 RawMode = FALSE;\r
179 TraceMode = FALSE;\r
180 ProfileMode = FALSE;\r
181 ExcludeMode = FALSE;\r
a06795c6
CS
182 CumulativeMode = FALSE;\r
183 CustomCumulativeData = NULL;\r
196ccda0 184 ShellStatus = SHELL_SUCCESS;\r
d41bc92c 185\r
186 // Get DP's entry time as soon as possible.\r
187 // This is used as the Shell-Phase end time.\r
188 //\r
189 Ticker = GetPerformanceCounter ();\r
190\r
191 //\r
192 // initialize the shell lib (we must be in non-auto-init...)\r
193 //\r
194 Status = ShellInitialize();\r
195 ASSERT_EFI_ERROR(Status);\r
196\r
197 Status = CommandInit();\r
198 ASSERT_EFI_ERROR(Status);\r
199\r
200 //\r
201 // Process Command Line arguments\r
202 //\r
203 Status = ShellCommandLineParse (ParamList, &ParamPackage, NULL, TRUE);\r
204 if (EFI_ERROR(Status)) {\r
205 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_INVALID_ARG), gDpHiiHandle);\r
206 return SHELL_INVALID_PARAMETER;\r
207 }\r
208\r
209 //\r
210 // Boolean options\r
211 //\r
212 VerboseMode = ShellCommandLineGetFlag (ParamPackage, L"-v");\r
213 SummaryMode = (BOOLEAN) (ShellCommandLineGetFlag (ParamPackage, L"-S") || ShellCommandLineGetFlag (ParamPackage, L"-s"));\r
214 AllMode = ShellCommandLineGetFlag (ParamPackage, L"-A");\r
215 RawMode = ShellCommandLineGetFlag (ParamPackage, L"-R");\r
216#if PROFILING_IMPLEMENTED\r
217 TraceMode = ShellCommandLineGetFlag (ParamPackage, L"-T");\r
218 ProfileMode = ShellCommandLineGetFlag (ParamPackage, L"-P");\r
219#endif // PROFILING_IMPLEMENTED\r
220 ExcludeMode = ShellCommandLineGetFlag (ParamPackage, L"-x");\r
221 mShowId = ShellCommandLineGetFlag (ParamPackage, L"-i");\r
a06795c6 222 CumulativeMode = ShellCommandLineGetFlag (ParamPackage, L"-c");\r
d41bc92c 223\r
224 // Options with Values\r
225 CmdLineArg = ShellCommandLineGetValue (ParamPackage, L"-n");\r
226 if (CmdLineArg == NULL) {\r
227 Number2Display = DEFAULT_DISPLAYCOUNT;\r
228 } else {\r
229 Number2Display = StrDecimalToUintn(CmdLineArg);\r
230 if (Number2Display == 0) {\r
231 Number2Display = MAXIMUM_DISPLAYCOUNT;\r
232 }\r
233 }\r
234\r
235 CmdLineArg = ShellCommandLineGetValue (ParamPackage, L"-t");\r
236 if (CmdLineArg == NULL) {\r
237 mInterestThreshold = DEFAULT_THRESHOLD; // 1ms := 1,000 us\r
238 } else {\r
239 mInterestThreshold = StrDecimalToUint64(CmdLineArg);\r
240 }\r
241\r
242 // Handle Flag combinations and default behaviors\r
243 // If both TraceMode and ProfileMode are FALSE, set them both to TRUE\r
244 if ((! TraceMode) && (! ProfileMode)) {\r
245 TraceMode = TRUE;\r
246#if PROFILING_IMPLEMENTED\r
247 ProfileMode = TRUE;\r
248#endif // PROFILING_IMPLEMENTED\r
249 }\r
250\r
303ec9bc
CS
251 //\r
252 // Initialize the pre-defined cumulative data.\r
253 //\r
254 InitCumulativeData ();\r
255\r
a06795c6
CS
256 //\r
257 // Init the custom cumulative data.\r
258 //\r
259 CustomCumulativeToken = ShellCommandLineGetValue (ParamPackage, L"-c");\r
260 if (CustomCumulativeToken != NULL) {\r
261 CustomCumulativeData = AllocateZeroPool (sizeof (PERF_CUM_DATA));\r
d758f809
RN
262 if (CustomCumulativeData == NULL) {\r
263 return SHELL_OUT_OF_RESOURCES;\r
264 }\r
a06795c6
CS
265 CustomCumulativeData->MinDur = 0;\r
266 CustomCumulativeData->MaxDur = 0;\r
267 CustomCumulativeData->Count = 0;\r
268 CustomCumulativeData->Duration = 0;\r
46213c8e
SZ
269 NameSize = StrLen (CustomCumulativeToken) + 1;\r
270 CustomCumulativeData->Name = AllocateZeroPool (NameSize);\r
d758f809
RN
271 if (CustomCumulativeData->Name == NULL) {\r
272 FreePool (CustomCumulativeData);\r
273 return SHELL_OUT_OF_RESOURCES;\r
274 }\r
46213c8e 275 UnicodeStrToAsciiStrS (CustomCumulativeToken, CustomCumulativeData->Name, NameSize);\r
a06795c6
CS
276 }\r
277\r
d41bc92c 278 //\r
279 // Timer specific processing\r
280 //\r
281 // Get the Performance counter characteristics:\r
282 // Freq = Frequency in Hz\r
283 // StartCount = Value loaded into the counter when it starts counting\r
284 // EndCount = Value counter counts to before it needs to be reset\r
285 //\r
286 Freq = GetPerformanceCounterProperties (&TimerInfo.StartCount, &TimerInfo.EndCount);\r
287\r
288 // Convert the Frequency from Hz to KHz\r
289 TimerInfo.Frequency = (UINT32)DivU64x32 (Freq, 1000);\r
290\r
291 // Determine in which direction the performance counter counts.\r
292 TimerInfo.CountUp = (BOOLEAN) (TimerInfo.EndCount >= TimerInfo.StartCount);\r
293\r
294 //\r
295 // Print header\r
296 //\r
297 // print DP's build version\r
298 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_BUILD_REVISION), gDpHiiHandle, DP_MAJOR_VERSION, DP_MINOR_VERSION);\r
299\r
300 // print performance timer characteristics\r
301 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_KHZ), gDpHiiHandle, TimerInfo.Frequency);\r
302\r
303 if (VerboseMode && !RawMode) {\r
304 StringPtr = HiiGetString (gDpHiiHandle,\r
305 (EFI_STRING_ID) (TimerInfo.CountUp ? STRING_TOKEN (STR_DP_UP) : STRING_TOKEN (STR_DP_DOWN)), NULL);\r
306 ASSERT (StringPtr != NULL);\r
307 // Print Timer count range and direction\r
308 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TIMER_PROPERTIES), gDpHiiHandle,\r
309 StringPtr,\r
310 TimerInfo.StartCount,\r
311 TimerInfo.EndCount\r
312 );\r
313 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_VERBOSE_THRESHOLD), gDpHiiHandle, mInterestThreshold);\r
314 }\r
315\r
316/****************************************************************************\r
317**** Print Sections based on command line options\r
318****\r
319**** Option modes have the following priority:\r
320**** v Verbose -- Valid in combination with any other options\r
321**** t Threshold -- Modifies All, Raw, and Cooked output\r
322**** Default is 0 for All and Raw mode\r
323**** Default is DEFAULT_THRESHOLD for "Cooked" mode\r
324**** n Number2Display Used by All and Raw mode. Otherwise ignored.\r
325**** A All -- R and S options are ignored\r
326**** R Raw -- S option is ignored\r
327**** s Summary -- Modifies "Cooked" output only\r
328**** Cooked (Default)\r
329****\r
330**** The All, Raw, and Cooked modes are modified by the Trace and Profile\r
331**** options.\r
332**** !T && !P := (0) Default, Both are displayed\r
333**** T && !P := (1) Only Trace records are displayed\r
334**** !T && P := (2) Only Profile records are displayed\r
335**** T && P := (3) Same as Default, both are displayed\r
336****************************************************************************/\r
a06795c6
CS
337 GatherStatistics (CustomCumulativeData);\r
338 if (CumulativeMode) { \r
339 ProcessCumulative (CustomCumulativeData);\r
340 } else if (AllMode) {\r
d41bc92c 341 if (TraceMode) {\r
196ccda0
CS
342 Status = DumpAllTrace( Number2Display, ExcludeMode);\r
343 if (Status == EFI_ABORTED) {\r
344 ShellStatus = SHELL_ABORTED;\r
345 goto Done;\r
346 }\r
d41bc92c 347 }\r
348 if (ProfileMode) {\r
349 DumpAllProfile( Number2Display, ExcludeMode);\r
350 }\r
351 } else if (RawMode) {\r
352 if (TraceMode) {\r
196ccda0
CS
353 Status = DumpRawTrace( Number2Display, ExcludeMode);\r
354 if (Status == EFI_ABORTED) {\r
355 ShellStatus = SHELL_ABORTED;\r
356 goto Done;\r
357 }\r
d41bc92c 358 }\r
359 if (ProfileMode) {\r
360 DumpRawProfile( Number2Display, ExcludeMode);\r
361 }\r
362 } else {\r
363 //------------- Begin Cooked Mode Processing\r
364 if (TraceMode) {\r
365 ProcessPhases ( Ticker );\r
366 if ( ! SummaryMode) {\r
367 Status = ProcessHandles ( ExcludeMode);\r
196ccda0
CS
368 if (Status == EFI_ABORTED) {\r
369 ShellStatus = SHELL_ABORTED;\r
370 goto Done;\r
371 }\r
372\r
373 Status = ProcessPeims ();\r
374 if (Status == EFI_ABORTED) {\r
375 ShellStatus = SHELL_ABORTED;\r
376 goto Done;\r
377 }\r
378\r
379 Status = ProcessGlobal ();\r
380 if (Status == EFI_ABORTED) {\r
381 ShellStatus = SHELL_ABORTED;\r
382 goto Done;\r
d41bc92c 383 }\r
196ccda0
CS
384\r
385 ProcessCumulative (NULL);\r
d41bc92c 386 }\r
387 }\r
388 if (ProfileMode) {\r
389 DumpAllProfile( Number2Display, ExcludeMode);\r
390 }\r
391 } //------------- End of Cooked Mode Processing\r
392 if ( VerboseMode || SummaryMode) {\r
393 DumpStatistics();\r
394 }\r
395\r
196ccda0 396Done:\r
3751a092
CS
397 if (ParamPackage != NULL) {\r
398 ShellCommandLineFreeVarList (ParamPackage);\r
399 }\r
d41bc92c 400 SHELL_FREE_NON_NULL (StringPtr);\r
a06795c6
CS
401 if (CustomCumulativeData != NULL) {\r
402 SHELL_FREE_NON_NULL (CustomCumulativeData->Name);\r
403 }\r
404 SHELL_FREE_NON_NULL (CustomCumulativeData);\r
d41bc92c 405\r
196ccda0 406 return ShellStatus;\r
d41bc92c 407}\r