]> git.proxmox.com Git - mirror_edk2.git/blob - PerformancePkg/Dp_App/DpTrace.c
PerformancePkg Dp_App: Remove TimerLib dependency
[mirror_edk2.git] / PerformancePkg / Dp_App / DpTrace.c
1 /** @file
2 Trace reporting for the Dp utility.
3
4 Copyright (c) 2009 - 2017, 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
10
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.
13 **/
14
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/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 @param[in, out] CustomCumulativeData A pointer to the cumtom cumulative data.
47
48 **/
49 VOID
50 GatherStatistics(
51 IN OUT PERF_CUM_DATA *CustomCumulativeData OPTIONAL
52 )
53 {
54 MEASUREMENT_RECORD Measurement;
55 UINT64 Duration;
56 UINTN LogEntryKey;
57 INTN TIndex;
58
59 LogEntryKey = 0;
60 while ((LogEntryKey = GetPerformanceMeasurementEx (
61 LogEntryKey,
62 &Measurement.Handle,
63 &Measurement.Token,
64 &Measurement.Module,
65 &Measurement.StartTimeStamp,
66 &Measurement.EndTimeStamp,
67 &Measurement.Identifier)) != 0)
68 {
69 ++SummaryData.NumTrace; // Count the number of TRACE Measurement records
70 if (Measurement.EndTimeStamp == 0) {
71 ++SummaryData.NumIncomplete; // Count the incomplete records
72 continue;
73 }
74
75 if (Measurement.Handle != NULL) {
76 ++SummaryData.NumHandles; // Count the number of measurements with non-NULL handles
77 }
78
79 if (IsPhase( &Measurement)) {
80 ++SummaryData.NumSummary; // Count the number of major phases
81 }
82 else { // !IsPhase(...
83 if(Measurement.Handle == NULL) {
84 ++SummaryData.NumGlobal;
85 }
86 }
87
88 if (AsciiStrnCmp (Measurement.Token, ALit_PEIM, PERF_TOKEN_LENGTH) == 0) {
89 ++SummaryData.NumPEIMs; // Count PEIM measurements
90 }
91
92 Duration = GetDuration (&Measurement);
93 TIndex = GetCumulativeItem (&Measurement);
94 if (TIndex >= 0) {
95 CumData[TIndex].Duration += Duration;
96 CumData[TIndex].Count++;
97 if ( Duration < CumData[TIndex].MinDur ) {
98 CumData[TIndex].MinDur = Duration;
99 }
100 if ( Duration > CumData[TIndex].MaxDur ) {
101 CumData[TIndex].MaxDur = Duration;
102 }
103 }
104
105 //
106 // Collect the data for custom cumulative data.
107 //
108 if ((CustomCumulativeData != NULL) && (AsciiStrCmp (Measurement.Token, CustomCumulativeData->Name) == 0)) {
109 CustomCumulativeData->Duration += Duration;
110 CustomCumulativeData->Count++;
111 if (Duration < CustomCumulativeData->MinDur) {
112 CustomCumulativeData->MinDur = Duration;
113 }
114 if (Duration > CustomCumulativeData->MaxDur) {
115 CustomCumulativeData->MaxDur = Duration;
116 }
117 }
118 }
119 }
120
121 /**
122 Gather and print ALL Trace Records.
123
124 Displays all "interesting" Trace measurements in order.<BR>
125 The number of records displayed is controlled by:
126 - records with a duration less than mInterestThreshold microseconds are not displayed.
127 - No more than Limit records are displayed. A Limit of zero will not limit the output.
128 - If the ExcludeFlag is TRUE, records matching entries in the CumData array are not
129 displayed.
130
131 @pre The mInterestThreshold global variable is set to the shortest duration to be printed.
132 The mGaugeString and mUnicodeToken global arrays are used for temporary string storage.
133 They must not be in use by a calling function.
134
135 @param[in] Limit The number of records to print. Zero is ALL.
136 @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.
137
138 @retval EFI_SUCCESS The operation was successful.
139 @retval EFI_ABORTED The user aborts the operation.
140 @return Others from a call to gBS->LocateHandleBuffer().
141 **/
142 EFI_STATUS
143 DumpAllTrace(
144 IN UINTN Limit,
145 IN BOOLEAN ExcludeFlag
146 )
147 {
148 MEASUREMENT_RECORD Measurement;
149 UINT64 ElapsedTime;
150 UINT64 Duration;
151 const CHAR16 *IncFlag;
152 UINTN LogEntryKey;
153 UINTN Count;
154 UINTN Index;
155 UINTN TIndex;
156
157 EFI_HANDLE *HandleBuffer;
158 UINTN HandleCount;
159 EFI_STATUS Status;
160 EFI_STRING StringPtrUnknown;
161
162 StringPtrUnknown = HiiGetString (gHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
163 IncFlag = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_ALL), NULL);
164 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),
165 (IncFlag == NULL) ? StringPtrUnknown : IncFlag);
166 FreePool (StringPtrUnknown);
167
168 // Get Handle information
169 //
170 Status = gBS->LocateHandleBuffer (AllHandles, NULL, NULL, &HandleCount, &HandleBuffer);
171 if (EFI_ERROR (Status)) {
172 PrintToken (STRING_TOKEN (STR_DP_HANDLES_ERROR), Status);
173 }
174 else {
175 // We have successfully populated the HandleBuffer
176 // Display ALL Measurement Records
177 // Up to Limit lines displayed
178 // Display only records with Elapsed times >= mInterestThreshold
179 // Display driver names in Module field for records with Handles.
180 //
181 if (mShowId) {
182 PrintToken (STRING_TOKEN (STR_DP_ALL_HEADR2) );
183 PrintToken (STRING_TOKEN (STR_DP_ALL_DASHES2) );
184 } else {
185 PrintToken (STRING_TOKEN (STR_DP_ALL_HEADR) );
186 PrintToken (STRING_TOKEN (STR_DP_DASHES) );
187 }
188
189 LogEntryKey = 0;
190 Count = 0;
191 Index = 0;
192 while ( WITHIN_LIMIT(Count, Limit) &&
193 ((LogEntryKey = GetPerformanceMeasurementEx (
194 LogEntryKey,
195 &Measurement.Handle,
196 &Measurement.Token,
197 &Measurement.Module,
198 &Measurement.StartTimeStamp,
199 &Measurement.EndTimeStamp,
200 &Measurement.Identifier)) != 0)
201 )
202 {
203 ++Index; // Count every record. First record is 1.
204 ElapsedTime = 0;
205 SafeFreePool ((VOID *) IncFlag);
206 if (Measurement.EndTimeStamp != 0) {
207 Duration = GetDuration (&Measurement);
208 ElapsedTime = DurationInMicroSeconds ( Duration );
209 IncFlag = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_COMPLETE), NULL);
210 }
211 else {
212 IncFlag = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_INCOMPLETE), NULL); // Mark incomplete records
213 }
214 if (((Measurement.EndTimeStamp != 0) && (ElapsedTime < mInterestThreshold)) ||
215 ((ExcludeFlag) && (GetCumulativeItem(&Measurement) >= 0))
216 ) { // Ignore "uninteresting" or excluded records
217 continue;
218 }
219 ++Count; // Count the number of records printed
220
221 // If Handle is non-zero, see if we can determine a name for the driver
222 AsciiStrToUnicodeStrS (Measurement.Module, mGaugeString, ARRAY_SIZE (mGaugeString)); // Use Module by default
223 AsciiStrToUnicodeStrS (Measurement.Token, mUnicodeToken, ARRAY_SIZE (mUnicodeToken));
224 if (Measurement.Handle != NULL) {
225 // See if the Handle is in the HandleBuffer
226 for (TIndex = 0; TIndex < HandleCount; TIndex++) {
227 if (Measurement.Handle == HandleBuffer[TIndex]) {
228 GetNameFromHandle (HandleBuffer[TIndex]);
229 break;
230 }
231 }
232 }
233
234 if (AsciiStrnCmp (Measurement.Token, ALit_PEIM, PERF_TOKEN_LENGTH) == 0) {
235 UnicodeSPrint (mGaugeString, sizeof (mGaugeString), L"%g", Measurement.Handle);
236 }
237
238 // Ensure that the argument strings are not too long.
239 mGaugeString[DP_GAUGE_STRING_LENGTH] = 0;
240 mUnicodeToken[13] = 0;
241
242 if (mShowId) {
243 PrintToken( STRING_TOKEN (STR_DP_ALL_VARS2),
244 Index, // 1 based, Which measurement record is being printed
245 IncFlag,
246 Measurement.Handle,
247 mGaugeString,
248 mUnicodeToken,
249 ElapsedTime,
250 Measurement.Identifier
251 );
252 } else {
253 PrintToken( STRING_TOKEN (STR_DP_ALL_VARS),
254 Index, // 1 based, Which measurement record is being printed
255 IncFlag,
256 Measurement.Handle,
257 mGaugeString,
258 mUnicodeToken,
259 ElapsedTime
260 );
261 }
262 if (ShellGetExecutionBreakFlag ()) {
263 Status = EFI_ABORTED;
264 break;
265 }
266 }
267 }
268 if (HandleBuffer != NULL) {
269 FreePool (HandleBuffer);
270 }
271 SafeFreePool ((VOID *) IncFlag);
272 return Status;
273 }
274
275 /**
276 Gather and print Raw Trace Records.
277
278 All Trace measurements with a duration greater than or equal to
279 mInterestThreshold are printed without interpretation.
280
281 The number of records displayed is controlled by:
282 - records with a duration less than mInterestThreshold microseconds are not displayed.
283 - No more than Limit records are displayed. A Limit of zero will not limit the output.
284 - If the ExcludeFlag is TRUE, records matching entries in the CumData array are not
285 displayed.
286
287 @pre The mInterestThreshold global variable is set to the shortest duration to be printed.
288
289 @param[in] Limit The number of records to print. Zero is ALL.
290 @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.
291
292 @retval EFI_SUCCESS The operation was successful.
293 @retval EFI_ABORTED The user aborts the operation.
294 **/
295 EFI_STATUS
296 DumpRawTrace(
297 IN UINTN Limit,
298 IN BOOLEAN ExcludeFlag
299 )
300 {
301 MEASUREMENT_RECORD Measurement;
302 UINT64 ElapsedTime;
303 UINT64 Duration;
304 UINTN LogEntryKey;
305 UINTN Count;
306 UINTN Index;
307
308 EFI_STRING StringPtr;
309 EFI_STRING StringPtrUnknown;
310 EFI_STATUS Status;
311
312 Status = EFI_SUCCESS;
313
314 StringPtrUnknown = HiiGetString (gHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
315 StringPtr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_RAWTRACE), NULL);
316 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),
317 (StringPtr == NULL) ? StringPtrUnknown : StringPtr);
318 FreePool (StringPtr);
319 FreePool (StringPtrUnknown);
320
321 if (mShowId) {
322 PrintToken (STRING_TOKEN (STR_DP_RAW_HEADR2) );
323 PrintToken (STRING_TOKEN (STR_DP_RAW_DASHES2) );
324 } else {
325 PrintToken (STRING_TOKEN (STR_DP_RAW_HEADR) );
326 PrintToken (STRING_TOKEN (STR_DP_RAW_DASHES) );
327 }
328
329 LogEntryKey = 0;
330 Count = 0;
331 Index = 0;
332 while ( WITHIN_LIMIT(Count, Limit) &&
333 ((LogEntryKey = GetPerformanceMeasurementEx (
334 LogEntryKey,
335 &Measurement.Handle,
336 &Measurement.Token,
337 &Measurement.Module,
338 &Measurement.StartTimeStamp,
339 &Measurement.EndTimeStamp,
340 &Measurement.Identifier)) != 0)
341 )
342 {
343 ++Index; // Count every record. First record is 1.
344 ElapsedTime = 0;
345 if (Measurement.EndTimeStamp != 0) {
346 Duration = GetDuration (&Measurement);
347 ElapsedTime = DurationInMicroSeconds ( Duration );
348 }
349 if ((ElapsedTime < mInterestThreshold) ||
350 ((ExcludeFlag) && (GetCumulativeItem(&Measurement) >= 0))
351 ) { // Ignore "uninteresting" or Excluded records
352 continue;
353 }
354 ++Count; // Count the number of records printed
355
356 if (mShowId) {
357 PrintToken (STRING_TOKEN (STR_DP_RAW_VARS2),
358 Index, // 1 based, Which measurement record is being printed
359 Measurement.Handle,
360 Measurement.StartTimeStamp,
361 Measurement.EndTimeStamp,
362 Measurement.Token,
363 Measurement.Module,
364 Measurement.Identifier
365 );
366 } else {
367 PrintToken (STRING_TOKEN (STR_DP_RAW_VARS),
368 Index, // 1 based, Which measurement record is being printed
369 Measurement.Handle,
370 Measurement.StartTimeStamp,
371 Measurement.EndTimeStamp,
372 Measurement.Token,
373 Measurement.Module
374 );
375 }
376 if (ShellGetExecutionBreakFlag ()) {
377 Status = EFI_ABORTED;
378 break;
379 }
380 }
381 return Status;
382 }
383
384 /**
385 Gather and print Major Phase metrics.
386
387 **/
388 VOID
389 ProcessPhases(
390 VOID
391 )
392 {
393 MEASUREMENT_RECORD Measurement;
394 UINT64 BdsTimeoutValue;
395 UINT64 SecTime;
396 UINT64 PeiTime;
397 UINT64 DxeTime;
398 UINT64 BdsTime;
399 UINT64 ElapsedTime;
400 UINT64 Duration;
401 UINT64 Total;
402 EFI_STRING StringPtr;
403 UINTN LogEntryKey;
404 EFI_STRING StringPtrUnknown;
405
406 BdsTimeoutValue = 0;
407 SecTime = 0;
408 PeiTime = 0;
409 DxeTime = 0;
410 BdsTime = 0;
411 //
412 // Get Execution Phase Statistics
413 //
414 StringPtrUnknown = HiiGetString (gHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
415 StringPtr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_PHASES), NULL);
416 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),
417 (StringPtr == NULL) ? StringPtrUnknown : StringPtr);
418 FreePool (StringPtr);
419 FreePool (StringPtrUnknown);
420
421 LogEntryKey = 0;
422 while ((LogEntryKey = GetPerformanceMeasurementEx (
423 LogEntryKey,
424 &Measurement.Handle,
425 &Measurement.Token,
426 &Measurement.Module,
427 &Measurement.StartTimeStamp,
428 &Measurement.EndTimeStamp,
429 &Measurement.Identifier)) != 0)
430 {
431 if (Measurement.EndTimeStamp == 0) { // Skip "incomplete" records
432 continue;
433 }
434 Duration = GetDuration (&Measurement);
435 if ( Measurement.Handle != NULL
436 && (AsciiStrnCmp (Measurement.Token, ALit_BdsTO, PERF_TOKEN_LENGTH) == 0)
437 )
438 {
439 BdsTimeoutValue = Duration;
440 } else if (AsciiStrnCmp (Measurement.Token, ALit_SEC, PERF_TOKEN_LENGTH) == 0) {
441 SecTime = Duration;
442 } else if (AsciiStrnCmp (Measurement.Token, ALit_PEI, PERF_TOKEN_LENGTH) == 0) {
443 PeiTime = Duration;
444 } else if (AsciiStrnCmp (Measurement.Token, ALit_DXE, PERF_TOKEN_LENGTH) == 0) {
445 DxeTime = Duration;
446 } else if (AsciiStrnCmp (Measurement.Token, ALit_BDS, PERF_TOKEN_LENGTH) == 0) {
447 BdsTime = Duration;
448 }
449 }
450
451 Total = 0;
452
453 // print SEC phase duration time
454 //
455 if (SecTime > 0) {
456 ElapsedTime = DurationInMicroSeconds ( SecTime ); // Calculate elapsed time in microseconds
457 Total += DivU64x32 (ElapsedTime, 1000); // Accumulate time in milliseconds
458 PrintToken (STRING_TOKEN (STR_DP_SEC_PHASE), ElapsedTime);
459 }
460
461 // print PEI phase duration time
462 //
463 if (PeiTime > 0) {
464 ElapsedTime = DivU64x32 (
465 PeiTime,
466 (UINT32)TimerInfo.Frequency
467 );
468 Total += ElapsedTime;
469 PrintToken (STRING_TOKEN (STR_DP_PHASE_DURATION), ALit_PEI, ElapsedTime);
470 }
471
472 // print DXE phase duration time
473 //
474 if (DxeTime > 0) {
475 ElapsedTime = DivU64x32 (
476 DxeTime,
477 (UINT32)TimerInfo.Frequency
478 );
479 Total += ElapsedTime;
480 PrintToken (STRING_TOKEN (STR_DP_PHASE_DURATION), ALit_DXE, ElapsedTime);
481 }
482
483 // print BDS phase duration time
484 //
485 if (BdsTime > 0) {
486 ElapsedTime = DivU64x32 (
487 BdsTime,
488 (UINT32)TimerInfo.Frequency
489 );
490 Total += ElapsedTime;
491 PrintToken (STRING_TOKEN (STR_DP_PHASE_DURATION), ALit_BDS, ElapsedTime);
492 }
493
494 if (BdsTimeoutValue > 0) {
495 ElapsedTime = DivU64x32 (
496 BdsTimeoutValue,
497 (UINT32)TimerInfo.Frequency
498 );
499 PrintToken (STRING_TOKEN (STR_DP_PHASE_BDSTO), ALit_BdsTO, ElapsedTime);
500 }
501
502 PrintToken (STRING_TOKEN (STR_DP_TOTAL_DURATION), Total);
503 }
504
505 /**
506 Gather and print Handle data.
507
508 @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.
509
510 @retval EFI_SUCCESS The operation was successful.
511 @retval EFI_ABORTED The user aborts the operation.
512 @return Others from a call to gBS->LocateHandleBuffer().
513 **/
514 EFI_STATUS
515 ProcessHandles(
516 IN BOOLEAN ExcludeFlag
517 )
518 {
519 MEASUREMENT_RECORD Measurement;
520 UINT64 ElapsedTime;
521 UINT64 Duration;
522 EFI_HANDLE *HandleBuffer;
523 EFI_STRING StringPtr;
524 UINTN Index;
525 UINTN LogEntryKey;
526 UINTN Count;
527 UINTN HandleCount;
528 EFI_STATUS Status;
529 EFI_STRING StringPtrUnknown;
530
531 StringPtrUnknown = HiiGetString (gHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
532 StringPtr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_DRIVERS), NULL);
533 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),
534 (StringPtr == NULL) ? StringPtrUnknown : StringPtr);
535 FreePool (StringPtr);
536 FreePool (StringPtrUnknown);
537
538 Status = gBS->LocateHandleBuffer (AllHandles, NULL, NULL, &HandleCount, &HandleBuffer);
539 if (EFI_ERROR (Status)) {
540 PrintToken (STRING_TOKEN (STR_DP_HANDLES_ERROR), Status);
541 }
542 else {
543 #if DP_DEBUG == 2
544 Print (L"There are %,d Handles defined.\n", (Size / sizeof(HandleBuffer[0])));
545 #endif
546
547 if (mShowId) {
548 PrintToken (STRING_TOKEN (STR_DP_HANDLE_SECTION2) );
549 } else {
550 PrintToken (STRING_TOKEN (STR_DP_HANDLE_SECTION) );
551 }
552 PrintToken (STRING_TOKEN (STR_DP_DASHES) );
553
554 LogEntryKey = 0;
555 Count = 0;
556 while ((LogEntryKey = GetPerformanceMeasurementEx (
557 LogEntryKey,
558 &Measurement.Handle,
559 &Measurement.Token,
560 &Measurement.Module,
561 &Measurement.StartTimeStamp,
562 &Measurement.EndTimeStamp,
563 &Measurement.Identifier)) != 0)
564 {
565 Count++;
566 Duration = GetDuration (&Measurement);
567 ElapsedTime = DurationInMicroSeconds ( Duration );
568 if ((ElapsedTime < mInterestThreshold) ||
569 (Measurement.EndTimeStamp == 0) ||
570 (Measurement.Handle == NULL) ||
571 ((ExcludeFlag) && (GetCumulativeItem(&Measurement) >= 0))
572 ) { // Ignore "uninteresting" or excluded records
573 continue;
574 }
575 mGaugeString[0] = 0; // Empty driver name by default
576 AsciiStrToUnicodeStrS (Measurement.Token, mUnicodeToken, ARRAY_SIZE (mUnicodeToken));
577 // See if the Handle is in the HandleBuffer
578 for (Index = 0; Index < HandleCount; Index++) {
579 if (Measurement.Handle == HandleBuffer[Index]) {
580 GetNameFromHandle (HandleBuffer[Index]); // Name is put into mGaugeString
581 break;
582 }
583 }
584 // Ensure that the argument strings are not too long.
585 mGaugeString[DP_GAUGE_STRING_LENGTH] = 0;
586 mUnicodeToken[11] = 0;
587 if (mGaugeString[0] != 0) {
588 // Display the record if it has a valid handle.
589 if (mShowId) {
590 PrintToken (
591 STRING_TOKEN (STR_DP_HANDLE_VARS2),
592 Count, // 1 based, Which measurement record is being printed
593 Index + 1, // 1 based, Which handle is being printed
594 mGaugeString,
595 mUnicodeToken,
596 ElapsedTime,
597 Measurement.Identifier
598 );
599 } else {
600 PrintToken (
601 STRING_TOKEN (STR_DP_HANDLE_VARS),
602 Count, // 1 based, Which measurement record is being printed
603 Index + 1, // 1 based, Which handle is being printed
604 mGaugeString,
605 mUnicodeToken,
606 ElapsedTime
607 );
608 }
609 }
610 if (ShellGetExecutionBreakFlag ()) {
611 Status = EFI_ABORTED;
612 break;
613 }
614 }
615 }
616 if (HandleBuffer != NULL) {
617 FreePool (HandleBuffer);
618 }
619 return Status;
620 }
621
622 /**
623 Gather and print PEIM data.
624
625 Only prints complete PEIM records
626
627 @retval EFI_SUCCESS The operation was successful.
628 @retval EFI_ABORTED The user aborts the operation.
629 **/
630 EFI_STATUS
631 ProcessPeims(
632 VOID
633 )
634 {
635 MEASUREMENT_RECORD Measurement;
636 UINT64 Duration;
637 UINT64 ElapsedTime;
638 EFI_STRING StringPtr;
639 UINTN LogEntryKey;
640 UINTN TIndex;
641 EFI_STRING StringPtrUnknown;
642 EFI_STATUS Status;
643
644 Status = EFI_SUCCESS;
645
646 StringPtrUnknown = HiiGetString (gHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
647 StringPtr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_PEIMS), NULL);
648 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),
649 (StringPtr == NULL) ? StringPtrUnknown : StringPtr);
650 FreePool (StringPtr);
651 FreePool (StringPtrUnknown);
652
653 if (mShowId) {
654 PrintToken (STRING_TOKEN (STR_DP_PEIM_SECTION2));
655 } else {
656 PrintToken (STRING_TOKEN (STR_DP_PEIM_SECTION));
657 }
658 PrintToken (STRING_TOKEN (STR_DP_DASHES));
659 TIndex = 0;
660 LogEntryKey = 0;
661 while ((LogEntryKey = GetPerformanceMeasurementEx (
662 LogEntryKey,
663 &Measurement.Handle,
664 &Measurement.Token,
665 &Measurement.Module,
666 &Measurement.StartTimeStamp,
667 &Measurement.EndTimeStamp,
668 &Measurement.Identifier)) != 0)
669 {
670 TIndex++;
671 if ((Measurement.EndTimeStamp == 0) ||
672 (AsciiStrnCmp (Measurement.Token, ALit_PEIM, PERF_TOKEN_LENGTH) != 0)
673 ) {
674 continue;
675 }
676
677 Duration = GetDuration (&Measurement);
678 ElapsedTime = DurationInMicroSeconds ( Duration ); // Calculate elapsed time in microseconds
679 if (ElapsedTime >= mInterestThreshold) {
680 // PEIM FILE Handle is the start address of its FFS file that contains its file guid.
681 if (mShowId) {
682 PrintToken (STRING_TOKEN (STR_DP_PEIM_VARS2),
683 TIndex, // 1 based, Which measurement record is being printed
684 Measurement.Handle, // base address
685 Measurement.Handle, // file guid
686 ElapsedTime,
687 Measurement.Identifier
688 );
689 } else {
690 PrintToken (STRING_TOKEN (STR_DP_PEIM_VARS),
691 TIndex, // 1 based, Which measurement record is being printed
692 Measurement.Handle, // base address
693 Measurement.Handle, // file guid
694 ElapsedTime
695 );
696 }
697 }
698 if (ShellGetExecutionBreakFlag ()) {
699 Status = EFI_ABORTED;
700 break;
701 }
702 }
703 return Status;
704 }
705
706 /**
707 Gather and print global data.
708
709 Strips out incomplete or "Execution Phase" records
710 Only prints records where Handle is NULL
711 Increment TIndex for every record, even skipped ones, so that we have an
712 indication of every measurement record taken.
713
714 @retval EFI_SUCCESS The operation was successful.
715 @retval EFI_ABORTED The user aborts the operation.
716 **/
717 EFI_STATUS
718 ProcessGlobal(
719 VOID
720 )
721 {
722 MEASUREMENT_RECORD Measurement;
723 UINT64 Duration;
724 UINT64 ElapsedTime;
725 EFI_STRING StringPtr;
726 UINTN LogEntryKey;
727 UINTN Index; // Index, or number, of the measurement record being processed
728 EFI_STRING StringPtrUnknown;
729 EFI_STATUS Status;
730
731 Status = EFI_SUCCESS;
732
733 StringPtrUnknown = HiiGetString (gHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
734 StringPtr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_GENERAL), NULL);
735 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),
736 (StringPtr == NULL) ? StringPtrUnknown: StringPtr);
737 FreePool (StringPtr);
738 FreePool (StringPtrUnknown);
739
740 if (mShowId) {
741 PrintToken (STRING_TOKEN (STR_DP_GLOBAL_SECTION2));
742 } else {
743 PrintToken (STRING_TOKEN (STR_DP_GLOBAL_SECTION));
744 }
745 PrintToken (STRING_TOKEN (STR_DP_DASHES));
746
747 Index = 1;
748 LogEntryKey = 0;
749
750 while ((LogEntryKey = GetPerformanceMeasurementEx (
751 LogEntryKey,
752 &Measurement.Handle,
753 &Measurement.Token,
754 &Measurement.Module,
755 &Measurement.StartTimeStamp,
756 &Measurement.EndTimeStamp,
757 &Measurement.Identifier)) != 0)
758 {
759 AsciiStrToUnicodeStrS (Measurement.Module, mGaugeString, ARRAY_SIZE (mGaugeString));
760 AsciiStrToUnicodeStrS (Measurement.Token, mUnicodeToken, ARRAY_SIZE (mUnicodeToken));
761 mGaugeString[25] = 0;
762 mUnicodeToken[31] = 0;
763 if ( ! ( IsPhase( &Measurement) ||
764 (Measurement.Handle != NULL) ||
765 (Measurement.EndTimeStamp == 0)
766 ))
767 {
768 Duration = GetDuration (&Measurement);
769 ElapsedTime = DurationInMicroSeconds ( Duration );
770 if (ElapsedTime >= mInterestThreshold) {
771 if (mShowId) {
772 PrintToken (
773 STRING_TOKEN (STR_DP_GLOBAL_VARS2),
774 Index,
775 mGaugeString,
776 mUnicodeToken,
777 ElapsedTime,
778 Measurement.Identifier
779 );
780 } else {
781 PrintToken (
782 STRING_TOKEN (STR_DP_GLOBAL_VARS),
783 Index,
784 mGaugeString,
785 mUnicodeToken,
786 ElapsedTime
787 );
788 }
789 }
790 }
791 if (ShellGetExecutionBreakFlag ()) {
792 Status = EFI_ABORTED;
793 break;
794 }
795 Index++;
796 }
797 return Status;
798 }
799
800 /**
801 Gather and print cumulative data.
802
803 Traverse the measurement records and:<BR>
804 For each record with a Token listed in the CumData array:<BR>
805 - Update the instance count and the total, minimum, and maximum durations.
806 Finally, print the gathered cumulative statistics.
807
808 @param[in] CustomCumulativeData A pointer to the cumtom cumulative data.
809
810 **/
811 VOID
812 ProcessCumulative(
813 IN PERF_CUM_DATA *CustomCumulativeData OPTIONAL
814 )
815 {
816 UINT64 AvgDur; // the computed average duration
817 UINT64 Dur;
818 UINT64 MinDur;
819 UINT64 MaxDur;
820 EFI_STRING StringPtr;
821 UINTN TIndex;
822 EFI_STRING StringPtrUnknown;
823
824 StringPtrUnknown = HiiGetString (gHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
825 StringPtr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_CUMULATIVE), NULL);
826 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),
827 (StringPtr == NULL) ? StringPtrUnknown: StringPtr);
828 FreePool (StringPtr);
829 FreePool (StringPtrUnknown);
830
831 PrintToken (STRING_TOKEN (STR_DP_CUMULATIVE_SECT_1));
832 PrintToken (STRING_TOKEN (STR_DP_CUMULATIVE_SECT_2));
833 PrintToken (STRING_TOKEN (STR_DP_DASHES));
834
835 for ( TIndex = 0; TIndex < NumCum; ++TIndex) {
836 if (CumData[TIndex].Count != 0) {
837 AvgDur = DivU64x32 (CumData[TIndex].Duration, CumData[TIndex].Count);
838 AvgDur = DurationInMicroSeconds(AvgDur);
839 Dur = DurationInMicroSeconds(CumData[TIndex].Duration);
840 MaxDur = DurationInMicroSeconds(CumData[TIndex].MaxDur);
841 MinDur = DurationInMicroSeconds(CumData[TIndex].MinDur);
842
843 PrintToken (STRING_TOKEN (STR_DP_CUMULATIVE_STATS),
844 CumData[TIndex].Name,
845 CumData[TIndex].Count,
846 Dur,
847 AvgDur,
848 MinDur,
849 MaxDur
850 );
851 }
852 }
853
854 //
855 // Print the custom cumulative data.
856 //
857 if (CustomCumulativeData != NULL) {
858 if (CustomCumulativeData->Count != 0) {
859 AvgDur = DivU64x32 (CustomCumulativeData->Duration, CustomCumulativeData->Count);
860 AvgDur = DurationInMicroSeconds (AvgDur);
861 Dur = DurationInMicroSeconds (CustomCumulativeData->Duration);
862 MaxDur = DurationInMicroSeconds (CustomCumulativeData->MaxDur);
863 MinDur = DurationInMicroSeconds (CustomCumulativeData->MinDur);
864 } else {
865 AvgDur = 0;
866 Dur = 0;
867 MaxDur = 0;
868 MinDur = 0;
869 }
870 PrintToken (STRING_TOKEN (STR_DP_CUMULATIVE_STATS),
871 CustomCumulativeData->Name,
872 CustomCumulativeData->Count,
873 Dur,
874 AvgDur,
875 MinDur,
876 MaxDur
877 );
878 }
879 }