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