]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiDpLib/Dp.c
ShellPkg/UefiDpLib: Fix a DP cumulative data issue
[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
16 Copyright (c) 2009 - 2013, 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
82 {L"-n", TypeValue}, // -n # Number of records to display for A and R\r
83 {L"-t", TypeValue}, // -t # Threshold of interest\r
84 {NULL, TypeMax}\r
85 };\r
86\r
87///@}\r
88\r
89/**\r
90 Display the trailing Verbose information.\r
91**/\r
92VOID\r
93DumpStatistics( void )\r
94{\r
95 EFI_STRING StringPtr;\r
96 EFI_STRING StringPtrUnknown;\r
97 StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_STATISTICS), NULL);\r
98 StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);\r
99 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,\r
100 (StringPtr == NULL) ? StringPtrUnknown : StringPtr);\r
101 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMTRACE), gDpHiiHandle, SummaryData.NumTrace);\r
102 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMINCOMPLETE), gDpHiiHandle, SummaryData.NumIncomplete);\r
103 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMPHASES), gDpHiiHandle, SummaryData.NumSummary);\r
104 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMHANDLES), gDpHiiHandle, SummaryData.NumHandles, SummaryData.NumTrace - SummaryData.NumHandles);\r
105 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMPEIMS), gDpHiiHandle, SummaryData.NumPEIMs);\r
106 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMGLOBALS), gDpHiiHandle, SummaryData.NumGlobal);\r
107#if PROFILING_IMPLEMENTED\r
108 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMPROFILE), gDpHiiHandle, SummaryData.NumProfile);\r
109#endif // PROFILING_IMPLEMENTED\r
110 SHELL_FREE_NON_NULL (StringPtr);\r
111 SHELL_FREE_NON_NULL (StringPtrUnknown);\r
112}\r
113\r
303ec9bc
CS
114/**\r
115 Initialize the cumulative data.\r
116\r
117**/\r
118VOID\r
119InitCumulativeData (\r
120 VOID\r
121 )\r
122{\r
123 UINTN Index;\r
124\r
125 for (Index = 0; Index < NumCum; ++Index) {\r
126 CumData[Index].Count = 0;\r
127 CumData[Index].MinDur = PERF_MAXDUR;\r
128 CumData[Index].MaxDur = 0;\r
129 CumData[Index].Duration = 0;\r
130 }\r
131}\r
132\r
133/**\r
d41bc92c 134 Dump performance data.\r
135 \r
136 @param[in] ImageHandle The image handle.\r
137 @param[in] SystemTable The system table.\r
138 \r
139 @retval EFI_SUCCESS Command completed successfully.\r
140 @retval EFI_INVALID_PARAMETER Command usage error.\r
141 @retval value Unknown error.\r
142 \r
143**/\r
144SHELL_STATUS\r
145EFIAPI\r
146ShellCommandRunDp (\r
147 IN EFI_HANDLE ImageHandle,\r
148 IN EFI_SYSTEM_TABLE *SystemTable\r
149 )\r
150{\r
151 LIST_ENTRY *ParamPackage;\r
152 CONST CHAR16 *CmdLineArg;\r
153 EFI_STATUS Status;\r
154\r
155 UINT64 Freq;\r
156 UINT64 Ticker;\r
157 UINTN Number2Display;\r
158\r
a9b4ff8d
ED
159 EFI_STRING StringPtr;\r
160 BOOLEAN SummaryMode;\r
161 BOOLEAN VerboseMode;\r
162 BOOLEAN AllMode;\r
163 BOOLEAN RawMode;\r
164 BOOLEAN TraceMode;\r
165 BOOLEAN ProfileMode;\r
166 BOOLEAN ExcludeMode;\r
167\r
168 StringPtr = NULL;\r
169 SummaryMode = FALSE;\r
170 VerboseMode = FALSE;\r
171 AllMode = FALSE;\r
172 RawMode = FALSE;\r
173 TraceMode = FALSE;\r
174 ProfileMode = FALSE;\r
175 ExcludeMode = FALSE;\r
d41bc92c 176\r
177 // Get DP's entry time as soon as possible.\r
178 // This is used as the Shell-Phase end time.\r
179 //\r
180 Ticker = GetPerformanceCounter ();\r
181\r
182 //\r
183 // initialize the shell lib (we must be in non-auto-init...)\r
184 //\r
185 Status = ShellInitialize();\r
186 ASSERT_EFI_ERROR(Status);\r
187\r
188 Status = CommandInit();\r
189 ASSERT_EFI_ERROR(Status);\r
190\r
191 //\r
192 // Process Command Line arguments\r
193 //\r
194 Status = ShellCommandLineParse (ParamList, &ParamPackage, NULL, TRUE);\r
195 if (EFI_ERROR(Status)) {\r
196 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_INVALID_ARG), gDpHiiHandle);\r
197 return SHELL_INVALID_PARAMETER;\r
198 }\r
199\r
200 //\r
201 // Boolean options\r
202 //\r
203 VerboseMode = ShellCommandLineGetFlag (ParamPackage, L"-v");\r
204 SummaryMode = (BOOLEAN) (ShellCommandLineGetFlag (ParamPackage, L"-S") || ShellCommandLineGetFlag (ParamPackage, L"-s"));\r
205 AllMode = ShellCommandLineGetFlag (ParamPackage, L"-A");\r
206 RawMode = ShellCommandLineGetFlag (ParamPackage, L"-R");\r
207#if PROFILING_IMPLEMENTED\r
208 TraceMode = ShellCommandLineGetFlag (ParamPackage, L"-T");\r
209 ProfileMode = ShellCommandLineGetFlag (ParamPackage, L"-P");\r
210#endif // PROFILING_IMPLEMENTED\r
211 ExcludeMode = ShellCommandLineGetFlag (ParamPackage, L"-x");\r
212 mShowId = ShellCommandLineGetFlag (ParamPackage, L"-i");\r
213\r
214 // Options with Values\r
215 CmdLineArg = ShellCommandLineGetValue (ParamPackage, L"-n");\r
216 if (CmdLineArg == NULL) {\r
217 Number2Display = DEFAULT_DISPLAYCOUNT;\r
218 } else {\r
219 Number2Display = StrDecimalToUintn(CmdLineArg);\r
220 if (Number2Display == 0) {\r
221 Number2Display = MAXIMUM_DISPLAYCOUNT;\r
222 }\r
223 }\r
224\r
225 CmdLineArg = ShellCommandLineGetValue (ParamPackage, L"-t");\r
226 if (CmdLineArg == NULL) {\r
227 mInterestThreshold = DEFAULT_THRESHOLD; // 1ms := 1,000 us\r
228 } else {\r
229 mInterestThreshold = StrDecimalToUint64(CmdLineArg);\r
230 }\r
231\r
232 // Handle Flag combinations and default behaviors\r
233 // If both TraceMode and ProfileMode are FALSE, set them both to TRUE\r
234 if ((! TraceMode) && (! ProfileMode)) {\r
235 TraceMode = TRUE;\r
236#if PROFILING_IMPLEMENTED\r
237 ProfileMode = TRUE;\r
238#endif // PROFILING_IMPLEMENTED\r
239 }\r
240\r
303ec9bc
CS
241 //\r
242 // Initialize the pre-defined cumulative data.\r
243 //\r
244 InitCumulativeData ();\r
245\r
d41bc92c 246 //\r
247 // Timer specific processing\r
248 //\r
249 // Get the Performance counter characteristics:\r
250 // Freq = Frequency in Hz\r
251 // StartCount = Value loaded into the counter when it starts counting\r
252 // EndCount = Value counter counts to before it needs to be reset\r
253 //\r
254 Freq = GetPerformanceCounterProperties (&TimerInfo.StartCount, &TimerInfo.EndCount);\r
255\r
256 // Convert the Frequency from Hz to KHz\r
257 TimerInfo.Frequency = (UINT32)DivU64x32 (Freq, 1000);\r
258\r
259 // Determine in which direction the performance counter counts.\r
260 TimerInfo.CountUp = (BOOLEAN) (TimerInfo.EndCount >= TimerInfo.StartCount);\r
261\r
262 //\r
263 // Print header\r
264 //\r
265 // print DP's build version\r
266 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_BUILD_REVISION), gDpHiiHandle, DP_MAJOR_VERSION, DP_MINOR_VERSION);\r
267\r
268 // print performance timer characteristics\r
269 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_KHZ), gDpHiiHandle, TimerInfo.Frequency);\r
270\r
271 if (VerboseMode && !RawMode) {\r
272 StringPtr = HiiGetString (gDpHiiHandle,\r
273 (EFI_STRING_ID) (TimerInfo.CountUp ? STRING_TOKEN (STR_DP_UP) : STRING_TOKEN (STR_DP_DOWN)), NULL);\r
274 ASSERT (StringPtr != NULL);\r
275 // Print Timer count range and direction\r
276 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TIMER_PROPERTIES), gDpHiiHandle,\r
277 StringPtr,\r
278 TimerInfo.StartCount,\r
279 TimerInfo.EndCount\r
280 );\r
281 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_VERBOSE_THRESHOLD), gDpHiiHandle, mInterestThreshold);\r
282 }\r
283\r
284/****************************************************************************\r
285**** Print Sections based on command line options\r
286****\r
287**** Option modes have the following priority:\r
288**** v Verbose -- Valid in combination with any other options\r
289**** t Threshold -- Modifies All, Raw, and Cooked output\r
290**** Default is 0 for All and Raw mode\r
291**** Default is DEFAULT_THRESHOLD for "Cooked" mode\r
292**** n Number2Display Used by All and Raw mode. Otherwise ignored.\r
293**** A All -- R and S options are ignored\r
294**** R Raw -- S option is ignored\r
295**** s Summary -- Modifies "Cooked" output only\r
296**** Cooked (Default)\r
297****\r
298**** The All, Raw, and Cooked modes are modified by the Trace and Profile\r
299**** options.\r
300**** !T && !P := (0) Default, Both are displayed\r
301**** T && !P := (1) Only Trace records are displayed\r
302**** !T && P := (2) Only Profile records are displayed\r
303**** T && P := (3) Same as Default, both are displayed\r
304****************************************************************************/\r
305 GatherStatistics();\r
306 if (AllMode) {\r
307 if (TraceMode) {\r
308 DumpAllTrace( Number2Display, ExcludeMode);\r
309 }\r
310 if (ProfileMode) {\r
311 DumpAllProfile( Number2Display, ExcludeMode);\r
312 }\r
313 } else if (RawMode) {\r
314 if (TraceMode) {\r
315 DumpRawTrace( Number2Display, ExcludeMode);\r
316 }\r
317 if (ProfileMode) {\r
318 DumpRawProfile( Number2Display, ExcludeMode);\r
319 }\r
320 } else {\r
321 //------------- Begin Cooked Mode Processing\r
322 if (TraceMode) {\r
323 ProcessPhases ( Ticker );\r
324 if ( ! SummaryMode) {\r
325 Status = ProcessHandles ( ExcludeMode);\r
326 if ( ! EFI_ERROR( Status)) {\r
327 ProcessPeims ();\r
328 ProcessGlobal ();\r
329 ProcessCumulative ();\r
330 }\r
331 }\r
332 }\r
333 if (ProfileMode) {\r
334 DumpAllProfile( Number2Display, ExcludeMode);\r
335 }\r
336 } //------------- End of Cooked Mode Processing\r
337 if ( VerboseMode || SummaryMode) {\r
338 DumpStatistics();\r
339 }\r
340\r
341 SHELL_FREE_NON_NULL (StringPtr);\r
342\r
343 return SHELL_SUCCESS;\r
344}\r