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