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