]> git.proxmox.com Git - mirror_edk2.git/blob - PerformancePkg/Dp_App/DpTrace.c
MdePkg: add missing #defines for decoding PCIe 2.1 extended capability structures
[mirror_edk2.git] / PerformancePkg / Dp_App / DpTrace.c
1 /** @file
2 Trace reporting for the Dp utility.
3
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
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 = GetPerformanceMeasurementEx (
58 LogEntryKey,
59 &Measurement.Handle,
60 &Measurement.Token,
61 &Measurement.Module,
62 &Measurement.StartTimeStamp,
63 &Measurement.EndTimeStamp,
64 &Measurement.Identifier)) != 0)
65 {
66 ++SummaryData.NumTrace; // Count the number of TRACE Measurement records
67 if (Measurement.EndTimeStamp == 0) {
68 ++SummaryData.NumIncomplete; // Count the incomplete records
69 continue;
70 }
71
72 if (Measurement.Handle != NULL) {
73 ++SummaryData.NumHandles; // Count the number of measurements with non-NULL handles
74 }
75
76 if (IsPhase( &Measurement)) {
77 ++SummaryData.NumSummary; // Count the number of major phases
78 }
79 else { // !IsPhase(...
80 if(Measurement.Handle == NULL) {
81 ++SummaryData.NumGlobal;
82 }
83 }
84
85 if (AsciiStrnCmp (Measurement.Token, ALit_PEIM, PERF_TOKEN_LENGTH) == 0) {
86 ++SummaryData.NumPEIMs; // Count PEIM measurements
87 }
88
89 Duration = GetDuration (&Measurement);
90 TIndex = GetCumulativeItem (&Measurement);
91 if (TIndex >= 0) {
92 CumData[TIndex].Duration += Duration;
93 CumData[TIndex].Count++;
94 if ( Duration < CumData[TIndex].MinDur ) {
95 CumData[TIndex].MinDur = Duration;
96 }
97 if ( Duration > CumData[TIndex].MaxDur ) {
98 CumData[TIndex].MaxDur = Duration;
99 }
100 }
101 }
102 }
103
104 /**
105 Gather and print ALL Trace Records.
106
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
112 displayed.
113
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.
117
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.
120
121 **/
122 VOID
123 DumpAllTrace(
124 IN UINTN Limit,
125 IN BOOLEAN ExcludeFlag
126 )
127 {
128 MEASUREMENT_RECORD Measurement;
129 UINT64 ElapsedTime;
130 UINT64 Duration;
131 const CHAR16 *IncFlag;
132 UINTN LogEntryKey;
133 UINTN Count;
134 UINTN Index;
135 UINTN TIndex;
136
137 EFI_HANDLE *HandleBuffer;
138 UINTN Size;
139 EFI_HANDLE TempHandle;
140 EFI_STATUS Status;
141 EFI_STRING StringPtrUnknown;
142
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);
148
149 // Get Handle information
150 //
151 Size = 0;
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) {
158 return;
159 }
160 Status = gBS->LocateHandle (AllHandles, NULL, NULL, &Size, HandleBuffer);
161 }
162 if (EFI_ERROR (Status)) {
163 PrintToken (STRING_TOKEN (STR_DP_HANDLES_ERROR), Status);
164 }
165 else {
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.
171 //
172 if (mShowId) {
173 PrintToken (STRING_TOKEN (STR_DP_ALL_HEADR2) );
174 PrintToken (STRING_TOKEN (STR_DP_ALL_DASHES2) );
175 } else {
176 PrintToken (STRING_TOKEN (STR_DP_ALL_HEADR) );
177 PrintToken (STRING_TOKEN (STR_DP_DASHES) );
178 }
179
180 LogEntryKey = 0;
181 Count = 0;
182 Index = 0;
183 while ( WITHIN_LIMIT(Count, Limit) &&
184 ((LogEntryKey = GetPerformanceMeasurementEx (
185 LogEntryKey,
186 &Measurement.Handle,
187 &Measurement.Token,
188 &Measurement.Module,
189 &Measurement.StartTimeStamp,
190 &Measurement.EndTimeStamp,
191 &Measurement.Identifier)) != 0)
192 )
193 {
194 ++Index; // Count every record. First record is 1.
195 ElapsedTime = 0;
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);
201 }
202 else {
203 IncFlag = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_INCOMPLETE), NULL); // Mark incomplete records
204 }
205 if (((Measurement.EndTimeStamp != 0) && (ElapsedTime < mInterestThreshold)) ||
206 ((ExcludeFlag) && (GetCumulativeItem(&Measurement) >= 0))
207 ) { // Ignore "uninteresting" or excluded records
208 continue;
209 }
210 ++Count; // Count the number of records printed
211
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]);
220 break;
221 }
222 }
223 }
224
225 if (AsciiStrnCmp (Measurement.Token, ALit_PEIM, PERF_TOKEN_LENGTH) == 0) {
226 UnicodeSPrint (mGaugeString, sizeof (mGaugeString), L"%g", Measurement.Handle);
227 }
228
229 // Ensure that the argument strings are not too long.
230 mGaugeString[DP_GAUGE_STRING_LENGTH] = 0;
231 mUnicodeToken[13] = 0;
232
233 if (mShowId) {
234 PrintToken( STRING_TOKEN (STR_DP_ALL_VARS2),
235 Index, // 1 based, Which measurement record is being printed
236 IncFlag,
237 Measurement.Handle,
238 mGaugeString,
239 mUnicodeToken,
240 ElapsedTime,
241 Measurement.Identifier
242 );
243 } else {
244 PrintToken( STRING_TOKEN (STR_DP_ALL_VARS),
245 Index, // 1 based, Which measurement record is being printed
246 IncFlag,
247 Measurement.Handle,
248 mGaugeString,
249 mUnicodeToken,
250 ElapsedTime
251 );
252 }
253 }
254 }
255 if (HandleBuffer != &TempHandle) {
256 FreePool (HandleBuffer);
257 }
258 SafeFreePool ((VOID *) IncFlag);
259 }
260
261 /**
262 Gather and print Raw Trace Records.
263
264 All Trace measurements with a duration greater than or equal to
265 mInterestThreshold are printed without interpretation.
266
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
271 displayed.
272
273 @pre The mInterestThreshold global variable is set to the shortest duration to be printed.
274
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.
277
278 **/
279 VOID
280 DumpRawTrace(
281 IN UINTN Limit,
282 IN BOOLEAN ExcludeFlag
283 )
284 {
285 MEASUREMENT_RECORD Measurement;
286 UINT64 ElapsedTime;
287 UINT64 Duration;
288 UINTN LogEntryKey;
289 UINTN Count;
290 UINTN Index;
291
292 EFI_STRING StringPtr;
293 EFI_STRING StringPtrUnknown;
294
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);
301
302 if (mShowId) {
303 PrintToken (STRING_TOKEN (STR_DP_RAW_HEADR2) );
304 PrintToken (STRING_TOKEN (STR_DP_RAW_DASHES2) );
305 } else {
306 PrintToken (STRING_TOKEN (STR_DP_RAW_HEADR) );
307 PrintToken (STRING_TOKEN (STR_DP_RAW_DASHES) );
308 }
309
310 LogEntryKey = 0;
311 Count = 0;
312 Index = 0;
313 while ( WITHIN_LIMIT(Count, Limit) &&
314 ((LogEntryKey = GetPerformanceMeasurementEx (
315 LogEntryKey,
316 &Measurement.Handle,
317 &Measurement.Token,
318 &Measurement.Module,
319 &Measurement.StartTimeStamp,
320 &Measurement.EndTimeStamp,
321 &Measurement.Identifier)) != 0)
322 )
323 {
324 ++Index; // Count every record. First record is 1.
325 ElapsedTime = 0;
326 if (Measurement.EndTimeStamp != 0) {
327 Duration = GetDuration (&Measurement);
328 ElapsedTime = DurationInMicroSeconds ( Duration );
329 }
330 if ((ElapsedTime < mInterestThreshold) ||
331 ((ExcludeFlag) && (GetCumulativeItem(&Measurement) >= 0))
332 ) { // Ignore "uninteresting" or Excluded records
333 continue;
334 }
335 ++Count; // Count the number of records printed
336
337 if (mShowId) {
338 PrintToken (STRING_TOKEN (STR_DP_RAW_VARS2),
339 Index, // 1 based, Which measurement record is being printed
340 Measurement.Handle,
341 Measurement.StartTimeStamp,
342 Measurement.EndTimeStamp,
343 Measurement.Token,
344 Measurement.Module,
345 Measurement.Identifier
346 );
347 } else {
348 PrintToken (STRING_TOKEN (STR_DP_RAW_VARS),
349 Index, // 1 based, Which measurement record is being printed
350 Measurement.Handle,
351 Measurement.StartTimeStamp,
352 Measurement.EndTimeStamp,
353 Measurement.Token,
354 Measurement.Module
355 );
356 }
357 }
358 }
359
360 /**
361 Gather and print Major Phase metrics.
362
363 @param[in] Ticker The timer value for the END of Shell phase
364
365 **/
366 VOID
367 ProcessPhases(
368 IN UINT64 Ticker
369 )
370 {
371 MEASUREMENT_RECORD Measurement;
372 UINT64 BdsTimeoutValue;
373 UINT64 SecTime;
374 UINT64 PeiTime;
375 UINT64 DxeTime;
376 UINT64 BdsTime;
377 UINT64 ShellTime;
378 UINT64 ElapsedTime;
379 UINT64 Duration;
380 UINT64 Total;
381 EFI_STRING StringPtr;
382 UINTN LogEntryKey;
383 EFI_STRING StringPtrUnknown;
384
385 BdsTimeoutValue = 0;
386 SecTime = 0;
387 PeiTime = 0;
388 DxeTime = 0;
389 BdsTime = 0;
390 ShellTime = 0;
391 //
392 // Get Execution Phase Statistics
393 //
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);
400
401 LogEntryKey = 0;
402 while ((LogEntryKey = GetPerformanceMeasurementEx (
403 LogEntryKey,
404 &Measurement.Handle,
405 &Measurement.Token,
406 &Measurement.Module,
407 &Measurement.StartTimeStamp,
408 &Measurement.EndTimeStamp,
409 &Measurement.Identifier)) != 0)
410 {
411 if (AsciiStrnCmp (Measurement.Token, ALit_SHELL, PERF_TOKEN_LENGTH) == 0) {
412 Measurement.EndTimeStamp = Ticker;
413 }
414 if (Measurement.EndTimeStamp == 0) { // Skip "incomplete" records
415 continue;
416 }
417 Duration = GetDuration (&Measurement);
418 if ( Measurement.Handle != NULL
419 && (AsciiStrnCmp (Measurement.Token, ALit_BdsTO, PERF_TOKEN_LENGTH) == 0)
420 )
421 {
422 BdsTimeoutValue = Duration;
423 } else if (AsciiStrnCmp (Measurement.Token, ALit_SEC, PERF_TOKEN_LENGTH) == 0) {
424 SecTime = Duration;
425 } else if (AsciiStrnCmp (Measurement.Token, ALit_PEI, PERF_TOKEN_LENGTH) == 0) {
426 PeiTime = Duration;
427 } else if (AsciiStrnCmp (Measurement.Token, ALit_DXE, PERF_TOKEN_LENGTH) == 0) {
428 DxeTime = Duration;
429 } else if (AsciiStrnCmp (Measurement.Token, ALit_BDS, PERF_TOKEN_LENGTH) == 0) {
430 BdsTime = Duration;
431 } else if (AsciiStrnCmp (Measurement.Token, ALit_SHELL, PERF_TOKEN_LENGTH) == 0) {
432 ShellTime = Duration;
433 }
434 }
435
436 Total = 0;
437
438 // print SEC phase duration time
439 //
440 if (SecTime > 0) {
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);
444 }
445
446 // print PEI phase duration time
447 //
448 if (PeiTime > 0) {
449 ElapsedTime = DivU64x32 (
450 PeiTime,
451 (UINT32)TimerInfo.Frequency
452 );
453 Total += ElapsedTime;
454 PrintToken (STRING_TOKEN (STR_DP_PHASE_DURATION), ALit_PEI, ElapsedTime);
455 }
456
457 // print DXE phase duration time
458 //
459 if (DxeTime > 0) {
460 ElapsedTime = DivU64x32 (
461 DxeTime,
462 (UINT32)TimerInfo.Frequency
463 );
464 Total += ElapsedTime;
465 PrintToken (STRING_TOKEN (STR_DP_PHASE_DURATION), ALit_DXE, ElapsedTime);
466 }
467
468 // print BDS phase duration time
469 //
470 if (BdsTime > 0) {
471 ElapsedTime = DivU64x32 (
472 BdsTime,
473 (UINT32)TimerInfo.Frequency
474 );
475 Total += ElapsedTime;
476 PrintToken (STRING_TOKEN (STR_DP_PHASE_DURATION), ALit_BDS, ElapsedTime);
477 }
478
479 if (BdsTimeoutValue > 0) {
480 ElapsedTime = DivU64x32 (
481 BdsTimeoutValue,
482 (UINT32)TimerInfo.Frequency
483 );
484 PrintToken (STRING_TOKEN (STR_DP_PHASE_BDSTO), ALit_BdsTO, ElapsedTime);
485 }
486
487 // print SHELL phase duration time
488 //
489 if (ShellTime > 0) {
490 ElapsedTime = DivU64x32 (
491 ShellTime,
492 (UINT32)TimerInfo.Frequency
493 );
494 Total += ElapsedTime;
495 PrintToken (STRING_TOKEN (STR_DP_PHASE_DURATION), ALit_SHELL, ElapsedTime);
496 }
497
498 PrintToken (STRING_TOKEN (STR_DP_TOTAL_DURATION), Total);
499 }
500
501 /**
502 Gather and print Handle data.
503
504 @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.
505
506 @return Status from a call to gBS->LocateHandle().
507 **/
508 EFI_STATUS
509 ProcessHandles(
510 IN BOOLEAN ExcludeFlag
511 )
512 {
513 MEASUREMENT_RECORD Measurement;
514 UINT64 ElapsedTime;
515 UINT64 Duration;
516 EFI_HANDLE *HandleBuffer;
517 EFI_STRING StringPtr;
518 UINTN Index;
519 UINTN LogEntryKey;
520 UINTN Count;
521 UINTN Size;
522 EFI_HANDLE TempHandle;
523 EFI_STATUS Status;
524 EFI_STRING StringPtrUnknown;
525
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);
532
533 Size = 0;
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) {
540 return Status;
541 }
542 Status = gBS->LocateHandle (AllHandles, NULL, NULL, &Size, HandleBuffer);
543 }
544 if (EFI_ERROR (Status)) {
545 PrintToken (STRING_TOKEN (STR_DP_HANDLES_ERROR), Status);
546 }
547 else {
548 #if DP_DEBUG == 2
549 Print (L"There are %,d Handles defined.\n", (Size / sizeof(HandleBuffer[0])));
550 #endif
551
552 if (mShowId) {
553 PrintToken (STRING_TOKEN (STR_DP_HANDLE_SECTION2) );
554 } else {
555 PrintToken (STRING_TOKEN (STR_DP_HANDLE_SECTION) );
556 }
557 PrintToken (STRING_TOKEN (STR_DP_DASHES) );
558
559 LogEntryKey = 0;
560 Count = 0;
561 while ((LogEntryKey = GetPerformanceMeasurementEx (
562 LogEntryKey,
563 &Measurement.Handle,
564 &Measurement.Token,
565 &Measurement.Module,
566 &Measurement.StartTimeStamp,
567 &Measurement.EndTimeStamp,
568 &Measurement.Identifier)) != 0)
569 {
570 Count++;
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
578 continue;
579 }
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
586 break;
587 }
588 }
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.
594 if (mShowId) {
595 PrintToken (
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
599 mGaugeString,
600 mUnicodeToken,
601 ElapsedTime,
602 Measurement.Identifier
603 );
604 } else {
605 PrintToken (
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
609 mGaugeString,
610 mUnicodeToken,
611 ElapsedTime
612 );
613 }
614 }
615 }
616 }
617 if (HandleBuffer != &TempHandle) {
618 FreePool (HandleBuffer);
619 }
620 return Status;
621 }
622
623 /**
624 Gather and print PEIM data.
625
626 Only prints complete PEIM records
627
628 **/
629 VOID
630 ProcessPeims(
631 VOID
632 )
633 {
634 MEASUREMENT_RECORD Measurement;
635 UINT64 Duration;
636 UINT64 ElapsedTime;
637 EFI_STRING StringPtr;
638 UINTN LogEntryKey;
639 UINTN TIndex;
640 EFI_STRING StringPtrUnknown;
641
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);
648
649 if (mShowId) {
650 PrintToken (STRING_TOKEN (STR_DP_PEIM_SECTION2));
651 } else {
652 PrintToken (STRING_TOKEN (STR_DP_PEIM_SECTION));
653 }
654 PrintToken (STRING_TOKEN (STR_DP_DASHES));
655 TIndex = 0;
656 LogEntryKey = 0;
657 while ((LogEntryKey = GetPerformanceMeasurementEx (
658 LogEntryKey,
659 &Measurement.Handle,
660 &Measurement.Token,
661 &Measurement.Module,
662 &Measurement.StartTimeStamp,
663 &Measurement.EndTimeStamp,
664 &Measurement.Identifier)) != 0)
665 {
666 TIndex++;
667 if ((Measurement.EndTimeStamp == 0) ||
668 (AsciiStrnCmp (Measurement.Token, ALit_PEIM, PERF_TOKEN_LENGTH) != 0)
669 ) {
670 continue;
671 }
672
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.
677 if (mShowId) {
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
682 ElapsedTime,
683 Measurement.Identifier
684 );
685 } else {
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
690 ElapsedTime
691 );
692 }
693 }
694 }
695 }
696
697 /**
698 Gather and print global data.
699
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.
704
705 **/
706 VOID
707 ProcessGlobal(
708 VOID
709 )
710 {
711 MEASUREMENT_RECORD Measurement;
712 UINT64 Duration;
713 UINT64 ElapsedTime;
714 EFI_STRING StringPtr;
715 UINTN LogEntryKey;
716 UINTN Index; // Index, or number, of the measurement record being processed
717 EFI_STRING StringPtrUnknown;
718
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);
725
726 if (mShowId) {
727 PrintToken (STRING_TOKEN (STR_DP_GLOBAL_SECTION2));
728 } else {
729 PrintToken (STRING_TOKEN (STR_DP_GLOBAL_SECTION));
730 }
731 PrintToken (STRING_TOKEN (STR_DP_DASHES));
732
733 Index = 1;
734 LogEntryKey = 0;
735
736 while ((LogEntryKey = GetPerformanceMeasurementEx (
737 LogEntryKey,
738 &Measurement.Handle,
739 &Measurement.Token,
740 &Measurement.Module,
741 &Measurement.StartTimeStamp,
742 &Measurement.EndTimeStamp,
743 &Measurement.Identifier)) != 0)
744 {
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)
752 ))
753 {
754 Duration = GetDuration (&Measurement);
755 ElapsedTime = DurationInMicroSeconds ( Duration );
756 if (ElapsedTime >= mInterestThreshold) {
757 if (mShowId) {
758 PrintToken (
759 STRING_TOKEN (STR_DP_GLOBAL_VARS2),
760 Index,
761 mGaugeString,
762 mUnicodeToken,
763 ElapsedTime,
764 Measurement.Identifier
765 );
766 } else {
767 PrintToken (
768 STRING_TOKEN (STR_DP_GLOBAL_VARS),
769 Index,
770 mGaugeString,
771 mUnicodeToken,
772 ElapsedTime
773 );
774 }
775 }
776 }
777 Index++;
778 }
779 }
780
781 /**
782 Gather and print cumulative data.
783
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.
788
789 **/
790 VOID
791 ProcessCumulative(
792 VOID
793 )
794 {
795 UINT64 AvgDur; // the computed average duration
796 UINT64 Dur;
797 UINT64 MinDur;
798 UINT64 MaxDur;
799 EFI_STRING StringPtr;
800 UINTN TIndex;
801 EFI_STRING StringPtrUnknown;
802
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);
809
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));
813
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);
821
822 PrintToken (STRING_TOKEN (STR_DP_CUMULATIVE_STATS),
823 CumData[TIndex].Name,
824 CumData[TIndex].Count,
825 Dur,
826 AvgDur,
827 MinDur,
828 MaxDur
829 );
830 }
831 }
832 }