]> git.proxmox.com Git - mirror_edk2.git/blame - 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
c06ad33e 1/** @file\r
86da563d
ED
2 Trace reporting for the Dp utility.\r
3\r
0b84f444 4 Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>\r
86da563d
ED
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
c06ad33e 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
0b84f444 57 while ((LogEntryKey = GetPerformanceMeasurementEx (\r
c06ad33e 58 LogEntryKey,\r
59 &Measurement.Handle,\r
60 &Measurement.Token,\r
61 &Measurement.Module,\r
62 &Measurement.StartTimeStamp,\r
0b84f444
SZ
63 &Measurement.EndTimeStamp,\r
64 &Measurement.Identifier)) != 0)\r
c06ad33e 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
9dd74618
ED
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
c06ad33e 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
88359546 141 EFI_STRING StringPtrUnknown;\r
c06ad33e 142\r
88359546 143 StringPtrUnknown = HiiGetString (gHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL); \r
c06ad33e 144 IncFlag = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_ALL), NULL);\r
145 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),\r
88359546
ED
146 (IncFlag == NULL) ? StringPtrUnknown : IncFlag);\r
147 FreePool (StringPtrUnknown);\r
c06ad33e 148\r
149 // Get Handle information\r
150 //\r
151 Size = 0;\r
fc48db0d 152 HandleBuffer = &TempHandle;\r
c06ad33e 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
fc48db0d
ED
157 if (HandleBuffer == NULL) {\r
158 return;\r
159 }\r
c06ad33e 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
0b84f444
SZ
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
c06ad33e 179\r
180 LogEntryKey = 0;\r
181 Count = 0;\r
182 Index = 0;\r
183 while ( WITHIN_LIMIT(Count, Limit) &&\r
0b84f444 184 ((LogEntryKey = GetPerformanceMeasurementEx (\r
c06ad33e 185 LogEntryKey,\r
186 &Measurement.Handle,\r
187 &Measurement.Token,\r
188 &Measurement.Module,\r
189 &Measurement.StartTimeStamp,\r
0b84f444
SZ
190 &Measurement.EndTimeStamp,\r
191 &Measurement.Identifier)) != 0)\r
c06ad33e 192 )\r
193 {\r
194 ++Index; // Count every record. First record is 1.\r
195 ElapsedTime = 0;\r
0b84f444 196 SafeFreePool ((VOID *) IncFlag);\r
c06ad33e 197 if (Measurement.EndTimeStamp != 0) {\r
198 Duration = GetDuration (&Measurement);\r
199 ElapsedTime = DurationInMicroSeconds ( Duration );\r
88359546 200 IncFlag = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_COMPLETE), NULL);\r
c06ad33e 201 }\r
202 else {\r
88359546 203 IncFlag = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_INCOMPLETE), NULL); // Mark incomplete records\r
c06ad33e 204 }\r
a2daf8db 205 if (((Measurement.EndTimeStamp != 0) && (ElapsedTime < mInterestThreshold)) ||\r
c06ad33e 206 ((ExcludeFlag) && (GetCumulativeItem(&Measurement) >= 0))\r
207 ) { // Ignore "uninteresting" or excluded records\r
208 continue;\r
209 }\r
c06ad33e 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
a2daf8db
SZ
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
c06ad33e 229 // Ensure that the argument strings are not too long.\r
a2daf8db
SZ
230 mGaugeString[DP_GAUGE_STRING_LENGTH] = 0;\r
231 mUnicodeToken[13] = 0;\r
c06ad33e 232\r
0b84f444
SZ
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
c06ad33e 253 }\r
254 }\r
fc48db0d
ED
255 if (HandleBuffer != &TempHandle) {\r
256 FreePool (HandleBuffer);\r
257 }\r
0b84f444 258 SafeFreePool ((VOID *) IncFlag);\r
c06ad33e 259}\r
260\r
9dd74618
ED
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
c06ad33e 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
88359546 293 EFI_STRING StringPtrUnknown;\r
c06ad33e 294\r
88359546 295 StringPtrUnknown = HiiGetString (gHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL); \r
c06ad33e 296 StringPtr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_RAWTRACE), NULL);\r
297 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),\r
88359546
ED
298 (StringPtr == NULL) ? StringPtrUnknown : StringPtr);\r
299 FreePool (StringPtr);\r
300 FreePool (StringPtrUnknown);\r
c06ad33e 301\r
0b84f444
SZ
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
c06ad33e 309\r
310 LogEntryKey = 0;\r
311 Count = 0;\r
312 Index = 0;\r
313 while ( WITHIN_LIMIT(Count, Limit) &&\r
0b84f444 314 ((LogEntryKey = GetPerformanceMeasurementEx (\r
c06ad33e 315 LogEntryKey,\r
316 &Measurement.Handle,\r
317 &Measurement.Token,\r
318 &Measurement.Module,\r
319 &Measurement.StartTimeStamp,\r
0b84f444
SZ
320 &Measurement.EndTimeStamp,\r
321 &Measurement.Identifier)) != 0)\r
c06ad33e 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
0b84f444
SZ
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
c06ad33e 357 }\r
358}\r
359\r
9dd74618
ED
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
c06ad33e 365**/\r
366VOID\r
367ProcessPhases(\r
cbdf19a5 368 IN UINT64 Ticker\r
c06ad33e 369 )\r
370{\r
371 MEASUREMENT_RECORD Measurement;\r
9dd74618
ED
372 UINT64 BdsTimeoutValue;\r
373 UINT64 SecTime;\r
374 UINT64 PeiTime;\r
375 UINT64 DxeTime;\r
376 UINT64 BdsTime;\r
377 UINT64 ShellTime;\r
c06ad33e 378 UINT64 ElapsedTime;\r
379 UINT64 Duration;\r
380 UINT64 Total;\r
381 EFI_STRING StringPtr;\r
382 UINTN LogEntryKey;\r
88359546 383 EFI_STRING StringPtrUnknown;\r
c06ad33e 384\r
9dd74618
ED
385 BdsTimeoutValue = 0;\r
386 SecTime = 0;\r
387 PeiTime = 0;\r
388 DxeTime = 0;\r
389 BdsTime = 0;\r
390 ShellTime = 0; \r
c06ad33e 391 //\r
392 // Get Execution Phase Statistics\r
393 //\r
88359546 394 StringPtrUnknown = HiiGetString (gHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL); \r
c06ad33e 395 StringPtr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_PHASES), NULL);\r
396 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),\r
88359546
ED
397 (StringPtr == NULL) ? StringPtrUnknown : StringPtr);\r
398 FreePool (StringPtr);\r
399 FreePool (StringPtrUnknown);\r
c06ad33e 400\r
401 LogEntryKey = 0;\r
0b84f444 402 while ((LogEntryKey = GetPerformanceMeasurementEx (\r
c06ad33e 403 LogEntryKey,\r
404 &Measurement.Handle,\r
405 &Measurement.Token,\r
406 &Measurement.Module,\r
407 &Measurement.StartTimeStamp,\r
0b84f444
SZ
408 &Measurement.EndTimeStamp,\r
409 &Measurement.Identifier)) != 0)\r
c06ad33e 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
9dd74618
ED
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
c06ad33e 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
88359546 524 EFI_STRING StringPtrUnknown;\r
c06ad33e 525\r
88359546 526 StringPtrUnknown = HiiGetString (gHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL); \r
c06ad33e 527 StringPtr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_DRIVERS), NULL);\r
528 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),\r
88359546
ED
529 (StringPtr == NULL) ? StringPtrUnknown : StringPtr);\r
530 FreePool (StringPtr);\r
531 FreePool (StringPtrUnknown);\r
c06ad33e 532\r
533 Size = 0;\r
fc48db0d 534 HandleBuffer = &TempHandle;\r
c06ad33e 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
fc48db0d 539 if (HandleBuffer == NULL) {\r
224beee0 540 return Status;\r
fc48db0d 541 }\r
c06ad33e 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
0b84f444
SZ
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
c06ad33e 557 PrintToken (STRING_TOKEN (STR_DP_DASHES) );\r
558\r
559 LogEntryKey = 0;\r
560 Count = 0;\r
0b84f444 561 while ((LogEntryKey = GetPerformanceMeasurementEx (\r
c06ad33e 562 LogEntryKey,\r
563 &Measurement.Handle,\r
564 &Measurement.Token,\r
565 &Measurement.Module,\r
566 &Measurement.StartTimeStamp,\r
0b84f444
SZ
567 &Measurement.EndTimeStamp,\r
568 &Measurement.Identifier)) != 0)\r
c06ad33e 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
a2daf8db
SZ
590 mGaugeString[DP_GAUGE_STRING_LENGTH] = 0;\r
591 mUnicodeToken[11] = 0;\r
c06ad33e 592 if (mGaugeString[0] != 0) {\r
593 // Display the record if it has a valid handle.\r
0b84f444
SZ
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
c06ad33e 614 }\r
615 }\r
616 }\r
fc48db0d
ED
617 if (HandleBuffer != &TempHandle) {\r
618 FreePool (HandleBuffer);\r
619 }\r
c06ad33e 620 return Status;\r
621}\r
622\r
9dd74618
ED
623/** \r
624 Gather and print PEIM data.\r
625 \r
626 Only prints complete PEIM records\r
627 \r
c06ad33e 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
88359546 640 EFI_STRING StringPtrUnknown;\r
c06ad33e 641\r
88359546 642 StringPtrUnknown = HiiGetString (gHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL); \r
c06ad33e 643 StringPtr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_PEIMS), NULL);\r
644 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),\r
88359546
ED
645 (StringPtr == NULL) ? StringPtrUnknown : StringPtr);\r
646 FreePool (StringPtr);\r
647 FreePool (StringPtrUnknown);\r
c06ad33e 648\r
0b84f444
SZ
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
c06ad33e 654 PrintToken (STRING_TOKEN (STR_DP_DASHES));\r
655 TIndex = 0;\r
656 LogEntryKey = 0;\r
0b84f444 657 while ((LogEntryKey = GetPerformanceMeasurementEx (\r
c06ad33e 658 LogEntryKey,\r
659 &Measurement.Handle,\r
660 &Measurement.Token,\r
661 &Measurement.Module,\r
662 &Measurement.StartTimeStamp,\r
0b84f444
SZ
663 &Measurement.EndTimeStamp,\r
664 &Measurement.Identifier)) != 0)\r
c06ad33e 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
c3522526 676 // PEIM FILE Handle is the start address of its FFS file that contains its file guid.\r
0b84f444
SZ
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
c06ad33e 693 }\r
694 }\r
695}\r
696\r
9dd74618
ED
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
c06ad33e 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
88359546 717 EFI_STRING StringPtrUnknown;\r
c06ad33e 718\r
88359546 719 StringPtrUnknown = HiiGetString (gHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL); \r
c06ad33e 720 StringPtr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_GENERAL), NULL);\r
721 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),\r
88359546
ED
722 (StringPtr == NULL) ? StringPtrUnknown: StringPtr);\r
723 FreePool (StringPtr);\r
724 FreePool (StringPtrUnknown);\r
c06ad33e 725\r
0b84f444
SZ
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
c06ad33e 731 PrintToken (STRING_TOKEN (STR_DP_DASHES));\r
732\r
733 Index = 1;\r
734 LogEntryKey = 0;\r
735\r
0b84f444 736 while ((LogEntryKey = GetPerformanceMeasurementEx (\r
c06ad33e 737 LogEntryKey,\r
738 &Measurement.Handle,\r
739 &Measurement.Token,\r
740 &Measurement.Module,\r
741 &Measurement.StartTimeStamp,\r
0b84f444
SZ
742 &Measurement.EndTimeStamp,\r
743 &Measurement.Identifier)) != 0)\r
c06ad33e 744 {\r
745 AsciiStrToUnicodeStr (Measurement.Module, mGaugeString);\r
746 AsciiStrToUnicodeStr (Measurement.Token, mUnicodeToken);\r
0b84f444 747 mGaugeString[25] = 0;\r
a2daf8db 748 mUnicodeToken[31] = 0;\r
c06ad33e 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
0b84f444
SZ
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
c06ad33e 775 }\r
776 }\r
777 Index++;\r
778 }\r
779}\r
780\r
9dd74618
ED
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
c06ad33e 789**/\r
790VOID\r
791ProcessCumulative(\r
792 VOID\r
793)\r
794{\r
5460c4bb
ED
795 UINT64 AvgDur; // the computed average duration\r
796 UINT64 Dur;\r
797 UINT64 MinDur;\r
798 UINT64 MaxDur;\r
c06ad33e 799 EFI_STRING StringPtr;\r
800 UINTN TIndex;\r
88359546 801 EFI_STRING StringPtrUnknown;\r
c06ad33e 802\r
88359546 803 StringPtrUnknown = HiiGetString (gHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL); \r
c06ad33e 804 StringPtr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_CUMULATIVE), NULL);\r
805 PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),\r
88359546
ED
806 (StringPtr == NULL) ? StringPtrUnknown: StringPtr);\r
807 FreePool (StringPtr);\r
808 FreePool (StringPtrUnknown);\r
c06ad33e 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
0d70a709
SZ
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
5460c4bb 821 \r
0d70a709
SZ
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
c06ad33e 831 }\r
832}\r