]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiDpLib/DpTrace.c
PerformancePkg/Dp_App: Support execution break
[mirror_edk2.git] / ShellPkg / Library / UefiDpLib / DpTrace.c
CommitLineData
d41bc92c 1/** @file\r
2 Trace reporting for the Dp utility.\r
3\r
4 Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.\r
64c51ed1 5 (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>\r
d41bc92c 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
a06795c6
CS
46\r
47 @param[in, out] CustomCumulativeData A pointer to the cumtom cumulative data.\r
48\r
d41bc92c 49**/\r
50VOID\r
51GatherStatistics(\r
a06795c6
CS
52 IN OUT PERF_CUM_DATA *CustomCumulativeData OPTIONAL\r
53 )\r
d41bc92c 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
a06795c6
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
d41bc92c 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**/\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 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
64c51ed1 156 UINTN HandleCount;\r
d41bc92c 157 EFI_STATUS Status;\r
158 EFI_STRING StringPtrUnknown;\r
159\r
160 StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);\r
161 IncFlag = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_ALL), NULL);\r
162 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,\r
163 (IncFlag == NULL) ? StringPtrUnknown : IncFlag);\r
164 FreePool (StringPtrUnknown);\r
165\r
166 // Get Handle information\r
167 //\r
64c51ed1 168 Status = gBS->LocateHandleBuffer (AllHandles, NULL, NULL, &HandleCount, &HandleBuffer);\r
d41bc92c 169 if (EFI_ERROR (Status)) {\r
170 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLES_ERROR), gDpHiiHandle, 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
179 if (mShowId) {\r
180 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_ALL_HEADR2), gDpHiiHandle);\r
181 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_ALL_DASHES2), gDpHiiHandle);\r
182 } else {\r
183 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_ALL_HEADR), gDpHiiHandle);\r
184 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), gDpHiiHandle);\r
185 }\r
186\r
187 LogEntryKey = 0;\r
188 Count = 0;\r
189 Index = 0;\r
190 while ( WITHIN_LIMIT(Count, Limit) &&\r
191 ((LogEntryKey = GetPerformanceMeasurementEx (\r
192 LogEntryKey,\r
193 &Measurement.Handle,\r
194 &Measurement.Token,\r
195 &Measurement.Module,\r
196 &Measurement.StartTimeStamp,\r
197 &Measurement.EndTimeStamp,\r
198 &Measurement.Identifier)) != 0)\r
199 )\r
200 {\r
201 ++Index; // Count every record. First record is 1.\r
202 ElapsedTime = 0;\r
203 SHELL_FREE_NON_NULL (IncFlag);\r
204 if (Measurement.EndTimeStamp != 0) {\r
205 Duration = GetDuration (&Measurement);\r
206 ElapsedTime = DurationInMicroSeconds ( Duration );\r
207 IncFlag = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_COMPLETE), NULL);\r
208 }\r
209 else {\r
210 IncFlag = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_INCOMPLETE), NULL); // Mark incomplete records\r
211 }\r
212 if (((Measurement.EndTimeStamp != 0) && (ElapsedTime < mInterestThreshold)) ||\r
213 ((ExcludeFlag) && (GetCumulativeItem(&Measurement) >= 0))\r
214 ) { // Ignore "uninteresting" or excluded records\r
215 continue;\r
216 }\r
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
64c51ed1 224 for (TIndex = 0; TIndex < HandleCount; TIndex++) {\r
d41bc92c 225 if (Measurement.Handle == HandleBuffer[TIndex]) {\r
2c55a81a 226 DpGetNameFromHandle (HandleBuffer[TIndex]);\r
d41bc92c 227 break;\r
228 }\r
229 }\r
230 }\r
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
236 // Ensure that the argument strings are not too long.\r
237 mGaugeString[DP_GAUGE_STRING_LENGTH] = 0;\r
238 mUnicodeToken[13] = 0;\r
239\r
240 if (mShowId) {\r
241 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_ALL_VARS2), gDpHiiHandle,\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 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_ALL_VARS), gDpHiiHandle,\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
260 }\r
261 }\r
64c51ed1 262 if (HandleBuffer != NULL) {\r
d41bc92c 263 FreePool (HandleBuffer);\r
264 }\r
265 SHELL_FREE_NON_NULL (IncFlag);\r
266}\r
267\r
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
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
300 EFI_STRING StringPtrUnknown;\r
301\r
302 StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL); \r
303 StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_RAWTRACE), NULL);\r
304 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,\r
305 (StringPtr == NULL) ? StringPtrUnknown : StringPtr);\r
306 FreePool (StringPtr);\r
307 FreePool (StringPtrUnknown);\r
308\r
309 if (mShowId) {\r
310 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_HEADR2), gDpHiiHandle);\r
311 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_DASHES2), gDpHiiHandle);\r
312 } else {\r
313 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_HEADR), gDpHiiHandle);\r
314 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_DASHES), gDpHiiHandle);\r
315 }\r
316\r
317 LogEntryKey = 0;\r
318 Count = 0;\r
319 Index = 0;\r
320 while ( WITHIN_LIMIT(Count, Limit) &&\r
321 ((LogEntryKey = GetPerformanceMeasurementEx (\r
322 LogEntryKey,\r
323 &Measurement.Handle,\r
324 &Measurement.Token,\r
325 &Measurement.Module,\r
326 &Measurement.StartTimeStamp,\r
327 &Measurement.EndTimeStamp,\r
328 &Measurement.Identifier)) != 0)\r
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
343\r
344 if (mShowId) {\r
345 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_VARS2), gDpHiiHandle,\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 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_VARS), gDpHiiHandle,\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
364 }\r
365}\r
366\r
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
372**/\r
373VOID\r
374ProcessPhases(\r
375 IN UINT64 Ticker\r
376 )\r
377{\r
378 MEASUREMENT_RECORD Measurement;\r
379 UINT64 BdsTimeoutValue;\r
380 UINT64 SecTime;\r
381 UINT64 PeiTime;\r
382 UINT64 DxeTime;\r
383 UINT64 BdsTime;\r
384 UINT64 ShellTime;\r
385 UINT64 ElapsedTime;\r
386 UINT64 Duration;\r
387 UINT64 Total;\r
388 EFI_STRING StringPtr;\r
389 UINTN LogEntryKey;\r
390 EFI_STRING StringPtrUnknown;\r
391\r
392 BdsTimeoutValue = 0;\r
393 SecTime = 0;\r
394 PeiTime = 0;\r
395 DxeTime = 0;\r
396 BdsTime = 0;\r
397 ShellTime = 0; \r
398 //\r
399 // Get Execution Phase Statistics\r
400 //\r
401 StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL); \r
402 StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_PHASES), NULL);\r
403 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,\r
404 (StringPtr == NULL) ? StringPtrUnknown : StringPtr);\r
405 FreePool (StringPtr);\r
406 FreePool (StringPtrUnknown);\r
407\r
408 LogEntryKey = 0;\r
409 while ((LogEntryKey = GetPerformanceMeasurementEx (\r
410 LogEntryKey,\r
411 &Measurement.Handle,\r
412 &Measurement.Token,\r
413 &Measurement.Module,\r
414 &Measurement.StartTimeStamp,\r
415 &Measurement.EndTimeStamp,\r
416 &Measurement.Identifier)) != 0)\r
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 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SEC_PHASE), gDpHiiHandle, 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 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PHASE_DURATION), gDpHiiHandle, 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 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PHASE_DURATION), gDpHiiHandle, 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 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PHASE_DURATION), gDpHiiHandle, 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 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PHASE_BDSTO), gDpHiiHandle, 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 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PHASE_DURATION), gDpHiiHandle, ALit_SHELL, ElapsedTime);\r
503 }\r
504\r
505 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TOTAL_DURATION), gDpHiiHandle, Total);\r
506}\r
507\r
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
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
64c51ed1 528 UINTN HandleCount;\r
d41bc92c 529 EFI_STATUS Status;\r
530 EFI_STRING StringPtrUnknown;\r
531\r
532 StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL); \r
533 StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_DRIVERS), NULL);\r
534 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,\r
535 (StringPtr == NULL) ? StringPtrUnknown : StringPtr);\r
536 FreePool (StringPtr);\r
537 FreePool (StringPtrUnknown);\r
538\r
64c51ed1 539 Status = gBS->LocateHandleBuffer (AllHandles, NULL, NULL, &HandleCount, &HandleBuffer);\r
d41bc92c 540 if (EFI_ERROR (Status)) {\r
541 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLES_ERROR), gDpHiiHandle, 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
548 if (mShowId) {\r
549 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLE_SECTION2), gDpHiiHandle);\r
550 } else {\r
551 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLE_SECTION), gDpHiiHandle);\r
552 }\r
553 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), gDpHiiHandle);\r
554\r
555 LogEntryKey = 0;\r
556 Count = 0;\r
557 while ((LogEntryKey = GetPerformanceMeasurementEx (\r
558 LogEntryKey,\r
559 &Measurement.Handle,\r
560 &Measurement.Token,\r
561 &Measurement.Module,\r
562 &Measurement.StartTimeStamp,\r
563 &Measurement.EndTimeStamp,\r
564 &Measurement.Identifier)) != 0)\r
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
64c51ed1 579 for (Index = 0; Index < HandleCount; Index++) {\r
d41bc92c 580 if (Measurement.Handle == HandleBuffer[Index]) {\r
2c55a81a 581 DpGetNameFromHandle (HandleBuffer[Index]); // Name is put into mGaugeString\r
d41bc92c 582 break;\r
583 }\r
584 }\r
585 // Ensure that the argument strings are not too long.\r
586 mGaugeString[DP_GAUGE_STRING_LENGTH] = 0;\r
587 mUnicodeToken[11] = 0;\r
588 if (mGaugeString[0] != 0) {\r
589 // Display the record if it has a valid handle.\r
590 if (mShowId) {\r
591 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLE_VARS2), gDpHiiHandle,\r
592 Count, // 1 based, Which measurement record is being printed\r
593 Index + 1, // 1 based, Which handle is being printed\r
594 mGaugeString,\r
595 mUnicodeToken,\r
596 ElapsedTime,\r
597 Measurement.Identifier\r
598 );\r
599 } else {\r
600 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLE_VARS), gDpHiiHandle,\r
601 Count, // 1 based, Which measurement record is being printed\r
602 Index + 1, // 1 based, Which handle is being printed\r
603 mGaugeString,\r
604 mUnicodeToken,\r
605 ElapsedTime\r
606 );\r
607 }\r
608 }\r
609 }\r
610 }\r
64c51ed1 611 if (HandleBuffer != NULL) {\r
d41bc92c 612 FreePool (HandleBuffer);\r
613 }\r
614 return Status;\r
615}\r
616\r
617/** \r
618 Gather and print PEIM data.\r
619 \r
620 Only prints complete PEIM records\r
621 \r
622**/\r
623VOID\r
624ProcessPeims(\r
625 VOID\r
626)\r
627{\r
628 MEASUREMENT_RECORD Measurement;\r
629 UINT64 Duration;\r
630 UINT64 ElapsedTime;\r
631 EFI_STRING StringPtr;\r
632 UINTN LogEntryKey;\r
633 UINTN TIndex;\r
634 EFI_STRING StringPtrUnknown;\r
635\r
636 StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL); \r
637 StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_PEIMS), NULL);\r
638 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,\r
639 (StringPtr == NULL) ? StringPtrUnknown : StringPtr);\r
640 FreePool (StringPtr);\r
641 FreePool (StringPtrUnknown);\r
642\r
643 if (mShowId) {\r
644 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PEIM_SECTION2), gDpHiiHandle);\r
645 } else {\r
646 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PEIM_SECTION), gDpHiiHandle);\r
647 }\r
648 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), gDpHiiHandle);\r
649 TIndex = 0;\r
650 LogEntryKey = 0;\r
651 while ((LogEntryKey = GetPerformanceMeasurementEx (\r
652 LogEntryKey,\r
653 &Measurement.Handle,\r
654 &Measurement.Token,\r
655 &Measurement.Module,\r
656 &Measurement.StartTimeStamp,\r
657 &Measurement.EndTimeStamp,\r
658 &Measurement.Identifier)) != 0)\r
659 {\r
660 TIndex++;\r
661 if ((Measurement.EndTimeStamp == 0) ||\r
662 (AsciiStrnCmp (Measurement.Token, ALit_PEIM, PERF_TOKEN_LENGTH) != 0)\r
663 ) {\r
664 continue;\r
665 }\r
666\r
667 Duration = GetDuration (&Measurement);\r
668 ElapsedTime = DurationInMicroSeconds ( Duration ); // Calculate elapsed time in microseconds\r
669 if (ElapsedTime >= mInterestThreshold) {\r
670 // PEIM FILE Handle is the start address of its FFS file that contains its file guid.\r
671 if (mShowId) {\r
672 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PEIM_VARS2), gDpHiiHandle,\r
673 TIndex, // 1 based, Which measurement record is being printed\r
674 Measurement.Handle, // base address\r
675 Measurement.Handle, // file guid\r
676 ElapsedTime,\r
677 Measurement.Identifier\r
678 );\r
679 } else {\r
680 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PEIM_VARS), gDpHiiHandle,\r
681 TIndex, // 1 based, Which measurement record is being printed\r
682 Measurement.Handle, // base address\r
683 Measurement.Handle, // file guid\r
684 ElapsedTime\r
685 );\r
686 }\r
687 }\r
688 }\r
689}\r
690\r
691/** \r
692 Gather and print global data.\r
693 \r
694 Strips out incomplete or "Execution Phase" records\r
695 Only prints records where Handle is NULL\r
696 Increment TIndex for every record, even skipped ones, so that we have an\r
697 indication of every measurement record taken.\r
698 \r
699**/\r
700VOID\r
701ProcessGlobal(\r
702 VOID\r
703)\r
704{\r
705 MEASUREMENT_RECORD Measurement;\r
706 UINT64 Duration;\r
707 UINT64 ElapsedTime;\r
708 EFI_STRING StringPtr;\r
709 UINTN LogEntryKey;\r
710 UINTN Index; // Index, or number, of the measurement record being processed\r
711 EFI_STRING StringPtrUnknown;\r
712\r
713 StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL); \r
714 StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_GENERAL), NULL);\r
715 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,\r
716 (StringPtr == NULL) ? StringPtrUnknown: StringPtr);\r
717 FreePool (StringPtr);\r
718 FreePool (StringPtrUnknown);\r
719\r
720 if (mShowId) {\r
721 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GLOBAL_SECTION2), gDpHiiHandle);\r
722 } else {\r
723 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GLOBAL_SECTION), gDpHiiHandle);\r
724 }\r
725 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), gDpHiiHandle);\r
726\r
727 Index = 1;\r
728 LogEntryKey = 0;\r
729\r
730 while ((LogEntryKey = GetPerformanceMeasurementEx (\r
731 LogEntryKey,\r
732 &Measurement.Handle,\r
733 &Measurement.Token,\r
734 &Measurement.Module,\r
735 &Measurement.StartTimeStamp,\r
736 &Measurement.EndTimeStamp,\r
737 &Measurement.Identifier)) != 0)\r
738 {\r
739 AsciiStrToUnicodeStr (Measurement.Module, mGaugeString);\r
740 AsciiStrToUnicodeStr (Measurement.Token, mUnicodeToken);\r
741 mGaugeString[25] = 0;\r
742 mUnicodeToken[31] = 0;\r
743 if ( ! ( IsPhase( &Measurement) ||\r
744 (Measurement.Handle != NULL) ||\r
745 (Measurement.EndTimeStamp == 0)\r
746 ))\r
747 {\r
748 Duration = GetDuration (&Measurement);\r
749 ElapsedTime = DurationInMicroSeconds ( Duration );\r
750 if (ElapsedTime >= mInterestThreshold) {\r
751 if (mShowId) {\r
752 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GLOBAL_VARS2), gDpHiiHandle,\r
753 Index,\r
754 mGaugeString,\r
755 mUnicodeToken,\r
756 ElapsedTime,\r
757 Measurement.Identifier\r
758 );\r
759 } else {\r
760 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GLOBAL_VARS), gDpHiiHandle,\r
761 Index,\r
762 mGaugeString,\r
763 mUnicodeToken,\r
764 ElapsedTime\r
765 );\r
766 }\r
767 }\r
768 }\r
769 Index++;\r
770 }\r
771}\r
772\r
773/** \r
774 Gather and print cumulative data.\r
775 \r
776 Traverse the measurement records and:<BR>\r
777 For each record with a Token listed in the CumData array:<BR>\r
778 - Update the instance count and the total, minimum, and maximum durations.\r
779 Finally, print the gathered cumulative statistics.\r
a06795c6
CS
780\r
781 @param[in] CustomCumulativeData A pointer to the cumtom cumulative data.\r
782\r
d41bc92c 783**/\r
784VOID\r
785ProcessCumulative(\r
a06795c6
CS
786 IN PERF_CUM_DATA *CustomCumulativeData OPTIONAL\r
787 )\r
d41bc92c 788{\r
789 UINT64 AvgDur; // the computed average duration\r
790 UINT64 Dur;\r
791 UINT64 MinDur;\r
792 UINT64 MaxDur;\r
793 EFI_STRING StringPtr;\r
794 UINTN TIndex;\r
795 EFI_STRING StringPtrUnknown;\r
796\r
797 StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL); \r
798 StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_CUMULATIVE), NULL);\r
799 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,\r
800 (StringPtr == NULL) ? StringPtrUnknown: StringPtr);\r
801 FreePool (StringPtr);\r
802 FreePool (StringPtrUnknown);\r
803\r
804 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_CUMULATIVE_SECT_1), gDpHiiHandle);\r
805 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_CUMULATIVE_SECT_2), gDpHiiHandle);\r
806 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), gDpHiiHandle);\r
807\r
808 for ( TIndex = 0; TIndex < NumCum; ++TIndex) {\r
809 if (CumData[TIndex].Count != 0) {\r
810 AvgDur = DivU64x32 (CumData[TIndex].Duration, CumData[TIndex].Count);\r
811 AvgDur = DurationInMicroSeconds(AvgDur);\r
812 Dur = DurationInMicroSeconds(CumData[TIndex].Duration);\r
813 MaxDur = DurationInMicroSeconds(CumData[TIndex].MaxDur);\r
814 MinDur = DurationInMicroSeconds(CumData[TIndex].MinDur);\r
815 \r
816 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_CUMULATIVE_STATS), gDpHiiHandle,\r
817 CumData[TIndex].Name,\r
818 CumData[TIndex].Count,\r
819 Dur,\r
820 AvgDur,\r
821 MinDur,\r
822 MaxDur\r
823 );\r
824 }\r
825 }\r
a06795c6
CS
826\r
827 //\r
828 // Print the custom cumulative data.\r
829 //\r
830 if (CustomCumulativeData != NULL) {\r
831 if (CustomCumulativeData->Count != 0) {\r
832 AvgDur = DivU64x32 (CustomCumulativeData->Duration, CustomCumulativeData->Count);\r
833 AvgDur = DurationInMicroSeconds (AvgDur);\r
834 Dur = DurationInMicroSeconds (CustomCumulativeData->Duration);\r
835 MaxDur = DurationInMicroSeconds (CustomCumulativeData->MaxDur);\r
836 MinDur = DurationInMicroSeconds (CustomCumulativeData->MinDur);\r
837 } else {\r
838 AvgDur = 0;\r
839 Dur = 0;\r
840 MaxDur = 0;\r
841 MinDur = 0;\r
842 }\r
843 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_CUMULATIVE_STATS), gDpHiiHandle,\r
844 CustomCumulativeData->Name,\r
845 CustomCumulativeData->Count,\r
846 Dur,\r
847 AvgDur,\r
848 MinDur,\r
849 MaxDur\r
850 );\r
851 }\r
d41bc92c 852}\r