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