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