2 Shell command for Displaying Performance Metrics.
4 The Dp command reads performance data and presents it in several
5 different formats depending upon the needs of the user. Both
6 Trace and Measured Profiling information is processed and presented.
8 Dp uses the "PerformanceLib" to read the measurement records.
9 The "TimerLib" provides information about the timer, such as frequency,
10 beginning, and ending counter values.
11 Measurement records contain identifying information (Handle, Token, Module)
12 and start and end time values.
13 Dp uses this information to group records in different ways. It also uses
14 timer information to calculate elapsed time for each measurement.
16 Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
17 (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>
18 SPDX-License-Identifier: BSD-2-Clause-Patent
23 #include "DpInternal.h"
28 EFI_ACPI_DESCRIPTION_HEADER Header
;
33 EFI_ACPI_DESCRIPTION_HEADER Header
;
39 EFI_HII_HANDLE mDpHiiHandle
;
46 HANDLE_GUID_MAP
*mCacheHandleGuidTable
;
47 UINTN mCachePairCount
= 0;
50 /// Module-Global Variables
52 CHAR16 mGaugeString
[DP_GAUGE_STRING_LENGTH
+ 1];
53 CHAR16 mUnicodeToken
[DXE_PERFORMANCE_STRING_SIZE
];
54 UINT64 mInterestThreshold
;
55 BOOLEAN mShowId
= FALSE
;
56 UINT8
*mBootPerformanceTable
;
57 UINTN mBootPerformanceTableSize
;
58 BOOLEAN mPeiPhase
= FALSE
;
59 BOOLEAN mDxePhase
= FALSE
;
62 PERF_SUMMARY_DATA SummaryData
= { 0 }; ///< Create the SummaryData structure and init. to ZERO.
63 MEASUREMENT_RECORD
*mMeasurementList
= NULL
;
64 UINTN mMeasurementNum
= 0;
66 /// Items for which to gather cumulative statistics.
67 PERF_CUM_DATA CumData
[] = {
68 PERF_INIT_CUM_DATA (LOAD_IMAGE_TOK
),
69 PERF_INIT_CUM_DATA (START_IMAGE_TOK
),
70 PERF_INIT_CUM_DATA (DRIVERBINDING_START_TOK
),
71 PERF_INIT_CUM_DATA (DRIVERBINDING_SUPPORT_TOK
),
72 PERF_INIT_CUM_DATA (DRIVERBINDING_STOP_TOK
)
75 /// Number of items for which we are gathering cumulative statistics.
76 UINT32
const NumCum
= sizeof (CumData
) / sizeof (PERF_CUM_DATA
);
78 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
79 { L
"-v", TypeFlag
}, // -v Verbose Mode
80 { L
"-A", TypeFlag
}, // -A All, Cooked
81 { L
"-R", TypeFlag
}, // -R RAW All
82 { L
"-s", TypeFlag
}, // -s Summary
83 { L
"-x", TypeFlag
}, // -x eXclude Cumulative Items
84 { L
"-i", TypeFlag
}, // -i Display Identifier
85 { L
"-c", TypeValue
}, // -c Display cumulative data.
86 { L
"-n", TypeValue
}, // -n # Number of records to display for A and R
87 { L
"-t", TypeValue
}, // -t # Threshold of interest
94 Display the trailing Verbose information.
101 EFI_STRING StringPtr
;
102 EFI_STRING StringPtrUnknown
;
104 StringPtr
= HiiGetString (mDpHiiHandle
, STRING_TOKEN (STR_DP_SECTION_STATISTICS
), NULL
);
105 StringPtrUnknown
= HiiGetString (mDpHiiHandle
, STRING_TOKEN (STR_ALIT_UNKNOWN
), NULL
);
110 STRING_TOKEN (STR_DP_SECTION_HEADER
),
112 (StringPtr
== NULL
) ? StringPtrUnknown
: StringPtr
114 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_STATS_NUMTRACE
), mDpHiiHandle
, SummaryData
.NumTrace
);
115 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_STATS_NUMINCOMPLETE
), mDpHiiHandle
, SummaryData
.NumIncomplete
);
116 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_STATS_NUMPHASES
), mDpHiiHandle
, SummaryData
.NumSummary
);
117 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_STATS_NUMHANDLES
), mDpHiiHandle
, SummaryData
.NumHandles
, SummaryData
.NumTrace
- SummaryData
.NumHandles
);
118 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_STATS_NUMPEIMS
), mDpHiiHandle
, SummaryData
.NumPEIMs
);
119 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_STATS_NUMGLOBALS
), mDpHiiHandle
, SummaryData
.NumGlobal
);
120 SHELL_FREE_NON_NULL (StringPtr
);
121 SHELL_FREE_NON_NULL (StringPtrUnknown
);
125 Get Boot performance table form Acpi table.
129 GetBootPerformanceTable (
132 FIRMWARE_PERFORMANCE_TABLE
*FirmwarePerformanceTable
;
134 FirmwarePerformanceTable
= (FIRMWARE_PERFORMANCE_TABLE
*)EfiLocateFirstAcpiTable (
135 EFI_ACPI_5_0_FIRMWARE_PERFORMANCE_DATA_TABLE_SIGNATURE
137 if (FirmwarePerformanceTable
== NULL
) {
138 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_GET_ACPI_FPDT_FAIL
), mDpHiiHandle
);
139 return EFI_NOT_FOUND
;
142 mBootPerformanceTable
= (UINT8
*)(UINTN
)FirmwarePerformanceTable
->BootPointerRecord
.BootPerformanceTablePointer
;
143 mBootPerformanceTableSize
= ((BOOT_PERFORMANCE_TABLE
*)mBootPerformanceTable
)->Header
.Length
;
149 Get Handle form Module Guid.
151 @param ModuleGuid Module Guid.
152 @param Handle The handle to be returned.
156 GetHandleFormModuleGuid (
157 IN EFI_GUID
*ModuleGuid
,
158 IN OUT EFI_HANDLE
*Handle
163 if (IsZeroGuid (ModuleGuid
)) {
168 // Try to get the Handle from the cached array.
170 for (Index
= 0; Index
< mCachePairCount
; Index
++) {
171 if (CompareGuid (ModuleGuid
, &mCacheHandleGuidTable
[Index
].ModuleGuid
)) {
172 *Handle
= mCacheHandleGuidTable
[Index
].Handle
;
177 if (Index
>= mCachePairCount
) {
183 Cache the GUID and handle mapping pairs. In order to save time for searching.
187 BuildCachedGuidHandleTable (
192 EFI_HANDLE
*HandleBuffer
;
195 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
196 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
198 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*FvFilePath
;
200 Status
= gBS
->LocateHandleBuffer (AllHandles
, NULL
, NULL
, &HandleCount
, &HandleBuffer
);
201 if (EFI_ERROR (Status
)) {
202 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_HANDLES_ERROR
), mDpHiiHandle
, Status
);
206 mCacheHandleGuidTable
= AllocateZeroPool (HandleCount
* sizeof (HANDLE_GUID_MAP
));
207 if (mCacheHandleGuidTable
== NULL
) {
208 return EFI_OUT_OF_RESOURCES
;
211 for (Index
= 0; Index
< HandleCount
; Index
++) {
213 // Try Handle as ImageHandle.
215 Status
= gBS
->HandleProtocol (
217 &gEfiLoadedImageProtocolGuid
,
218 (VOID
**)&LoadedImage
220 if (EFI_ERROR (Status
)) {
222 // Try Handle as Controller Handle
224 Status
= gBS
->OpenProtocol (
226 &gEfiDriverBindingProtocolGuid
,
227 (VOID
**)&DriverBinding
,
230 EFI_OPEN_PROTOCOL_GET_PROTOCOL
232 if (!EFI_ERROR (Status
)) {
234 // Get Image protocol from ImageHandle
236 Status
= gBS
->HandleProtocol (
237 DriverBinding
->ImageHandle
,
238 &gEfiLoadedImageProtocolGuid
,
239 (VOID
**)&LoadedImage
244 if (!EFI_ERROR (Status
) && (LoadedImage
!= NULL
)) {
246 // Get Module Guid from DevicePath.
248 if ((LoadedImage
->FilePath
!= NULL
) &&
249 (LoadedImage
->FilePath
->Type
== MEDIA_DEVICE_PATH
) &&
250 (LoadedImage
->FilePath
->SubType
== MEDIA_PIWG_FW_FILE_DP
)
253 FvFilePath
= (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*)LoadedImage
->FilePath
;
254 TempGuid
= &FvFilePath
->FvFileName
;
256 mCacheHandleGuidTable
[mCachePairCount
].Handle
= HandleBuffer
[Index
];
257 CopyGuid (&mCacheHandleGuidTable
[mCachePairCount
].ModuleGuid
, TempGuid
);
263 if (HandleBuffer
!= NULL
) {
264 FreePool (HandleBuffer
);
272 Get Measurement form Fpdt records.
274 @param RecordHeader Pointer to the start record.
275 @param IsStart Is start record or End record.
276 @param Measurement Pointer to the measurement which need to be filled.
281 IN EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER
*RecordHeader
,
283 IN OUT MEASUREMENT_RECORD
*Measurement
287 EFI_HANDLE StartHandle
;
289 switch (RecordHeader
->Type
) {
290 case FPDT_GUID_EVENT_TYPE
:
291 ModuleGuid
= &(((FPDT_GUID_EVENT_RECORD
*)RecordHeader
)->Guid
);
292 Measurement
->Identifier
= ((UINT32
)((FPDT_GUID_EVENT_RECORD
*)RecordHeader
)->ProgressID
);
294 Measurement
->StartTimeStamp
= ((FPDT_GUID_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
296 Measurement
->EndTimeStamp
= ((FPDT_GUID_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
299 switch (Measurement
->Identifier
) {
300 case MODULE_START_ID
:
303 Measurement
->Token
= ALit_PEIM
;
304 Measurement
->Module
= ALit_PEIM
;
305 } else if (mDxePhase
) {
306 Measurement
->Token
= ALit_START_IMAGE
;
307 Measurement
->Module
= ALit_START_IMAGE
;
315 if ((Measurement
->Token
!= NULL
) && (AsciiStrCmp (Measurement
->Token
, ALit_PEIM
) == 0)) {
316 Measurement
->Handle
= &(((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->Guid
);
318 GetHandleFormModuleGuid (ModuleGuid
, &StartHandle
);
319 Measurement
->Handle
= StartHandle
;
321 // When no perf entry to record the PEI and DXE phase,
322 // For start image, we need detect the PEIM and non PEIM here.
324 if (Measurement
->Token
== NULL
) {
325 if ((StartHandle
== NULL
) && !IsZeroGuid (ModuleGuid
)) {
326 Measurement
->Token
= ALit_PEIM
;
327 Measurement
->Module
= ALit_PEIM
;
328 Measurement
->Handle
= ModuleGuid
;
330 Measurement
->Token
= ALit_START_IMAGE
;
331 Measurement
->Module
= ALit_START_IMAGE
;
338 case FPDT_DYNAMIC_STRING_EVENT_TYPE
:
339 ModuleGuid
= &(((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->Guid
);
340 Measurement
->Identifier
= ((UINT32
)((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->ProgressID
);
342 Measurement
->StartTimeStamp
= ((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
344 Measurement
->EndTimeStamp
= ((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
347 switch (Measurement
->Identifier
) {
348 case MODULE_START_ID
:
351 Measurement
->Token
= ALit_PEIM
;
352 } else if (mDxePhase
) {
353 Measurement
->Token
= ALit_START_IMAGE
;
358 case MODULE_LOADIMAGE_START_ID
:
359 case MODULE_LOADIMAGE_END_ID
:
360 Measurement
->Token
= ALit_LOAD_IMAGE
;
363 case MODULE_DB_START_ID
:
364 case MODULE_DB_END_ID
:
365 Measurement
->Token
= ALit_DB_START
;
368 case MODULE_DB_SUPPORT_START_ID
:
369 case MODULE_DB_SUPPORT_END_ID
:
370 Measurement
->Token
= ALit_DB_SUPPORT
;
373 case MODULE_DB_STOP_START_ID
:
374 case MODULE_DB_STOP_END_ID
:
375 Measurement
->Token
= ALit_DB_STOP
;
379 Measurement
->Token
= ((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->String
;
383 Measurement
->Module
= ((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->String
;
385 if ((Measurement
->Token
!= NULL
) && (AsciiStrCmp (Measurement
->Token
, ALit_PEIM
) == 0)) {
386 Measurement
->Handle
= &(((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->Guid
);
388 GetHandleFormModuleGuid (ModuleGuid
, &StartHandle
);
389 Measurement
->Handle
= StartHandle
;
391 // When no perf entry to record the PEI and DXE phase,
392 // For start image, we need detect the PEIM and non PEIM here.
394 if ((Measurement
->Token
== NULL
) && ((Measurement
->Identifier
== MODULE_START_ID
) || (Measurement
->Identifier
== MODULE_END_ID
))) {
395 if ((StartHandle
== NULL
) && !IsZeroGuid (ModuleGuid
)) {
396 Measurement
->Token
= ALit_PEIM
;
397 Measurement
->Handle
= ModuleGuid
;
399 Measurement
->Token
= ALit_START_IMAGE
;
406 case FPDT_GUID_QWORD_EVENT_TYPE
:
407 ModuleGuid
= &(((FPDT_GUID_QWORD_EVENT_RECORD
*)RecordHeader
)->Guid
);
408 Measurement
->Identifier
= ((UINT32
)((FPDT_GUID_QWORD_EVENT_RECORD
*)RecordHeader
)->ProgressID
);
410 Measurement
->StartTimeStamp
= ((FPDT_GUID_QWORD_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
412 Measurement
->EndTimeStamp
= ((FPDT_GUID_QWORD_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
415 switch (Measurement
->Identifier
) {
416 case MODULE_DB_START_ID
:
417 Measurement
->Token
= ALit_DB_START
;
418 Measurement
->Module
= ALit_DB_START
;
421 case MODULE_DB_SUPPORT_START_ID
:
422 case MODULE_DB_SUPPORT_END_ID
:
423 Measurement
->Token
= ALit_DB_SUPPORT
;
424 Measurement
->Module
= ALit_DB_SUPPORT
;
427 case MODULE_DB_STOP_START_ID
:
428 case MODULE_DB_STOP_END_ID
:
429 Measurement
->Token
= ALit_DB_STOP
;
430 Measurement
->Module
= ALit_DB_STOP
;
433 case MODULE_LOADIMAGE_START_ID
:
434 case MODULE_LOADIMAGE_END_ID
:
435 Measurement
->Token
= ALit_LOAD_IMAGE
;
436 Measurement
->Module
= ALit_LOAD_IMAGE
;
443 GetHandleFormModuleGuid (ModuleGuid
, &StartHandle
);
444 Measurement
->Handle
= StartHandle
;
447 case FPDT_GUID_QWORD_STRING_EVENT_TYPE
:
448 ModuleGuid
= &(((FPDT_GUID_QWORD_STRING_EVENT_RECORD
*)RecordHeader
)->Guid
);
449 Measurement
->Identifier
= ((UINT32
)((FPDT_GUID_QWORD_STRING_EVENT_RECORD
*)RecordHeader
)->ProgressID
);
451 Measurement
->StartTimeStamp
= ((FPDT_GUID_QWORD_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
453 Measurement
->EndTimeStamp
= ((FPDT_GUID_QWORD_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
457 // Currently only "DB:Start:" end record with FPDT_GUID_QWORD_STRING_EVENT_TYPE.
459 switch (Measurement
->Identifier
) {
460 case MODULE_DB_END_ID
:
461 Measurement
->Token
= ALit_DB_START
;
462 Measurement
->Module
= ALit_DB_START
;
468 GetHandleFormModuleGuid (ModuleGuid
, &StartHandle
);
469 Measurement
->Handle
= StartHandle
;
472 case FPDT_DUAL_GUID_STRING_EVENT_TYPE
:
473 ModuleGuid
= &(((FPDT_DUAL_GUID_STRING_EVENT_RECORD
*)RecordHeader
)->Guid1
);
474 Measurement
->Identifier
= ((UINT32
)((FPDT_DUAL_GUID_STRING_EVENT_RECORD
*)RecordHeader
)->ProgressID
);
476 Measurement
->StartTimeStamp
= ((FPDT_DUAL_GUID_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
478 Measurement
->EndTimeStamp
= ((FPDT_DUAL_GUID_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
481 Measurement
->Token
= ((FPDT_DUAL_GUID_STRING_EVENT_RECORD
*)RecordHeader
)->String
;
482 Measurement
->Module
= ((FPDT_DUAL_GUID_STRING_EVENT_RECORD
*)RecordHeader
)->String
;
483 GetHandleFormModuleGuid (ModuleGuid
, &StartHandle
);
484 Measurement
->Handle
= StartHandle
;
493 Search the start measurement in the mMeasurementList for the end measurement.
495 @param EndMeasureMent Measurement for end record.
500 IN MEASUREMENT_RECORD
*EndMeasureMent
505 for (Index
= mMeasurementNum
- 1; Index
>= 0; Index
--) {
506 if (AsciiStrCmp (EndMeasureMent
->Token
, ALit_PEIM
) == 0) {
507 if ((mMeasurementList
[Index
].EndTimeStamp
== 0) && (EndMeasureMent
->Handle
!= NULL
) && (mMeasurementList
[Index
].Handle
!= NULL
) &&
508 CompareGuid (mMeasurementList
[Index
].Handle
, EndMeasureMent
->Handle
) &&
509 (AsciiStrCmp (mMeasurementList
[Index
].Token
, EndMeasureMent
->Token
) == 0) &&
510 (AsciiStrCmp (mMeasurementList
[Index
].Module
, EndMeasureMent
->Module
) == 0))
512 mMeasurementList
[Index
].EndTimeStamp
= EndMeasureMent
->EndTimeStamp
;
515 } else if (EndMeasureMent
->Identifier
== PERF_CROSSMODULE_END_ID
) {
516 if ((mMeasurementList
[Index
].EndTimeStamp
== 0) &&
517 (AsciiStrCmp (mMeasurementList
[Index
].Token
, EndMeasureMent
->Token
) == 0) &&
518 (AsciiStrCmp (mMeasurementList
[Index
].Module
, EndMeasureMent
->Module
) == 0) &&
519 (mMeasurementList
[Index
].Identifier
== PERF_CROSSMODULE_START_ID
))
521 mMeasurementList
[Index
].EndTimeStamp
= EndMeasureMent
->EndTimeStamp
;
525 if ((mMeasurementList
[Index
].EndTimeStamp
== 0) && (mMeasurementList
[Index
].Handle
== EndMeasureMent
->Handle
) &&
526 (AsciiStrCmp (mMeasurementList
[Index
].Token
, EndMeasureMent
->Token
) == 0) &&
527 (AsciiStrCmp (mMeasurementList
[Index
].Module
, EndMeasureMent
->Module
) == 0))
529 mMeasurementList
[Index
].EndTimeStamp
= EndMeasureMent
->EndTimeStamp
;
537 Generate the measure record array.
541 BuildMeasurementList (
544 EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER
*RecordHeader
;
545 UINT8
*PerformanceTablePtr
;
546 UINT8
*BasicBootTablePtr
;
548 UINT16 StartProgressId
;
550 UINT8
*StartRecordEvent
;
551 MEASUREMENT_RECORD MeasureMent
;
553 mMeasurementList
= AllocateZeroPool (mBootPerformanceTableSize
);
554 if (mMeasurementList
== NULL
) {
555 return EFI_OUT_OF_RESOURCES
;
559 // Update the ResetEnd which was logged at the beginning of firmware image execution
561 TableLength
= sizeof (EFI_ACPI_5_0_FPDT_PERFORMANCE_TABLE_HEADER
);
562 BasicBootTablePtr
= (mBootPerformanceTable
+ TableLength
);
563 ResetEnd
= ((EFI_ACPI_5_0_FPDT_FIRMWARE_BASIC_BOOT_RECORD
*)BasicBootTablePtr
)->ResetEnd
;
566 mResetEnd
= ResetEnd
;
569 TableLength
= sizeof (BOOT_PERFORMANCE_TABLE
);
570 PerformanceTablePtr
= (mBootPerformanceTable
+ TableLength
);
572 while (TableLength
< mBootPerformanceTableSize
) {
573 RecordHeader
= (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER
*)PerformanceTablePtr
;
574 StartRecordEvent
= (UINT8
*)RecordHeader
;
575 StartProgressId
= ((FPDT_GUID_EVENT_RECORD
*)StartRecordEvent
)->ProgressID
;
578 // If the record with ProgressId 0, the record doesn't appear in pairs. The timestamp in the record is the EndTimeStamp, its StartTimeStamp is 0.
579 // If the record is the start record, fill the info to the measurement in the mMeasurementList.
580 // If the record is the end record, find the related start measurement in the mMeasurementList and fill the EndTimeStamp.
582 if (StartProgressId
== 0) {
583 GetMeasurementInfo (RecordHeader
, FALSE
, &(mMeasurementList
[mMeasurementNum
]));
585 } else if ((((StartProgressId
>= PERF_EVENTSIGNAL_START_ID
) && ((StartProgressId
& 0x000F) == 0)) ||
586 ((StartProgressId
< PERF_EVENTSIGNAL_START_ID
) && ((StartProgressId
& 0x0001) != 0))))
589 // Since PEIM and StartImage has same Type and ID when PCD PcdEdkiiFpdtStringRecordEnableOnly = FALSE
590 // So we need to identify these two kinds of record through different phase.
592 if (StartProgressId
== PERF_CROSSMODULE_START_ID
) {
593 if (AsciiStrCmp (((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)StartRecordEvent
)->String
, ALit_PEI
) == 0) {
595 } else if (AsciiStrCmp (((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)StartRecordEvent
)->String
, ALit_DXE
) == 0) {
601 // Get measurement info form the start record to the mMeasurementList.
602 GetMeasurementInfo (RecordHeader
, TRUE
, &(mMeasurementList
[mMeasurementNum
]));
605 ZeroMem (&MeasureMent
, sizeof (MEASUREMENT_RECORD
));
606 GetMeasurementInfo (RecordHeader
, FALSE
, &MeasureMent
);
607 SearchMeasurement (&MeasureMent
);
610 TableLength
+= RecordHeader
->Length
;
611 PerformanceTablePtr
+= RecordHeader
->Length
;
618 Initialize the cumulative data.
628 for (Index
= 0; Index
< NumCum
; ++Index
) {
629 CumData
[Index
].Count
= 0;
630 CumData
[Index
].MinDur
= PERF_MAXDUR
;
631 CumData
[Index
].MaxDur
= 0;
632 CumData
[Index
].Duration
= 0;
637 Initialize the Summary data.
645 SummaryData
.NumTrace
= 0;
646 SummaryData
.NumIncomplete
= 0;
647 SummaryData
.NumSummary
= 0;
648 SummaryData
.NumHandles
= 0;
649 SummaryData
.NumPEIMs
= 0;
650 SummaryData
.NumGlobal
= 0;
654 Dump performance data.
656 @param[in] ImageHandle The image handle.
657 @param[in] SystemTable The system table.
659 @retval SHELL_SUCCESS Command completed successfully.
660 @retval SHELL_INVALID_PARAMETER Command usage error.
661 @retval SHELL_ABORTED The user aborts the operation.
662 @retval value Unknown error.
666 IN EFI_HANDLE ImageHandle
,
667 IN EFI_SYSTEM_TABLE
*SystemTable
670 LIST_ENTRY
*ParamPackage
;
671 CONST CHAR16
*CmdLineArg
;
674 PERFORMANCE_PROPERTY
*PerformanceProperty
;
675 UINTN Number2Display
;
677 EFI_STRING StringPtr
;
683 BOOLEAN CumulativeMode
;
684 CONST CHAR16
*CustomCumulativeToken
;
685 PERF_CUM_DATA
*CustomCumulativeData
;
687 SHELL_STATUS ShellStatus
;
688 TIMER_INFO TimerInfo
;
697 CumulativeMode
= FALSE
;
698 CustomCumulativeData
= NULL
;
699 ShellStatus
= SHELL_SUCCESS
;
702 // initialize the shell lib (we must be in non-auto-init...)
704 Status
= ShellInitialize ();
705 ASSERT_EFI_ERROR (Status
);
708 // Process Command Line arguments
710 Status
= ShellCommandLineParse (ParamList
, &ParamPackage
, NULL
, TRUE
);
711 if (EFI_ERROR (Status
)) {
712 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_INVALID_ARG
), mDpHiiHandle
);
713 return SHELL_INVALID_PARAMETER
;
714 } else if (ShellCommandLineGetCount (ParamPackage
) > 1) {
715 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_TOO_MANY
), mDpHiiHandle
);
716 return SHELL_INVALID_PARAMETER
;
722 VerboseMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-v");
723 SummaryMode
= (BOOLEAN
)(ShellCommandLineGetFlag (ParamPackage
, L
"-S") || ShellCommandLineGetFlag (ParamPackage
, L
"-s"));
724 AllMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-A");
725 RawMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-R");
726 ExcludeMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-x");
727 mShowId
= ShellCommandLineGetFlag (ParamPackage
, L
"-i");
728 CumulativeMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-c");
730 if (AllMode
&& RawMode
) {
731 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_CONFLICT_ARG
), mDpHiiHandle
, L
"-A", L
"-R");
732 return SHELL_INVALID_PARAMETER
;
735 // Options with Values
736 if (ShellCommandLineGetFlag (ParamPackage
, L
"-n")) {
737 CmdLineArg
= ShellCommandLineGetValue (ParamPackage
, L
"-n");
738 if (CmdLineArg
== NULL
) {
739 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_TOO_FEW
), mDpHiiHandle
);
740 return SHELL_INVALID_PARAMETER
;
742 if (!(RawMode
|| AllMode
)) {
743 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_NO_RAW_ALL
), mDpHiiHandle
);
744 return SHELL_INVALID_PARAMETER
;
747 Status
= ShellConvertStringToUint64 (CmdLineArg
, &Intermediate
, FALSE
, TRUE
);
748 if (EFI_ERROR (Status
)) {
749 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_INVALID_NUM_ARG
), mDpHiiHandle
, L
"-n");
750 return SHELL_INVALID_PARAMETER
;
752 Number2Display
= (UINTN
)Intermediate
;
753 if ((Number2Display
== 0) || (Number2Display
> MAXIMUM_DISPLAYCOUNT
)) {
754 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_INVALID_RANGE
), mDpHiiHandle
, L
"-n", 0, MAXIMUM_DISPLAYCOUNT
);
755 return SHELL_INVALID_PARAMETER
;
760 Number2Display
= DEFAULT_DISPLAYCOUNT
;
763 if (ShellCommandLineGetFlag (ParamPackage
, L
"-t")) {
764 CmdLineArg
= ShellCommandLineGetValue (ParamPackage
, L
"-t");
765 if (CmdLineArg
== NULL
) {
766 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_TOO_FEW
), mDpHiiHandle
);
767 return SHELL_INVALID_PARAMETER
;
769 Status
= ShellConvertStringToUint64 (CmdLineArg
, &Intermediate
, FALSE
, TRUE
);
770 if (EFI_ERROR (Status
)) {
771 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_INVALID_NUM_ARG
), mDpHiiHandle
, L
"-t");
772 return SHELL_INVALID_PARAMETER
;
774 mInterestThreshold
= Intermediate
;
778 mInterestThreshold
= DEFAULT_THRESHOLD
; // 1ms := 1,000 us
781 if (ShellCommandLineGetFlag (ParamPackage
, L
"-c")) {
782 CustomCumulativeToken
= ShellCommandLineGetValue (ParamPackage
, L
"-c");
783 if (CustomCumulativeToken
== NULL
) {
784 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_TOO_FEW
), mDpHiiHandle
);
785 return SHELL_INVALID_PARAMETER
;
787 CustomCumulativeData
= AllocateZeroPool (sizeof (PERF_CUM_DATA
));
788 if (CustomCumulativeData
== NULL
) {
789 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
793 CustomCumulativeData
->MinDur
= PERF_MAXDUR
;
794 CustomCumulativeData
->MaxDur
= 0;
795 CustomCumulativeData
->Count
= 0;
796 CustomCumulativeData
->Duration
= 0;
797 NameSize
= StrLen (CustomCumulativeToken
) + 1;
798 CustomCumulativeData
->Name
= AllocateZeroPool (NameSize
);
799 if (CustomCumulativeData
->Name
== NULL
) {
800 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
804 UnicodeStrToAsciiStrS (CustomCumulativeToken
, CustomCumulativeData
->Name
, NameSize
);
809 // DP dump performance data by parsing FPDT table in ACPI table.
810 // Folloing 3 steps are to get the measurement form the FPDT table.
814 // 1. Get FPDT from ACPI table.
816 Status
= GetBootPerformanceTable ();
817 if (EFI_ERROR (Status
)) {
818 ShellStatus
= Status
;
823 // 2. Cache the ModuleGuid and hanlde mapping table.
825 Status
= BuildCachedGuidHandleTable ();
826 if (EFI_ERROR (Status
)) {
827 ShellStatus
= Status
;
832 // 3. Build the measurement array form the FPDT records.
834 Status
= BuildMeasurementList ();
835 if (EFI_ERROR (Status
)) {
836 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
841 // Initialize the pre-defined cumulative data.
843 InitCumulativeData ();
846 // Initialize the Summary data.
851 // Timer specific processing
853 // Get the Performance counter characteristics:
854 // Freq = Frequency in Hz
855 // StartCount = Value loaded into the counter when it starts counting
856 // EndCount = Value counter counts to before it needs to be reset
858 Status
= EfiGetSystemConfigurationTable (&gPerformanceProtocolGuid
, (VOID
**)&PerformanceProperty
);
859 if (EFI_ERROR (Status
) || (PerformanceProperty
== NULL
)) {
860 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_PERF_PROPERTY_NOT_FOUND
), mDpHiiHandle
);
864 TimerInfo
.Frequency
= (UINT32
)DivU64x32 (PerformanceProperty
->Frequency
, 1000);
865 TimerInfo
.StartCount
= 0;
866 TimerInfo
.EndCount
= 0xFFFF;
867 TimerInfo
.CountUp
= TRUE
;
872 // print DP's build version
873 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_BUILD_REVISION
), mDpHiiHandle
, DP_MAJOR_VERSION
, DP_MINOR_VERSION
);
875 // print performance timer characteristics
876 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_KHZ
), mDpHiiHandle
, TimerInfo
.Frequency
);
878 if (VerboseMode
&& !RawMode
) {
879 StringPtr
= HiiGetString (
881 (EFI_STRING_ID
)(TimerInfo
.CountUp
? STRING_TOKEN (STR_DP_UP
) : STRING_TOKEN (STR_DP_DOWN
)),
884 ASSERT (StringPtr
!= NULL
);
885 // Print Timer count range and direction
890 STRING_TOKEN (STR_DP_TIMER_PROPERTIES
),
893 TimerInfo
.StartCount
,
896 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_VERBOSE_THRESHOLD
), mDpHiiHandle
, mInterestThreshold
);
899 /****************************************************************************
900 **** Print Sections based on command line options
902 **** Option modes have the following priority:
903 **** v Verbose -- Valid in combination with any other options
904 **** t Threshold -- Modifies All, Raw, and Cooked output
905 **** Default is 0 for All and Raw mode
906 **** Default is DEFAULT_THRESHOLD for "Cooked" mode
907 **** n Number2Display Used by All and Raw mode. Otherwise ignored.
908 **** A All -- R and S options are ignored
909 **** R Raw -- S option is ignored
910 **** s Summary -- Modifies "Cooked" output only
911 **** Cooked (Default)
912 ****************************************************************************/
913 GatherStatistics (CustomCumulativeData
);
914 if (CumulativeMode
) {
915 ProcessCumulative (CustomCumulativeData
);
916 } else if (AllMode
) {
917 Status
= DumpAllTrace (Number2Display
, ExcludeMode
);
918 if (Status
== EFI_ABORTED
) {
919 ShellStatus
= SHELL_ABORTED
;
922 } else if (RawMode
) {
923 Status
= DumpRawTrace (Number2Display
, ExcludeMode
);
924 if (Status
== EFI_ABORTED
) {
925 ShellStatus
= SHELL_ABORTED
;
929 // ------------- Begin Cooked Mode Processing
932 Status
= ProcessHandles (ExcludeMode
);
933 if (Status
== EFI_ABORTED
) {
934 ShellStatus
= SHELL_ABORTED
;
938 Status
= ProcessPeims ();
939 if (Status
== EFI_ABORTED
) {
940 ShellStatus
= SHELL_ABORTED
;
944 Status
= ProcessGlobal ();
945 if (Status
== EFI_ABORTED
) {
946 ShellStatus
= SHELL_ABORTED
;
950 ProcessCumulative (NULL
);
952 } // ------------- End of Cooked Mode Processing
954 if ( VerboseMode
|| SummaryMode
) {
959 if (ParamPackage
!= NULL
) {
960 ShellCommandLineFreeVarList (ParamPackage
);
963 SHELL_FREE_NON_NULL (StringPtr
);
964 if (CustomCumulativeData
!= NULL
) {
965 SHELL_FREE_NON_NULL (CustomCumulativeData
->Name
);
968 SHELL_FREE_NON_NULL (CustomCumulativeData
);
970 SHELL_FREE_NON_NULL (mMeasurementList
);
972 SHELL_FREE_NON_NULL (mCacheHandleGuidTable
);
980 Retrieve HII package list from ImageHandle and publish to HII database.
982 @param ImageHandle The image handle of the process.
987 InitializeHiiPackage (
988 EFI_HANDLE ImageHandle
992 EFI_HII_PACKAGE_LIST_HEADER
*PackageList
;
993 EFI_HII_HANDLE HiiHandle
;
996 // Retrieve HII package list from ImageHandle
998 Status
= gBS
->OpenProtocol (
1000 &gEfiHiiPackageListProtocolGuid
,
1001 (VOID
**)&PackageList
,
1004 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1006 ASSERT_EFI_ERROR (Status
);
1007 if (EFI_ERROR (Status
)) {
1012 // Publish HII package list to HII Database.
1014 Status
= gHiiDatabase
->NewPackageList (
1020 ASSERT_EFI_ERROR (Status
);
1021 if (EFI_ERROR (Status
)) {