2 Trace reporting for the Dp utility.
4 Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
5 (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include <Library/BaseLib.h>
16 #include <Library/BaseMemoryLib.h>
17 #include <Library/MemoryAllocationLib.h>
18 #include <Library/DebugLib.h>
19 #include <Library/UefiBootServicesTableLib.h>
20 #include <Library/TimerLib.h>
21 #include <Library/PeCoffGetEntryPointLib.h>
22 #include <Library/PerformanceLib.h>
23 #include <Library/PrintLib.h>
24 #include <Library/HiiLib.h>
25 #include <Library/PcdLib.h>
27 #include <Guid/Performance.h>
31 #include "DpInternal.h"
34 Collect verbose statistics about the logged performance measurements.
36 General Summary information for all Trace measurements is gathered and
37 stored within the SummaryData structure. This information is both
38 used internally by subsequent reporting functions, and displayed
39 at the end of verbose reports.
41 @pre The SummaryData and CumData structures must be initialized
42 prior to calling this function.
44 @post The SummaryData and CumData structures contain statistics for the
45 current performance logs.
47 @param[in, out] CustomCumulativeData A pointer to the cumtom cumulative data.
52 IN OUT PERF_CUM_DATA
*CustomCumulativeData OPTIONAL
55 MEASUREMENT_RECORD Measurement
;
61 while ((LogEntryKey
= GetPerformanceMeasurementEx (
66 &Measurement
.StartTimeStamp
,
67 &Measurement
.EndTimeStamp
,
68 &Measurement
.Identifier
)) != 0)
70 ++SummaryData
.NumTrace
; // Count the number of TRACE Measurement records
71 if (Measurement
.EndTimeStamp
== 0) {
72 ++SummaryData
.NumIncomplete
; // Count the incomplete records
76 if (Measurement
.Handle
!= NULL
) {
77 ++SummaryData
.NumHandles
; // Count the number of measurements with non-NULL handles
80 if (IsPhase( &Measurement
)) {
81 ++SummaryData
.NumSummary
; // Count the number of major phases
83 else { // !IsPhase(...
84 if(Measurement
.Handle
== NULL
) {
85 ++SummaryData
.NumGlobal
;
89 if (AsciiStrnCmp (Measurement
.Token
, ALit_PEIM
, PERF_TOKEN_LENGTH
) == 0) {
90 ++SummaryData
.NumPEIMs
; // Count PEIM measurements
93 Duration
= GetDuration (&Measurement
);
94 TIndex
= GetCumulativeItem (&Measurement
);
96 CumData
[TIndex
].Duration
+= Duration
;
97 CumData
[TIndex
].Count
++;
98 if ( Duration
< CumData
[TIndex
].MinDur
) {
99 CumData
[TIndex
].MinDur
= Duration
;
101 if ( Duration
> CumData
[TIndex
].MaxDur
) {
102 CumData
[TIndex
].MaxDur
= Duration
;
107 // Collect the data for custom cumulative data.
109 if ((CustomCumulativeData
!= NULL
) && (AsciiStrCmp (Measurement
.Token
, CustomCumulativeData
->Name
) == 0)) {
110 CustomCumulativeData
->Duration
+= Duration
;
111 CustomCumulativeData
->Count
++;
112 if (Duration
< CustomCumulativeData
->MinDur
) {
113 CustomCumulativeData
->MinDur
= Duration
;
115 if (Duration
> CustomCumulativeData
->MaxDur
) {
116 CustomCumulativeData
->MaxDur
= Duration
;
123 Gather and print ALL Trace Records.
125 Displays all "interesting" Trace measurements in order.<BR>
126 The number of records displayed is controlled by:
127 - records with a duration less than mInterestThreshold microseconds are not displayed.
128 - No more than Limit records are displayed. A Limit of zero will not limit the output.
129 - If the ExcludeFlag is TRUE, records matching entries in the CumData array are not
132 @pre The mInterestThreshold global variable is set to the shortest duration to be printed.
133 The mGaugeString and mUnicodeToken global arrays are used for temporary string storage.
134 They must not be in use by a calling function.
136 @param[in] Limit The number of records to print. Zero is ALL.
137 @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.
143 IN BOOLEAN ExcludeFlag
146 MEASUREMENT_RECORD Measurement
;
149 const CHAR16
*IncFlag
;
155 EFI_HANDLE
*HandleBuffer
;
158 EFI_STRING StringPtrUnknown
;
160 StringPtrUnknown
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_ALIT_UNKNOWN
), NULL
);
161 IncFlag
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_SECTION_ALL
), NULL
);
162 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER
),
163 (IncFlag
== NULL
) ? StringPtrUnknown
: IncFlag
);
164 FreePool (StringPtrUnknown
);
166 // Get Handle information
168 Status
= gBS
->LocateHandleBuffer (AllHandles
, NULL
, NULL
, &HandleCount
, &HandleBuffer
);
169 if (EFI_ERROR (Status
)) {
170 PrintToken (STRING_TOKEN (STR_DP_HANDLES_ERROR
), Status
);
173 // We have successfully populated the HandleBuffer
174 // Display ALL Measurement Records
175 // Up to Limit lines displayed
176 // Display only records with Elapsed times >= mInterestThreshold
177 // Display driver names in Module field for records with Handles.
180 PrintToken (STRING_TOKEN (STR_DP_ALL_HEADR2
) );
181 PrintToken (STRING_TOKEN (STR_DP_ALL_DASHES2
) );
183 PrintToken (STRING_TOKEN (STR_DP_ALL_HEADR
) );
184 PrintToken (STRING_TOKEN (STR_DP_DASHES
) );
190 while ( WITHIN_LIMIT(Count
, Limit
) &&
191 ((LogEntryKey
= GetPerformanceMeasurementEx (
196 &Measurement
.StartTimeStamp
,
197 &Measurement
.EndTimeStamp
,
198 &Measurement
.Identifier
)) != 0)
201 ++Index
; // Count every record. First record is 1.
203 SafeFreePool ((VOID
*) IncFlag
);
204 if (Measurement
.EndTimeStamp
!= 0) {
205 Duration
= GetDuration (&Measurement
);
206 ElapsedTime
= DurationInMicroSeconds ( Duration
);
207 IncFlag
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_COMPLETE
), NULL
);
210 IncFlag
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_INCOMPLETE
), NULL
); // Mark incomplete records
212 if (((Measurement
.EndTimeStamp
!= 0) && (ElapsedTime
< mInterestThreshold
)) ||
213 ((ExcludeFlag
) && (GetCumulativeItem(&Measurement
) >= 0))
214 ) { // Ignore "uninteresting" or excluded records
217 ++Count
; // Count the number of records printed
219 // If Handle is non-zero, see if we can determine a name for the driver
220 AsciiStrToUnicodeStr (Measurement
.Module
, mGaugeString
); // Use Module by default
221 AsciiStrToUnicodeStr (Measurement
.Token
, mUnicodeToken
);
222 if (Measurement
.Handle
!= NULL
) {
223 // See if the Handle is in the HandleBuffer
224 for (TIndex
= 0; TIndex
< HandleCount
; TIndex
++) {
225 if (Measurement
.Handle
== HandleBuffer
[TIndex
]) {
226 GetNameFromHandle (HandleBuffer
[TIndex
]);
232 if (AsciiStrnCmp (Measurement
.Token
, ALit_PEIM
, PERF_TOKEN_LENGTH
) == 0) {
233 UnicodeSPrint (mGaugeString
, sizeof (mGaugeString
), L
"%g", Measurement
.Handle
);
236 // Ensure that the argument strings are not too long.
237 mGaugeString
[DP_GAUGE_STRING_LENGTH
] = 0;
238 mUnicodeToken
[13] = 0;
241 PrintToken( STRING_TOKEN (STR_DP_ALL_VARS2
),
242 Index
, // 1 based, Which measurement record is being printed
248 Measurement
.Identifier
251 PrintToken( STRING_TOKEN (STR_DP_ALL_VARS
),
252 Index
, // 1 based, Which measurement record is being printed
262 if (HandleBuffer
!= NULL
) {
263 FreePool (HandleBuffer
);
265 SafeFreePool ((VOID
*) IncFlag
);
269 Gather and print Raw Trace Records.
271 All Trace measurements with a duration greater than or equal to
272 mInterestThreshold are printed without interpretation.
274 The number of records displayed is controlled by:
275 - records with a duration less than mInterestThreshold microseconds are not displayed.
276 - No more than Limit records are displayed. A Limit of zero will not limit the output.
277 - If the ExcludeFlag is TRUE, records matching entries in the CumData array are not
280 @pre The mInterestThreshold global variable is set to the shortest duration to be printed.
282 @param[in] Limit The number of records to print. Zero is ALL.
283 @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.
289 IN BOOLEAN ExcludeFlag
292 MEASUREMENT_RECORD Measurement
;
299 EFI_STRING StringPtr
;
300 EFI_STRING StringPtrUnknown
;
302 StringPtrUnknown
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_ALIT_UNKNOWN
), NULL
);
303 StringPtr
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_SECTION_RAWTRACE
), NULL
);
304 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER
),
305 (StringPtr
== NULL
) ? StringPtrUnknown
: StringPtr
);
306 FreePool (StringPtr
);
307 FreePool (StringPtrUnknown
);
310 PrintToken (STRING_TOKEN (STR_DP_RAW_HEADR2
) );
311 PrintToken (STRING_TOKEN (STR_DP_RAW_DASHES2
) );
313 PrintToken (STRING_TOKEN (STR_DP_RAW_HEADR
) );
314 PrintToken (STRING_TOKEN (STR_DP_RAW_DASHES
) );
320 while ( WITHIN_LIMIT(Count
, Limit
) &&
321 ((LogEntryKey
= GetPerformanceMeasurementEx (
326 &Measurement
.StartTimeStamp
,
327 &Measurement
.EndTimeStamp
,
328 &Measurement
.Identifier
)) != 0)
331 ++Index
; // Count every record. First record is 1.
333 if (Measurement
.EndTimeStamp
!= 0) {
334 Duration
= GetDuration (&Measurement
);
335 ElapsedTime
= DurationInMicroSeconds ( Duration
);
337 if ((ElapsedTime
< mInterestThreshold
) ||
338 ((ExcludeFlag
) && (GetCumulativeItem(&Measurement
) >= 0))
339 ) { // Ignore "uninteresting" or Excluded records
342 ++Count
; // Count the number of records printed
345 PrintToken (STRING_TOKEN (STR_DP_RAW_VARS2
),
346 Index
, // 1 based, Which measurement record is being printed
348 Measurement
.StartTimeStamp
,
349 Measurement
.EndTimeStamp
,
352 Measurement
.Identifier
355 PrintToken (STRING_TOKEN (STR_DP_RAW_VARS
),
356 Index
, // 1 based, Which measurement record is being printed
358 Measurement
.StartTimeStamp
,
359 Measurement
.EndTimeStamp
,
368 Gather and print Major Phase metrics.
370 @param[in] Ticker The timer value for the END of Shell phase
378 MEASUREMENT_RECORD Measurement
;
379 UINT64 BdsTimeoutValue
;
388 EFI_STRING StringPtr
;
390 EFI_STRING StringPtrUnknown
;
399 // Get Execution Phase Statistics
401 StringPtrUnknown
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_ALIT_UNKNOWN
), NULL
);
402 StringPtr
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_SECTION_PHASES
), NULL
);
403 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER
),
404 (StringPtr
== NULL
) ? StringPtrUnknown
: StringPtr
);
405 FreePool (StringPtr
);
406 FreePool (StringPtrUnknown
);
409 while ((LogEntryKey
= GetPerformanceMeasurementEx (
414 &Measurement
.StartTimeStamp
,
415 &Measurement
.EndTimeStamp
,
416 &Measurement
.Identifier
)) != 0)
418 if (AsciiStrnCmp (Measurement
.Token
, ALit_SHELL
, PERF_TOKEN_LENGTH
) == 0) {
419 Measurement
.EndTimeStamp
= Ticker
;
421 if (Measurement
.EndTimeStamp
== 0) { // Skip "incomplete" records
424 Duration
= GetDuration (&Measurement
);
425 if ( Measurement
.Handle
!= NULL
426 && (AsciiStrnCmp (Measurement
.Token
, ALit_BdsTO
, PERF_TOKEN_LENGTH
) == 0)
429 BdsTimeoutValue
= Duration
;
430 } else if (AsciiStrnCmp (Measurement
.Token
, ALit_SEC
, PERF_TOKEN_LENGTH
) == 0) {
432 } else if (AsciiStrnCmp (Measurement
.Token
, ALit_PEI
, PERF_TOKEN_LENGTH
) == 0) {
434 } else if (AsciiStrnCmp (Measurement
.Token
, ALit_DXE
, PERF_TOKEN_LENGTH
) == 0) {
436 } else if (AsciiStrnCmp (Measurement
.Token
, ALit_BDS
, PERF_TOKEN_LENGTH
) == 0) {
438 } else if (AsciiStrnCmp (Measurement
.Token
, ALit_SHELL
, PERF_TOKEN_LENGTH
) == 0) {
439 ShellTime
= Duration
;
445 // print SEC phase duration time
448 ElapsedTime
= DurationInMicroSeconds ( SecTime
); // Calculate elapsed time in microseconds
449 Total
+= DivU64x32 (ElapsedTime
, 1000); // Accumulate time in milliseconds
450 PrintToken (STRING_TOKEN (STR_DP_SEC_PHASE
), ElapsedTime
);
453 // print PEI phase duration time
456 ElapsedTime
= DivU64x32 (
458 (UINT32
)TimerInfo
.Frequency
460 Total
+= ElapsedTime
;
461 PrintToken (STRING_TOKEN (STR_DP_PHASE_DURATION
), ALit_PEI
, ElapsedTime
);
464 // print DXE phase duration time
467 ElapsedTime
= DivU64x32 (
469 (UINT32
)TimerInfo
.Frequency
471 Total
+= ElapsedTime
;
472 PrintToken (STRING_TOKEN (STR_DP_PHASE_DURATION
), ALit_DXE
, ElapsedTime
);
475 // print BDS phase duration time
478 ElapsedTime
= DivU64x32 (
480 (UINT32
)TimerInfo
.Frequency
482 Total
+= ElapsedTime
;
483 PrintToken (STRING_TOKEN (STR_DP_PHASE_DURATION
), ALit_BDS
, ElapsedTime
);
486 if (BdsTimeoutValue
> 0) {
487 ElapsedTime
= DivU64x32 (
489 (UINT32
)TimerInfo
.Frequency
491 PrintToken (STRING_TOKEN (STR_DP_PHASE_BDSTO
), ALit_BdsTO
, ElapsedTime
);
494 // print SHELL phase duration time
497 ElapsedTime
= DivU64x32 (
499 (UINT32
)TimerInfo
.Frequency
501 Total
+= ElapsedTime
;
502 PrintToken (STRING_TOKEN (STR_DP_PHASE_DURATION
), ALit_SHELL
, ElapsedTime
);
505 PrintToken (STRING_TOKEN (STR_DP_TOTAL_DURATION
), Total
);
509 Gather and print Handle data.
511 @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.
513 @return Status from a call to gBS->LocateHandle().
517 IN BOOLEAN ExcludeFlag
520 MEASUREMENT_RECORD Measurement
;
523 EFI_HANDLE
*HandleBuffer
;
524 EFI_STRING StringPtr
;
530 EFI_STRING StringPtrUnknown
;
532 StringPtrUnknown
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_ALIT_UNKNOWN
), NULL
);
533 StringPtr
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_SECTION_DRIVERS
), NULL
);
534 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER
),
535 (StringPtr
== NULL
) ? StringPtrUnknown
: StringPtr
);
536 FreePool (StringPtr
);
537 FreePool (StringPtrUnknown
);
539 Status
= gBS
->LocateHandleBuffer (AllHandles
, NULL
, NULL
, &HandleCount
, &HandleBuffer
);
540 if (EFI_ERROR (Status
)) {
541 PrintToken (STRING_TOKEN (STR_DP_HANDLES_ERROR
), Status
);
545 Print (L
"There are %,d Handles defined.\n", (Size
/ sizeof(HandleBuffer
[0])));
549 PrintToken (STRING_TOKEN (STR_DP_HANDLE_SECTION2
) );
551 PrintToken (STRING_TOKEN (STR_DP_HANDLE_SECTION
) );
553 PrintToken (STRING_TOKEN (STR_DP_DASHES
) );
557 while ((LogEntryKey
= GetPerformanceMeasurementEx (
562 &Measurement
.StartTimeStamp
,
563 &Measurement
.EndTimeStamp
,
564 &Measurement
.Identifier
)) != 0)
567 Duration
= GetDuration (&Measurement
);
568 ElapsedTime
= DurationInMicroSeconds ( Duration
);
569 if ((ElapsedTime
< mInterestThreshold
) ||
570 (Measurement
.EndTimeStamp
== 0) ||
571 (Measurement
.Handle
== NULL
) ||
572 ((ExcludeFlag
) && (GetCumulativeItem(&Measurement
) >= 0))
573 ) { // Ignore "uninteresting" or excluded records
576 mGaugeString
[0] = 0; // Empty driver name by default
577 AsciiStrToUnicodeStr (Measurement
.Token
, mUnicodeToken
);
578 // See if the Handle is in the HandleBuffer
579 for (Index
= 0; Index
< HandleCount
; Index
++) {
580 if (Measurement
.Handle
== HandleBuffer
[Index
]) {
581 GetNameFromHandle (HandleBuffer
[Index
]); // Name is put into mGaugeString
585 // Ensure that the argument strings are not too long.
586 mGaugeString
[DP_GAUGE_STRING_LENGTH
] = 0;
587 mUnicodeToken
[11] = 0;
588 if (mGaugeString
[0] != 0) {
589 // Display the record if it has a valid handle.
592 STRING_TOKEN (STR_DP_HANDLE_VARS2
),
593 Count
, // 1 based, Which measurement record is being printed
594 Index
+ 1, // 1 based, Which handle is being printed
598 Measurement
.Identifier
602 STRING_TOKEN (STR_DP_HANDLE_VARS
),
603 Count
, // 1 based, Which measurement record is being printed
604 Index
+ 1, // 1 based, Which handle is being printed
613 if (HandleBuffer
!= NULL
) {
614 FreePool (HandleBuffer
);
620 Gather and print PEIM data.
622 Only prints complete PEIM records
630 MEASUREMENT_RECORD Measurement
;
633 EFI_STRING StringPtr
;
636 EFI_STRING StringPtrUnknown
;
638 StringPtrUnknown
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_ALIT_UNKNOWN
), NULL
);
639 StringPtr
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_SECTION_PEIMS
), NULL
);
640 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER
),
641 (StringPtr
== NULL
) ? StringPtrUnknown
: StringPtr
);
642 FreePool (StringPtr
);
643 FreePool (StringPtrUnknown
);
646 PrintToken (STRING_TOKEN (STR_DP_PEIM_SECTION2
));
648 PrintToken (STRING_TOKEN (STR_DP_PEIM_SECTION
));
650 PrintToken (STRING_TOKEN (STR_DP_DASHES
));
653 while ((LogEntryKey
= GetPerformanceMeasurementEx (
658 &Measurement
.StartTimeStamp
,
659 &Measurement
.EndTimeStamp
,
660 &Measurement
.Identifier
)) != 0)
663 if ((Measurement
.EndTimeStamp
== 0) ||
664 (AsciiStrnCmp (Measurement
.Token
, ALit_PEIM
, PERF_TOKEN_LENGTH
) != 0)
669 Duration
= GetDuration (&Measurement
);
670 ElapsedTime
= DurationInMicroSeconds ( Duration
); // Calculate elapsed time in microseconds
671 if (ElapsedTime
>= mInterestThreshold
) {
672 // PEIM FILE Handle is the start address of its FFS file that contains its file guid.
674 PrintToken (STRING_TOKEN (STR_DP_PEIM_VARS2
),
675 TIndex
, // 1 based, Which measurement record is being printed
676 Measurement
.Handle
, // base address
677 Measurement
.Handle
, // file guid
679 Measurement
.Identifier
682 PrintToken (STRING_TOKEN (STR_DP_PEIM_VARS
),
683 TIndex
, // 1 based, Which measurement record is being printed
684 Measurement
.Handle
, // base address
685 Measurement
.Handle
, // file guid
694 Gather and print global data.
696 Strips out incomplete or "Execution Phase" records
697 Only prints records where Handle is NULL
698 Increment TIndex for every record, even skipped ones, so that we have an
699 indication of every measurement record taken.
707 MEASUREMENT_RECORD Measurement
;
710 EFI_STRING StringPtr
;
712 UINTN Index
; // Index, or number, of the measurement record being processed
713 EFI_STRING StringPtrUnknown
;
715 StringPtrUnknown
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_ALIT_UNKNOWN
), NULL
);
716 StringPtr
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_SECTION_GENERAL
), NULL
);
717 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER
),
718 (StringPtr
== NULL
) ? StringPtrUnknown
: StringPtr
);
719 FreePool (StringPtr
);
720 FreePool (StringPtrUnknown
);
723 PrintToken (STRING_TOKEN (STR_DP_GLOBAL_SECTION2
));
725 PrintToken (STRING_TOKEN (STR_DP_GLOBAL_SECTION
));
727 PrintToken (STRING_TOKEN (STR_DP_DASHES
));
732 while ((LogEntryKey
= GetPerformanceMeasurementEx (
737 &Measurement
.StartTimeStamp
,
738 &Measurement
.EndTimeStamp
,
739 &Measurement
.Identifier
)) != 0)
741 AsciiStrToUnicodeStr (Measurement
.Module
, mGaugeString
);
742 AsciiStrToUnicodeStr (Measurement
.Token
, mUnicodeToken
);
743 mGaugeString
[25] = 0;
744 mUnicodeToken
[31] = 0;
745 if ( ! ( IsPhase( &Measurement
) ||
746 (Measurement
.Handle
!= NULL
) ||
747 (Measurement
.EndTimeStamp
== 0)
750 Duration
= GetDuration (&Measurement
);
751 ElapsedTime
= DurationInMicroSeconds ( Duration
);
752 if (ElapsedTime
>= mInterestThreshold
) {
755 STRING_TOKEN (STR_DP_GLOBAL_VARS2
),
760 Measurement
.Identifier
764 STRING_TOKEN (STR_DP_GLOBAL_VARS
),
778 Gather and print cumulative data.
780 Traverse the measurement records and:<BR>
781 For each record with a Token listed in the CumData array:<BR>
782 - Update the instance count and the total, minimum, and maximum durations.
783 Finally, print the gathered cumulative statistics.
785 @param[in] CustomCumulativeData A pointer to the cumtom cumulative data.
790 IN PERF_CUM_DATA
*CustomCumulativeData OPTIONAL
793 UINT64 AvgDur
; // the computed average duration
797 EFI_STRING StringPtr
;
799 EFI_STRING StringPtrUnknown
;
801 StringPtrUnknown
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_ALIT_UNKNOWN
), NULL
);
802 StringPtr
= HiiGetString (gHiiHandle
, STRING_TOKEN (STR_DP_SECTION_CUMULATIVE
), NULL
);
803 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER
),
804 (StringPtr
== NULL
) ? StringPtrUnknown
: StringPtr
);
805 FreePool (StringPtr
);
806 FreePool (StringPtrUnknown
);
808 PrintToken (STRING_TOKEN (STR_DP_CUMULATIVE_SECT_1
));
809 PrintToken (STRING_TOKEN (STR_DP_CUMULATIVE_SECT_2
));
810 PrintToken (STRING_TOKEN (STR_DP_DASHES
));
812 for ( TIndex
= 0; TIndex
< NumCum
; ++TIndex
) {
813 if (CumData
[TIndex
].Count
!= 0) {
814 AvgDur
= DivU64x32 (CumData
[TIndex
].Duration
, CumData
[TIndex
].Count
);
815 AvgDur
= DurationInMicroSeconds(AvgDur
);
816 Dur
= DurationInMicroSeconds(CumData
[TIndex
].Duration
);
817 MaxDur
= DurationInMicroSeconds(CumData
[TIndex
].MaxDur
);
818 MinDur
= DurationInMicroSeconds(CumData
[TIndex
].MinDur
);
820 PrintToken (STRING_TOKEN (STR_DP_CUMULATIVE_STATS
),
821 CumData
[TIndex
].Name
,
822 CumData
[TIndex
].Count
,
832 // Print the custom cumulative data.
834 if (CustomCumulativeData
!= NULL
) {
835 if (CustomCumulativeData
->Count
!= 0) {
836 AvgDur
= DivU64x32 (CustomCumulativeData
->Duration
, CustomCumulativeData
->Count
);
837 AvgDur
= DurationInMicroSeconds (AvgDur
);
838 Dur
= DurationInMicroSeconds (CustomCumulativeData
->Duration
);
839 MaxDur
= DurationInMicroSeconds (CustomCumulativeData
->MaxDur
);
840 MinDur
= DurationInMicroSeconds (CustomCumulativeData
->MinDur
);
847 PrintToken (STRING_TOKEN (STR_DP_CUMULATIVE_STATS
),
848 CustomCumulativeData
->Name
,
849 CustomCumulativeData
->Count
,