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