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