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