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