]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/DynamicCommand/DpDynamicCommand/DpTrace.c
ShellPkg/dp: Convert from NULL class library to Dynamic Command
[mirror_edk2.git] / ShellPkg / DynamicCommand / DpDynamicCommand / DpTrace.c
CommitLineData
d41bc92c 1/** @file\r
2 Trace reporting for the Dp utility.\r
3\r
ef224032 4 Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.\r
64c51ed1 5 (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>\r
d41bc92c 6 This program and the accompanying materials\r
7 are licensed and made available under the terms and conditions of the BSD License\r
8 which accompanies this distribution. The full text of the license may be found at\r
9 http://opensource.org/licenses/bsd-license.php\r
10\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13**/\r
14\r
15#include <Library/BaseLib.h>\r
16#include <Library/BaseMemoryLib.h>\r
17#include <Library/MemoryAllocationLib.h>\r
18#include <Library/DebugLib.h>\r
19#include <Library/UefiBootServicesTableLib.h>\r
d41bc92c 20#include <Library/PeCoffGetEntryPointLib.h>\r
21#include <Library/PerformanceLib.h>\r
22#include <Library/PrintLib.h>\r
23#include <Library/HiiLib.h>\r
24#include <Library/PcdLib.h>\r
25\r
26#include <Guid/Performance.h>\r
27\r
28#include "Dp.h"\r
29#include "Literals.h"\r
30#include "DpInternal.h"\r
31\r
92034c4c 32/**\r
d41bc92c 33 Collect verbose statistics about the logged performance measurements.\r
92034c4c 34\r
d41bc92c 35 General Summary information for all Trace measurements is gathered and\r
36 stored within the SummaryData structure. This information is both\r
37 used internally by subsequent reporting functions, and displayed\r
38 at the end of verbose reports.\r
92034c4c 39\r
d41bc92c 40 @pre The SummaryData and CumData structures must be initialized\r
41 prior to calling this function.\r
92034c4c 42\r
d41bc92c 43 @post The SummaryData and CumData structures contain statistics for the\r
44 current performance logs.\r
a06795c6
CS
45\r
46 @param[in, out] CustomCumulativeData A pointer to the cumtom cumulative data.\r
47\r
d41bc92c 48**/\r
49VOID\r
50GatherStatistics(\r
a06795c6
CS
51 IN OUT PERF_CUM_DATA *CustomCumulativeData OPTIONAL\r
52 )\r
d41bc92c 53{\r
54 MEASUREMENT_RECORD Measurement;\r
55 UINT64 Duration;\r
56 UINTN LogEntryKey;\r
57 INTN TIndex;\r
58\r
59 LogEntryKey = 0;\r
60 while ((LogEntryKey = GetPerformanceMeasurementEx (\r
61 LogEntryKey,\r
62 &Measurement.Handle,\r
63 &Measurement.Token,\r
64 &Measurement.Module,\r
65 &Measurement.StartTimeStamp,\r
66 &Measurement.EndTimeStamp,\r
67 &Measurement.Identifier)) != 0)\r
68 {\r
69 ++SummaryData.NumTrace; // Count the number of TRACE Measurement records\r
70 if (Measurement.EndTimeStamp == 0) {\r
71 ++SummaryData.NumIncomplete; // Count the incomplete records\r
72 continue;\r
73 }\r
74\r
75 if (Measurement.Handle != NULL) {\r
76 ++SummaryData.NumHandles; // Count the number of measurements with non-NULL handles\r
77 }\r
78\r
79 if (IsPhase( &Measurement)) {\r
80 ++SummaryData.NumSummary; // Count the number of major phases\r
81 }\r
82 else { // !IsPhase(...\r
83 if(Measurement.Handle == NULL) {\r
84 ++SummaryData.NumGlobal;\r
85 }\r
86 }\r
87\r
88 if (AsciiStrnCmp (Measurement.Token, ALit_PEIM, PERF_TOKEN_LENGTH) == 0) {\r
89 ++SummaryData.NumPEIMs; // Count PEIM measurements\r
90 }\r
91\r
92 Duration = GetDuration (&Measurement);\r
93 TIndex = GetCumulativeItem (&Measurement);\r
94 if (TIndex >= 0) {\r
95 CumData[TIndex].Duration += Duration;\r
96 CumData[TIndex].Count++;\r
97 if ( Duration < CumData[TIndex].MinDur ) {\r
98 CumData[TIndex].MinDur = Duration;\r
99 }\r
100 if ( Duration > CumData[TIndex].MaxDur ) {\r
101 CumData[TIndex].MaxDur = Duration;\r
102 }\r
103 }\r
a06795c6
CS
104\r
105 //\r
106 // Collect the data for custom cumulative data.\r
107 //\r
108 if ((CustomCumulativeData != NULL) && (AsciiStrCmp (Measurement.Token, CustomCumulativeData->Name) == 0)) {\r
109 CustomCumulativeData->Duration += Duration;\r
110 CustomCumulativeData->Count++;\r
111 if (Duration < CustomCumulativeData->MinDur) {\r
112 CustomCumulativeData->MinDur = Duration;\r
113 }\r
114 if (Duration > CustomCumulativeData->MaxDur) {\r
115 CustomCumulativeData->MaxDur = Duration;\r
116 }\r
117 }\r
d41bc92c 118 }\r
119}\r
120\r
92034c4c 121/**\r
d41bc92c 122 Gather and print ALL Trace Records.\r
92034c4c 123\r
d41bc92c 124 Displays all "interesting" Trace measurements in order.<BR>\r
125 The number of records displayed is controlled by:\r
126 - records with a duration less than mInterestThreshold microseconds are not displayed.\r
127 - No more than Limit records are displayed. A Limit of zero will not limit the output.\r
128 - If the ExcludeFlag is TRUE, records matching entries in the CumData array are not\r
129 displayed.\r
92034c4c 130\r
d41bc92c 131 @pre The mInterestThreshold global variable is set to the shortest duration to be printed.\r
132 The mGaugeString and mUnicodeToken global arrays are used for temporary string storage.\r
133 They must not be in use by a calling function.\r
92034c4c 134\r
d41bc92c 135 @param[in] Limit The number of records to print. Zero is ALL.\r
136 @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.\r
92034c4c 137\r
196ccda0
CS
138 @retval EFI_SUCCESS The operation was successful.\r
139 @retval EFI_ABORTED The user aborts the operation.\r
140 @return Others from a call to gBS->LocateHandleBuffer().\r
d41bc92c 141**/\r
196ccda0 142EFI_STATUS\r
d41bc92c 143DumpAllTrace(\r
144 IN UINTN Limit,\r
145 IN BOOLEAN ExcludeFlag\r
146 )\r
147{\r
148 MEASUREMENT_RECORD Measurement;\r
149 UINT64 ElapsedTime;\r
150 UINT64 Duration;\r
151 CHAR16 *IncFlag;\r
152 UINTN LogEntryKey;\r
153 UINTN Count;\r
154 UINTN Index;\r
155 UINTN TIndex;\r
156\r
157 EFI_HANDLE *HandleBuffer;\r
64c51ed1 158 UINTN HandleCount;\r
d41bc92c 159 EFI_STATUS Status;\r
160 EFI_STRING StringPtrUnknown;\r
161\r
92034c4c
RN
162 StringPtrUnknown = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);\r
163 IncFlag = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_ALL), NULL);\r
164 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), mDpHiiHandle,\r
d41bc92c 165 (IncFlag == NULL) ? StringPtrUnknown : IncFlag);\r
166 FreePool (StringPtrUnknown);\r
167\r
168 // Get Handle information\r
169 //\r
64c51ed1 170 Status = gBS->LocateHandleBuffer (AllHandles, NULL, NULL, &HandleCount, &HandleBuffer);\r
d41bc92c 171 if (EFI_ERROR (Status)) {\r
92034c4c 172 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLES_ERROR), mDpHiiHandle, Status);\r
d41bc92c 173 }\r
174 else {\r
175 // We have successfully populated the HandleBuffer\r
176 // Display ALL Measurement Records\r
177 // Up to Limit lines displayed\r
178 // Display only records with Elapsed times >= mInterestThreshold\r
179 // Display driver names in Module field for records with Handles.\r
180 //\r
181 if (mShowId) {\r
92034c4c
RN
182 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_ALL_HEADR2), mDpHiiHandle);\r
183 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_ALL_DASHES2), mDpHiiHandle);\r
d41bc92c 184 } else {\r
92034c4c
RN
185 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_ALL_HEADR), mDpHiiHandle);\r
186 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), mDpHiiHandle);\r
d41bc92c 187 }\r
188\r
189 LogEntryKey = 0;\r
190 Count = 0;\r
191 Index = 0;\r
192 while ( WITHIN_LIMIT(Count, Limit) &&\r
193 ((LogEntryKey = GetPerformanceMeasurementEx (\r
194 LogEntryKey,\r
195 &Measurement.Handle,\r
196 &Measurement.Token,\r
197 &Measurement.Module,\r
198 &Measurement.StartTimeStamp,\r
199 &Measurement.EndTimeStamp,\r
200 &Measurement.Identifier)) != 0)\r
201 )\r
202 {\r
203 ++Index; // Count every record. First record is 1.\r
204 ElapsedTime = 0;\r
205 SHELL_FREE_NON_NULL (IncFlag);\r
206 if (Measurement.EndTimeStamp != 0) {\r
207 Duration = GetDuration (&Measurement);\r
208 ElapsedTime = DurationInMicroSeconds ( Duration );\r
92034c4c 209 IncFlag = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_DP_COMPLETE), NULL);\r
d41bc92c 210 }\r
211 else {\r
92034c4c 212 IncFlag = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_DP_INCOMPLETE), NULL); // Mark incomplete records\r
d41bc92c 213 }\r
214 if (((Measurement.EndTimeStamp != 0) && (ElapsedTime < mInterestThreshold)) ||\r
215 ((ExcludeFlag) && (GetCumulativeItem(&Measurement) >= 0))\r
216 ) { // Ignore "uninteresting" or excluded records\r
217 continue;\r
218 }\r
219 ++Count; // Count the number of records printed\r
220\r
221 // If Handle is non-zero, see if we can determine a name for the driver\r
cb4669e0
LE
222 AsciiStrToUnicodeStrS (Measurement.Module, mGaugeString, ARRAY_SIZE (mGaugeString)); // Use Module by default\r
223 AsciiStrToUnicodeStrS (Measurement.Token, mUnicodeToken, ARRAY_SIZE (mUnicodeToken));\r
d41bc92c 224 if (Measurement.Handle != NULL) {\r
225 // See if the Handle is in the HandleBuffer\r
64c51ed1 226 for (TIndex = 0; TIndex < HandleCount; TIndex++) {\r
d41bc92c 227 if (Measurement.Handle == HandleBuffer[TIndex]) {\r
2c55a81a 228 DpGetNameFromHandle (HandleBuffer[TIndex]);\r
d41bc92c 229 break;\r
230 }\r
231 }\r
232 }\r
233\r
234 if (AsciiStrnCmp (Measurement.Token, ALit_PEIM, PERF_TOKEN_LENGTH) == 0) {\r
235 UnicodeSPrint (mGaugeString, sizeof (mGaugeString), L"%g", Measurement.Handle);\r
236 }\r
237\r
238 // Ensure that the argument strings are not too long.\r
239 mGaugeString[DP_GAUGE_STRING_LENGTH] = 0;\r
240 mUnicodeToken[13] = 0;\r
241\r
242 if (mShowId) {\r
92034c4c 243 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_ALL_VARS2), mDpHiiHandle,\r
d41bc92c 244 Index, // 1 based, Which measurement record is being printed\r
245 IncFlag,\r
246 Measurement.Handle,\r
247 mGaugeString,\r
248 mUnicodeToken,\r
249 ElapsedTime,\r
250 Measurement.Identifier\r
251 );\r
252 } else {\r
92034c4c 253 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_ALL_VARS), mDpHiiHandle,\r
d41bc92c 254 Index, // 1 based, Which measurement record is being printed\r
255 IncFlag,\r
256 Measurement.Handle,\r
257 mGaugeString,\r
258 mUnicodeToken,\r
259 ElapsedTime\r
260 );\r
261 }\r
196ccda0
CS
262 if (ShellGetExecutionBreakFlag ()) {\r
263 Status = EFI_ABORTED;\r
264 break;\r
265 }\r
d41bc92c 266 }\r
267 }\r
64c51ed1 268 if (HandleBuffer != NULL) {\r
d41bc92c 269 FreePool (HandleBuffer);\r
270 }\r
271 SHELL_FREE_NON_NULL (IncFlag);\r
196ccda0
CS
272\r
273 return Status;\r
d41bc92c 274}\r
275\r
92034c4c 276/**\r
d41bc92c 277 Gather and print Raw Trace Records.\r
92034c4c 278\r
d41bc92c 279 All Trace measurements with a duration greater than or equal to\r
280 mInterestThreshold are printed without interpretation.\r
92034c4c 281\r
d41bc92c 282 The number of records displayed is controlled by:\r
283 - records with a duration less than mInterestThreshold microseconds are not displayed.\r
284 - No more than Limit records are displayed. A Limit of zero will not limit the output.\r
285 - If the ExcludeFlag is TRUE, records matching entries in the CumData array are not\r
286 displayed.\r
92034c4c 287\r
d41bc92c 288 @pre The mInterestThreshold global variable is set to the shortest duration to be printed.\r
92034c4c 289\r
d41bc92c 290 @param[in] Limit The number of records to print. Zero is ALL.\r
291 @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.\r
196ccda0
CS
292\r
293 @retval EFI_SUCCESS The operation was successful.\r
294 @retval EFI_ABORTED The user aborts the operation.\r
d41bc92c 295**/\r
196ccda0 296EFI_STATUS\r
d41bc92c 297DumpRawTrace(\r
298 IN UINTN Limit,\r
299 IN BOOLEAN ExcludeFlag\r
300 )\r
301{\r
302 MEASUREMENT_RECORD Measurement;\r
303 UINT64 ElapsedTime;\r
304 UINT64 Duration;\r
305 UINTN LogEntryKey;\r
306 UINTN Count;\r
307 UINTN Index;\r
308\r
309 EFI_STRING StringPtr;\r
310 EFI_STRING StringPtrUnknown;\r
196ccda0
CS
311 EFI_STATUS Status;\r
312\r
313 Status = EFI_SUCCESS;\r
d41bc92c 314\r
92034c4c
RN
315 StringPtrUnknown = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);\r
316 StringPtr = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_RAWTRACE), NULL);\r
317 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), mDpHiiHandle,\r
d41bc92c 318 (StringPtr == NULL) ? StringPtrUnknown : StringPtr);\r
319 FreePool (StringPtr);\r
320 FreePool (StringPtrUnknown);\r
321\r
322 if (mShowId) {\r
92034c4c
RN
323 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_HEADR2), mDpHiiHandle);\r
324 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_DASHES2), mDpHiiHandle);\r
d41bc92c 325 } else {\r
92034c4c
RN
326 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_HEADR), mDpHiiHandle);\r
327 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_DASHES), mDpHiiHandle);\r
d41bc92c 328 }\r
329\r
330 LogEntryKey = 0;\r
331 Count = 0;\r
332 Index = 0;\r
333 while ( WITHIN_LIMIT(Count, Limit) &&\r
334 ((LogEntryKey = GetPerformanceMeasurementEx (\r
335 LogEntryKey,\r
336 &Measurement.Handle,\r
337 &Measurement.Token,\r
338 &Measurement.Module,\r
339 &Measurement.StartTimeStamp,\r
340 &Measurement.EndTimeStamp,\r
341 &Measurement.Identifier)) != 0)\r
342 )\r
343 {\r
344 ++Index; // Count every record. First record is 1.\r
345 ElapsedTime = 0;\r
346 if (Measurement.EndTimeStamp != 0) {\r
347 Duration = GetDuration (&Measurement);\r
348 ElapsedTime = DurationInMicroSeconds ( Duration );\r
349 }\r
350 if ((ElapsedTime < mInterestThreshold) ||\r
351 ((ExcludeFlag) && (GetCumulativeItem(&Measurement) >= 0))\r
352 ) { // Ignore "uninteresting" or Excluded records\r
353 continue;\r
354 }\r
355 ++Count; // Count the number of records printed\r
356\r
357 if (mShowId) {\r
92034c4c 358 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_VARS2), mDpHiiHandle,\r
d41bc92c 359 Index, // 1 based, Which measurement record is being printed\r
360 Measurement.Handle,\r
361 Measurement.StartTimeStamp,\r
362 Measurement.EndTimeStamp,\r
363 Measurement.Token,\r
364 Measurement.Module,\r
365 Measurement.Identifier\r
366 );\r
367 } else {\r
92034c4c 368 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_VARS), mDpHiiHandle,\r
d41bc92c 369 Index, // 1 based, Which measurement record is being printed\r
370 Measurement.Handle,\r
371 Measurement.StartTimeStamp,\r
372 Measurement.EndTimeStamp,\r
373 Measurement.Token,\r
374 Measurement.Module\r
375 );\r
376 }\r
196ccda0
CS
377 if (ShellGetExecutionBreakFlag ()) {\r
378 Status = EFI_ABORTED;\r
379 break;\r
380 }\r
d41bc92c 381 }\r
196ccda0 382 return Status;\r
d41bc92c 383}\r
384\r
92034c4c 385/**\r
d41bc92c 386 Gather and print Major Phase metrics.\r
92034c4c 387\r
d41bc92c 388**/\r
389VOID\r
390ProcessPhases(\r
ef224032 391 VOID\r
d41bc92c 392 )\r
393{\r
394 MEASUREMENT_RECORD Measurement;\r
395 UINT64 BdsTimeoutValue;\r
396 UINT64 SecTime;\r
397 UINT64 PeiTime;\r
398 UINT64 DxeTime;\r
399 UINT64 BdsTime;\r
d41bc92c 400 UINT64 ElapsedTime;\r
401 UINT64 Duration;\r
402 UINT64 Total;\r
403 EFI_STRING StringPtr;\r
404 UINTN LogEntryKey;\r
405 EFI_STRING StringPtrUnknown;\r
406\r
407 BdsTimeoutValue = 0;\r
408 SecTime = 0;\r
409 PeiTime = 0;\r
410 DxeTime = 0;\r
411 BdsTime = 0;\r
d41bc92c 412 //\r
413 // Get Execution Phase Statistics\r
414 //\r
92034c4c
RN
415 StringPtrUnknown = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);\r
416 StringPtr = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_PHASES), NULL);\r
417 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), mDpHiiHandle,\r
d41bc92c 418 (StringPtr == NULL) ? StringPtrUnknown : StringPtr);\r
419 FreePool (StringPtr);\r
420 FreePool (StringPtrUnknown);\r
421\r
422 LogEntryKey = 0;\r
423 while ((LogEntryKey = GetPerformanceMeasurementEx (\r
424 LogEntryKey,\r
425 &Measurement.Handle,\r
426 &Measurement.Token,\r
427 &Measurement.Module,\r
428 &Measurement.StartTimeStamp,\r
429 &Measurement.EndTimeStamp,\r
430 &Measurement.Identifier)) != 0)\r
431 {\r
d41bc92c 432 if (Measurement.EndTimeStamp == 0) { // Skip "incomplete" records\r
433 continue;\r
434 }\r
435 Duration = GetDuration (&Measurement);\r
436 if ( Measurement.Handle != NULL\r
437 && (AsciiStrnCmp (Measurement.Token, ALit_BdsTO, PERF_TOKEN_LENGTH) == 0)\r
438 )\r
439 {\r
440 BdsTimeoutValue = Duration;\r
441 } else if (AsciiStrnCmp (Measurement.Token, ALit_SEC, PERF_TOKEN_LENGTH) == 0) {\r
442 SecTime = Duration;\r
443 } else if (AsciiStrnCmp (Measurement.Token, ALit_PEI, PERF_TOKEN_LENGTH) == 0) {\r
444 PeiTime = Duration;\r
445 } else if (AsciiStrnCmp (Measurement.Token, ALit_DXE, PERF_TOKEN_LENGTH) == 0) {\r
446 DxeTime = Duration;\r
447 } else if (AsciiStrnCmp (Measurement.Token, ALit_BDS, PERF_TOKEN_LENGTH) == 0) {\r
448 BdsTime = Duration;\r
d41bc92c 449 }\r
450 }\r
451\r
452 Total = 0;\r
453\r
454 // print SEC phase duration time\r
455 //\r
456 if (SecTime > 0) {\r
457 ElapsedTime = DurationInMicroSeconds ( SecTime ); // Calculate elapsed time in microseconds\r
458 Total += DivU64x32 (ElapsedTime, 1000); // Accumulate time in milliseconds\r
92034c4c 459 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SEC_PHASE), mDpHiiHandle, ElapsedTime);\r
d41bc92c 460 }\r
461\r
462 // print PEI phase duration time\r
463 //\r
464 if (PeiTime > 0) {\r
465 ElapsedTime = DivU64x32 (\r
466 PeiTime,\r
467 (UINT32)TimerInfo.Frequency\r
468 );\r
469 Total += ElapsedTime;\r
92034c4c 470 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PHASE_DURATION), mDpHiiHandle, ALit_PEI, ElapsedTime);\r
d41bc92c 471 }\r
472\r
473 // print DXE phase duration time\r
474 //\r
475 if (DxeTime > 0) {\r
476 ElapsedTime = DivU64x32 (\r
477 DxeTime,\r
478 (UINT32)TimerInfo.Frequency\r
479 );\r
480 Total += ElapsedTime;\r
92034c4c 481 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PHASE_DURATION), mDpHiiHandle, ALit_DXE, ElapsedTime);\r
d41bc92c 482 }\r
483\r
484 // print BDS phase duration time\r
485 //\r
486 if (BdsTime > 0) {\r
487 ElapsedTime = DivU64x32 (\r
488 BdsTime,\r
489 (UINT32)TimerInfo.Frequency\r
490 );\r
491 Total += ElapsedTime;\r
92034c4c 492 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PHASE_DURATION), mDpHiiHandle, ALit_BDS, ElapsedTime);\r
d41bc92c 493 }\r
494\r
495 if (BdsTimeoutValue > 0) {\r
496 ElapsedTime = DivU64x32 (\r
497 BdsTimeoutValue,\r
498 (UINT32)TimerInfo.Frequency\r
499 );\r
92034c4c 500 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PHASE_BDSTO), mDpHiiHandle, ALit_BdsTO, ElapsedTime);\r
d41bc92c 501 }\r
502\r
92034c4c 503 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TOTAL_DURATION), mDpHiiHandle, Total);\r
d41bc92c 504}\r
505\r
92034c4c 506/**\r
d41bc92c 507 Gather and print Handle data.\r
92034c4c 508\r
d41bc92c 509 @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.\r
92034c4c 510\r
196ccda0
CS
511 @retval EFI_SUCCESS The operation was successful.\r
512 @retval EFI_ABORTED The user aborts the operation.\r
513 @return Others from a call to gBS->LocateHandleBuffer().\r
d41bc92c 514**/\r
515EFI_STATUS\r
516ProcessHandles(\r
517 IN BOOLEAN ExcludeFlag\r
518 )\r
519{\r
520 MEASUREMENT_RECORD Measurement;\r
521 UINT64 ElapsedTime;\r
522 UINT64 Duration;\r
523 EFI_HANDLE *HandleBuffer;\r
524 EFI_STRING StringPtr;\r
525 UINTN Index;\r
526 UINTN LogEntryKey;\r
527 UINTN Count;\r
64c51ed1 528 UINTN HandleCount;\r
d41bc92c 529 EFI_STATUS Status;\r
530 EFI_STRING StringPtrUnknown;\r
531\r
92034c4c
RN
532 StringPtrUnknown = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);\r
533 StringPtr = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_DRIVERS), NULL);\r
534 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), mDpHiiHandle,\r
d41bc92c 535 (StringPtr == NULL) ? StringPtrUnknown : StringPtr);\r
536 FreePool (StringPtr);\r
537 FreePool (StringPtrUnknown);\r
538\r
64c51ed1 539 Status = gBS->LocateHandleBuffer (AllHandles, NULL, NULL, &HandleCount, &HandleBuffer);\r
d41bc92c 540 if (EFI_ERROR (Status)) {\r
92034c4c 541 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLES_ERROR), mDpHiiHandle, Status);\r
d41bc92c 542 }\r
543 else {\r
544#if DP_DEBUG == 2\r
545 Print (L"There are %,d Handles defined.\n", (Size / sizeof(HandleBuffer[0])));\r
546#endif\r
547\r
548 if (mShowId) {\r
92034c4c 549 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLE_SECTION2), mDpHiiHandle);\r
d41bc92c 550 } else {\r
92034c4c 551 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLE_SECTION), mDpHiiHandle);\r
d41bc92c 552 }\r
92034c4c 553 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), mDpHiiHandle);\r
d41bc92c 554\r
555 LogEntryKey = 0;\r
556 Count = 0;\r
557 while ((LogEntryKey = GetPerformanceMeasurementEx (\r
558 LogEntryKey,\r
559 &Measurement.Handle,\r
560 &Measurement.Token,\r
561 &Measurement.Module,\r
562 &Measurement.StartTimeStamp,\r
563 &Measurement.EndTimeStamp,\r
564 &Measurement.Identifier)) != 0)\r
565 {\r
566 Count++;\r
567 Duration = GetDuration (&Measurement);\r
568 ElapsedTime = DurationInMicroSeconds ( Duration );\r
569 if ((ElapsedTime < mInterestThreshold) ||\r
570 (Measurement.EndTimeStamp == 0) ||\r
571 (Measurement.Handle == NULL) ||\r
572 ((ExcludeFlag) && (GetCumulativeItem(&Measurement) >= 0))\r
573 ) { // Ignore "uninteresting" or excluded records\r
574 continue;\r
575 }\r
576 mGaugeString[0] = 0; // Empty driver name by default\r
cb4669e0 577 AsciiStrToUnicodeStrS (Measurement.Token, mUnicodeToken, ARRAY_SIZE (mUnicodeToken));\r
d41bc92c 578 // See if the Handle is in the HandleBuffer\r
64c51ed1 579 for (Index = 0; Index < HandleCount; Index++) {\r
d41bc92c 580 if (Measurement.Handle == HandleBuffer[Index]) {\r
2c55a81a 581 DpGetNameFromHandle (HandleBuffer[Index]); // Name is put into mGaugeString\r
d41bc92c 582 break;\r
583 }\r
584 }\r
585 // Ensure that the argument strings are not too long.\r
586 mGaugeString[DP_GAUGE_STRING_LENGTH] = 0;\r
587 mUnicodeToken[11] = 0;\r
588 if (mGaugeString[0] != 0) {\r
589 // Display the record if it has a valid handle.\r
590 if (mShowId) {\r
92034c4c 591 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLE_VARS2), mDpHiiHandle,\r
d41bc92c 592 Count, // 1 based, Which measurement record is being printed\r
593 Index + 1, // 1 based, Which handle is being printed\r
594 mGaugeString,\r
595 mUnicodeToken,\r
596 ElapsedTime,\r
597 Measurement.Identifier\r
598 );\r
599 } else {\r
92034c4c 600 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLE_VARS), mDpHiiHandle,\r
d41bc92c 601 Count, // 1 based, Which measurement record is being printed\r
602 Index + 1, // 1 based, Which handle is being printed\r
603 mGaugeString,\r
604 mUnicodeToken,\r
605 ElapsedTime\r
606 );\r
607 }\r
608 }\r
196ccda0
CS
609 if (ShellGetExecutionBreakFlag ()) {\r
610 Status = EFI_ABORTED;\r
611 break;\r
612 }\r
d41bc92c 613 }\r
614 }\r
64c51ed1 615 if (HandleBuffer != NULL) {\r
d41bc92c 616 FreePool (HandleBuffer);\r
617 }\r
618 return Status;\r
619}\r
620\r
92034c4c 621/**\r
d41bc92c 622 Gather and print PEIM data.\r
92034c4c 623\r
d41bc92c 624 Only prints complete PEIM records\r
92034c4c 625\r
196ccda0
CS
626 @retval EFI_SUCCESS The operation was successful.\r
627 @retval EFI_ABORTED The user aborts the operation.\r
d41bc92c 628**/\r
196ccda0 629EFI_STATUS\r
d41bc92c 630ProcessPeims(\r
631 VOID\r
632)\r
633{\r
634 MEASUREMENT_RECORD Measurement;\r
635 UINT64 Duration;\r
636 UINT64 ElapsedTime;\r
637 EFI_STRING StringPtr;\r
638 UINTN LogEntryKey;\r
639 UINTN TIndex;\r
640 EFI_STRING StringPtrUnknown;\r
196ccda0
CS
641 EFI_STATUS Status;\r
642\r
643 Status = EFI_SUCCESS;\r
d41bc92c 644\r
92034c4c
RN
645 StringPtrUnknown = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);\r
646 StringPtr = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_PEIMS), NULL);\r
647 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), mDpHiiHandle,\r
d41bc92c 648 (StringPtr == NULL) ? StringPtrUnknown : StringPtr);\r
649 FreePool (StringPtr);\r
650 FreePool (StringPtrUnknown);\r
651\r
652 if (mShowId) {\r
92034c4c 653 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PEIM_SECTION2), mDpHiiHandle);\r
d41bc92c 654 } else {\r
92034c4c 655 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PEIM_SECTION), mDpHiiHandle);\r
d41bc92c 656 }\r
92034c4c 657 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), mDpHiiHandle);\r
d41bc92c 658 TIndex = 0;\r
659 LogEntryKey = 0;\r
660 while ((LogEntryKey = GetPerformanceMeasurementEx (\r
661 LogEntryKey,\r
662 &Measurement.Handle,\r
663 &Measurement.Token,\r
664 &Measurement.Module,\r
665 &Measurement.StartTimeStamp,\r
666 &Measurement.EndTimeStamp,\r
667 &Measurement.Identifier)) != 0)\r
668 {\r
669 TIndex++;\r
670 if ((Measurement.EndTimeStamp == 0) ||\r
671 (AsciiStrnCmp (Measurement.Token, ALit_PEIM, PERF_TOKEN_LENGTH) != 0)\r
672 ) {\r
673 continue;\r
674 }\r
675\r
676 Duration = GetDuration (&Measurement);\r
677 ElapsedTime = DurationInMicroSeconds ( Duration ); // Calculate elapsed time in microseconds\r
678 if (ElapsedTime >= mInterestThreshold) {\r
679 // PEIM FILE Handle is the start address of its FFS file that contains its file guid.\r
680 if (mShowId) {\r
92034c4c 681 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PEIM_VARS2), mDpHiiHandle,\r
d41bc92c 682 TIndex, // 1 based, Which measurement record is being printed\r
683 Measurement.Handle, // base address\r
684 Measurement.Handle, // file guid\r
685 ElapsedTime,\r
686 Measurement.Identifier\r
687 );\r
688 } else {\r
92034c4c 689 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PEIM_VARS), mDpHiiHandle,\r
d41bc92c 690 TIndex, // 1 based, Which measurement record is being printed\r
691 Measurement.Handle, // base address\r
692 Measurement.Handle, // file guid\r
693 ElapsedTime\r
694 );\r
695 }\r
696 }\r
196ccda0
CS
697 if (ShellGetExecutionBreakFlag ()) {\r
698 Status = EFI_ABORTED;\r
699 break;\r
700 }\r
d41bc92c 701 }\r
196ccda0 702 return Status;\r
d41bc92c 703}\r
704\r
92034c4c 705/**\r
d41bc92c 706 Gather and print global data.\r
92034c4c 707\r
d41bc92c 708 Strips out incomplete or "Execution Phase" records\r
709 Only prints records where Handle is NULL\r
710 Increment TIndex for every record, even skipped ones, so that we have an\r
711 indication of every measurement record taken.\r
92034c4c 712\r
196ccda0
CS
713 @retval EFI_SUCCESS The operation was successful.\r
714 @retval EFI_ABORTED The user aborts the operation.\r
d41bc92c 715**/\r
196ccda0 716EFI_STATUS\r
d41bc92c 717ProcessGlobal(\r
718 VOID\r
719)\r
720{\r
721 MEASUREMENT_RECORD Measurement;\r
722 UINT64 Duration;\r
723 UINT64 ElapsedTime;\r
724 EFI_STRING StringPtr;\r
725 UINTN LogEntryKey;\r
726 UINTN Index; // Index, or number, of the measurement record being processed\r
727 EFI_STRING StringPtrUnknown;\r
196ccda0
CS
728 EFI_STATUS Status;\r
729\r
730 Status = EFI_SUCCESS;\r
d41bc92c 731\r
92034c4c
RN
732 StringPtrUnknown = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);\r
733 StringPtr = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_GENERAL), NULL);\r
734 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), mDpHiiHandle,\r
d41bc92c 735 (StringPtr == NULL) ? StringPtrUnknown: StringPtr);\r
736 FreePool (StringPtr);\r
737 FreePool (StringPtrUnknown);\r
738\r
739 if (mShowId) {\r
92034c4c 740 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GLOBAL_SECTION2), mDpHiiHandle);\r
d41bc92c 741 } else {\r
92034c4c 742 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GLOBAL_SECTION), mDpHiiHandle);\r
d41bc92c 743 }\r
92034c4c 744 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), mDpHiiHandle);\r
d41bc92c 745\r
746 Index = 1;\r
747 LogEntryKey = 0;\r
748\r
749 while ((LogEntryKey = GetPerformanceMeasurementEx (\r
750 LogEntryKey,\r
751 &Measurement.Handle,\r
752 &Measurement.Token,\r
753 &Measurement.Module,\r
754 &Measurement.StartTimeStamp,\r
755 &Measurement.EndTimeStamp,\r
756 &Measurement.Identifier)) != 0)\r
757 {\r
cb4669e0
LE
758 AsciiStrToUnicodeStrS (Measurement.Module, mGaugeString, ARRAY_SIZE (mGaugeString));\r
759 AsciiStrToUnicodeStrS (Measurement.Token, mUnicodeToken, ARRAY_SIZE (mUnicodeToken));\r
d41bc92c 760 mGaugeString[25] = 0;\r
761 mUnicodeToken[31] = 0;\r
762 if ( ! ( IsPhase( &Measurement) ||\r
763 (Measurement.Handle != NULL) ||\r
764 (Measurement.EndTimeStamp == 0)\r
765 ))\r
766 {\r
767 Duration = GetDuration (&Measurement);\r
768 ElapsedTime = DurationInMicroSeconds ( Duration );\r
769 if (ElapsedTime >= mInterestThreshold) {\r
770 if (mShowId) {\r
92034c4c 771 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GLOBAL_VARS2), mDpHiiHandle,\r
d41bc92c 772 Index,\r
773 mGaugeString,\r
774 mUnicodeToken,\r
775 ElapsedTime,\r
776 Measurement.Identifier\r
777 );\r
778 } else {\r
92034c4c 779 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GLOBAL_VARS), mDpHiiHandle,\r
d41bc92c 780 Index,\r
781 mGaugeString,\r
782 mUnicodeToken,\r
783 ElapsedTime\r
784 );\r
785 }\r
786 }\r
787 }\r
196ccda0
CS
788 if (ShellGetExecutionBreakFlag ()) {\r
789 Status = EFI_ABORTED;\r
790 break;\r
791 }\r
d41bc92c 792 Index++;\r
793 }\r
d0a23f9f 794 return Status;\r
d41bc92c 795}\r
796\r
92034c4c 797/**\r
d41bc92c 798 Gather and print cumulative data.\r
92034c4c 799\r
d41bc92c 800 Traverse the measurement records and:<BR>\r
801 For each record with a Token listed in the CumData array:<BR>\r
802 - Update the instance count and the total, minimum, and maximum durations.\r
803 Finally, print the gathered cumulative statistics.\r
a06795c6
CS
804\r
805 @param[in] CustomCumulativeData A pointer to the cumtom cumulative data.\r
806\r
d41bc92c 807**/\r
808VOID\r
809ProcessCumulative(\r
a06795c6
CS
810 IN PERF_CUM_DATA *CustomCumulativeData OPTIONAL\r
811 )\r
d41bc92c 812{\r
813 UINT64 AvgDur; // the computed average duration\r
814 UINT64 Dur;\r
815 UINT64 MinDur;\r
816 UINT64 MaxDur;\r
817 EFI_STRING StringPtr;\r
818 UINTN TIndex;\r
819 EFI_STRING StringPtrUnknown;\r
820\r
92034c4c
RN
821 StringPtrUnknown = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);\r
822 StringPtr = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_CUMULATIVE), NULL);\r
823 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), mDpHiiHandle,\r
d41bc92c 824 (StringPtr == NULL) ? StringPtrUnknown: StringPtr);\r
825 FreePool (StringPtr);\r
826 FreePool (StringPtrUnknown);\r
827\r
92034c4c
RN
828 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_CUMULATIVE_SECT_1), mDpHiiHandle);\r
829 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_CUMULATIVE_SECT_2), mDpHiiHandle);\r
830 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), mDpHiiHandle);\r
d41bc92c 831\r
832 for ( TIndex = 0; TIndex < NumCum; ++TIndex) {\r
833 if (CumData[TIndex].Count != 0) {\r
834 AvgDur = DivU64x32 (CumData[TIndex].Duration, CumData[TIndex].Count);\r
835 AvgDur = DurationInMicroSeconds(AvgDur);\r
836 Dur = DurationInMicroSeconds(CumData[TIndex].Duration);\r
837 MaxDur = DurationInMicroSeconds(CumData[TIndex].MaxDur);\r
838 MinDur = DurationInMicroSeconds(CumData[TIndex].MinDur);\r
92034c4c
RN
839\r
840 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_CUMULATIVE_STATS), mDpHiiHandle,\r
d41bc92c 841 CumData[TIndex].Name,\r
842 CumData[TIndex].Count,\r
843 Dur,\r
844 AvgDur,\r
845 MinDur,\r
846 MaxDur\r
847 );\r
848 }\r
849 }\r
a06795c6
CS
850\r
851 //\r
852 // Print the custom cumulative data.\r
853 //\r
854 if (CustomCumulativeData != NULL) {\r
855 if (CustomCumulativeData->Count != 0) {\r
856 AvgDur = DivU64x32 (CustomCumulativeData->Duration, CustomCumulativeData->Count);\r
857 AvgDur = DurationInMicroSeconds (AvgDur);\r
858 Dur = DurationInMicroSeconds (CustomCumulativeData->Duration);\r
859 MaxDur = DurationInMicroSeconds (CustomCumulativeData->MaxDur);\r
860 MinDur = DurationInMicroSeconds (CustomCumulativeData->MinDur);\r
861 } else {\r
862 AvgDur = 0;\r
863 Dur = 0;\r
864 MaxDur = 0;\r
865 MinDur = 0;\r
866 }\r
92034c4c 867 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_CUMULATIVE_STATS), mDpHiiHandle,\r
a06795c6
CS
868 CustomCumulativeData->Name,\r
869 CustomCumulativeData->Count,\r
870 Dur,\r
871 AvgDur,\r
872 MinDur,\r
873 MaxDur\r
874 );\r
875 }\r
d41bc92c 876}\r