2 Trace reporting for the Dp utility.
4 Copyright (c) 2009 - 2012, 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
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.
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>
26 #include <Guid/Performance.h>
30 #include "DpInternal.h"
33 Collect verbose statistics about the logged performance measurements.
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.
40 @pre The SummaryData and CumData structures must be initialized
41 prior to calling this function.
43 @post The SummaryData and CumData structures contain statistics for the
44 current performance logs.
51 MEASUREMENT_RECORD Measurement
;
57 while ((LogEntryKey
= GetPerformanceMeasurementEx (
62 &Measurement
.StartTimeStamp
,
63 &Measurement
.EndTimeStamp
,
64 &Measurement
.Identifier
)) != 0)
66 ++SummaryData
.NumTrace
; // Count the number of TRACE Measurement records
67 if (Measurement
.EndTimeStamp
== 0) {
68 ++SummaryData
.NumIncomplete
; // Count the incomplete records
72 if (Measurement
.Handle
!= NULL
) {
73 ++SummaryData
.NumHandles
; // Count the number of measurements with non-NULL handles
76 if (IsPhase( &Measurement
)) {
77 ++SummaryData
.NumSummary
; // Count the number of major phases
79 else { // !IsPhase(...
80 if(Measurement
.Handle
== NULL
) {
81 ++SummaryData
.NumGlobal
;
85 if (AsciiStrnCmp (Measurement
.Token
, ALit_PEIM
, PERF_TOKEN_LENGTH
) == 0) {
86 ++SummaryData
.NumPEIMs
; // Count PEIM measurements
89 Duration
= GetDuration (&Measurement
);
90 TIndex
= GetCumulativeItem (&Measurement
);
92 CumData
[TIndex
].Duration
+= Duration
;
93 CumData
[TIndex
].Count
++;
94 if ( Duration
< CumData
[TIndex
].MinDur
) {
95 CumData
[TIndex
].MinDur
= Duration
;
97 if ( Duration
> CumData
[TIndex
].MaxDur
) {
98 CumData
[TIndex
].MaxDur
= Duration
;
105 Gather and print ALL Trace Records.
107 Displays all "interesting" Trace measurements in order.<BR>
108 The number of records displayed is controlled by:
109 - records with a duration less than mInterestThreshold microseconds are not displayed.
110 - No more than Limit records are displayed. A Limit of zero will not limit the output.
111 - If the ExcludeFlag is TRUE, records matching entries in the CumData array are not
114 @pre The mInterestThreshold global variable is set to the shortest duration to be printed.
115 The mGaugeString and mUnicodeToken global arrays are used for temporary string storage.
116 They must not be in use by a calling function.
118 @param[in] Limit The number of records to print. Zero is ALL.
119 @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.
125 IN BOOLEAN ExcludeFlag
128 MEASUREMENT_RECORD Measurement
;
131 const CHAR16
*IncFlag
;
137 EFI_HANDLE
*HandleBuffer
;
139 EFI_HANDLE TempHandle
;
141 EFI_STRING StringPtrUnknown
;
143 StringPtrUnknown
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_ALIT_UNKNOWN
), NULL
);
144 IncFlag
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_SECTION_ALL
), NULL
);
145 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER
),
146 (IncFlag
== NULL
) ? StringPtrUnknown
: IncFlag
);
147 FreePool (StringPtrUnknown
);
149 // Get Handle information
152 HandleBuffer
= &TempHandle
;
153 Status
= gBS
->LocateHandle (AllHandles
, NULL
, NULL
, &Size
, &TempHandle
);
154 if (Status
== EFI_BUFFER_TOO_SMALL
) {
155 HandleBuffer
= AllocatePool (Size
);
156 ASSERT (HandleBuffer
!= NULL
);
157 if (HandleBuffer
== NULL
) {
160 Status
= gBS
->LocateHandle (AllHandles
, NULL
, NULL
, &Size
, HandleBuffer
);
162 if (EFI_ERROR (Status
)) {
163 PrintToken (STRING_TOKEN (STR_DP_HANDLES_ERROR
), Status
);
166 // We have successfully populated the HandleBuffer
167 // Display ALL Measurement Records
168 // Up to Limit lines displayed
169 // Display only records with Elapsed times >= mInterestThreshold
170 // Display driver names in Module field for records with Handles.
173 PrintToken (STRING_TOKEN (STR_DP_ALL_HEADR2
) );
174 PrintToken (STRING_TOKEN (STR_DP_ALL_DASHES2
) );
176 PrintToken (STRING_TOKEN (STR_DP_ALL_HEADR
) );
177 PrintToken (STRING_TOKEN (STR_DP_DASHES
) );
183 while ( WITHIN_LIMIT(Count
, Limit
) &&
184 ((LogEntryKey
= GetPerformanceMeasurementEx (
189 &Measurement
.StartTimeStamp
,
190 &Measurement
.EndTimeStamp
,
191 &Measurement
.Identifier
)) != 0)
194 ++Index
; // Count every record. First record is 1.
196 SafeFreePool ((VOID
*) IncFlag
);
197 if (Measurement
.EndTimeStamp
!= 0) {
198 Duration
= GetDuration (&Measurement
);
199 ElapsedTime
= DurationInMicroSeconds ( Duration
);
200 IncFlag
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_COMPLETE
), NULL
);
203 IncFlag
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_INCOMPLETE
), NULL
); // Mark incomplete records
205 if (((Measurement
.EndTimeStamp
!= 0) && (ElapsedTime
< mInterestThreshold
)) ||
206 ((ExcludeFlag
) && (GetCumulativeItem(&Measurement
) >= 0))
207 ) { // Ignore "uninteresting" or excluded records
210 ++Count
; // Count the number of records printed
212 // If Handle is non-zero, see if we can determine a name for the driver
213 AsciiStrToUnicodeStr (Measurement
.Module
, mGaugeString
); // Use Module by default
214 AsciiStrToUnicodeStr (Measurement
.Token
, mUnicodeToken
);
215 if (Measurement
.Handle
!= NULL
) {
216 // See if the Handle is in the HandleBuffer
217 for (TIndex
= 0; TIndex
< (Size
/ sizeof(HandleBuffer
[0])); TIndex
++) {
218 if (Measurement
.Handle
== HandleBuffer
[TIndex
]) {
219 GetNameFromHandle (HandleBuffer
[TIndex
]);
225 if (AsciiStrnCmp (Measurement
.Token
, ALit_PEIM
, PERF_TOKEN_LENGTH
) == 0) {
226 UnicodeSPrint (mGaugeString
, sizeof (mGaugeString
), L
"%g", Measurement
.Handle
);
229 // Ensure that the argument strings are not too long.
230 mGaugeString
[DP_GAUGE_STRING_LENGTH
] = 0;
231 mUnicodeToken
[13] = 0;
234 PrintToken( STRING_TOKEN (STR_DP_ALL_VARS2
),
235 Index
, // 1 based, Which measurement record is being printed
241 Measurement
.Identifier
244 PrintToken( STRING_TOKEN (STR_DP_ALL_VARS
),
245 Index
, // 1 based, Which measurement record is being printed
255 if (HandleBuffer
!= &TempHandle
) {
256 FreePool (HandleBuffer
);
258 SafeFreePool ((VOID
*) IncFlag
);
262 Gather and print Raw Trace Records.
264 All Trace measurements with a duration greater than or equal to
265 mInterestThreshold are printed without interpretation.
267 The number of records displayed is controlled by:
268 - records with a duration less than mInterestThreshold microseconds are not displayed.
269 - No more than Limit records are displayed. A Limit of zero will not limit the output.
270 - If the ExcludeFlag is TRUE, records matching entries in the CumData array are not
273 @pre The mInterestThreshold global variable is set to the shortest duration to be printed.
275 @param[in] Limit The number of records to print. Zero is ALL.
276 @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.
282 IN BOOLEAN ExcludeFlag
285 MEASUREMENT_RECORD Measurement
;
292 EFI_STRING StringPtr
;
293 EFI_STRING StringPtrUnknown
;
295 StringPtrUnknown
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_ALIT_UNKNOWN
), NULL
);
296 StringPtr
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_SECTION_RAWTRACE
), NULL
);
297 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER
),
298 (StringPtr
== NULL
) ? StringPtrUnknown
: StringPtr
);
299 FreePool (StringPtr
);
300 FreePool (StringPtrUnknown
);
303 PrintToken (STRING_TOKEN (STR_DP_RAW_HEADR2
) );
304 PrintToken (STRING_TOKEN (STR_DP_RAW_DASHES2
) );
306 PrintToken (STRING_TOKEN (STR_DP_RAW_HEADR
) );
307 PrintToken (STRING_TOKEN (STR_DP_RAW_DASHES
) );
313 while ( WITHIN_LIMIT(Count
, Limit
) &&
314 ((LogEntryKey
= GetPerformanceMeasurementEx (
319 &Measurement
.StartTimeStamp
,
320 &Measurement
.EndTimeStamp
,
321 &Measurement
.Identifier
)) != 0)
324 ++Index
; // Count every record. First record is 1.
326 if (Measurement
.EndTimeStamp
!= 0) {
327 Duration
= GetDuration (&Measurement
);
328 ElapsedTime
= DurationInMicroSeconds ( Duration
);
330 if ((ElapsedTime
< mInterestThreshold
) ||
331 ((ExcludeFlag
) && (GetCumulativeItem(&Measurement
) >= 0))
332 ) { // Ignore "uninteresting" or Excluded records
335 ++Count
; // Count the number of records printed
338 PrintToken (STRING_TOKEN (STR_DP_RAW_VARS2
),
339 Index
, // 1 based, Which measurement record is being printed
341 Measurement
.StartTimeStamp
,
342 Measurement
.EndTimeStamp
,
345 Measurement
.Identifier
348 PrintToken (STRING_TOKEN (STR_DP_RAW_VARS
),
349 Index
, // 1 based, Which measurement record is being printed
351 Measurement
.StartTimeStamp
,
352 Measurement
.EndTimeStamp
,
361 Gather and print Major Phase metrics.
363 @param[in] Ticker The timer value for the END of Shell phase
371 MEASUREMENT_RECORD Measurement
;
372 UINT64 BdsTimeoutValue
;
381 EFI_STRING StringPtr
;
383 EFI_STRING StringPtrUnknown
;
392 // Get Execution Phase Statistics
394 StringPtrUnknown
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_ALIT_UNKNOWN
), NULL
);
395 StringPtr
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_SECTION_PHASES
), NULL
);
396 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER
),
397 (StringPtr
== NULL
) ? StringPtrUnknown
: StringPtr
);
398 FreePool (StringPtr
);
399 FreePool (StringPtrUnknown
);
402 while ((LogEntryKey
= GetPerformanceMeasurementEx (
407 &Measurement
.StartTimeStamp
,
408 &Measurement
.EndTimeStamp
,
409 &Measurement
.Identifier
)) != 0)
411 if (AsciiStrnCmp (Measurement
.Token
, ALit_SHELL
, PERF_TOKEN_LENGTH
) == 0) {
412 Measurement
.EndTimeStamp
= Ticker
;
414 if (Measurement
.EndTimeStamp
== 0) { // Skip "incomplete" records
417 Duration
= GetDuration (&Measurement
);
418 if ( Measurement
.Handle
!= NULL
419 && (AsciiStrnCmp (Measurement
.Token
, ALit_BdsTO
, PERF_TOKEN_LENGTH
) == 0)
422 BdsTimeoutValue
= Duration
;
423 } else if (AsciiStrnCmp (Measurement
.Token
, ALit_SEC
, PERF_TOKEN_LENGTH
) == 0) {
425 } else if (AsciiStrnCmp (Measurement
.Token
, ALit_PEI
, PERF_TOKEN_LENGTH
) == 0) {
427 } else if (AsciiStrnCmp (Measurement
.Token
, ALit_DXE
, PERF_TOKEN_LENGTH
) == 0) {
429 } else if (AsciiStrnCmp (Measurement
.Token
, ALit_BDS
, PERF_TOKEN_LENGTH
) == 0) {
431 } else if (AsciiStrnCmp (Measurement
.Token
, ALit_SHELL
, PERF_TOKEN_LENGTH
) == 0) {
432 ShellTime
= Duration
;
438 // print SEC phase duration time
441 ElapsedTime
= DurationInMicroSeconds ( SecTime
); // Calculate elapsed time in microseconds
442 Total
+= DivU64x32 (ElapsedTime
, 1000); // Accumulate time in milliseconds
443 PrintToken (STRING_TOKEN (STR_DP_SEC_PHASE
), ElapsedTime
);
446 // print PEI phase duration time
449 ElapsedTime
= DivU64x32 (
451 (UINT32
)TimerInfo
.Frequency
453 Total
+= ElapsedTime
;
454 PrintToken (STRING_TOKEN (STR_DP_PHASE_DURATION
), ALit_PEI
, ElapsedTime
);
457 // print DXE phase duration time
460 ElapsedTime
= DivU64x32 (
462 (UINT32
)TimerInfo
.Frequency
464 Total
+= ElapsedTime
;
465 PrintToken (STRING_TOKEN (STR_DP_PHASE_DURATION
), ALit_DXE
, ElapsedTime
);
468 // print BDS phase duration time
471 ElapsedTime
= DivU64x32 (
473 (UINT32
)TimerInfo
.Frequency
475 Total
+= ElapsedTime
;
476 PrintToken (STRING_TOKEN (STR_DP_PHASE_DURATION
), ALit_BDS
, ElapsedTime
);
479 if (BdsTimeoutValue
> 0) {
480 ElapsedTime
= DivU64x32 (
482 (UINT32
)TimerInfo
.Frequency
484 PrintToken (STRING_TOKEN (STR_DP_PHASE_BDSTO
), ALit_BdsTO
, ElapsedTime
);
487 // print SHELL phase duration time
490 ElapsedTime
= DivU64x32 (
492 (UINT32
)TimerInfo
.Frequency
494 Total
+= ElapsedTime
;
495 PrintToken (STRING_TOKEN (STR_DP_PHASE_DURATION
), ALit_SHELL
, ElapsedTime
);
498 PrintToken (STRING_TOKEN (STR_DP_TOTAL_DURATION
), Total
);
502 Gather and print Handle data.
504 @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.
506 @return Status from a call to gBS->LocateHandle().
510 IN BOOLEAN ExcludeFlag
513 MEASUREMENT_RECORD Measurement
;
516 EFI_HANDLE
*HandleBuffer
;
517 EFI_STRING StringPtr
;
522 EFI_HANDLE TempHandle
;
524 EFI_STRING StringPtrUnknown
;
526 StringPtrUnknown
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_ALIT_UNKNOWN
), NULL
);
527 StringPtr
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_SECTION_DRIVERS
), NULL
);
528 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER
),
529 (StringPtr
== NULL
) ? StringPtrUnknown
: StringPtr
);
530 FreePool (StringPtr
);
531 FreePool (StringPtrUnknown
);
534 HandleBuffer
= &TempHandle
;
535 Status
= gBS
->LocateHandle (AllHandles
, NULL
, NULL
, &Size
, &TempHandle
);
536 if (Status
== EFI_BUFFER_TOO_SMALL
) {
537 HandleBuffer
= AllocatePool (Size
);
538 ASSERT (HandleBuffer
!= NULL
);
539 if (HandleBuffer
== NULL
) {
542 Status
= gBS
->LocateHandle (AllHandles
, NULL
, NULL
, &Size
, HandleBuffer
);
544 if (EFI_ERROR (Status
)) {
545 PrintToken (STRING_TOKEN (STR_DP_HANDLES_ERROR
), Status
);
549 Print (L
"There are %,d Handles defined.\n", (Size
/ sizeof(HandleBuffer
[0])));
553 PrintToken (STRING_TOKEN (STR_DP_HANDLE_SECTION2
) );
555 PrintToken (STRING_TOKEN (STR_DP_HANDLE_SECTION
) );
557 PrintToken (STRING_TOKEN (STR_DP_DASHES
) );
561 while ((LogEntryKey
= GetPerformanceMeasurementEx (
566 &Measurement
.StartTimeStamp
,
567 &Measurement
.EndTimeStamp
,
568 &Measurement
.Identifier
)) != 0)
571 Duration
= GetDuration (&Measurement
);
572 ElapsedTime
= DurationInMicroSeconds ( Duration
);
573 if ((ElapsedTime
< mInterestThreshold
) ||
574 (Measurement
.EndTimeStamp
== 0) ||
575 (Measurement
.Handle
== NULL
) ||
576 ((ExcludeFlag
) && (GetCumulativeItem(&Measurement
) >= 0))
577 ) { // Ignore "uninteresting" or excluded records
580 mGaugeString
[0] = 0; // Empty driver name by default
581 AsciiStrToUnicodeStr (Measurement
.Token
, mUnicodeToken
);
582 // See if the Handle is in the HandleBuffer
583 for (Index
= 0; Index
< (Size
/ sizeof(HandleBuffer
[0])); Index
++) {
584 if (Measurement
.Handle
== HandleBuffer
[Index
]) {
585 GetNameFromHandle (HandleBuffer
[Index
]); // Name is put into mGaugeString
589 // Ensure that the argument strings are not too long.
590 mGaugeString
[DP_GAUGE_STRING_LENGTH
] = 0;
591 mUnicodeToken
[11] = 0;
592 if (mGaugeString
[0] != 0) {
593 // Display the record if it has a valid handle.
596 STRING_TOKEN (STR_DP_HANDLE_VARS2
),
597 Count
, // 1 based, Which measurement record is being printed
598 Index
+ 1, // 1 based, Which handle is being printed
602 Measurement
.Identifier
606 STRING_TOKEN (STR_DP_HANDLE_VARS
),
607 Count
, // 1 based, Which measurement record is being printed
608 Index
+ 1, // 1 based, Which handle is being printed
617 if (HandleBuffer
!= &TempHandle
) {
618 FreePool (HandleBuffer
);
624 Gather and print PEIM data.
626 Only prints complete PEIM records
634 MEASUREMENT_RECORD Measurement
;
637 EFI_STRING StringPtr
;
640 EFI_STRING StringPtrUnknown
;
642 StringPtrUnknown
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_ALIT_UNKNOWN
), NULL
);
643 StringPtr
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_SECTION_PEIMS
), NULL
);
644 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER
),
645 (StringPtr
== NULL
) ? StringPtrUnknown
: StringPtr
);
646 FreePool (StringPtr
);
647 FreePool (StringPtrUnknown
);
650 PrintToken (STRING_TOKEN (STR_DP_PEIM_SECTION2
));
652 PrintToken (STRING_TOKEN (STR_DP_PEIM_SECTION
));
654 PrintToken (STRING_TOKEN (STR_DP_DASHES
));
657 while ((LogEntryKey
= GetPerformanceMeasurementEx (
662 &Measurement
.StartTimeStamp
,
663 &Measurement
.EndTimeStamp
,
664 &Measurement
.Identifier
)) != 0)
667 if ((Measurement
.EndTimeStamp
== 0) ||
668 (AsciiStrnCmp (Measurement
.Token
, ALit_PEIM
, PERF_TOKEN_LENGTH
) != 0)
673 Duration
= GetDuration (&Measurement
);
674 ElapsedTime
= DurationInMicroSeconds ( Duration
); // Calculate elapsed time in microseconds
675 if (ElapsedTime
>= mInterestThreshold
) {
676 // PEIM FILE Handle is the start address of its FFS file that contains its file guid.
678 PrintToken (STRING_TOKEN (STR_DP_PEIM_VARS2
),
679 TIndex
, // 1 based, Which measurement record is being printed
680 Measurement
.Handle
, // base address
681 Measurement
.Handle
, // file guid
683 Measurement
.Identifier
686 PrintToken (STRING_TOKEN (STR_DP_PEIM_VARS
),
687 TIndex
, // 1 based, Which measurement record is being printed
688 Measurement
.Handle
, // base address
689 Measurement
.Handle
, // file guid
698 Gather and print global data.
700 Strips out incomplete or "Execution Phase" records
701 Only prints records where Handle is NULL
702 Increment TIndex for every record, even skipped ones, so that we have an
703 indication of every measurement record taken.
711 MEASUREMENT_RECORD Measurement
;
714 EFI_STRING StringPtr
;
716 UINTN Index
; // Index, or number, of the measurement record being processed
717 EFI_STRING StringPtrUnknown
;
719 StringPtrUnknown
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_ALIT_UNKNOWN
), NULL
);
720 StringPtr
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_SECTION_GENERAL
), NULL
);
721 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER
),
722 (StringPtr
== NULL
) ? StringPtrUnknown
: StringPtr
);
723 FreePool (StringPtr
);
724 FreePool (StringPtrUnknown
);
727 PrintToken (STRING_TOKEN (STR_DP_GLOBAL_SECTION2
));
729 PrintToken (STRING_TOKEN (STR_DP_GLOBAL_SECTION
));
731 PrintToken (STRING_TOKEN (STR_DP_DASHES
));
736 while ((LogEntryKey
= GetPerformanceMeasurementEx (
741 &Measurement
.StartTimeStamp
,
742 &Measurement
.EndTimeStamp
,
743 &Measurement
.Identifier
)) != 0)
745 AsciiStrToUnicodeStr (Measurement
.Module
, mGaugeString
);
746 AsciiStrToUnicodeStr (Measurement
.Token
, mUnicodeToken
);
747 mGaugeString
[25] = 0;
748 mUnicodeToken
[31] = 0;
749 if ( ! ( IsPhase( &Measurement
) ||
750 (Measurement
.Handle
!= NULL
) ||
751 (Measurement
.EndTimeStamp
== 0)
754 Duration
= GetDuration (&Measurement
);
755 ElapsedTime
= DurationInMicroSeconds ( Duration
);
756 if (ElapsedTime
>= mInterestThreshold
) {
759 STRING_TOKEN (STR_DP_GLOBAL_VARS2
),
764 Measurement
.Identifier
768 STRING_TOKEN (STR_DP_GLOBAL_VARS
),
782 Gather and print cumulative data.
784 Traverse the measurement records and:<BR>
785 For each record with a Token listed in the CumData array:<BR>
786 - Update the instance count and the total, minimum, and maximum durations.
787 Finally, print the gathered cumulative statistics.
795 UINT64 AvgDur
; // the computed average duration
799 EFI_STRING StringPtr
;
801 EFI_STRING StringPtrUnknown
;
803 StringPtrUnknown
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_ALIT_UNKNOWN
), NULL
);
804 StringPtr
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_SECTION_CUMULATIVE
), NULL
);
805 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER
),
806 (StringPtr
== NULL
) ? StringPtrUnknown
: StringPtr
);
807 FreePool (StringPtr
);
808 FreePool (StringPtrUnknown
);
810 PrintToken (STRING_TOKEN (STR_DP_CUMULATIVE_SECT_1
));
811 PrintToken (STRING_TOKEN (STR_DP_CUMULATIVE_SECT_2
));
812 PrintToken (STRING_TOKEN (STR_DP_DASHES
));
814 for ( TIndex
= 0; TIndex
< NumCum
; ++TIndex
) {
815 if (CumData
[TIndex
].Count
!= 0) {
816 AvgDur
= DivU64x32 (CumData
[TIndex
].Duration
, CumData
[TIndex
].Count
);
817 AvgDur
= DurationInMicroSeconds(AvgDur
);
818 Dur
= DurationInMicroSeconds(CumData
[TIndex
].Duration
);
819 MaxDur
= DurationInMicroSeconds(CumData
[TIndex
].MaxDur
);
820 MinDur
= DurationInMicroSeconds(CumData
[TIndex
].MinDur
);
822 PrintToken (STRING_TOKEN (STR_DP_CUMULATIVE_STATS
),
823 CumData
[TIndex
].Name
,
824 CumData
[TIndex
].Count
,