]> git.proxmox.com Git - mirror_edk2.git/blame - PerformancePkg/Dp_App/DpTrace.c
Add Doxygen style comments to the EFI_SIZE_TO_PAGES() and EFI_PAGES_TO_SIZE() macros...
[mirror_edk2.git] / PerformancePkg / Dp_App / DpTrace.c
CommitLineData
c06ad33e 1/** @file\r
2 * Trace reporting for the Dp utility.\r
3 *\r
92ea1df8 4 * Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r
c06ad33e 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/** Collect verbose statistics about the logged performance measurements.\r
33 *\r
34 * General Summary information for all Trace measurements is gathered and\r
35 * stored within the SummaryData structure. This information is both\r
36 * used internally by subsequent reporting functions, and displayed\r
37 * at the end of verbose reports.\r
38 *\r
39 * @pre The SummaryData and CumData structures must be initialized\r
40 * prior to calling this function.\r
41 *\r
42 * @post The SummaryData and CumData structures contain statistics for the\r
43 * current performance logs.\r
44**/\r
45VOID\r
46GatherStatistics(\r
47 VOID\r
48)\r
49{\r
50 MEASUREMENT_RECORD Measurement;\r
51 UINT64 Duration;\r
52 UINTN LogEntryKey;\r
fc48db0d 53 INTN TIndex;\r
c06ad33e 54\r
55 LogEntryKey = 0;\r
56 while ((LogEntryKey = GetPerformanceMeasurement (\r
57 LogEntryKey,\r
58 &Measurement.Handle,\r
59 &Measurement.Token,\r
60 &Measurement.Module,\r
61 &Measurement.StartTimeStamp,\r
62 &Measurement.EndTimeStamp)) != 0)\r
63 {\r
64 ++SummaryData.NumTrace; // Count the number of TRACE Measurement records\r
65 if (Measurement.EndTimeStamp == 0) {\r
66 ++SummaryData.NumIncomplete; // Count the incomplete records\r
67 continue;\r
68 }\r
69\r
70 if (Measurement.Handle != NULL) {\r
71 ++SummaryData.NumHandles; // Count the number of measurements with non-NULL handles\r
72 }\r
73\r
74 if (IsPhase( &Measurement)) {\r
75 ++SummaryData.NumSummary; // Count the number of major phases\r
76 }\r
77 else { // !IsPhase(...\r
78 if(Measurement.Handle == NULL) {\r
79 ++SummaryData.NumGlobal;\r
80 }\r
81 }\r
82\r
83 if (AsciiStrnCmp (Measurement.Token, ALit_PEIM, PERF_TOKEN_LENGTH) == 0) {\r
84 ++SummaryData.NumPEIMs; // Count PEIM measurements\r
85 }\r
86\r
87 Duration = GetDuration (&Measurement);\r
88 TIndex = GetCumulativeItem (&Measurement);\r
89 if (TIndex >= 0) {\r
90 CumData[TIndex].Duration += Duration;\r
91 CumData[TIndex].Count++;\r
92 if ( Duration < CumData[TIndex].MinDur ) {\r
93 CumData[TIndex].MinDur = Duration;\r
94 }\r
95 if ( Duration > CumData[TIndex].MaxDur ) {\r
96 CumData[TIndex].MaxDur = Duration;\r
97 }\r
98 }\r
99 }\r
100}\r
101\r
102/** Gather and print ALL Trace Records.\r
103 *\r
104 * Displays all "interesting" Trace measurements in order.<BR>\r
105 * The number of records displayed is controlled by:\r
106 * - records with a duration less than mInterestThreshold microseconds are not displayed.\r
107 * - No more than Limit records are displayed. A Limit of zero will not limit the output.\r
108 * - If the ExcludeFlag is TRUE, records matching entries in the CumData array are not\r
109 * displayed.\r
110 *\r
111 * @pre The mInterestThreshold global variable is set to the shortest duration to be printed.\r
112 * The mGaugeString and mUnicodeToken global arrays are used for temporary string storage.\r
113 * They must not be in use by a calling function.\r
114 *\r
115 * @param[in] Limit The number of records to print. Zero is ALL.\r
116 * @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.\r
117 *\r
118**/\r
119VOID\r
120DumpAllTrace(\r
121 IN UINTN Limit,\r
122 IN BOOLEAN ExcludeFlag\r
123 )\r
124{\r
125 MEASUREMENT_RECORD Measurement;\r
126 UINT64 ElapsedTime;\r
127 UINT64 Duration;\r
128 const CHAR16 *IncFlag;\r
129 UINTN LogEntryKey;\r
130 UINTN Count;\r
131 UINTN Index;\r
132 UINTN TIndex;\r
133\r
134 EFI_HANDLE *HandleBuffer;\r
135 UINTN Size;\r
136 EFI_HANDLE TempHandle;\r
137 EFI_STATUS Status;\r
138\r
139 IncFlag = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_ALL), NULL);\r
140 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),\r
141 (IncFlag == NULL) ? ALit_UNKNOWN: IncFlag);\r
142\r
143 // Get Handle information\r
144 //\r
145 Size = 0;\r
fc48db0d 146 HandleBuffer = &TempHandle;\r
c06ad33e 147 Status = gBS->LocateHandle (AllHandles, NULL, NULL, &Size, &TempHandle);\r
148 if (Status == EFI_BUFFER_TOO_SMALL) {\r
149 HandleBuffer = AllocatePool (Size);\r
150 ASSERT (HandleBuffer != NULL);\r
fc48db0d
ED
151 if (HandleBuffer == NULL) {\r
152 return;\r
153 }\r
c06ad33e 154 Status = gBS->LocateHandle (AllHandles, NULL, NULL, &Size, HandleBuffer);\r
155 }\r
156 if (EFI_ERROR (Status)) {\r
157 PrintToken (STRING_TOKEN (STR_DP_HANDLES_ERROR), Status);\r
158 }\r
159 else {\r
160 // We have successfully populated the HandleBuffer\r
161 // Display ALL Measurement Records\r
162 // Up to Limit lines displayed\r
163 // Display only records with Elapsed times >= mInterestThreshold\r
164 // Display driver names in Module field for records with Handles.\r
165 //\r
166 PrintToken (STRING_TOKEN (STR_DP_ALL_HEADR) );\r
167 PrintToken (STRING_TOKEN (STR_DP_DASHES) );\r
168\r
169 LogEntryKey = 0;\r
170 Count = 0;\r
171 Index = 0;\r
172 while ( WITHIN_LIMIT(Count, Limit) &&\r
173 ((LogEntryKey = GetPerformanceMeasurement (\r
174 LogEntryKey,\r
175 &Measurement.Handle,\r
176 &Measurement.Token,\r
177 &Measurement.Module,\r
178 &Measurement.StartTimeStamp,\r
179 &Measurement.EndTimeStamp)) != 0)\r
180 )\r
181 {\r
182 ++Index; // Count every record. First record is 1.\r
183 ElapsedTime = 0;\r
184 if (Measurement.EndTimeStamp != 0) {\r
185 Duration = GetDuration (&Measurement);\r
186 ElapsedTime = DurationInMicroSeconds ( Duration );\r
187 IncFlag = STR_DP_COMPLETE;\r
188 }\r
189 else {\r
190 IncFlag = STR_DP_INCOMPLETE; // Mark incomplete records\r
191 }\r
192 if ((ElapsedTime < mInterestThreshold) ||\r
193 ((ExcludeFlag) && (GetCumulativeItem(&Measurement) >= 0))\r
194 ) { // Ignore "uninteresting" or excluded records\r
195 continue;\r
196 }\r
197 if (Measurement.EndTimeStamp == 0) {\r
198 ElapsedTime = Measurement.StartTimeStamp;\r
199 }\r
200 ++Count; // Count the number of records printed\r
201\r
202 // If Handle is non-zero, see if we can determine a name for the driver\r
203 AsciiStrToUnicodeStr (Measurement.Module, mGaugeString); // Use Module by default\r
204 AsciiStrToUnicodeStr (Measurement.Token, mUnicodeToken);\r
205 if (Measurement.Handle != NULL) {\r
206 // See if the Handle is in the HandleBuffer\r
207 for (TIndex = 0; TIndex < (Size / sizeof(HandleBuffer[0])); TIndex++) {\r
208 if (Measurement.Handle == HandleBuffer[TIndex]) {\r
209 GetNameFromHandle (HandleBuffer[TIndex]);\r
210 break;\r
211 }\r
212 }\r
213 }\r
214 // Ensure that the argument strings are not too long.\r
215 mGaugeString[31] = 0;\r
216 mUnicodeToken[18] = 0;\r
217\r
218 PrintToken( STRING_TOKEN (STR_DP_ALL_STATS),\r
219 Index, // 1 based, Which measurement record is being printed\r
220 IncFlag,\r
221 Measurement.Handle,\r
222 mGaugeString,\r
223 mUnicodeToken,\r
224 ElapsedTime\r
225 );\r
226 }\r
227 }\r
fc48db0d
ED
228 if (HandleBuffer != &TempHandle) {\r
229 FreePool (HandleBuffer);\r
230 }\r
c06ad33e 231}\r
232\r
233/** Gather and print Raw Trace Records.\r
234 *\r
235 * All Trace measurements with a duration greater than or equal to\r
236 * mInterestThreshold are printed without interpretation.\r
237 *\r
238 * The number of records displayed is controlled by:\r
239 * - records with a duration less than mInterestThreshold microseconds are not displayed.\r
240 * - No more than Limit records are displayed. A Limit of zero will not limit the output.\r
241 * - If the ExcludeFlag is TRUE, records matching entries in the CumData array are not\r
242 * displayed.\r
243 *\r
244 * @pre The mInterestThreshold global variable is set to the shortest duration to be printed.\r
245 *\r
246 * @param[in] Limit The number of records to print. Zero is ALL.\r
247 * @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.\r
248 *\r
249**/\r
250VOID\r
251DumpRawTrace(\r
252 IN UINTN Limit,\r
253 IN BOOLEAN ExcludeFlag\r
254 )\r
255{\r
256 MEASUREMENT_RECORD Measurement;\r
257 UINT64 ElapsedTime;\r
258 UINT64 Duration;\r
259 UINTN LogEntryKey;\r
260 UINTN Count;\r
261 UINTN Index;\r
262\r
263 EFI_STRING StringPtr;\r
264\r
265 StringPtr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_RAWTRACE), NULL);\r
266 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),\r
267 (StringPtr == NULL) ? ALit_UNKNOWN: StringPtr);\r
268\r
269 PrintToken (STRING_TOKEN (STR_DP_RAW_HEADR) );\r
270 PrintToken (STRING_TOKEN (STR_DP_RAW_DASHES) );\r
271\r
272 LogEntryKey = 0;\r
273 Count = 0;\r
274 Index = 0;\r
275 while ( WITHIN_LIMIT(Count, Limit) &&\r
276 ((LogEntryKey = GetPerformanceMeasurement (\r
277 LogEntryKey,\r
278 &Measurement.Handle,\r
279 &Measurement.Token,\r
280 &Measurement.Module,\r
281 &Measurement.StartTimeStamp,\r
282 &Measurement.EndTimeStamp)) != 0)\r
283 )\r
284 {\r
285 ++Index; // Count every record. First record is 1.\r
286 ElapsedTime = 0;\r
287 if (Measurement.EndTimeStamp != 0) {\r
288 Duration = GetDuration (&Measurement);\r
289 ElapsedTime = DurationInMicroSeconds ( Duration );\r
290 }\r
291 if ((ElapsedTime < mInterestThreshold) ||\r
292 ((ExcludeFlag) && (GetCumulativeItem(&Measurement) >= 0))\r
293 ) { // Ignore "uninteresting" or Excluded records\r
294 continue;\r
295 }\r
296 ++Count; // Count the number of records printed\r
297 PrintToken (STRING_TOKEN (STR_DP_RAW_VARS),\r
298 Index, // 1 based, Which measurement record is being printed\r
299 Measurement.Handle,\r
300 Measurement.StartTimeStamp,\r
301 Measurement.EndTimeStamp,\r
302 Measurement.Token,\r
303 Measurement.Module\r
304 );\r
305 }\r
306}\r
307\r
308/** Gather and print Major Phase metrics.\r
309 *\r
310 * @param[in] Ticker The timer value for the END of Shell phase\r
311 *\r
312**/\r
313VOID\r
314ProcessPhases(\r
315 UINT64 Ticker\r
316 )\r
317{\r
318 MEASUREMENT_RECORD Measurement;\r
319 UINT64 BdsTimeoutValue = 0;\r
320 UINT64 SecTime = 0;\r
321 UINT64 PeiTime = 0;\r
322 UINT64 DxeTime = 0;\r
323 UINT64 BdsTime = 0;\r
324 UINT64 ShellTime = 0;\r
325 UINT64 ElapsedTime;\r
326 UINT64 Duration;\r
327 UINT64 Total;\r
328 EFI_STRING StringPtr;\r
329 UINTN LogEntryKey;\r
330\r
331 //\r
332 // Get Execution Phase Statistics\r
333 //\r
334 StringPtr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_PHASES), NULL);\r
335 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),\r
336 (StringPtr == NULL) ? ALit_UNKNOWN: StringPtr);\r
337\r
338 LogEntryKey = 0;\r
339 while ((LogEntryKey = GetPerformanceMeasurement (\r
340 LogEntryKey,\r
341 &Measurement.Handle,\r
342 &Measurement.Token,\r
343 &Measurement.Module,\r
344 &Measurement.StartTimeStamp,\r
345 &Measurement.EndTimeStamp)) != 0)\r
346 {\r
347 if (AsciiStrnCmp (Measurement.Token, ALit_SHELL, PERF_TOKEN_LENGTH) == 0) {\r
348 Measurement.EndTimeStamp = Ticker;\r
349 }\r
350 if (Measurement.EndTimeStamp == 0) { // Skip "incomplete" records\r
351 continue;\r
352 }\r
353 Duration = GetDuration (&Measurement);\r
354 if ( Measurement.Handle != NULL\r
355 && (AsciiStrnCmp (Measurement.Token, ALit_BdsTO, PERF_TOKEN_LENGTH) == 0)\r
356 )\r
357 {\r
358 BdsTimeoutValue = Duration;\r
359 } else if (AsciiStrnCmp (Measurement.Token, ALit_SEC, PERF_TOKEN_LENGTH) == 0) {\r
360 SecTime = Duration;\r
361 } else if (AsciiStrnCmp (Measurement.Token, ALit_PEI, PERF_TOKEN_LENGTH) == 0) {\r
362 PeiTime = Duration;\r
363 } else if (AsciiStrnCmp (Measurement.Token, ALit_DXE, PERF_TOKEN_LENGTH) == 0) {\r
364 DxeTime = Duration;\r
365 } else if (AsciiStrnCmp (Measurement.Token, ALit_BDS, PERF_TOKEN_LENGTH) == 0) {\r
366 BdsTime = Duration;\r
367 } else if (AsciiStrnCmp (Measurement.Token, ALit_SHELL, PERF_TOKEN_LENGTH) == 0) {\r
368 ShellTime = Duration;\r
369 }\r
370 }\r
371\r
372 Total = 0;\r
373\r
374 // print SEC phase duration time\r
375 //\r
376 if (SecTime > 0) {\r
377 ElapsedTime = DurationInMicroSeconds ( SecTime ); // Calculate elapsed time in microseconds\r
378 Total += DivU64x32 (ElapsedTime, 1000); // Accumulate time in milliseconds\r
379 PrintToken (STRING_TOKEN (STR_DP_SEC_PHASE), ElapsedTime);\r
380 }\r
381\r
382 // print PEI phase duration time\r
383 //\r
384 if (PeiTime > 0) {\r
385 ElapsedTime = DivU64x32 (\r
386 PeiTime,\r
387 (UINT32)TimerInfo.Frequency\r
388 );\r
389 Total += ElapsedTime;\r
390 PrintToken (STRING_TOKEN (STR_DP_PHASE_DURATION), ALit_PEI, ElapsedTime);\r
391 }\r
392\r
393 // print DXE phase duration time\r
394 //\r
395 if (DxeTime > 0) {\r
396 ElapsedTime = DivU64x32 (\r
397 DxeTime,\r
398 (UINT32)TimerInfo.Frequency\r
399 );\r
400 Total += ElapsedTime;\r
401 PrintToken (STRING_TOKEN (STR_DP_PHASE_DURATION), ALit_DXE, ElapsedTime);\r
402 }\r
403\r
404 // print BDS phase duration time\r
405 //\r
406 if (BdsTime > 0) {\r
407 ElapsedTime = DivU64x32 (\r
408 BdsTime,\r
409 (UINT32)TimerInfo.Frequency\r
410 );\r
411 Total += ElapsedTime;\r
412 PrintToken (STRING_TOKEN (STR_DP_PHASE_DURATION), ALit_BDS, ElapsedTime);\r
413 }\r
414\r
415 if (BdsTimeoutValue > 0) {\r
416 ElapsedTime = DivU64x32 (\r
417 BdsTimeoutValue,\r
418 (UINT32)TimerInfo.Frequency\r
419 );\r
420 PrintToken (STRING_TOKEN (STR_DP_PHASE_BDSTO), ALit_BdsTO, ElapsedTime);\r
421 }\r
422\r
423 // print SHELL phase duration time\r
424 //\r
425 if (ShellTime > 0) {\r
426 ElapsedTime = DivU64x32 (\r
427 ShellTime,\r
428 (UINT32)TimerInfo.Frequency\r
429 );\r
430 Total += ElapsedTime;\r
431 PrintToken (STRING_TOKEN (STR_DP_PHASE_DURATION), ALit_SHELL, ElapsedTime);\r
432 }\r
433\r
434 PrintToken (STRING_TOKEN (STR_DP_TOTAL_DURATION), Total);\r
435}\r
436\r
437/** Gather and print Handle data.\r
438 *\r
439 * @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.\r
440 *\r
441 * @return Status from a call to gBS->LocateHandle().\r
442**/\r
443EFI_STATUS\r
444ProcessHandles(\r
445 IN BOOLEAN ExcludeFlag\r
446 )\r
447{\r
448 MEASUREMENT_RECORD Measurement;\r
449 UINT64 ElapsedTime;\r
450 UINT64 Duration;\r
451 EFI_HANDLE *HandleBuffer;\r
452 EFI_STRING StringPtr;\r
453 UINTN Index;\r
454 UINTN LogEntryKey;\r
455 UINTN Count;\r
456 UINTN Size;\r
457 EFI_HANDLE TempHandle;\r
458 EFI_STATUS Status;\r
459\r
460 StringPtr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_DRIVERS), NULL);\r
461 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),\r
462 (StringPtr == NULL) ? ALit_UNKNOWN: StringPtr);\r
463\r
464 Size = 0;\r
fc48db0d 465 HandleBuffer = &TempHandle;\r
c06ad33e 466 Status = gBS->LocateHandle (AllHandles, NULL, NULL, &Size, &TempHandle);\r
467 if (Status == EFI_BUFFER_TOO_SMALL) {\r
468 HandleBuffer = AllocatePool (Size);\r
469 ASSERT (HandleBuffer != NULL);\r
fc48db0d
ED
470 if (HandleBuffer == NULL) {\r
471 return;\r
472 }\r
c06ad33e 473 Status = gBS->LocateHandle (AllHandles, NULL, NULL, &Size, HandleBuffer);\r
474 }\r
475 if (EFI_ERROR (Status)) {\r
476 PrintToken (STRING_TOKEN (STR_DP_HANDLES_ERROR), Status);\r
477 }\r
478 else {\r
479#if DP_DEBUG == 2\r
480 Print (L"There are %,d Handles defined.\n", (Size / sizeof(HandleBuffer[0])));\r
481#endif\r
482\r
483 PrintToken (STRING_TOKEN (STR_DP_HANDLE_GUID) );\r
484 PrintToken (STRING_TOKEN (STR_DP_DASHES) );\r
485\r
486 LogEntryKey = 0;\r
487 Count = 0;\r
488 while ((LogEntryKey = GetPerformanceMeasurement (\r
489 LogEntryKey,\r
490 &Measurement.Handle,\r
491 &Measurement.Token,\r
492 &Measurement.Module,\r
493 &Measurement.StartTimeStamp,\r
494 &Measurement.EndTimeStamp)) != 0)\r
495 {\r
496 Count++;\r
497 Duration = GetDuration (&Measurement);\r
498 ElapsedTime = DurationInMicroSeconds ( Duration );\r
499 if ((ElapsedTime < mInterestThreshold) ||\r
500 (Measurement.EndTimeStamp == 0) ||\r
501 (Measurement.Handle == NULL) ||\r
502 ((ExcludeFlag) && (GetCumulativeItem(&Measurement) >= 0))\r
503 ) { // Ignore "uninteresting" or excluded records\r
504 continue;\r
505 }\r
506 mGaugeString[0] = 0; // Empty driver name by default\r
507 AsciiStrToUnicodeStr (Measurement.Token, mUnicodeToken);\r
508 // See if the Handle is in the HandleBuffer\r
509 for (Index = 0; Index < (Size / sizeof(HandleBuffer[0])); Index++) {\r
510 if (Measurement.Handle == HandleBuffer[Index]) {\r
511 GetNameFromHandle (HandleBuffer[Index]); // Name is put into mGaugeString\r
512 break;\r
513 }\r
514 }\r
515 // Ensure that the argument strings are not too long.\r
516 mGaugeString[31] = 0;\r
517 mUnicodeToken[18] = 0;\r
518 if (mGaugeString[0] != 0) {\r
519 // Display the record if it has a valid handle.\r
520 PrintToken (\r
521 STRING_TOKEN (STR_DP_HANDLE_VARS),\r
522 Count, // 1 based, Which measurement record is being printed\r
523 Index + 1, // 1 based, Which handle is being printed\r
524 mGaugeString,\r
525 mUnicodeToken,\r
526 ElapsedTime\r
527 );\r
528 }\r
529 }\r
530 }\r
fc48db0d
ED
531 if (HandleBuffer != &TempHandle) {\r
532 FreePool (HandleBuffer);\r
533 }\r
c06ad33e 534 return Status;\r
535}\r
536\r
537/** Gather and print PEIM data.\r
538 *\r
539 * Only prints complete PEIM records\r
540 *\r
541**/\r
542VOID\r
543ProcessPeims(\r
544 VOID\r
545)\r
546{\r
547 MEASUREMENT_RECORD Measurement;\r
548 UINT64 Duration;\r
549 UINT64 ElapsedTime;\r
550 EFI_STRING StringPtr;\r
551 UINTN LogEntryKey;\r
552 UINTN TIndex;\r
553\r
554\r
555 StringPtr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_PEIMS), NULL);\r
556 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),\r
557 (StringPtr == NULL) ? ALit_UNKNOWN: StringPtr);\r
558\r
559 PrintToken (STRING_TOKEN (STR_DP_PEIM_SECTION));\r
560 PrintToken (STRING_TOKEN (STR_DP_DASHES));\r
561 TIndex = 0;\r
562 LogEntryKey = 0;\r
563 while ((LogEntryKey = GetPerformanceMeasurement (\r
564 LogEntryKey,\r
565 &Measurement.Handle,\r
566 &Measurement.Token,\r
567 &Measurement.Module,\r
568 &Measurement.StartTimeStamp,\r
569 &Measurement.EndTimeStamp)) != 0)\r
570 {\r
571 TIndex++;\r
572 if ((Measurement.EndTimeStamp == 0) ||\r
573 (AsciiStrnCmp (Measurement.Token, ALit_PEIM, PERF_TOKEN_LENGTH) != 0)\r
574 ) {\r
575 continue;\r
576 }\r
577\r
578 Duration = GetDuration (&Measurement);\r
579 ElapsedTime = DurationInMicroSeconds ( Duration ); // Calculate elapsed time in microseconds\r
580 if (ElapsedTime >= mInterestThreshold) {\r
16d5d168 581 GetNameFromHandle ((EFI_HANDLE) Measurement.Handle); // Name placed in mGaugeString\r
c06ad33e 582 PrintToken (STRING_TOKEN (STR_DP_PEIM_STAT2),\r
583 TIndex, // 1 based, Which measurement record is being printed\r
584 Measurement.Handle,\r
585 mGaugeString,\r
586 ElapsedTime\r
587 );\r
588 }\r
589 }\r
590}\r
591\r
592/** Gather and print global data.\r
593 *\r
594 * Strips out incomplete or "Execution Phase" records\r
595 * Only prints records where Handle is NULL\r
596 * Increment TIndex for every record, even skipped ones, so that we have an\r
597 * indication of every measurement record taken.\r
598 *\r
599 *\r
600**/\r
601VOID\r
602ProcessGlobal(\r
603 VOID\r
604)\r
605{\r
606 MEASUREMENT_RECORD Measurement;\r
607 UINT64 Duration;\r
608 UINT64 ElapsedTime;\r
609 EFI_STRING StringPtr;\r
610 UINTN LogEntryKey;\r
611 UINTN Index; // Index, or number, of the measurement record being processed\r
612\r
613 StringPtr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_GENERAL), NULL);\r
614 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),\r
615 (StringPtr == NULL) ? ALit_UNKNOWN: StringPtr);\r
616\r
617 PrintToken (STRING_TOKEN (STR_DP_GLOBAL_SECTION));\r
618 PrintToken (STRING_TOKEN (STR_DP_DASHES));\r
619\r
620 Index = 1;\r
621 LogEntryKey = 0;\r
622\r
623 while ((LogEntryKey = GetPerformanceMeasurement (\r
624 LogEntryKey,\r
625 &Measurement.Handle,\r
626 &Measurement.Token,\r
627 &Measurement.Module,\r
628 &Measurement.StartTimeStamp,\r
629 &Measurement.EndTimeStamp)) != 0)\r
630 {\r
631 AsciiStrToUnicodeStr (Measurement.Module, mGaugeString);\r
632 AsciiStrToUnicodeStr (Measurement.Token, mUnicodeToken);\r
633 if ( ! ( IsPhase( &Measurement) ||\r
634 (Measurement.Handle != NULL) ||\r
635 (Measurement.EndTimeStamp == 0)\r
636 ))\r
637 {\r
638 Duration = GetDuration (&Measurement);\r
639 ElapsedTime = DurationInMicroSeconds ( Duration );\r
640 if (ElapsedTime >= mInterestThreshold) {\r
641 PrintToken (\r
642 STRING_TOKEN (STR_DP_FOUR_VARS_2),\r
643 Index,\r
644 mGaugeString,\r
645 mUnicodeToken,\r
646 ElapsedTime\r
647 );\r
648 }\r
649 }\r
650 Index++;\r
651 }\r
652}\r
653\r
654/** Gather and print cumulative data.\r
655 *\r
656 * Traverse the measurement records and:<BR>\r
657 * For each record with a Token listed in the CumData array:<BR>\r
658 * - Update the instance count and the total, minimum, and maximum durations.\r
659 * Finally, print the gathered cumulative statistics.\r
660 *\r
661**/\r
662VOID\r
663ProcessCumulative(\r
664 VOID\r
665)\r
666{\r
667 UINT64 avgval; // the computed average duration\r
668 EFI_STRING StringPtr;\r
669 UINTN TIndex;\r
670\r
671\r
672 StringPtr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_CUMULATIVE), NULL);\r
673 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),\r
674 (StringPtr == NULL) ? ALit_UNKNOWN: StringPtr);\r
675\r
676 PrintToken (STRING_TOKEN (STR_DP_CUMULATIVE_SECT_1));\r
677 PrintToken (STRING_TOKEN (STR_DP_CUMULATIVE_SECT_2));\r
678 PrintToken (STRING_TOKEN (STR_DP_DASHES));\r
679\r
680 for ( TIndex = 0; TIndex < NumCum; ++TIndex) {\r
681 avgval = DivU64x32 (CumData[TIndex].Duration, CumData[TIndex].Count);\r
682 PrintToken (STRING_TOKEN (STR_DP_CUMULATIVE_STATS),\r
683 CumData[TIndex].Name,\r
684 CumData[TIndex].Count,\r
685 DurationInMicroSeconds(CumData[TIndex].Duration),\r
686 DurationInMicroSeconds(avgval),\r
687 DurationInMicroSeconds(CumData[TIndex].MinDur),\r
688 DurationInMicroSeconds(CumData[TIndex].MaxDur)\r
689 );\r
690 }\r
691}\r