]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiDpLib/DpTrace.c
ShellPkg UefiDpLib: Remove TimerLib dependency
[mirror_edk2.git] / ShellPkg / Library / UefiDpLib / DpTrace.c
CommitLineData
d41bc92c 1/** @file\r
2 Trace reporting for the Dp utility.\r
3\r
ef224032 4 Copyright (c) 2009 - 2017, 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
d41bc92c 20#include <Library/PeCoffGetEntryPointLib.h>\r
21#include <Library/PerformanceLib.h>\r
22#include <Library/PrintLib.h>\r
23#include <Library/HiiLib.h>\r
24#include <Library/PcdLib.h>\r
25\r
26#include <Guid/Performance.h>\r
27\r
28#include "Dp.h"\r
29#include "Literals.h"\r
30#include "DpInternal.h"\r
31\r
32/** \r
33 Collect verbose statistics about the logged performance measurements.\r
34 \r
35 General Summary information for all Trace measurements is gathered and\r
36 stored within the SummaryData structure. This information is both\r
37 used internally by subsequent reporting functions, and displayed\r
38 at the end of verbose reports.\r
39 \r
40 @pre The SummaryData and CumData structures must be initialized\r
41 prior to calling this function.\r
42 \r
43 @post The SummaryData and CumData structures contain statistics for the\r
44 current performance logs.\r
a06795c6
CS
45\r
46 @param[in, out] CustomCumulativeData A pointer to the cumtom cumulative data.\r
47\r
d41bc92c 48**/\r
49VOID\r
50GatherStatistics(\r
a06795c6
CS
51 IN OUT PERF_CUM_DATA *CustomCumulativeData OPTIONAL\r
52 )\r
d41bc92c 53{\r
54 MEASUREMENT_RECORD Measurement;\r
55 UINT64 Duration;\r
56 UINTN LogEntryKey;\r
57 INTN TIndex;\r
58\r
59 LogEntryKey = 0;\r
60 while ((LogEntryKey = GetPerformanceMeasurementEx (\r
61 LogEntryKey,\r
62 &Measurement.Handle,\r
63 &Measurement.Token,\r
64 &Measurement.Module,\r
65 &Measurement.StartTimeStamp,\r
66 &Measurement.EndTimeStamp,\r
67 &Measurement.Identifier)) != 0)\r
68 {\r
69 ++SummaryData.NumTrace; // Count the number of TRACE Measurement records\r
70 if (Measurement.EndTimeStamp == 0) {\r
71 ++SummaryData.NumIncomplete; // Count the incomplete records\r
72 continue;\r
73 }\r
74\r
75 if (Measurement.Handle != NULL) {\r
76 ++SummaryData.NumHandles; // Count the number of measurements with non-NULL handles\r
77 }\r
78\r
79 if (IsPhase( &Measurement)) {\r
80 ++SummaryData.NumSummary; // Count the number of major phases\r
81 }\r
82 else { // !IsPhase(...\r
83 if(Measurement.Handle == NULL) {\r
84 ++SummaryData.NumGlobal;\r
85 }\r
86 }\r
87\r
88 if (AsciiStrnCmp (Measurement.Token, ALit_PEIM, PERF_TOKEN_LENGTH) == 0) {\r
89 ++SummaryData.NumPEIMs; // Count PEIM measurements\r
90 }\r
91\r
92 Duration = GetDuration (&Measurement);\r
93 TIndex = GetCumulativeItem (&Measurement);\r
94 if (TIndex >= 0) {\r
95 CumData[TIndex].Duration += Duration;\r
96 CumData[TIndex].Count++;\r
97 if ( Duration < CumData[TIndex].MinDur ) {\r
98 CumData[TIndex].MinDur = Duration;\r
99 }\r
100 if ( Duration > CumData[TIndex].MaxDur ) {\r
101 CumData[TIndex].MaxDur = Duration;\r
102 }\r
103 }\r
a06795c6
CS
104\r
105 //\r
106 // Collect the data for custom cumulative data.\r
107 //\r
108 if ((CustomCumulativeData != NULL) && (AsciiStrCmp (Measurement.Token, CustomCumulativeData->Name) == 0)) {\r
109 CustomCumulativeData->Duration += Duration;\r
110 CustomCumulativeData->Count++;\r
111 if (Duration < CustomCumulativeData->MinDur) {\r
112 CustomCumulativeData->MinDur = Duration;\r
113 }\r
114 if (Duration > CustomCumulativeData->MaxDur) {\r
115 CustomCumulativeData->MaxDur = Duration;\r
116 }\r
117 }\r
d41bc92c 118 }\r
119}\r
120\r
121/** \r
122 Gather and print ALL Trace Records.\r
123 \r
124 Displays all "interesting" Trace measurements in order.<BR>\r
125 The number of records displayed is controlled by:\r
126 - records with a duration less than mInterestThreshold microseconds are not displayed.\r
127 - No more than Limit records are displayed. A Limit of zero will not limit the output.\r
128 - If the ExcludeFlag is TRUE, records matching entries in the CumData array are not\r
129 displayed.\r
130 \r
131 @pre The mInterestThreshold global variable is set to the shortest duration to be printed.\r
132 The mGaugeString and mUnicodeToken global arrays are used for temporary string storage.\r
133 They must not be in use by a calling function.\r
134 \r
135 @param[in] Limit The number of records to print. Zero is ALL.\r
136 @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.\r
137 \r
196ccda0
CS
138 @retval EFI_SUCCESS The operation was successful.\r
139 @retval EFI_ABORTED The user aborts the operation.\r
140 @return Others from a call to gBS->LocateHandleBuffer().\r
d41bc92c 141**/\r
196ccda0 142EFI_STATUS\r
d41bc92c 143DumpAllTrace(\r
144 IN UINTN Limit,\r
145 IN BOOLEAN ExcludeFlag\r
146 )\r
147{\r
148 MEASUREMENT_RECORD Measurement;\r
149 UINT64 ElapsedTime;\r
150 UINT64 Duration;\r
151 CHAR16 *IncFlag;\r
152 UINTN LogEntryKey;\r
153 UINTN Count;\r
154 UINTN Index;\r
155 UINTN TIndex;\r
156\r
157 EFI_HANDLE *HandleBuffer;\r
64c51ed1 158 UINTN HandleCount;\r
d41bc92c 159 EFI_STATUS Status;\r
160 EFI_STRING StringPtrUnknown;\r
161\r
162 StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);\r
163 IncFlag = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_ALL), NULL);\r
164 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,\r
165 (IncFlag == NULL) ? StringPtrUnknown : IncFlag);\r
166 FreePool (StringPtrUnknown);\r
167\r
168 // Get Handle information\r
169 //\r
64c51ed1 170 Status = gBS->LocateHandleBuffer (AllHandles, NULL, NULL, &HandleCount, &HandleBuffer);\r
d41bc92c 171 if (EFI_ERROR (Status)) {\r
172 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLES_ERROR), gDpHiiHandle, Status);\r
173 }\r
174 else {\r
175 // We have successfully populated the HandleBuffer\r
176 // Display ALL Measurement Records\r
177 // Up to Limit lines displayed\r
178 // Display only records with Elapsed times >= mInterestThreshold\r
179 // Display driver names in Module field for records with Handles.\r
180 //\r
181 if (mShowId) {\r
182 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_ALL_HEADR2), gDpHiiHandle);\r
183 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_ALL_DASHES2), gDpHiiHandle);\r
184 } else {\r
185 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_ALL_HEADR), gDpHiiHandle);\r
186 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), gDpHiiHandle);\r
187 }\r
188\r
189 LogEntryKey = 0;\r
190 Count = 0;\r
191 Index = 0;\r
192 while ( WITHIN_LIMIT(Count, Limit) &&\r
193 ((LogEntryKey = GetPerformanceMeasurementEx (\r
194 LogEntryKey,\r
195 &Measurement.Handle,\r
196 &Measurement.Token,\r
197 &Measurement.Module,\r
198 &Measurement.StartTimeStamp,\r
199 &Measurement.EndTimeStamp,\r
200 &Measurement.Identifier)) != 0)\r
201 )\r
202 {\r
203 ++Index; // Count every record. First record is 1.\r
204 ElapsedTime = 0;\r
205 SHELL_FREE_NON_NULL (IncFlag);\r
206 if (Measurement.EndTimeStamp != 0) {\r
207 Duration = GetDuration (&Measurement);\r
208 ElapsedTime = DurationInMicroSeconds ( Duration );\r
209 IncFlag = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_COMPLETE), NULL);\r
210 }\r
211 else {\r
212 IncFlag = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_INCOMPLETE), NULL); // Mark incomplete records\r
213 }\r
214 if (((Measurement.EndTimeStamp != 0) && (ElapsedTime < mInterestThreshold)) ||\r
215 ((ExcludeFlag) && (GetCumulativeItem(&Measurement) >= 0))\r
216 ) { // Ignore "uninteresting" or excluded records\r
217 continue;\r
218 }\r
219 ++Count; // Count the number of records printed\r
220\r
221 // If Handle is non-zero, see if we can determine a name for the driver\r
cb4669e0
LE
222 AsciiStrToUnicodeStrS (Measurement.Module, mGaugeString, ARRAY_SIZE (mGaugeString)); // Use Module by default\r
223 AsciiStrToUnicodeStrS (Measurement.Token, mUnicodeToken, ARRAY_SIZE (mUnicodeToken));\r
d41bc92c 224 if (Measurement.Handle != NULL) {\r
225 // See if the Handle is in the HandleBuffer\r
64c51ed1 226 for (TIndex = 0; TIndex < HandleCount; TIndex++) {\r
d41bc92c 227 if (Measurement.Handle == HandleBuffer[TIndex]) {\r
2c55a81a 228 DpGetNameFromHandle (HandleBuffer[TIndex]);\r
d41bc92c 229 break;\r
230 }\r
231 }\r
232 }\r
233\r
234 if (AsciiStrnCmp (Measurement.Token, ALit_PEIM, PERF_TOKEN_LENGTH) == 0) {\r
235 UnicodeSPrint (mGaugeString, sizeof (mGaugeString), L"%g", Measurement.Handle);\r
236 }\r
237\r
238 // Ensure that the argument strings are not too long.\r
239 mGaugeString[DP_GAUGE_STRING_LENGTH] = 0;\r
240 mUnicodeToken[13] = 0;\r
241\r
242 if (mShowId) {\r
243 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_ALL_VARS2), gDpHiiHandle,\r
244 Index, // 1 based, Which measurement record is being printed\r
245 IncFlag,\r
246 Measurement.Handle,\r
247 mGaugeString,\r
248 mUnicodeToken,\r
249 ElapsedTime,\r
250 Measurement.Identifier\r
251 );\r
252 } else {\r
253 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_ALL_VARS), gDpHiiHandle,\r
254 Index, // 1 based, Which measurement record is being printed\r
255 IncFlag,\r
256 Measurement.Handle,\r
257 mGaugeString,\r
258 mUnicodeToken,\r
259 ElapsedTime\r
260 );\r
261 }\r
196ccda0
CS
262 if (ShellGetExecutionBreakFlag ()) {\r
263 Status = EFI_ABORTED;\r
264 break;\r
265 }\r
d41bc92c 266 }\r
267 }\r
64c51ed1 268 if (HandleBuffer != NULL) {\r
d41bc92c 269 FreePool (HandleBuffer);\r
270 }\r
271 SHELL_FREE_NON_NULL (IncFlag);\r
196ccda0
CS
272\r
273 return Status;\r
d41bc92c 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
196ccda0
CS
292\r
293 @retval EFI_SUCCESS The operation was successful.\r
294 @retval EFI_ABORTED The user aborts the operation.\r
d41bc92c 295**/\r
196ccda0 296EFI_STATUS\r
d41bc92c 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
196ccda0
CS
311 EFI_STATUS Status;\r
312\r
313 Status = EFI_SUCCESS;\r
d41bc92c 314\r
315 StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL); \r
316 StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_RAWTRACE), NULL);\r
317 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,\r
318 (StringPtr == NULL) ? StringPtrUnknown : StringPtr);\r
319 FreePool (StringPtr);\r
320 FreePool (StringPtrUnknown);\r
321\r
322 if (mShowId) {\r
323 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_HEADR2), gDpHiiHandle);\r
324 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_DASHES2), gDpHiiHandle);\r
325 } else {\r
326 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_HEADR), gDpHiiHandle);\r
327 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_DASHES), gDpHiiHandle);\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 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_VARS2), gDpHiiHandle,\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 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_VARS), gDpHiiHandle,\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
196ccda0
CS
377 if (ShellGetExecutionBreakFlag ()) {\r
378 Status = EFI_ABORTED;\r
379 break;\r
380 }\r
d41bc92c 381 }\r
196ccda0 382 return Status;\r
d41bc92c 383}\r
384\r
385/** \r
386 Gather and print Major Phase metrics.\r
387 \r
d41bc92c 388**/\r
389VOID\r
390ProcessPhases(\r
ef224032 391 VOID\r
d41bc92c 392 )\r
393{\r
394 MEASUREMENT_RECORD Measurement;\r
395 UINT64 BdsTimeoutValue;\r
396 UINT64 SecTime;\r
397 UINT64 PeiTime;\r
398 UINT64 DxeTime;\r
399 UINT64 BdsTime;\r
d41bc92c 400 UINT64 ElapsedTime;\r
401 UINT64 Duration;\r
402 UINT64 Total;\r
403 EFI_STRING StringPtr;\r
404 UINTN LogEntryKey;\r
405 EFI_STRING StringPtrUnknown;\r
406\r
407 BdsTimeoutValue = 0;\r
408 SecTime = 0;\r
409 PeiTime = 0;\r
410 DxeTime = 0;\r
411 BdsTime = 0;\r
d41bc92c 412 //\r
413 // Get Execution Phase Statistics\r
414 //\r
415 StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL); \r
416 StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_PHASES), NULL);\r
417 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,\r
418 (StringPtr == NULL) ? StringPtrUnknown : StringPtr);\r
419 FreePool (StringPtr);\r
420 FreePool (StringPtrUnknown);\r
421\r
422 LogEntryKey = 0;\r
423 while ((LogEntryKey = GetPerformanceMeasurementEx (\r
424 LogEntryKey,\r
425 &Measurement.Handle,\r
426 &Measurement.Token,\r
427 &Measurement.Module,\r
428 &Measurement.StartTimeStamp,\r
429 &Measurement.EndTimeStamp,\r
430 &Measurement.Identifier)) != 0)\r
431 {\r
d41bc92c 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
d41bc92c 449 }\r
450 }\r
451\r
452 Total = 0;\r
453\r
454 // print SEC phase duration time\r
455 //\r
456 if (SecTime > 0) {\r
457 ElapsedTime = DurationInMicroSeconds ( SecTime ); // Calculate elapsed time in microseconds\r
458 Total += DivU64x32 (ElapsedTime, 1000); // Accumulate time in milliseconds\r
459 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SEC_PHASE), gDpHiiHandle, ElapsedTime);\r
460 }\r
461\r
462 // print PEI phase duration time\r
463 //\r
464 if (PeiTime > 0) {\r
465 ElapsedTime = DivU64x32 (\r
466 PeiTime,\r
467 (UINT32)TimerInfo.Frequency\r
468 );\r
469 Total += ElapsedTime;\r
470 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PHASE_DURATION), gDpHiiHandle, ALit_PEI, ElapsedTime);\r
471 }\r
472\r
473 // print DXE phase duration time\r
474 //\r
475 if (DxeTime > 0) {\r
476 ElapsedTime = DivU64x32 (\r
477 DxeTime,\r
478 (UINT32)TimerInfo.Frequency\r
479 );\r
480 Total += ElapsedTime;\r
481 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PHASE_DURATION), gDpHiiHandle, ALit_DXE, ElapsedTime);\r
482 }\r
483\r
484 // print BDS phase duration time\r
485 //\r
486 if (BdsTime > 0) {\r
487 ElapsedTime = DivU64x32 (\r
488 BdsTime,\r
489 (UINT32)TimerInfo.Frequency\r
490 );\r
491 Total += ElapsedTime;\r
492 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PHASE_DURATION), gDpHiiHandle, ALit_BDS, ElapsedTime);\r
493 }\r
494\r
495 if (BdsTimeoutValue > 0) {\r
496 ElapsedTime = DivU64x32 (\r
497 BdsTimeoutValue,\r
498 (UINT32)TimerInfo.Frequency\r
499 );\r
500 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PHASE_BDSTO), gDpHiiHandle, ALit_BdsTO, ElapsedTime);\r
501 }\r
502\r
d41bc92c 503 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TOTAL_DURATION), gDpHiiHandle, Total);\r
504}\r
505\r
506/** \r
507 Gather and print Handle data.\r
508 \r
509 @param[in] ExcludeFlag TRUE to exclude individual Cumulative items from display.\r
510 \r
196ccda0
CS
511 @retval EFI_SUCCESS The operation was successful.\r
512 @retval EFI_ABORTED The user aborts the operation.\r
513 @return Others from a call to gBS->LocateHandleBuffer().\r
d41bc92c 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
cb4669e0 577 AsciiStrToUnicodeStrS (Measurement.Token, mUnicodeToken, ARRAY_SIZE (mUnicodeToken));\r
d41bc92c 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
196ccda0
CS
609 if (ShellGetExecutionBreakFlag ()) {\r
610 Status = EFI_ABORTED;\r
611 break;\r
612 }\r
d41bc92c 613 }\r
614 }\r
64c51ed1 615 if (HandleBuffer != NULL) {\r
d41bc92c 616 FreePool (HandleBuffer);\r
617 }\r
618 return Status;\r
619}\r
620\r
621/** \r
622 Gather and print PEIM data.\r
623 \r
624 Only prints complete PEIM records\r
625 \r
196ccda0
CS
626 @retval EFI_SUCCESS The operation was successful.\r
627 @retval EFI_ABORTED The user aborts the operation.\r
d41bc92c 628**/\r
196ccda0 629EFI_STATUS\r
d41bc92c 630ProcessPeims(\r
631 VOID\r
632)\r
633{\r
634 MEASUREMENT_RECORD Measurement;\r
635 UINT64 Duration;\r
636 UINT64 ElapsedTime;\r
637 EFI_STRING StringPtr;\r
638 UINTN LogEntryKey;\r
639 UINTN TIndex;\r
640 EFI_STRING StringPtrUnknown;\r
196ccda0
CS
641 EFI_STATUS Status;\r
642\r
643 Status = EFI_SUCCESS;\r
d41bc92c 644\r
645 StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL); \r
646 StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_PEIMS), NULL);\r
647 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,\r
648 (StringPtr == NULL) ? StringPtrUnknown : StringPtr);\r
649 FreePool (StringPtr);\r
650 FreePool (StringPtrUnknown);\r
651\r
652 if (mShowId) {\r
653 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PEIM_SECTION2), gDpHiiHandle);\r
654 } else {\r
655 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PEIM_SECTION), gDpHiiHandle);\r
656 }\r
657 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), gDpHiiHandle);\r
658 TIndex = 0;\r
659 LogEntryKey = 0;\r
660 while ((LogEntryKey = GetPerformanceMeasurementEx (\r
661 LogEntryKey,\r
662 &Measurement.Handle,\r
663 &Measurement.Token,\r
664 &Measurement.Module,\r
665 &Measurement.StartTimeStamp,\r
666 &Measurement.EndTimeStamp,\r
667 &Measurement.Identifier)) != 0)\r
668 {\r
669 TIndex++;\r
670 if ((Measurement.EndTimeStamp == 0) ||\r
671 (AsciiStrnCmp (Measurement.Token, ALit_PEIM, PERF_TOKEN_LENGTH) != 0)\r
672 ) {\r
673 continue;\r
674 }\r
675\r
676 Duration = GetDuration (&Measurement);\r
677 ElapsedTime = DurationInMicroSeconds ( Duration ); // Calculate elapsed time in microseconds\r
678 if (ElapsedTime >= mInterestThreshold) {\r
679 // PEIM FILE Handle is the start address of its FFS file that contains its file guid.\r
680 if (mShowId) {\r
681 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PEIM_VARS2), gDpHiiHandle,\r
682 TIndex, // 1 based, Which measurement record is being printed\r
683 Measurement.Handle, // base address\r
684 Measurement.Handle, // file guid\r
685 ElapsedTime,\r
686 Measurement.Identifier\r
687 );\r
688 } else {\r
689 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PEIM_VARS), gDpHiiHandle,\r
690 TIndex, // 1 based, Which measurement record is being printed\r
691 Measurement.Handle, // base address\r
692 Measurement.Handle, // file guid\r
693 ElapsedTime\r
694 );\r
695 }\r
696 }\r
196ccda0
CS
697 if (ShellGetExecutionBreakFlag ()) {\r
698 Status = EFI_ABORTED;\r
699 break;\r
700 }\r
d41bc92c 701 }\r
196ccda0 702 return Status;\r
d41bc92c 703}\r
704\r
705/** \r
706 Gather and print global data.\r
707 \r
708 Strips out incomplete or "Execution Phase" records\r
709 Only prints records where Handle is NULL\r
710 Increment TIndex for every record, even skipped ones, so that we have an\r
711 indication of every measurement record taken.\r
712 \r
196ccda0
CS
713 @retval EFI_SUCCESS The operation was successful.\r
714 @retval EFI_ABORTED The user aborts the operation.\r
d41bc92c 715**/\r
196ccda0 716EFI_STATUS\r
d41bc92c 717ProcessGlobal(\r
718 VOID\r
719)\r
720{\r
721 MEASUREMENT_RECORD Measurement;\r
722 UINT64 Duration;\r
723 UINT64 ElapsedTime;\r
724 EFI_STRING StringPtr;\r
725 UINTN LogEntryKey;\r
726 UINTN Index; // Index, or number, of the measurement record being processed\r
727 EFI_STRING StringPtrUnknown;\r
196ccda0
CS
728 EFI_STATUS Status;\r
729\r
730 Status = EFI_SUCCESS;\r
d41bc92c 731\r
732 StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL); \r
733 StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_GENERAL), NULL);\r
734 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,\r
735 (StringPtr == NULL) ? StringPtrUnknown: StringPtr);\r
736 FreePool (StringPtr);\r
737 FreePool (StringPtrUnknown);\r
738\r
739 if (mShowId) {\r
740 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GLOBAL_SECTION2), gDpHiiHandle);\r
741 } else {\r
742 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GLOBAL_SECTION), gDpHiiHandle);\r
743 }\r
744 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), gDpHiiHandle);\r
745\r
746 Index = 1;\r
747 LogEntryKey = 0;\r
748\r
749 while ((LogEntryKey = GetPerformanceMeasurementEx (\r
750 LogEntryKey,\r
751 &Measurement.Handle,\r
752 &Measurement.Token,\r
753 &Measurement.Module,\r
754 &Measurement.StartTimeStamp,\r
755 &Measurement.EndTimeStamp,\r
756 &Measurement.Identifier)) != 0)\r
757 {\r
cb4669e0
LE
758 AsciiStrToUnicodeStrS (Measurement.Module, mGaugeString, ARRAY_SIZE (mGaugeString));\r
759 AsciiStrToUnicodeStrS (Measurement.Token, mUnicodeToken, ARRAY_SIZE (mUnicodeToken));\r
d41bc92c 760 mGaugeString[25] = 0;\r
761 mUnicodeToken[31] = 0;\r
762 if ( ! ( IsPhase( &Measurement) ||\r
763 (Measurement.Handle != NULL) ||\r
764 (Measurement.EndTimeStamp == 0)\r
765 ))\r
766 {\r
767 Duration = GetDuration (&Measurement);\r
768 ElapsedTime = DurationInMicroSeconds ( Duration );\r
769 if (ElapsedTime >= mInterestThreshold) {\r
770 if (mShowId) {\r
771 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GLOBAL_VARS2), gDpHiiHandle,\r
772 Index,\r
773 mGaugeString,\r
774 mUnicodeToken,\r
775 ElapsedTime,\r
776 Measurement.Identifier\r
777 );\r
778 } else {\r
779 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GLOBAL_VARS), gDpHiiHandle,\r
780 Index,\r
781 mGaugeString,\r
782 mUnicodeToken,\r
783 ElapsedTime\r
784 );\r
785 }\r
786 }\r
787 }\r
196ccda0
CS
788 if (ShellGetExecutionBreakFlag ()) {\r
789 Status = EFI_ABORTED;\r
790 break;\r
791 }\r
d41bc92c 792 Index++;\r
793 }\r
d0a23f9f 794 return Status;\r
d41bc92c 795}\r
796\r
797/** \r
798 Gather and print cumulative data.\r
799 \r
800 Traverse the measurement records and:<BR>\r
801 For each record with a Token listed in the CumData array:<BR>\r
802 - Update the instance count and the total, minimum, and maximum durations.\r
803 Finally, print the gathered cumulative statistics.\r
a06795c6
CS
804\r
805 @param[in] CustomCumulativeData A pointer to the cumtom cumulative data.\r
806\r
d41bc92c 807**/\r
808VOID\r
809ProcessCumulative(\r
a06795c6
CS
810 IN PERF_CUM_DATA *CustomCumulativeData OPTIONAL\r
811 )\r
d41bc92c 812{\r
813 UINT64 AvgDur; // the computed average duration\r
814 UINT64 Dur;\r
815 UINT64 MinDur;\r
816 UINT64 MaxDur;\r
817 EFI_STRING StringPtr;\r
818 UINTN TIndex;\r
819 EFI_STRING StringPtrUnknown;\r
820\r
821 StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL); \r
822 StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_CUMULATIVE), NULL);\r
823 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,\r
824 (StringPtr == NULL) ? StringPtrUnknown: StringPtr);\r
825 FreePool (StringPtr);\r
826 FreePool (StringPtrUnknown);\r
827\r
828 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_CUMULATIVE_SECT_1), gDpHiiHandle);\r
829 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_CUMULATIVE_SECT_2), gDpHiiHandle);\r
830 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), gDpHiiHandle);\r
831\r
832 for ( TIndex = 0; TIndex < NumCum; ++TIndex) {\r
833 if (CumData[TIndex].Count != 0) {\r
834 AvgDur = DivU64x32 (CumData[TIndex].Duration, CumData[TIndex].Count);\r
835 AvgDur = DurationInMicroSeconds(AvgDur);\r
836 Dur = DurationInMicroSeconds(CumData[TIndex].Duration);\r
837 MaxDur = DurationInMicroSeconds(CumData[TIndex].MaxDur);\r
838 MinDur = DurationInMicroSeconds(CumData[TIndex].MinDur);\r
839 \r
840 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_CUMULATIVE_STATS), gDpHiiHandle,\r
841 CumData[TIndex].Name,\r
842 CumData[TIndex].Count,\r
843 Dur,\r
844 AvgDur,\r
845 MinDur,\r
846 MaxDur\r
847 );\r
848 }\r
849 }\r
a06795c6
CS
850\r
851 //\r
852 // Print the custom cumulative data.\r
853 //\r
854 if (CustomCumulativeData != NULL) {\r
855 if (CustomCumulativeData->Count != 0) {\r
856 AvgDur = DivU64x32 (CustomCumulativeData->Duration, CustomCumulativeData->Count);\r
857 AvgDur = DurationInMicroSeconds (AvgDur);\r
858 Dur = DurationInMicroSeconds (CustomCumulativeData->Duration);\r
859 MaxDur = DurationInMicroSeconds (CustomCumulativeData->MaxDur);\r
860 MinDur = DurationInMicroSeconds (CustomCumulativeData->MinDur);\r
861 } else {\r
862 AvgDur = 0;\r
863 Dur = 0;\r
864 MaxDur = 0;\r
865 MinDur = 0;\r
866 }\r
867 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_CUMULATIVE_STATS), gDpHiiHandle,\r
868 CustomCumulativeData->Name,\r
869 CustomCumulativeData->Count,\r
870 Dur,\r
871 AvgDur,\r
872 MinDur,\r
873 MaxDur\r
874 );\r
875 }\r
d41bc92c 876}\r