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