]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiDpLib/Dp.c
PerformancePkg/Dp_App: Support execution break
[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
9d41c48f 16 Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.\r
303ec9bc 17 (C) Copyright 2015 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
140 @retval EFI_SUCCESS Command completed successfully.\r
141 @retval EFI_INVALID_PARAMETER Command usage error.\r
142 @retval value Unknown error.\r
143 \r
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
a9b4ff8d
ED
171\r
172 StringPtr = NULL;\r
173 SummaryMode = FALSE;\r
174 VerboseMode = FALSE;\r
175 AllMode = FALSE;\r
176 RawMode = FALSE;\r
177 TraceMode = FALSE;\r
178 ProfileMode = FALSE;\r
179 ExcludeMode = FALSE;\r
a06795c6
CS
180 CumulativeMode = FALSE;\r
181 CustomCumulativeData = NULL;\r
d41bc92c 182\r
183 // Get DP's entry time as soon as possible.\r
184 // This is used as the Shell-Phase end time.\r
185 //\r
186 Ticker = GetPerformanceCounter ();\r
187\r
188 //\r
189 // initialize the shell lib (we must be in non-auto-init...)\r
190 //\r
191 Status = ShellInitialize();\r
192 ASSERT_EFI_ERROR(Status);\r
193\r
194 Status = CommandInit();\r
195 ASSERT_EFI_ERROR(Status);\r
196\r
197 //\r
198 // Process Command Line arguments\r
199 //\r
200 Status = ShellCommandLineParse (ParamList, &ParamPackage, NULL, TRUE);\r
201 if (EFI_ERROR(Status)) {\r
202 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_INVALID_ARG), gDpHiiHandle);\r
203 return SHELL_INVALID_PARAMETER;\r
204 }\r
205\r
206 //\r
207 // Boolean options\r
208 //\r
209 VerboseMode = ShellCommandLineGetFlag (ParamPackage, L"-v");\r
210 SummaryMode = (BOOLEAN) (ShellCommandLineGetFlag (ParamPackage, L"-S") || ShellCommandLineGetFlag (ParamPackage, L"-s"));\r
211 AllMode = ShellCommandLineGetFlag (ParamPackage, L"-A");\r
212 RawMode = ShellCommandLineGetFlag (ParamPackage, L"-R");\r
213#if PROFILING_IMPLEMENTED\r
214 TraceMode = ShellCommandLineGetFlag (ParamPackage, L"-T");\r
215 ProfileMode = ShellCommandLineGetFlag (ParamPackage, L"-P");\r
216#endif // PROFILING_IMPLEMENTED\r
217 ExcludeMode = ShellCommandLineGetFlag (ParamPackage, L"-x");\r
218 mShowId = ShellCommandLineGetFlag (ParamPackage, L"-i");\r
a06795c6 219 CumulativeMode = ShellCommandLineGetFlag (ParamPackage, L"-c");\r
d41bc92c 220\r
221 // Options with Values\r
222 CmdLineArg = ShellCommandLineGetValue (ParamPackage, L"-n");\r
223 if (CmdLineArg == NULL) {\r
224 Number2Display = DEFAULT_DISPLAYCOUNT;\r
225 } else {\r
226 Number2Display = StrDecimalToUintn(CmdLineArg);\r
227 if (Number2Display == 0) {\r
228 Number2Display = MAXIMUM_DISPLAYCOUNT;\r
229 }\r
230 }\r
231\r
232 CmdLineArg = ShellCommandLineGetValue (ParamPackage, L"-t");\r
233 if (CmdLineArg == NULL) {\r
234 mInterestThreshold = DEFAULT_THRESHOLD; // 1ms := 1,000 us\r
235 } else {\r
236 mInterestThreshold = StrDecimalToUint64(CmdLineArg);\r
237 }\r
238\r
239 // Handle Flag combinations and default behaviors\r
240 // If both TraceMode and ProfileMode are FALSE, set them both to TRUE\r
241 if ((! TraceMode) && (! ProfileMode)) {\r
242 TraceMode = TRUE;\r
243#if PROFILING_IMPLEMENTED\r
244 ProfileMode = TRUE;\r
245#endif // PROFILING_IMPLEMENTED\r
246 }\r
247\r
303ec9bc
CS
248 //\r
249 // Initialize the pre-defined cumulative data.\r
250 //\r
251 InitCumulativeData ();\r
252\r
a06795c6
CS
253 //\r
254 // Init the custom cumulative data.\r
255 //\r
256 CustomCumulativeToken = ShellCommandLineGetValue (ParamPackage, L"-c");\r
257 if (CustomCumulativeToken != NULL) {\r
258 CustomCumulativeData = AllocateZeroPool (sizeof (PERF_CUM_DATA));\r
9d41c48f 259 ASSERT (CustomCumulativeData != NULL);\r
a06795c6
CS
260 CustomCumulativeData->MinDur = 0;\r
261 CustomCumulativeData->MaxDur = 0;\r
262 CustomCumulativeData->Count = 0;\r
263 CustomCumulativeData->Duration = 0;\r
264 CustomCumulativeData->Name = AllocateZeroPool (StrLen (CustomCumulativeToken) + 1);\r
265 UnicodeStrToAsciiStr (CustomCumulativeToken, CustomCumulativeData->Name);\r
266 }\r
267\r
d41bc92c 268 //\r
269 // Timer specific processing\r
270 //\r
271 // Get the Performance counter characteristics:\r
272 // Freq = Frequency in Hz\r
273 // StartCount = Value loaded into the counter when it starts counting\r
274 // EndCount = Value counter counts to before it needs to be reset\r
275 //\r
276 Freq = GetPerformanceCounterProperties (&TimerInfo.StartCount, &TimerInfo.EndCount);\r
277\r
278 // Convert the Frequency from Hz to KHz\r
279 TimerInfo.Frequency = (UINT32)DivU64x32 (Freq, 1000);\r
280\r
281 // Determine in which direction the performance counter counts.\r
282 TimerInfo.CountUp = (BOOLEAN) (TimerInfo.EndCount >= TimerInfo.StartCount);\r
283\r
284 //\r
285 // Print header\r
286 //\r
287 // print DP's build version\r
288 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_BUILD_REVISION), gDpHiiHandle, DP_MAJOR_VERSION, DP_MINOR_VERSION);\r
289\r
290 // print performance timer characteristics\r
291 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_KHZ), gDpHiiHandle, TimerInfo.Frequency);\r
292\r
293 if (VerboseMode && !RawMode) {\r
294 StringPtr = HiiGetString (gDpHiiHandle,\r
295 (EFI_STRING_ID) (TimerInfo.CountUp ? STRING_TOKEN (STR_DP_UP) : STRING_TOKEN (STR_DP_DOWN)), NULL);\r
296 ASSERT (StringPtr != NULL);\r
297 // Print Timer count range and direction\r
298 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TIMER_PROPERTIES), gDpHiiHandle,\r
299 StringPtr,\r
300 TimerInfo.StartCount,\r
301 TimerInfo.EndCount\r
302 );\r
303 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_VERBOSE_THRESHOLD), gDpHiiHandle, mInterestThreshold);\r
304 }\r
305\r
306/****************************************************************************\r
307**** Print Sections based on command line options\r
308****\r
309**** Option modes have the following priority:\r
310**** v Verbose -- Valid in combination with any other options\r
311**** t Threshold -- Modifies All, Raw, and Cooked output\r
312**** Default is 0 for All and Raw mode\r
313**** Default is DEFAULT_THRESHOLD for "Cooked" mode\r
314**** n Number2Display Used by All and Raw mode. Otherwise ignored.\r
315**** A All -- R and S options are ignored\r
316**** R Raw -- S option is ignored\r
317**** s Summary -- Modifies "Cooked" output only\r
318**** Cooked (Default)\r
319****\r
320**** The All, Raw, and Cooked modes are modified by the Trace and Profile\r
321**** options.\r
322**** !T && !P := (0) Default, Both are displayed\r
323**** T && !P := (1) Only Trace records are displayed\r
324**** !T && P := (2) Only Profile records are displayed\r
325**** T && P := (3) Same as Default, both are displayed\r
326****************************************************************************/\r
a06795c6
CS
327 GatherStatistics (CustomCumulativeData);\r
328 if (CumulativeMode) { \r
329 ProcessCumulative (CustomCumulativeData);\r
330 } else if (AllMode) {\r
d41bc92c 331 if (TraceMode) {\r
332 DumpAllTrace( Number2Display, ExcludeMode);\r
333 }\r
334 if (ProfileMode) {\r
335 DumpAllProfile( Number2Display, ExcludeMode);\r
336 }\r
337 } else if (RawMode) {\r
338 if (TraceMode) {\r
339 DumpRawTrace( Number2Display, ExcludeMode);\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 ( Ticker );\r
348 if ( ! SummaryMode) {\r
349 Status = ProcessHandles ( ExcludeMode);\r
350 if ( ! EFI_ERROR( Status)) {\r
351 ProcessPeims ();\r
352 ProcessGlobal ();\r
a06795c6 353 ProcessCumulative (NULL);\r
d41bc92c 354 }\r
355 }\r
356 }\r
357 if (ProfileMode) {\r
358 DumpAllProfile( Number2Display, ExcludeMode);\r
359 }\r
360 } //------------- End of Cooked Mode Processing\r
361 if ( VerboseMode || SummaryMode) {\r
362 DumpStatistics();\r
363 }\r
364\r
365 SHELL_FREE_NON_NULL (StringPtr);\r
a06795c6
CS
366 if (CustomCumulativeData != NULL) {\r
367 SHELL_FREE_NON_NULL (CustomCumulativeData->Name);\r
368 }\r
369 SHELL_FREE_NON_NULL (CustomCumulativeData);\r
d41bc92c 370\r
371 return SHELL_SUCCESS;\r
372}\r