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