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