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