]> git.proxmox.com Git - mirror_edk2.git/blob - ShellPkg/Library/UefiDpLib/Dp.c
ShellPkg: Add "dp" command library to ShellPkg.
[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 - 2013, Intel Corporation. All rights reserved.
17 This program and the accompanying materials
18 are licensed and made available under the terms and conditions of the BSD License
19 which accompanies this distribution. The full text of the license may be found at
20 http://opensource.org/licenses/bsd-license.php
21
22 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
23 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
24 **/
25
26 #include "UefiDpLib.h"
27 #include <Guid/GlobalVariable.h>
28 #include <Library/PrintLib.h>
29 #include <Library/HandleParsingLib.h>
30 #include <Library/DevicePathLib.h>
31
32 #include <Library/ShellLib.h>
33 #include <Library/BaseLib.h>
34 #include <Library/MemoryAllocationLib.h>
35 #include <Library/DebugLib.h>
36 #include <Library/TimerLib.h>
37 #include <Library/UefiLib.h>
38
39 #include <Guid/Performance.h>
40
41 #include <PerformanceTokens.h>
42 #include "Dp.h"
43 #include "Literals.h"
44 #include "DpInternal.h"
45
46 //
47 /// Module-Global Variables
48 ///@{
49 CHAR16 mGaugeString[DP_GAUGE_STRING_LENGTH + 1];
50 CHAR16 mUnicodeToken[DXE_PERFORMANCE_STRING_SIZE];
51 UINT64 mInterestThreshold;
52 BOOLEAN mShowId = FALSE;
53
54 PERF_SUMMARY_DATA SummaryData = { 0 }; ///< Create the SummaryData structure and init. to ZERO.
55
56 /// Timer Specific Information.
57 TIMER_INFO TimerInfo;
58
59 /// Items for which to gather cumulative statistics.
60 PERF_CUM_DATA CumData[] = {
61 PERF_INIT_CUM_DATA (LOAD_IMAGE_TOK),
62 PERF_INIT_CUM_DATA (START_IMAGE_TOK),
63 PERF_INIT_CUM_DATA (DRIVERBINDING_START_TOK),
64 PERF_INIT_CUM_DATA (DRIVERBINDING_SUPPORT_TOK)
65 };
66
67 /// Number of items for which we are gathering cumulative statistics.
68 UINT32 const NumCum = sizeof(CumData) / sizeof(PERF_CUM_DATA);
69
70 STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
71 {L"-v", TypeFlag}, // -v Verbose Mode
72 {L"-A", TypeFlag}, // -A All, Cooked
73 {L"-R", TypeFlag}, // -R RAW All
74 {L"-s", TypeFlag}, // -s Summary
75 #if PROFILING_IMPLEMENTED
76 {L"-P", TypeFlag}, // -P Dump Profile Data
77 {L"-T", TypeFlag}, // -T Dump Trace Data
78 #endif // PROFILING_IMPLEMENTED
79 {L"-x", TypeFlag}, // -x eXclude Cumulative Items
80 {L"-i", TypeFlag}, // -i Display Identifier
81 {L"-n", TypeValue}, // -n # Number of records to display for A and R
82 {L"-t", TypeValue}, // -t # Threshold of interest
83 {NULL, TypeMax}
84 };
85
86 ///@}
87
88 /**
89 Display the trailing Verbose information.
90 **/
91 VOID
92 DumpStatistics( void )
93 {
94 EFI_STRING StringPtr;
95 EFI_STRING StringPtrUnknown;
96 StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_STATISTICS), NULL);
97 StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
98 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,
99 (StringPtr == NULL) ? StringPtrUnknown : StringPtr);
100 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMTRACE), gDpHiiHandle, SummaryData.NumTrace);
101 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMINCOMPLETE), gDpHiiHandle, SummaryData.NumIncomplete);
102 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMPHASES), gDpHiiHandle, SummaryData.NumSummary);
103 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMHANDLES), gDpHiiHandle, SummaryData.NumHandles, SummaryData.NumTrace - SummaryData.NumHandles);
104 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMPEIMS), gDpHiiHandle, SummaryData.NumPEIMs);
105 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMGLOBALS), gDpHiiHandle, SummaryData.NumGlobal);
106 #if PROFILING_IMPLEMENTED
107 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMPROFILE), gDpHiiHandle, SummaryData.NumProfile);
108 #endif // PROFILING_IMPLEMENTED
109 SHELL_FREE_NON_NULL (StringPtr);
110 SHELL_FREE_NON_NULL (StringPtrUnknown);
111 }
112
113 /**
114 Dump performance data.
115
116 @param[in] ImageHandle The image handle.
117 @param[in] SystemTable The system table.
118
119 @retval EFI_SUCCESS Command completed successfully.
120 @retval EFI_INVALID_PARAMETER Command usage error.
121 @retval value Unknown error.
122
123 **/
124 SHELL_STATUS
125 EFIAPI
126 ShellCommandRunDp (
127 IN EFI_HANDLE ImageHandle,
128 IN EFI_SYSTEM_TABLE *SystemTable
129 )
130 {
131 LIST_ENTRY *ParamPackage;
132 CONST CHAR16 *CmdLineArg;
133 EFI_STATUS Status;
134
135 UINT64 Freq;
136 UINT64 Ticker;
137 UINTN Number2Display;
138
139 EFI_STRING StringPtr = NULL;
140 BOOLEAN SummaryMode = FALSE;
141 BOOLEAN VerboseMode = FALSE;
142 BOOLEAN AllMode = FALSE;
143 BOOLEAN RawMode = FALSE;
144 BOOLEAN TraceMode = FALSE;
145 BOOLEAN ProfileMode = FALSE;
146 BOOLEAN ExcludeMode = FALSE;
147
148 // Get DP's entry time as soon as possible.
149 // This is used as the Shell-Phase end time.
150 //
151 Ticker = GetPerformanceCounter ();
152
153 //
154 // initialize the shell lib (we must be in non-auto-init...)
155 //
156 Status = ShellInitialize();
157 ASSERT_EFI_ERROR(Status);
158
159 Status = CommandInit();
160 ASSERT_EFI_ERROR(Status);
161
162 //
163 // Process Command Line arguments
164 //
165 Status = ShellCommandLineParse (ParamList, &ParamPackage, NULL, TRUE);
166 if (EFI_ERROR(Status)) {
167 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_INVALID_ARG), gDpHiiHandle);
168 return SHELL_INVALID_PARAMETER;
169 }
170
171 //
172 // Boolean options
173 //
174 VerboseMode = ShellCommandLineGetFlag (ParamPackage, L"-v");
175 SummaryMode = (BOOLEAN) (ShellCommandLineGetFlag (ParamPackage, L"-S") || ShellCommandLineGetFlag (ParamPackage, L"-s"));
176 AllMode = ShellCommandLineGetFlag (ParamPackage, L"-A");
177 RawMode = ShellCommandLineGetFlag (ParamPackage, L"-R");
178 #if PROFILING_IMPLEMENTED
179 TraceMode = ShellCommandLineGetFlag (ParamPackage, L"-T");
180 ProfileMode = ShellCommandLineGetFlag (ParamPackage, L"-P");
181 #endif // PROFILING_IMPLEMENTED
182 ExcludeMode = ShellCommandLineGetFlag (ParamPackage, L"-x");
183 mShowId = ShellCommandLineGetFlag (ParamPackage, L"-i");
184
185 // Options with Values
186 CmdLineArg = ShellCommandLineGetValue (ParamPackage, L"-n");
187 if (CmdLineArg == NULL) {
188 Number2Display = DEFAULT_DISPLAYCOUNT;
189 } else {
190 Number2Display = StrDecimalToUintn(CmdLineArg);
191 if (Number2Display == 0) {
192 Number2Display = MAXIMUM_DISPLAYCOUNT;
193 }
194 }
195
196 CmdLineArg = ShellCommandLineGetValue (ParamPackage, L"-t");
197 if (CmdLineArg == NULL) {
198 mInterestThreshold = DEFAULT_THRESHOLD; // 1ms := 1,000 us
199 } else {
200 mInterestThreshold = StrDecimalToUint64(CmdLineArg);
201 }
202
203 // Handle Flag combinations and default behaviors
204 // If both TraceMode and ProfileMode are FALSE, set them both to TRUE
205 if ((! TraceMode) && (! ProfileMode)) {
206 TraceMode = TRUE;
207 #if PROFILING_IMPLEMENTED
208 ProfileMode = TRUE;
209 #endif // PROFILING_IMPLEMENTED
210 }
211
212 //
213 // Timer specific processing
214 //
215 // Get the Performance counter characteristics:
216 // Freq = Frequency in Hz
217 // StartCount = Value loaded into the counter when it starts counting
218 // EndCount = Value counter counts to before it needs to be reset
219 //
220 Freq = GetPerformanceCounterProperties (&TimerInfo.StartCount, &TimerInfo.EndCount);
221
222 // Convert the Frequency from Hz to KHz
223 TimerInfo.Frequency = (UINT32)DivU64x32 (Freq, 1000);
224
225 // Determine in which direction the performance counter counts.
226 TimerInfo.CountUp = (BOOLEAN) (TimerInfo.EndCount >= TimerInfo.StartCount);
227
228 //
229 // Print header
230 //
231 // print DP's build version
232 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_BUILD_REVISION), gDpHiiHandle, DP_MAJOR_VERSION, DP_MINOR_VERSION);
233
234 // print performance timer characteristics
235 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_KHZ), gDpHiiHandle, TimerInfo.Frequency);
236
237 if (VerboseMode && !RawMode) {
238 StringPtr = HiiGetString (gDpHiiHandle,
239 (EFI_STRING_ID) (TimerInfo.CountUp ? STRING_TOKEN (STR_DP_UP) : STRING_TOKEN (STR_DP_DOWN)), NULL);
240 ASSERT (StringPtr != NULL);
241 // Print Timer count range and direction
242 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TIMER_PROPERTIES), gDpHiiHandle,
243 StringPtr,
244 TimerInfo.StartCount,
245 TimerInfo.EndCount
246 );
247 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_VERBOSE_THRESHOLD), gDpHiiHandle, mInterestThreshold);
248 }
249
250 /****************************************************************************
251 **** Print Sections based on command line options
252 ****
253 **** Option modes have the following priority:
254 **** v Verbose -- Valid in combination with any other options
255 **** t Threshold -- Modifies All, Raw, and Cooked output
256 **** Default is 0 for All and Raw mode
257 **** Default is DEFAULT_THRESHOLD for "Cooked" mode
258 **** n Number2Display Used by All and Raw mode. Otherwise ignored.
259 **** A All -- R and S options are ignored
260 **** R Raw -- S option is ignored
261 **** s Summary -- Modifies "Cooked" output only
262 **** Cooked (Default)
263 ****
264 **** The All, Raw, and Cooked modes are modified by the Trace and Profile
265 **** options.
266 **** !T && !P := (0) Default, Both are displayed
267 **** T && !P := (1) Only Trace records are displayed
268 **** !T && P := (2) Only Profile records are displayed
269 **** T && P := (3) Same as Default, both are displayed
270 ****************************************************************************/
271 GatherStatistics();
272 if (AllMode) {
273 if (TraceMode) {
274 DumpAllTrace( Number2Display, ExcludeMode);
275 }
276 if (ProfileMode) {
277 DumpAllProfile( Number2Display, ExcludeMode);
278 }
279 } else if (RawMode) {
280 if (TraceMode) {
281 DumpRawTrace( Number2Display, ExcludeMode);
282 }
283 if (ProfileMode) {
284 DumpRawProfile( Number2Display, ExcludeMode);
285 }
286 } else {
287 //------------- Begin Cooked Mode Processing
288 if (TraceMode) {
289 ProcessPhases ( Ticker );
290 if ( ! SummaryMode) {
291 Status = ProcessHandles ( ExcludeMode);
292 if ( ! EFI_ERROR( Status)) {
293 ProcessPeims ();
294 ProcessGlobal ();
295 ProcessCumulative ();
296 }
297 }
298 }
299 if (ProfileMode) {
300 DumpAllProfile( Number2Display, ExcludeMode);
301 }
302 } //------------- End of Cooked Mode Processing
303 if ( VerboseMode || SummaryMode) {
304 DumpStatistics();
305 }
306
307 SHELL_FREE_NON_NULL (StringPtr);
308
309 return SHELL_SUCCESS;
310 }