]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - ShellPkg/DynamicCommand/DpDynamicCommand/Dp.c
ShellPkg/DynamicCommand: Fix bug that cannot start in boot
[mirror_edk2.git] / ShellPkg / DynamicCommand / DpDynamicCommand / Dp.c
... / ...
CommitLineData
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
16 Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.\r
17 (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>\r
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 "PerformanceTokens.h"\r
28#include "Dp.h"\r
29#include "Literals.h"\r
30#include "DpInternal.h"\r
31\r
32EFI_HANDLE mDpHiiHandle;\r
33\r
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
69 {L"-c", TypeValue}, // -c Display cumulative data.\r
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
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
88 (StringPtr == NULL) ? StringPtrUnknown : StringPtr);\r
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
95#if PROFILING_IMPLEMENTED\r
96 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMPROFILE), mDpHiiHandle, SummaryData.NumProfile);\r
97#endif // PROFILING_IMPLEMENTED\r
98 SHELL_FREE_NON_NULL (StringPtr);\r
99 SHELL_FREE_NON_NULL (StringPtrUnknown);\r
100}\r
101\r
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
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
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
131**/\r
132SHELL_STATUS\r
133RunDp (\r
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
142 PERFORMANCE_PROPERTY *PerformanceProperty;\r
143 UINTN Number2Display;\r
144\r
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
153 BOOLEAN CumulativeMode;\r
154 CONST CHAR16 *CustomCumulativeToken;\r
155 PERF_CUM_DATA *CustomCumulativeData;\r
156 UINTN NameSize;\r
157 SHELL_STATUS ShellStatus;\r
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
167 CumulativeMode = FALSE;\r
168 CustomCumulativeData = NULL;\r
169 ShellStatus = SHELL_SUCCESS;\r
170\r
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
177 //\r
178 // Process Command Line arguments\r
179 //\r
180 Status = ShellCommandLineParse (ParamList, &ParamPackage, NULL, TRUE);\r
181 if (EFI_ERROR(Status)) {\r
182 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_INVALID_ARG), mDpHiiHandle);\r
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
199 CumulativeMode = ShellCommandLineGetFlag (ParamPackage, L"-c");\r
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
228 //\r
229 // Initialize the pre-defined cumulative data.\r
230 //\r
231 InitCumulativeData ();\r
232\r
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
239 if (CustomCumulativeData == NULL) {\r
240 return SHELL_OUT_OF_RESOURCES;\r
241 }\r
242 CustomCumulativeData->MinDur = PERF_MAXDUR;\r
243 CustomCumulativeData->MaxDur = 0;\r
244 CustomCumulativeData->Count = 0;\r
245 CustomCumulativeData->Duration = 0;\r
246 NameSize = StrLen (CustomCumulativeToken) + 1;\r
247 CustomCumulativeData->Name = AllocateZeroPool (NameSize);\r
248 if (CustomCumulativeData->Name == NULL) {\r
249 FreePool (CustomCumulativeData);\r
250 return SHELL_OUT_OF_RESOURCES;\r
251 }\r
252 UnicodeStrToAsciiStrS (CustomCumulativeToken, CustomCumulativeData->Name, NameSize);\r
253 }\r
254\r
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
263 Status = EfiGetSystemConfigurationTable (&gPerformanceProtocolGuid, (VOID **) &PerformanceProperty);\r
264 if (EFI_ERROR (Status) || (PerformanceProperty == NULL)) {\r
265 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PERF_PROPERTY_NOT_FOUND), mDpHiiHandle);\r
266 goto Done;\r
267 }\r
268\r
269 TimerInfo.Frequency = (UINT32)DivU64x32 (PerformanceProperty->Frequency, 1000);\r
270 TimerInfo.StartCount = PerformanceProperty->TimerStartValue;\r
271 TimerInfo.EndCount = PerformanceProperty->TimerEndValue;\r
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
280 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_BUILD_REVISION), mDpHiiHandle, DP_MAJOR_VERSION, DP_MINOR_VERSION);\r
281\r
282 // print performance timer characteristics\r
283 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_KHZ), mDpHiiHandle, TimerInfo.Frequency);\r
284\r
285 if (VerboseMode && !RawMode) {\r
286 StringPtr = HiiGetString (mDpHiiHandle,\r
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
290 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TIMER_PROPERTIES), mDpHiiHandle,\r
291 StringPtr,\r
292 TimerInfo.StartCount,\r
293 TimerInfo.EndCount\r
294 );\r
295 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_VERBOSE_THRESHOLD), mDpHiiHandle, mInterestThreshold);\r
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
319 GatherStatistics (CustomCumulativeData);\r
320 if (CumulativeMode) { \r
321 ProcessCumulative (CustomCumulativeData);\r
322 } else if (AllMode) {\r
323 if (TraceMode) {\r
324 Status = DumpAllTrace( Number2Display, ExcludeMode);\r
325 if (Status == EFI_ABORTED) {\r
326 ShellStatus = SHELL_ABORTED;\r
327 goto Done;\r
328 }\r
329 }\r
330 if (ProfileMode) {\r
331 DumpAllProfile( Number2Display, ExcludeMode);\r
332 }\r
333 } else if (RawMode) {\r
334 if (TraceMode) {\r
335 Status = DumpRawTrace( Number2Display, ExcludeMode);\r
336 if (Status == EFI_ABORTED) {\r
337 ShellStatus = SHELL_ABORTED;\r
338 goto Done;\r
339 }\r
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
347 ProcessPhases ();\r
348 if ( ! SummaryMode) {\r
349 Status = ProcessHandles ( ExcludeMode);\r
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
365 }\r
366\r
367 ProcessCumulative (NULL);\r
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
378Done:\r
379 if (ParamPackage != NULL) {\r
380 ShellCommandLineFreeVarList (ParamPackage);\r
381 }\r
382 SHELL_FREE_NON_NULL (StringPtr);\r
383 if (CustomCumulativeData != NULL) {\r
384 SHELL_FREE_NON_NULL (CustomCumulativeData->Name);\r
385 }\r
386 SHELL_FREE_NON_NULL (CustomCumulativeData);\r
387\r
388 return ShellStatus;\r
389}\r
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