]> git.proxmox.com Git - mirror_edk2.git/blob - PerformancePkg/Dp_App/DpTrace.c
Update DP to get Image name with the following methods orderly.
[mirror_edk2.git] / PerformancePkg / Dp_App / DpTrace.c
1 /** @file
2 * Trace reporting for the Dp utility.
3 *
4 * Copyright (c) 2009 - 2011, 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 (((Measurement.EndTimeStamp != 0) && (ElapsedTime < mInterestThreshold)) ||
201 ((ExcludeFlag) && (GetCumulativeItem(&Measurement) >= 0))
202 ) { // Ignore "uninteresting" or excluded records
203 continue;
204 }
205 ++Count; // Count the number of records printed
206
207 // If Handle is non-zero, see if we can determine a name for the driver
208 AsciiStrToUnicodeStr (Measurement.Module, mGaugeString); // Use Module by default
209 AsciiStrToUnicodeStr (Measurement.Token, mUnicodeToken);
210 if (Measurement.Handle != NULL) {
211 // See if the Handle is in the HandleBuffer
212 for (TIndex = 0; TIndex < (Size / sizeof(HandleBuffer[0])); TIndex++) {
213 if (Measurement.Handle == HandleBuffer[TIndex]) {
214 GetNameFromHandle (HandleBuffer[TIndex]);
215 break;
216 }
217 }
218 }
219
220 if (AsciiStrnCmp (Measurement.Token, ALit_PEIM, PERF_TOKEN_LENGTH) == 0) {
221 UnicodeSPrint (mGaugeString, sizeof (mGaugeString), L"%g", Measurement.Handle);
222 }
223
224 // Ensure that the argument strings are not too long.
225 mGaugeString[DP_GAUGE_STRING_LENGTH] = 0;
226 mUnicodeToken[13] = 0;
227
228 PrintToken( STRING_TOKEN (STR_DP_ALL_VARS),
229 Index, // 1 based, Which measurement record is being printed
230 IncFlag,
231 Measurement.Handle,
232 mGaugeString,
233 mUnicodeToken,
234 ElapsedTime
235 );
236 }
237 }
238 if (HandleBuffer != &TempHandle) {
239 FreePool (HandleBuffer);
240 }
241 FreePool ((void *)IncFlag);
242 }
243
244 /**
245 Gather and print Raw Trace Records.
246
247 All Trace measurements with a duration greater than or equal to
248 mInterestThreshold are printed without interpretation.
249
250 The number of records displayed is controlled by:
251 - records with a duration less than mInterestThreshold microseconds are not displayed.
252 - No more than Limit records are displayed. A Limit of zero will not limit the output.
253 - If the ExcludeFlag is TRUE, records matching entries in the CumData array are not
254 displayed.
255
256 @pre The mInterestThreshold global variable is set to the shortest duration to be printed.
257
258 @param[in] Limit The number of records to print. Zero is ALL.
259 @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.
260
261 **/
262 VOID
263 DumpRawTrace(
264 IN UINTN Limit,
265 IN BOOLEAN ExcludeFlag
266 )
267 {
268 MEASUREMENT_RECORD Measurement;
269 UINT64 ElapsedTime;
270 UINT64 Duration;
271 UINTN LogEntryKey;
272 UINTN Count;
273 UINTN Index;
274
275 EFI_STRING StringPtr;
276 EFI_STRING StringPtrUnknown;
277
278 StringPtrUnknown = HiiGetString (gHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
279 StringPtr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_RAWTRACE), NULL);
280 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),
281 (StringPtr == NULL) ? StringPtrUnknown : StringPtr);
282 FreePool (StringPtr);
283 FreePool (StringPtrUnknown);
284
285 PrintToken (STRING_TOKEN (STR_DP_RAW_HEADR) );
286 PrintToken (STRING_TOKEN (STR_DP_RAW_DASHES) );
287
288 LogEntryKey = 0;
289 Count = 0;
290 Index = 0;
291 while ( WITHIN_LIMIT(Count, Limit) &&
292 ((LogEntryKey = GetPerformanceMeasurement (
293 LogEntryKey,
294 &Measurement.Handle,
295 &Measurement.Token,
296 &Measurement.Module,
297 &Measurement.StartTimeStamp,
298 &Measurement.EndTimeStamp)) != 0)
299 )
300 {
301 ++Index; // Count every record. First record is 1.
302 ElapsedTime = 0;
303 if (Measurement.EndTimeStamp != 0) {
304 Duration = GetDuration (&Measurement);
305 ElapsedTime = DurationInMicroSeconds ( Duration );
306 }
307 if ((ElapsedTime < mInterestThreshold) ||
308 ((ExcludeFlag) && (GetCumulativeItem(&Measurement) >= 0))
309 ) { // Ignore "uninteresting" or Excluded records
310 continue;
311 }
312 ++Count; // Count the number of records printed
313 PrintToken (STRING_TOKEN (STR_DP_RAW_VARS),
314 Index, // 1 based, Which measurement record is being printed
315 Measurement.Handle,
316 Measurement.StartTimeStamp,
317 Measurement.EndTimeStamp,
318 Measurement.Token,
319 Measurement.Module
320 );
321 }
322 }
323
324 /**
325 Gather and print Major Phase metrics.
326
327 @param[in] Ticker The timer value for the END of Shell phase
328
329 **/
330 VOID
331 ProcessPhases(
332 IN UINT64 Ticker
333 )
334 {
335 MEASUREMENT_RECORD Measurement;
336 UINT64 BdsTimeoutValue;
337 UINT64 SecTime;
338 UINT64 PeiTime;
339 UINT64 DxeTime;
340 UINT64 BdsTime;
341 UINT64 ShellTime;
342 UINT64 ElapsedTime;
343 UINT64 Duration;
344 UINT64 Total;
345 EFI_STRING StringPtr;
346 UINTN LogEntryKey;
347 EFI_STRING StringPtrUnknown;
348
349 BdsTimeoutValue = 0;
350 SecTime = 0;
351 PeiTime = 0;
352 DxeTime = 0;
353 BdsTime = 0;
354 ShellTime = 0;
355 //
356 // Get Execution Phase Statistics
357 //
358 StringPtrUnknown = HiiGetString (gHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
359 StringPtr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_PHASES), NULL);
360 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),
361 (StringPtr == NULL) ? StringPtrUnknown : StringPtr);
362 FreePool (StringPtr);
363 FreePool (StringPtrUnknown);
364
365 LogEntryKey = 0;
366 while ((LogEntryKey = GetPerformanceMeasurement (
367 LogEntryKey,
368 &Measurement.Handle,
369 &Measurement.Token,
370 &Measurement.Module,
371 &Measurement.StartTimeStamp,
372 &Measurement.EndTimeStamp)) != 0)
373 {
374 if (AsciiStrnCmp (Measurement.Token, ALit_SHELL, PERF_TOKEN_LENGTH) == 0) {
375 Measurement.EndTimeStamp = Ticker;
376 }
377 if (Measurement.EndTimeStamp == 0) { // Skip "incomplete" records
378 continue;
379 }
380 Duration = GetDuration (&Measurement);
381 if ( Measurement.Handle != NULL
382 && (AsciiStrnCmp (Measurement.Token, ALit_BdsTO, PERF_TOKEN_LENGTH) == 0)
383 )
384 {
385 BdsTimeoutValue = Duration;
386 } else if (AsciiStrnCmp (Measurement.Token, ALit_SEC, PERF_TOKEN_LENGTH) == 0) {
387 SecTime = Duration;
388 } else if (AsciiStrnCmp (Measurement.Token, ALit_PEI, PERF_TOKEN_LENGTH) == 0) {
389 PeiTime = Duration;
390 } else if (AsciiStrnCmp (Measurement.Token, ALit_DXE, PERF_TOKEN_LENGTH) == 0) {
391 DxeTime = Duration;
392 } else if (AsciiStrnCmp (Measurement.Token, ALit_BDS, PERF_TOKEN_LENGTH) == 0) {
393 BdsTime = Duration;
394 } else if (AsciiStrnCmp (Measurement.Token, ALit_SHELL, PERF_TOKEN_LENGTH) == 0) {
395 ShellTime = Duration;
396 }
397 }
398
399 Total = 0;
400
401 // print SEC phase duration time
402 //
403 if (SecTime > 0) {
404 ElapsedTime = DurationInMicroSeconds ( SecTime ); // Calculate elapsed time in microseconds
405 Total += DivU64x32 (ElapsedTime, 1000); // Accumulate time in milliseconds
406 PrintToken (STRING_TOKEN (STR_DP_SEC_PHASE), ElapsedTime);
407 }
408
409 // print PEI phase duration time
410 //
411 if (PeiTime > 0) {
412 ElapsedTime = DivU64x32 (
413 PeiTime,
414 (UINT32)TimerInfo.Frequency
415 );
416 Total += ElapsedTime;
417 PrintToken (STRING_TOKEN (STR_DP_PHASE_DURATION), ALit_PEI, ElapsedTime);
418 }
419
420 // print DXE phase duration time
421 //
422 if (DxeTime > 0) {
423 ElapsedTime = DivU64x32 (
424 DxeTime,
425 (UINT32)TimerInfo.Frequency
426 );
427 Total += ElapsedTime;
428 PrintToken (STRING_TOKEN (STR_DP_PHASE_DURATION), ALit_DXE, ElapsedTime);
429 }
430
431 // print BDS phase duration time
432 //
433 if (BdsTime > 0) {
434 ElapsedTime = DivU64x32 (
435 BdsTime,
436 (UINT32)TimerInfo.Frequency
437 );
438 Total += ElapsedTime;
439 PrintToken (STRING_TOKEN (STR_DP_PHASE_DURATION), ALit_BDS, ElapsedTime);
440 }
441
442 if (BdsTimeoutValue > 0) {
443 ElapsedTime = DivU64x32 (
444 BdsTimeoutValue,
445 (UINT32)TimerInfo.Frequency
446 );
447 PrintToken (STRING_TOKEN (STR_DP_PHASE_BDSTO), ALit_BdsTO, ElapsedTime);
448 }
449
450 // print SHELL phase duration time
451 //
452 if (ShellTime > 0) {
453 ElapsedTime = DivU64x32 (
454 ShellTime,
455 (UINT32)TimerInfo.Frequency
456 );
457 Total += ElapsedTime;
458 PrintToken (STRING_TOKEN (STR_DP_PHASE_DURATION), ALit_SHELL, ElapsedTime);
459 }
460
461 PrintToken (STRING_TOKEN (STR_DP_TOTAL_DURATION), Total);
462 }
463
464 /**
465 Gather and print Handle data.
466
467 @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.
468
469 @return Status from a call to gBS->LocateHandle().
470 **/
471 EFI_STATUS
472 ProcessHandles(
473 IN BOOLEAN ExcludeFlag
474 )
475 {
476 MEASUREMENT_RECORD Measurement;
477 UINT64 ElapsedTime;
478 UINT64 Duration;
479 EFI_HANDLE *HandleBuffer;
480 EFI_STRING StringPtr;
481 UINTN Index;
482 UINTN LogEntryKey;
483 UINTN Count;
484 UINTN Size;
485 EFI_HANDLE TempHandle;
486 EFI_STATUS Status;
487 EFI_STRING StringPtrUnknown;
488
489 StringPtrUnknown = HiiGetString (gHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
490 StringPtr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_DRIVERS), NULL);
491 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),
492 (StringPtr == NULL) ? StringPtrUnknown : StringPtr);
493 FreePool (StringPtr);
494 FreePool (StringPtrUnknown);
495
496 Size = 0;
497 HandleBuffer = &TempHandle;
498 Status = gBS->LocateHandle (AllHandles, NULL, NULL, &Size, &TempHandle);
499 if (Status == EFI_BUFFER_TOO_SMALL) {
500 HandleBuffer = AllocatePool (Size);
501 ASSERT (HandleBuffer != NULL);
502 if (HandleBuffer == NULL) {
503 return Status;
504 }
505 Status = gBS->LocateHandle (AllHandles, NULL, NULL, &Size, HandleBuffer);
506 }
507 if (EFI_ERROR (Status)) {
508 PrintToken (STRING_TOKEN (STR_DP_HANDLES_ERROR), Status);
509 }
510 else {
511 #if DP_DEBUG == 2
512 Print (L"There are %,d Handles defined.\n", (Size / sizeof(HandleBuffer[0])));
513 #endif
514
515 PrintToken (STRING_TOKEN (STR_DP_HANDLE_SECTION) );
516 PrintToken (STRING_TOKEN (STR_DP_DASHES) );
517
518 LogEntryKey = 0;
519 Count = 0;
520 while ((LogEntryKey = GetPerformanceMeasurement (
521 LogEntryKey,
522 &Measurement.Handle,
523 &Measurement.Token,
524 &Measurement.Module,
525 &Measurement.StartTimeStamp,
526 &Measurement.EndTimeStamp)) != 0)
527 {
528 Count++;
529 Duration = GetDuration (&Measurement);
530 ElapsedTime = DurationInMicroSeconds ( Duration );
531 if ((ElapsedTime < mInterestThreshold) ||
532 (Measurement.EndTimeStamp == 0) ||
533 (Measurement.Handle == NULL) ||
534 ((ExcludeFlag) && (GetCumulativeItem(&Measurement) >= 0))
535 ) { // Ignore "uninteresting" or excluded records
536 continue;
537 }
538 mGaugeString[0] = 0; // Empty driver name by default
539 AsciiStrToUnicodeStr (Measurement.Token, mUnicodeToken);
540 // See if the Handle is in the HandleBuffer
541 for (Index = 0; Index < (Size / sizeof(HandleBuffer[0])); Index++) {
542 if (Measurement.Handle == HandleBuffer[Index]) {
543 GetNameFromHandle (HandleBuffer[Index]); // Name is put into mGaugeString
544 break;
545 }
546 }
547 // Ensure that the argument strings are not too long.
548 mGaugeString[DP_GAUGE_STRING_LENGTH] = 0;
549 mUnicodeToken[11] = 0;
550 if (mGaugeString[0] != 0) {
551 // Display the record if it has a valid handle.
552 PrintToken (
553 STRING_TOKEN (STR_DP_HANDLE_VARS),
554 Count, // 1 based, Which measurement record is being printed
555 Index + 1, // 1 based, Which handle is being printed
556 mGaugeString,
557 mUnicodeToken,
558 ElapsedTime
559 );
560 }
561 }
562 }
563 if (HandleBuffer != &TempHandle) {
564 FreePool (HandleBuffer);
565 }
566 return Status;
567 }
568
569 /**
570 Gather and print PEIM data.
571
572 Only prints complete PEIM records
573
574 **/
575 VOID
576 ProcessPeims(
577 VOID
578 )
579 {
580 MEASUREMENT_RECORD Measurement;
581 UINT64 Duration;
582 UINT64 ElapsedTime;
583 EFI_STRING StringPtr;
584 UINTN LogEntryKey;
585 UINTN TIndex;
586 EFI_STRING StringPtrUnknown;
587
588 StringPtrUnknown = HiiGetString (gHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
589 StringPtr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_PEIMS), NULL);
590 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),
591 (StringPtr == NULL) ? StringPtrUnknown : StringPtr);
592 FreePool (StringPtr);
593 FreePool (StringPtrUnknown);
594
595 PrintToken (STRING_TOKEN (STR_DP_PEIM_SECTION));
596 PrintToken (STRING_TOKEN (STR_DP_DASHES));
597 TIndex = 0;
598 LogEntryKey = 0;
599 while ((LogEntryKey = GetPerformanceMeasurement (
600 LogEntryKey,
601 &Measurement.Handle,
602 &Measurement.Token,
603 &Measurement.Module,
604 &Measurement.StartTimeStamp,
605 &Measurement.EndTimeStamp)) != 0)
606 {
607 TIndex++;
608 if ((Measurement.EndTimeStamp == 0) ||
609 (AsciiStrnCmp (Measurement.Token, ALit_PEIM, PERF_TOKEN_LENGTH) != 0)
610 ) {
611 continue;
612 }
613
614 Duration = GetDuration (&Measurement);
615 ElapsedTime = DurationInMicroSeconds ( Duration ); // Calculate elapsed time in microseconds
616 if (ElapsedTime >= mInterestThreshold) {
617 // PEIM FILE Handle is the start address of its FFS file that contains its file guid.
618 PrintToken (STRING_TOKEN (STR_DP_PEIM_VARS),
619 TIndex, // 1 based, Which measurement record is being printed
620 Measurement.Handle, // base address
621 Measurement.Handle, // file guid
622 ElapsedTime
623 );
624 }
625 }
626 }
627
628 /**
629 Gather and print global data.
630
631 Strips out incomplete or "Execution Phase" records
632 Only prints records where Handle is NULL
633 Increment TIndex for every record, even skipped ones, so that we have an
634 indication of every measurement record taken.
635
636 **/
637 VOID
638 ProcessGlobal(
639 VOID
640 )
641 {
642 MEASUREMENT_RECORD Measurement;
643 UINT64 Duration;
644 UINT64 ElapsedTime;
645 EFI_STRING StringPtr;
646 UINTN LogEntryKey;
647 UINTN Index; // Index, or number, of the measurement record being processed
648 EFI_STRING StringPtrUnknown;
649
650 StringPtrUnknown = HiiGetString (gHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
651 StringPtr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_GENERAL), NULL);
652 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),
653 (StringPtr == NULL) ? StringPtrUnknown: StringPtr);
654 FreePool (StringPtr);
655 FreePool (StringPtrUnknown);
656
657 PrintToken (STRING_TOKEN (STR_DP_GLOBAL_SECTION));
658 PrintToken (STRING_TOKEN (STR_DP_DASHES));
659
660 Index = 1;
661 LogEntryKey = 0;
662
663 while ((LogEntryKey = GetPerformanceMeasurement (
664 LogEntryKey,
665 &Measurement.Handle,
666 &Measurement.Token,
667 &Measurement.Module,
668 &Measurement.StartTimeStamp,
669 &Measurement.EndTimeStamp)) != 0)
670 {
671 AsciiStrToUnicodeStr (Measurement.Module, mGaugeString);
672 AsciiStrToUnicodeStr (Measurement.Token, mUnicodeToken);
673 mGaugeString[26] = 0;
674 mUnicodeToken[31] = 0;
675 if ( ! ( IsPhase( &Measurement) ||
676 (Measurement.Handle != NULL) ||
677 (Measurement.EndTimeStamp == 0)
678 ))
679 {
680 Duration = GetDuration (&Measurement);
681 ElapsedTime = DurationInMicroSeconds ( Duration );
682 if (ElapsedTime >= mInterestThreshold) {
683 PrintToken (
684 STRING_TOKEN (STR_DP_GLOBAL_VARS),
685 Index,
686 mGaugeString,
687 mUnicodeToken,
688 ElapsedTime
689 );
690 }
691 }
692 Index++;
693 }
694 }
695
696 /**
697 Gather and print cumulative data.
698
699 Traverse the measurement records and:<BR>
700 For each record with a Token listed in the CumData array:<BR>
701 - Update the instance count and the total, minimum, and maximum durations.
702 Finally, print the gathered cumulative statistics.
703
704 **/
705 VOID
706 ProcessCumulative(
707 VOID
708 )
709 {
710 UINT64 AvgDur; // the computed average duration
711 UINT64 Dur;
712 UINT64 MinDur;
713 UINT64 MaxDur;
714 EFI_STRING StringPtr;
715 UINTN TIndex;
716 EFI_STRING StringPtrUnknown;
717
718 StringPtrUnknown = HiiGetString (gHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
719 StringPtr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_CUMULATIVE), NULL);
720 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),
721 (StringPtr == NULL) ? StringPtrUnknown: StringPtr);
722 FreePool (StringPtr);
723 FreePool (StringPtrUnknown);
724
725 PrintToken (STRING_TOKEN (STR_DP_CUMULATIVE_SECT_1));
726 PrintToken (STRING_TOKEN (STR_DP_CUMULATIVE_SECT_2));
727 PrintToken (STRING_TOKEN (STR_DP_DASHES));
728
729 for ( TIndex = 0; TIndex < NumCum; ++TIndex) {
730 if (CumData[TIndex].Count != 0) {
731 AvgDur = DivU64x32 (CumData[TIndex].Duration, CumData[TIndex].Count);
732 AvgDur = DurationInMicroSeconds(AvgDur);
733 Dur = DurationInMicroSeconds(CumData[TIndex].Duration);
734 MaxDur = DurationInMicroSeconds(CumData[TIndex].MaxDur);
735 MinDur = DurationInMicroSeconds(CumData[TIndex].MinDur);
736
737 PrintToken (STRING_TOKEN (STR_DP_CUMULATIVE_STATS),
738 CumData[TIndex].Name,
739 CumData[TIndex].Count,
740 Dur,
741 AvgDur,
742 MinDur,
743 MaxDur
744 );
745 }
746 }
747 }