blob: de1d45aa8b7dee5e9f1d376494d5a7f5e8ff00ac [file] [log] [blame]
Vishal Bhoj82c80712015-12-15 21:13:33 +05301/** @file
2 Trace reporting for the Dp utility.
3
4 Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.
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**/
46VOID
47GatherStatistics(
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**/
122VOID
123DumpAllTrace(
124 IN UINTN Limit,
125 IN BOOLEAN ExcludeFlag
126 )
127{
128 MEASUREMENT_RECORD Measurement;
129 UINT64 ElapsedTime;
130 UINT64 Duration;
131 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 (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
144 IncFlag = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_ALL), NULL);
145 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,
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 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLES_ERROR), gDpHiiHandle, 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 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_ALL_HEADR2), gDpHiiHandle);
174 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_ALL_DASHES2), gDpHiiHandle);
175 } else {
176 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_ALL_HEADR), gDpHiiHandle);
177 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), gDpHiiHandle);
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 SHELL_FREE_NON_NULL (IncFlag);
197 if (Measurement.EndTimeStamp != 0) {
198 Duration = GetDuration (&Measurement);
199 ElapsedTime = DurationInMicroSeconds ( Duration );
200 IncFlag = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_COMPLETE), NULL);
201 }
202 else {
203 IncFlag = HiiGetString (gDpHiiHandle, 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 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_ALL_VARS2), gDpHiiHandle,
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 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_ALL_VARS), gDpHiiHandle,
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 SHELL_FREE_NON_NULL (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**/
279VOID
280DumpRawTrace(
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 (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
296 StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_RAWTRACE), NULL);
297 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,
298 (StringPtr == NULL) ? StringPtrUnknown : StringPtr);
299 FreePool (StringPtr);
300 FreePool (StringPtrUnknown);
301
302 if (mShowId) {
303 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_HEADR2), gDpHiiHandle);
304 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_DASHES2), gDpHiiHandle);
305 } else {
306 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_HEADR), gDpHiiHandle);
307 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_DASHES), gDpHiiHandle);
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 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_VARS2), gDpHiiHandle,
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 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_VARS), gDpHiiHandle,
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**/
366VOID
367ProcessPhases(
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 (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
395 StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_PHASES), NULL);
396 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,
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 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SEC_PHASE), gDpHiiHandle, 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 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PHASE_DURATION), gDpHiiHandle, 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 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PHASE_DURATION), gDpHiiHandle, 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 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PHASE_DURATION), gDpHiiHandle, ALit_BDS, ElapsedTime);
477 }
478
479 if (BdsTimeoutValue > 0) {
480 ElapsedTime = DivU64x32 (
481 BdsTimeoutValue,
482 (UINT32)TimerInfo.Frequency
483 );
484 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PHASE_BDSTO), gDpHiiHandle, 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 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PHASE_DURATION), gDpHiiHandle, ALit_SHELL, ElapsedTime);
496 }
497
498 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TOTAL_DURATION), gDpHiiHandle, 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**/
508EFI_STATUS
509ProcessHandles(
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 (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
527 StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_DRIVERS), NULL);
528 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,
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 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLES_ERROR), gDpHiiHandle, 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 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLE_SECTION2), gDpHiiHandle);
554 } else {
555 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLE_SECTION), gDpHiiHandle);
556 }
557 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), gDpHiiHandle);
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 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLE_VARS2), gDpHiiHandle,
596 Count, // 1 based, Which measurement record is being printed
597 Index + 1, // 1 based, Which handle is being printed
598 mGaugeString,
599 mUnicodeToken,
600 ElapsedTime,
601 Measurement.Identifier
602 );
603 } else {
604 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLE_VARS), gDpHiiHandle,
605 Count, // 1 based, Which measurement record is being printed
606 Index + 1, // 1 based, Which handle is being printed
607 mGaugeString,
608 mUnicodeToken,
609 ElapsedTime
610 );
611 }
612 }
613 }
614 }
615 if (HandleBuffer != &TempHandle) {
616 FreePool (HandleBuffer);
617 }
618 return Status;
619}
620
621/**
622 Gather and print PEIM data.
623
624 Only prints complete PEIM records
625
626**/
627VOID
628ProcessPeims(
629 VOID
630)
631{
632 MEASUREMENT_RECORD Measurement;
633 UINT64 Duration;
634 UINT64 ElapsedTime;
635 EFI_STRING StringPtr;
636 UINTN LogEntryKey;
637 UINTN TIndex;
638 EFI_STRING StringPtrUnknown;
639
640 StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
641 StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_PEIMS), NULL);
642 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,
643 (StringPtr == NULL) ? StringPtrUnknown : StringPtr);
644 FreePool (StringPtr);
645 FreePool (StringPtrUnknown);
646
647 if (mShowId) {
648 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PEIM_SECTION2), gDpHiiHandle);
649 } else {
650 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PEIM_SECTION), gDpHiiHandle);
651 }
652 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), gDpHiiHandle);
653 TIndex = 0;
654 LogEntryKey = 0;
655 while ((LogEntryKey = GetPerformanceMeasurementEx (
656 LogEntryKey,
657 &Measurement.Handle,
658 &Measurement.Token,
659 &Measurement.Module,
660 &Measurement.StartTimeStamp,
661 &Measurement.EndTimeStamp,
662 &Measurement.Identifier)) != 0)
663 {
664 TIndex++;
665 if ((Measurement.EndTimeStamp == 0) ||
666 (AsciiStrnCmp (Measurement.Token, ALit_PEIM, PERF_TOKEN_LENGTH) != 0)
667 ) {
668 continue;
669 }
670
671 Duration = GetDuration (&Measurement);
672 ElapsedTime = DurationInMicroSeconds ( Duration ); // Calculate elapsed time in microseconds
673 if (ElapsedTime >= mInterestThreshold) {
674 // PEIM FILE Handle is the start address of its FFS file that contains its file guid.
675 if (mShowId) {
676 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PEIM_VARS2), gDpHiiHandle,
677 TIndex, // 1 based, Which measurement record is being printed
678 Measurement.Handle, // base address
679 Measurement.Handle, // file guid
680 ElapsedTime,
681 Measurement.Identifier
682 );
683 } else {
684 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PEIM_VARS), gDpHiiHandle,
685 TIndex, // 1 based, Which measurement record is being printed
686 Measurement.Handle, // base address
687 Measurement.Handle, // file guid
688 ElapsedTime
689 );
690 }
691 }
692 }
693}
694
695/**
696 Gather and print global data.
697
698 Strips out incomplete or "Execution Phase" records
699 Only prints records where Handle is NULL
700 Increment TIndex for every record, even skipped ones, so that we have an
701 indication of every measurement record taken.
702
703**/
704VOID
705ProcessGlobal(
706 VOID
707)
708{
709 MEASUREMENT_RECORD Measurement;
710 UINT64 Duration;
711 UINT64 ElapsedTime;
712 EFI_STRING StringPtr;
713 UINTN LogEntryKey;
714 UINTN Index; // Index, or number, of the measurement record being processed
715 EFI_STRING StringPtrUnknown;
716
717 StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
718 StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_GENERAL), NULL);
719 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,
720 (StringPtr == NULL) ? StringPtrUnknown: StringPtr);
721 FreePool (StringPtr);
722 FreePool (StringPtrUnknown);
723
724 if (mShowId) {
725 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GLOBAL_SECTION2), gDpHiiHandle);
726 } else {
727 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GLOBAL_SECTION), gDpHiiHandle);
728 }
729 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), gDpHiiHandle);
730
731 Index = 1;
732 LogEntryKey = 0;
733
734 while ((LogEntryKey = GetPerformanceMeasurementEx (
735 LogEntryKey,
736 &Measurement.Handle,
737 &Measurement.Token,
738 &Measurement.Module,
739 &Measurement.StartTimeStamp,
740 &Measurement.EndTimeStamp,
741 &Measurement.Identifier)) != 0)
742 {
743 AsciiStrToUnicodeStr (Measurement.Module, mGaugeString);
744 AsciiStrToUnicodeStr (Measurement.Token, mUnicodeToken);
745 mGaugeString[25] = 0;
746 mUnicodeToken[31] = 0;
747 if ( ! ( IsPhase( &Measurement) ||
748 (Measurement.Handle != NULL) ||
749 (Measurement.EndTimeStamp == 0)
750 ))
751 {
752 Duration = GetDuration (&Measurement);
753 ElapsedTime = DurationInMicroSeconds ( Duration );
754 if (ElapsedTime >= mInterestThreshold) {
755 if (mShowId) {
756 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GLOBAL_VARS2), gDpHiiHandle,
757 Index,
758 mGaugeString,
759 mUnicodeToken,
760 ElapsedTime,
761 Measurement.Identifier
762 );
763 } else {
764 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GLOBAL_VARS), gDpHiiHandle,
765 Index,
766 mGaugeString,
767 mUnicodeToken,
768 ElapsedTime
769 );
770 }
771 }
772 }
773 Index++;
774 }
775}
776
777/**
778 Gather and print cumulative data.
779
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.
784
785**/
786VOID
787ProcessCumulative(
788 VOID
789)
790{
791 UINT64 AvgDur; // the computed average duration
792 UINT64 Dur;
793 UINT64 MinDur;
794 UINT64 MaxDur;
795 EFI_STRING StringPtr;
796 UINTN TIndex;
797 EFI_STRING StringPtrUnknown;
798
799 StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
800 StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_CUMULATIVE), NULL);
801 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,
802 (StringPtr == NULL) ? StringPtrUnknown: StringPtr);
803 FreePool (StringPtr);
804 FreePool (StringPtrUnknown);
805
806 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_CUMULATIVE_SECT_1), gDpHiiHandle);
807 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_CUMULATIVE_SECT_2), gDpHiiHandle);
808 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), gDpHiiHandle);
809
810 for ( TIndex = 0; TIndex < NumCum; ++TIndex) {
811 if (CumData[TIndex].Count != 0) {
812 AvgDur = DivU64x32 (CumData[TIndex].Duration, CumData[TIndex].Count);
813 AvgDur = DurationInMicroSeconds(AvgDur);
814 Dur = DurationInMicroSeconds(CumData[TIndex].Duration);
815 MaxDur = DurationInMicroSeconds(CumData[TIndex].MaxDur);
816 MinDur = DurationInMicroSeconds(CumData[TIndex].MinDur);
817
818 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_CUMULATIVE_STATS), gDpHiiHandle,
819 CumData[TIndex].Name,
820 CumData[TIndex].Count,
821 Dur,
822 AvgDur,
823 MinDur,
824 MaxDur
825 );
826 }
827 }
828}