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