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
;
61 PERF_SUMMARY_DATA SummaryData
= { 0 }; ///< Create the SummaryData structure and init. to ZERO.
62 MEASUREMENT_RECORD
*mMeasurementList
= NULL
;
63 UINTN mMeasurementNum
= 0;
65 /// Items for which to gather cumulative statistics.
66 PERF_CUM_DATA CumData
[] = {
67 PERF_INIT_CUM_DATA (LOAD_IMAGE_TOK
),
68 PERF_INIT_CUM_DATA (START_IMAGE_TOK
),
69 PERF_INIT_CUM_DATA (DRIVERBINDING_START_TOK
),
70 PERF_INIT_CUM_DATA (DRIVERBINDING_SUPPORT_TOK
),
71 PERF_INIT_CUM_DATA (DRIVERBINDING_STOP_TOK
)
74 /// Number of items for which we are gathering cumulative statistics.
75 UINT32
const NumCum
= sizeof (CumData
) / sizeof (PERF_CUM_DATA
);
77 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
78 { L
"-v", TypeFlag
}, // -v Verbose Mode
79 { L
"-A", TypeFlag
}, // -A All, Cooked
80 { L
"-R", TypeFlag
}, // -R RAW All
81 { L
"-s", TypeFlag
}, // -s Summary
82 { L
"-x", TypeFlag
}, // -x eXclude Cumulative Items
83 { L
"-i", TypeFlag
}, // -i Display Identifier
84 { L
"-c", TypeValue
}, // -c Display cumulative data.
85 { L
"-n", TypeValue
}, // -n # Number of records to display for A and R
86 { L
"-t", TypeValue
}, // -t # Threshold of interest
93 Display the trailing Verbose information.
100 EFI_STRING StringPtr
;
101 EFI_STRING StringPtrUnknown
;
103 StringPtr
= HiiGetString (mDpHiiHandle
, STRING_TOKEN (STR_DP_SECTION_STATISTICS
), NULL
);
104 StringPtrUnknown
= HiiGetString (mDpHiiHandle
, STRING_TOKEN (STR_ALIT_UNKNOWN
), NULL
);
109 STRING_TOKEN (STR_DP_SECTION_HEADER
),
111 (StringPtr
== NULL
) ? StringPtrUnknown
: StringPtr
113 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_STATS_NUMTRACE
), mDpHiiHandle
, SummaryData
.NumTrace
);
114 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_STATS_NUMINCOMPLETE
), mDpHiiHandle
, SummaryData
.NumIncomplete
);
115 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_STATS_NUMPHASES
), mDpHiiHandle
, SummaryData
.NumSummary
);
116 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_STATS_NUMHANDLES
), mDpHiiHandle
, SummaryData
.NumHandles
, SummaryData
.NumTrace
- SummaryData
.NumHandles
);
117 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_STATS_NUMPEIMS
), mDpHiiHandle
, SummaryData
.NumPEIMs
);
118 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_STATS_NUMGLOBALS
), mDpHiiHandle
, SummaryData
.NumGlobal
);
119 SHELL_FREE_NON_NULL (StringPtr
);
120 SHELL_FREE_NON_NULL (StringPtrUnknown
);
124 Get Boot performance table form Acpi table.
128 GetBootPerformanceTable (
131 FIRMWARE_PERFORMANCE_TABLE
*FirmwarePerformanceTable
;
133 FirmwarePerformanceTable
= (FIRMWARE_PERFORMANCE_TABLE
*)EfiLocateFirstAcpiTable (
134 EFI_ACPI_5_0_FIRMWARE_PERFORMANCE_DATA_TABLE_SIGNATURE
136 if (FirmwarePerformanceTable
== NULL
) {
137 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_GET_ACPI_FPDT_FAIL
), mDpHiiHandle
);
138 return EFI_NOT_FOUND
;
141 mBootPerformanceTable
= (UINT8
*)(UINTN
)FirmwarePerformanceTable
->BootPointerRecord
.BootPerformanceTablePointer
;
142 mBootPerformanceTableSize
= ((BOOT_PERFORMANCE_TABLE
*)mBootPerformanceTable
)->Header
.Length
;
148 Get Handle form Module Guid.
150 @param ModuleGuid Module Guid.
151 @param Handle The handle to be returned.
155 GetHandleFormModuleGuid (
156 IN EFI_GUID
*ModuleGuid
,
157 IN OUT EFI_HANDLE
*Handle
162 if (IsZeroGuid (ModuleGuid
)) {
167 // Try to get the Handle from the cached array.
169 for (Index
= 0; Index
< mCachePairCount
; Index
++) {
170 if (CompareGuid (ModuleGuid
, &mCacheHandleGuidTable
[Index
].ModuleGuid
)) {
171 *Handle
= mCacheHandleGuidTable
[Index
].Handle
;
176 if (Index
>= mCachePairCount
) {
182 Cache the GUID and handle mapping pairs. In order to save time for searching.
186 BuildCachedGuidHandleTable (
191 EFI_HANDLE
*HandleBuffer
;
194 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
195 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
197 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*FvFilePath
;
199 Status
= gBS
->LocateHandleBuffer (AllHandles
, NULL
, NULL
, &HandleCount
, &HandleBuffer
);
200 if (EFI_ERROR (Status
)) {
201 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_HANDLES_ERROR
), mDpHiiHandle
, Status
);
205 mCacheHandleGuidTable
= AllocateZeroPool (HandleCount
* sizeof (HANDLE_GUID_MAP
));
206 if (mCacheHandleGuidTable
== NULL
) {
207 return EFI_OUT_OF_RESOURCES
;
210 for (Index
= 0; Index
< HandleCount
; Index
++) {
212 // Try Handle as ImageHandle.
214 Status
= gBS
->HandleProtocol (
216 &gEfiLoadedImageProtocolGuid
,
217 (VOID
**)&LoadedImage
219 if (EFI_ERROR (Status
)) {
221 // Try Handle as Controller Handle
223 Status
= gBS
->OpenProtocol (
225 &gEfiDriverBindingProtocolGuid
,
226 (VOID
**)&DriverBinding
,
229 EFI_OPEN_PROTOCOL_GET_PROTOCOL
231 if (!EFI_ERROR (Status
)) {
233 // Get Image protocol from ImageHandle
235 Status
= gBS
->HandleProtocol (
236 DriverBinding
->ImageHandle
,
237 &gEfiLoadedImageProtocolGuid
,
238 (VOID
**)&LoadedImage
243 if (!EFI_ERROR (Status
) && (LoadedImage
!= NULL
)) {
245 // Get Module Guid from DevicePath.
247 if ((LoadedImage
->FilePath
!= NULL
) &&
248 (LoadedImage
->FilePath
->Type
== MEDIA_DEVICE_PATH
) &&
249 (LoadedImage
->FilePath
->SubType
== MEDIA_PIWG_FW_FILE_DP
)
252 FvFilePath
= (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*)LoadedImage
->FilePath
;
253 TempGuid
= &FvFilePath
->FvFileName
;
255 mCacheHandleGuidTable
[mCachePairCount
].Handle
= HandleBuffer
[Index
];
256 CopyGuid (&mCacheHandleGuidTable
[mCachePairCount
].ModuleGuid
, TempGuid
);
262 if (HandleBuffer
!= NULL
) {
263 FreePool (HandleBuffer
);
271 Get Measurement form Fpdt records.
273 @param RecordHeader Pointer to the start record.
274 @param IsStart Is start record or End record.
275 @param Measurement Pointer to the measurement which need to be filled.
280 IN EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER
*RecordHeader
,
282 IN OUT MEASUREMENT_RECORD
*Measurement
286 EFI_HANDLE StartHandle
;
288 switch (RecordHeader
->Type
) {
289 case FPDT_GUID_EVENT_TYPE
:
290 ModuleGuid
= &(((FPDT_GUID_EVENT_RECORD
*)RecordHeader
)->Guid
);
291 Measurement
->Identifier
= ((UINT32
)((FPDT_GUID_EVENT_RECORD
*)RecordHeader
)->ProgressID
);
293 Measurement
->StartTimeStamp
= ((FPDT_GUID_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
295 Measurement
->EndTimeStamp
= ((FPDT_GUID_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
298 switch (Measurement
->Identifier
) {
299 case MODULE_START_ID
:
302 Measurement
->Token
= ALit_PEIM
;
303 Measurement
->Module
= ALit_PEIM
;
304 } else if (mDxePhase
) {
305 Measurement
->Token
= ALit_START_IMAGE
;
306 Measurement
->Module
= ALit_START_IMAGE
;
314 if ((Measurement
->Token
!= NULL
) && (AsciiStrCmp (Measurement
->Token
, ALit_PEIM
) == 0)) {
315 Measurement
->Handle
= &(((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->Guid
);
317 GetHandleFormModuleGuid (ModuleGuid
, &StartHandle
);
318 Measurement
->Handle
= StartHandle
;
320 // When no perf entry to record the PEI and DXE phase,
321 // For start image, we need detect the PEIM and non PEIM here.
323 if (Measurement
->Token
== NULL
) {
324 if ((StartHandle
== NULL
) && !IsZeroGuid (ModuleGuid
)) {
325 Measurement
->Token
= ALit_PEIM
;
326 Measurement
->Module
= ALit_PEIM
;
327 Measurement
->Handle
= ModuleGuid
;
329 Measurement
->Token
= ALit_START_IMAGE
;
330 Measurement
->Module
= ALit_START_IMAGE
;
337 case FPDT_DYNAMIC_STRING_EVENT_TYPE
:
338 ModuleGuid
= &(((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->Guid
);
339 Measurement
->Identifier
= ((UINT32
)((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->ProgressID
);
341 Measurement
->StartTimeStamp
= ((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
343 Measurement
->EndTimeStamp
= ((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
346 switch (Measurement
->Identifier
) {
347 case MODULE_START_ID
:
350 Measurement
->Token
= ALit_PEIM
;
351 } else if (mDxePhase
) {
352 Measurement
->Token
= ALit_START_IMAGE
;
357 case MODULE_LOADIMAGE_START_ID
:
358 case MODULE_LOADIMAGE_END_ID
:
359 Measurement
->Token
= ALit_LOAD_IMAGE
;
362 case MODULE_DB_START_ID
:
363 case MODULE_DB_END_ID
:
364 Measurement
->Token
= ALit_DB_START
;
367 case MODULE_DB_SUPPORT_START_ID
:
368 case MODULE_DB_SUPPORT_END_ID
:
369 Measurement
->Token
= ALit_DB_SUPPORT
;
372 case MODULE_DB_STOP_START_ID
:
373 case MODULE_DB_STOP_END_ID
:
374 Measurement
->Token
= ALit_DB_STOP
;
378 Measurement
->Token
= ((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->String
;
382 Measurement
->Module
= ((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->String
;
384 if ((Measurement
->Token
!= NULL
) && (AsciiStrCmp (Measurement
->Token
, ALit_PEIM
) == 0)) {
385 Measurement
->Handle
= &(((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->Guid
);
387 GetHandleFormModuleGuid (ModuleGuid
, &StartHandle
);
388 Measurement
->Handle
= StartHandle
;
390 // When no perf entry to record the PEI and DXE phase,
391 // For start image, we need detect the PEIM and non PEIM here.
393 if ((Measurement
->Token
== NULL
) && ((Measurement
->Identifier
== MODULE_START_ID
) || (Measurement
->Identifier
== MODULE_END_ID
))) {
394 if ((StartHandle
== NULL
) && !IsZeroGuid (ModuleGuid
)) {
395 Measurement
->Token
= ALit_PEIM
;
396 Measurement
->Handle
= ModuleGuid
;
398 Measurement
->Token
= ALit_START_IMAGE
;
405 case FPDT_GUID_QWORD_EVENT_TYPE
:
406 ModuleGuid
= &(((FPDT_GUID_QWORD_EVENT_RECORD
*)RecordHeader
)->Guid
);
407 Measurement
->Identifier
= ((UINT32
)((FPDT_GUID_QWORD_EVENT_RECORD
*)RecordHeader
)->ProgressID
);
409 Measurement
->StartTimeStamp
= ((FPDT_GUID_QWORD_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
411 Measurement
->EndTimeStamp
= ((FPDT_GUID_QWORD_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
414 switch (Measurement
->Identifier
) {
415 case MODULE_DB_START_ID
:
416 Measurement
->Token
= ALit_DB_START
;
417 Measurement
->Module
= ALit_DB_START
;
420 case MODULE_DB_SUPPORT_START_ID
:
421 case MODULE_DB_SUPPORT_END_ID
:
422 Measurement
->Token
= ALit_DB_SUPPORT
;
423 Measurement
->Module
= ALit_DB_SUPPORT
;
426 case MODULE_DB_STOP_START_ID
:
427 case MODULE_DB_STOP_END_ID
:
428 Measurement
->Token
= ALit_DB_STOP
;
429 Measurement
->Module
= ALit_DB_STOP
;
432 case MODULE_LOADIMAGE_START_ID
:
433 case MODULE_LOADIMAGE_END_ID
:
434 Measurement
->Token
= ALit_LOAD_IMAGE
;
435 Measurement
->Module
= ALit_LOAD_IMAGE
;
442 GetHandleFormModuleGuid (ModuleGuid
, &StartHandle
);
443 Measurement
->Handle
= StartHandle
;
446 case FPDT_GUID_QWORD_STRING_EVENT_TYPE
:
447 ModuleGuid
= &(((FPDT_GUID_QWORD_STRING_EVENT_RECORD
*)RecordHeader
)->Guid
);
448 Measurement
->Identifier
= ((UINT32
)((FPDT_GUID_QWORD_STRING_EVENT_RECORD
*)RecordHeader
)->ProgressID
);
450 Measurement
->StartTimeStamp
= ((FPDT_GUID_QWORD_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
452 Measurement
->EndTimeStamp
= ((FPDT_GUID_QWORD_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
456 // Currently only "DB:Start:" end record with FPDT_GUID_QWORD_STRING_EVENT_TYPE.
458 switch (Measurement
->Identifier
) {
459 case MODULE_DB_END_ID
:
460 Measurement
->Token
= ALit_DB_START
;
461 Measurement
->Module
= ALit_DB_START
;
467 GetHandleFormModuleGuid (ModuleGuid
, &StartHandle
);
468 Measurement
->Handle
= StartHandle
;
471 case FPDT_DUAL_GUID_STRING_EVENT_TYPE
:
472 ModuleGuid
= &(((FPDT_DUAL_GUID_STRING_EVENT_RECORD
*)RecordHeader
)->Guid1
);
473 Measurement
->Identifier
= ((UINT32
)((FPDT_DUAL_GUID_STRING_EVENT_RECORD
*)RecordHeader
)->ProgressID
);
475 Measurement
->StartTimeStamp
= ((FPDT_DUAL_GUID_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
477 Measurement
->EndTimeStamp
= ((FPDT_DUAL_GUID_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
480 Measurement
->Token
= ((FPDT_DUAL_GUID_STRING_EVENT_RECORD
*)RecordHeader
)->String
;
481 Measurement
->Module
= ((FPDT_DUAL_GUID_STRING_EVENT_RECORD
*)RecordHeader
)->String
;
482 GetHandleFormModuleGuid (ModuleGuid
, &StartHandle
);
483 Measurement
->Handle
= StartHandle
;
492 Search the start measurement in the mMeasurementList for the end measurement.
494 @param EndMeasureMent Measurement for end record.
499 IN MEASUREMENT_RECORD
*EndMeasureMent
504 for (Index
= mMeasurementNum
- 1; Index
>= 0; Index
--) {
505 if (AsciiStrCmp (EndMeasureMent
->Token
, ALit_PEIM
) == 0) {
506 if ((mMeasurementList
[Index
].EndTimeStamp
== 0) && (EndMeasureMent
->Handle
!= NULL
) && (mMeasurementList
[Index
].Handle
!= NULL
) &&
507 CompareGuid (mMeasurementList
[Index
].Handle
, EndMeasureMent
->Handle
) &&
508 (AsciiStrCmp (mMeasurementList
[Index
].Token
, EndMeasureMent
->Token
) == 0) &&
509 (AsciiStrCmp (mMeasurementList
[Index
].Module
, EndMeasureMent
->Module
) == 0))
511 mMeasurementList
[Index
].EndTimeStamp
= EndMeasureMent
->EndTimeStamp
;
514 } else if (EndMeasureMent
->Identifier
== PERF_CROSSMODULE_END_ID
) {
515 if ((mMeasurementList
[Index
].EndTimeStamp
== 0) &&
516 (AsciiStrCmp (mMeasurementList
[Index
].Token
, EndMeasureMent
->Token
) == 0) &&
517 (AsciiStrCmp (mMeasurementList
[Index
].Module
, EndMeasureMent
->Module
) == 0) &&
518 (mMeasurementList
[Index
].Identifier
== PERF_CROSSMODULE_START_ID
))
520 mMeasurementList
[Index
].EndTimeStamp
= EndMeasureMent
->EndTimeStamp
;
524 if ((mMeasurementList
[Index
].EndTimeStamp
== 0) && (mMeasurementList
[Index
].Handle
== EndMeasureMent
->Handle
) &&
525 (AsciiStrCmp (mMeasurementList
[Index
].Token
, EndMeasureMent
->Token
) == 0) &&
526 (AsciiStrCmp (mMeasurementList
[Index
].Module
, EndMeasureMent
->Module
) == 0))
528 mMeasurementList
[Index
].EndTimeStamp
= EndMeasureMent
->EndTimeStamp
;
536 Generate the measure record array.
540 BuildMeasurementList (
543 EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER
*RecordHeader
;
544 UINT8
*PerformanceTablePtr
;
545 UINT16 StartProgressId
;
547 UINT8
*StartRecordEvent
;
548 MEASUREMENT_RECORD MeasureMent
;
550 mMeasurementList
= AllocateZeroPool (mBootPerformanceTableSize
);
551 if (mMeasurementList
== NULL
) {
552 return EFI_OUT_OF_RESOURCES
;
555 TableLength
= sizeof (BOOT_PERFORMANCE_TABLE
);
556 PerformanceTablePtr
= (mBootPerformanceTable
+ TableLength
);
558 while (TableLength
< mBootPerformanceTableSize
) {
559 RecordHeader
= (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER
*)PerformanceTablePtr
;
560 StartRecordEvent
= (UINT8
*)RecordHeader
;
561 StartProgressId
= ((FPDT_GUID_EVENT_RECORD
*)StartRecordEvent
)->ProgressID
;
564 // 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.
565 // If the record is the start record, fill the info to the measurement in the mMeasurementList.
566 // If the record is the end record, find the related start measurement in the mMeasurementList and fill the EndTimeStamp.
568 if (StartProgressId
== 0) {
569 GetMeasurementInfo (RecordHeader
, FALSE
, &(mMeasurementList
[mMeasurementNum
]));
571 } else if ((((StartProgressId
>= PERF_EVENTSIGNAL_START_ID
) && ((StartProgressId
& 0x000F) == 0)) ||
572 ((StartProgressId
< PERF_EVENTSIGNAL_START_ID
) && ((StartProgressId
& 0x0001) != 0))))
575 // Since PEIM and StartImage has same Type and ID when PCD PcdEdkiiFpdtStringRecordEnableOnly = FALSE
576 // So we need to identify these two kinds of record through different phase.
578 if (StartProgressId
== PERF_CROSSMODULE_START_ID
) {
579 if (AsciiStrCmp (((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)StartRecordEvent
)->String
, ALit_PEI
) == 0) {
581 } else if (AsciiStrCmp (((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)StartRecordEvent
)->String
, ALit_DXE
) == 0) {
587 // Get measurement info form the start record to the mMeasurementList.
588 GetMeasurementInfo (RecordHeader
, TRUE
, &(mMeasurementList
[mMeasurementNum
]));
591 ZeroMem (&MeasureMent
, sizeof (MEASUREMENT_RECORD
));
592 GetMeasurementInfo (RecordHeader
, FALSE
, &MeasureMent
);
593 SearchMeasurement (&MeasureMent
);
596 TableLength
+= RecordHeader
->Length
;
597 PerformanceTablePtr
+= RecordHeader
->Length
;
604 Initialize the cumulative data.
614 for (Index
= 0; Index
< NumCum
; ++Index
) {
615 CumData
[Index
].Count
= 0;
616 CumData
[Index
].MinDur
= PERF_MAXDUR
;
617 CumData
[Index
].MaxDur
= 0;
618 CumData
[Index
].Duration
= 0;
623 Initialize the Summary data.
631 SummaryData
.NumTrace
= 0;
632 SummaryData
.NumIncomplete
= 0;
633 SummaryData
.NumSummary
= 0;
634 SummaryData
.NumHandles
= 0;
635 SummaryData
.NumPEIMs
= 0;
636 SummaryData
.NumGlobal
= 0;
640 Dump performance data.
642 @param[in] ImageHandle The image handle.
643 @param[in] SystemTable The system table.
645 @retval SHELL_SUCCESS Command completed successfully.
646 @retval SHELL_INVALID_PARAMETER Command usage error.
647 @retval SHELL_ABORTED The user aborts the operation.
648 @retval value Unknown error.
652 IN EFI_HANDLE ImageHandle
,
653 IN EFI_SYSTEM_TABLE
*SystemTable
656 LIST_ENTRY
*ParamPackage
;
657 CONST CHAR16
*CmdLineArg
;
660 PERFORMANCE_PROPERTY
*PerformanceProperty
;
661 UINTN Number2Display
;
663 EFI_STRING StringPtr
;
669 BOOLEAN CumulativeMode
;
670 CONST CHAR16
*CustomCumulativeToken
;
671 PERF_CUM_DATA
*CustomCumulativeData
;
673 SHELL_STATUS ShellStatus
;
674 TIMER_INFO TimerInfo
;
683 CumulativeMode
= FALSE
;
684 CustomCumulativeData
= NULL
;
685 ShellStatus
= SHELL_SUCCESS
;
688 // initialize the shell lib (we must be in non-auto-init...)
690 Status
= ShellInitialize ();
691 ASSERT_EFI_ERROR (Status
);
694 // Process Command Line arguments
696 Status
= ShellCommandLineParse (ParamList
, &ParamPackage
, NULL
, TRUE
);
697 if (EFI_ERROR (Status
)) {
698 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_INVALID_ARG
), mDpHiiHandle
);
699 return SHELL_INVALID_PARAMETER
;
700 } else if (ShellCommandLineGetCount (ParamPackage
) > 1) {
701 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_TOO_MANY
), mDpHiiHandle
);
702 return SHELL_INVALID_PARAMETER
;
708 VerboseMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-v");
709 SummaryMode
= (BOOLEAN
)(ShellCommandLineGetFlag (ParamPackage
, L
"-S") || ShellCommandLineGetFlag (ParamPackage
, L
"-s"));
710 AllMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-A");
711 RawMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-R");
712 ExcludeMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-x");
713 mShowId
= ShellCommandLineGetFlag (ParamPackage
, L
"-i");
714 CumulativeMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-c");
716 if (AllMode
&& RawMode
) {
717 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_CONFLICT_ARG
), mDpHiiHandle
, L
"-A", L
"-R");
718 return SHELL_INVALID_PARAMETER
;
721 // Options with Values
722 if (ShellCommandLineGetFlag (ParamPackage
, L
"-n")) {
723 CmdLineArg
= ShellCommandLineGetValue (ParamPackage
, L
"-n");
724 if (CmdLineArg
== NULL
) {
725 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_TOO_FEW
), mDpHiiHandle
);
726 return SHELL_INVALID_PARAMETER
;
728 if (!(RawMode
|| AllMode
)) {
729 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_NO_RAW_ALL
), mDpHiiHandle
);
730 return SHELL_INVALID_PARAMETER
;
733 Status
= ShellConvertStringToUint64 (CmdLineArg
, &Intermediate
, FALSE
, TRUE
);
734 if (EFI_ERROR (Status
)) {
735 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_INVALID_NUM_ARG
), mDpHiiHandle
, L
"-n");
736 return SHELL_INVALID_PARAMETER
;
738 Number2Display
= (UINTN
)Intermediate
;
739 if ((Number2Display
== 0) || (Number2Display
> MAXIMUM_DISPLAYCOUNT
)) {
740 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_INVALID_RANGE
), mDpHiiHandle
, L
"-n", 0, MAXIMUM_DISPLAYCOUNT
);
741 return SHELL_INVALID_PARAMETER
;
746 Number2Display
= DEFAULT_DISPLAYCOUNT
;
749 if (ShellCommandLineGetFlag (ParamPackage
, L
"-t")) {
750 CmdLineArg
= ShellCommandLineGetValue (ParamPackage
, L
"-t");
751 if (CmdLineArg
== NULL
) {
752 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_TOO_FEW
), mDpHiiHandle
);
753 return SHELL_INVALID_PARAMETER
;
755 Status
= ShellConvertStringToUint64 (CmdLineArg
, &Intermediate
, FALSE
, TRUE
);
756 if (EFI_ERROR (Status
)) {
757 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_INVALID_NUM_ARG
), mDpHiiHandle
, L
"-t");
758 return SHELL_INVALID_PARAMETER
;
760 mInterestThreshold
= Intermediate
;
764 mInterestThreshold
= DEFAULT_THRESHOLD
; // 1ms := 1,000 us
767 if (ShellCommandLineGetFlag (ParamPackage
, L
"-c")) {
768 CustomCumulativeToken
= ShellCommandLineGetValue (ParamPackage
, L
"-c");
769 if (CustomCumulativeToken
== NULL
) {
770 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_TOO_FEW
), mDpHiiHandle
);
771 return SHELL_INVALID_PARAMETER
;
773 CustomCumulativeData
= AllocateZeroPool (sizeof (PERF_CUM_DATA
));
774 if (CustomCumulativeData
== NULL
) {
775 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
779 CustomCumulativeData
->MinDur
= PERF_MAXDUR
;
780 CustomCumulativeData
->MaxDur
= 0;
781 CustomCumulativeData
->Count
= 0;
782 CustomCumulativeData
->Duration
= 0;
783 NameSize
= StrLen (CustomCumulativeToken
) + 1;
784 CustomCumulativeData
->Name
= AllocateZeroPool (NameSize
);
785 if (CustomCumulativeData
->Name
== NULL
) {
786 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
790 UnicodeStrToAsciiStrS (CustomCumulativeToken
, CustomCumulativeData
->Name
, NameSize
);
795 // DP dump performance data by parsing FPDT table in ACPI table.
796 // Folloing 3 steps are to get the measurement form the FPDT table.
800 // 1. Get FPDT from ACPI table.
802 Status
= GetBootPerformanceTable ();
803 if (EFI_ERROR (Status
)) {
804 ShellStatus
= Status
;
809 // 2. Cache the ModuleGuid and hanlde mapping table.
811 Status
= BuildCachedGuidHandleTable ();
812 if (EFI_ERROR (Status
)) {
813 ShellStatus
= Status
;
818 // 3. Build the measurement array form the FPDT records.
820 Status
= BuildMeasurementList ();
821 if (EFI_ERROR (Status
)) {
822 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
827 // Initialize the pre-defined cumulative data.
829 InitCumulativeData ();
832 // Initialize the Summary data.
837 // Timer specific processing
839 // Get the Performance counter characteristics:
840 // Freq = Frequency in Hz
841 // StartCount = Value loaded into the counter when it starts counting
842 // EndCount = Value counter counts to before it needs to be reset
844 Status
= EfiGetSystemConfigurationTable (&gPerformanceProtocolGuid
, (VOID
**)&PerformanceProperty
);
845 if (EFI_ERROR (Status
) || (PerformanceProperty
== NULL
)) {
846 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_PERF_PROPERTY_NOT_FOUND
), mDpHiiHandle
);
850 TimerInfo
.Frequency
= (UINT32
)DivU64x32 (PerformanceProperty
->Frequency
, 1000);
851 TimerInfo
.StartCount
= 0;
852 TimerInfo
.EndCount
= 0xFFFF;
853 TimerInfo
.CountUp
= TRUE
;
858 // print DP's build version
859 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_BUILD_REVISION
), mDpHiiHandle
, DP_MAJOR_VERSION
, DP_MINOR_VERSION
);
861 // print performance timer characteristics
862 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_KHZ
), mDpHiiHandle
, TimerInfo
.Frequency
);
864 if (VerboseMode
&& !RawMode
) {
865 StringPtr
= HiiGetString (
867 (EFI_STRING_ID
)(TimerInfo
.CountUp
? STRING_TOKEN (STR_DP_UP
) : STRING_TOKEN (STR_DP_DOWN
)),
870 ASSERT (StringPtr
!= NULL
);
871 // Print Timer count range and direction
876 STRING_TOKEN (STR_DP_TIMER_PROPERTIES
),
879 TimerInfo
.StartCount
,
882 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_VERBOSE_THRESHOLD
), mDpHiiHandle
, mInterestThreshold
);
885 /****************************************************************************
886 **** Print Sections based on command line options
888 **** Option modes have the following priority:
889 **** v Verbose -- Valid in combination with any other options
890 **** t Threshold -- Modifies All, Raw, and Cooked output
891 **** Default is 0 for All and Raw mode
892 **** Default is DEFAULT_THRESHOLD for "Cooked" mode
893 **** n Number2Display Used by All and Raw mode. Otherwise ignored.
894 **** A All -- R and S options are ignored
895 **** R Raw -- S option is ignored
896 **** s Summary -- Modifies "Cooked" output only
897 **** Cooked (Default)
898 ****************************************************************************/
899 GatherStatistics (CustomCumulativeData
);
900 if (CumulativeMode
) {
901 ProcessCumulative (CustomCumulativeData
);
902 } else if (AllMode
) {
903 Status
= DumpAllTrace (Number2Display
, ExcludeMode
);
904 if (Status
== EFI_ABORTED
) {
905 ShellStatus
= SHELL_ABORTED
;
908 } else if (RawMode
) {
909 Status
= DumpRawTrace (Number2Display
, ExcludeMode
);
910 if (Status
== EFI_ABORTED
) {
911 ShellStatus
= SHELL_ABORTED
;
915 // ------------- Begin Cooked Mode Processing
918 Status
= ProcessHandles (ExcludeMode
);
919 if (Status
== EFI_ABORTED
) {
920 ShellStatus
= SHELL_ABORTED
;
924 Status
= ProcessPeims ();
925 if (Status
== EFI_ABORTED
) {
926 ShellStatus
= SHELL_ABORTED
;
930 Status
= ProcessGlobal ();
931 if (Status
== EFI_ABORTED
) {
932 ShellStatus
= SHELL_ABORTED
;
936 ProcessCumulative (NULL
);
938 } // ------------- End of Cooked Mode Processing
940 if ( VerboseMode
|| SummaryMode
) {
945 if (ParamPackage
!= NULL
) {
946 ShellCommandLineFreeVarList (ParamPackage
);
949 SHELL_FREE_NON_NULL (StringPtr
);
950 if (CustomCumulativeData
!= NULL
) {
951 SHELL_FREE_NON_NULL (CustomCumulativeData
->Name
);
954 SHELL_FREE_NON_NULL (CustomCumulativeData
);
956 SHELL_FREE_NON_NULL (mMeasurementList
);
958 SHELL_FREE_NON_NULL (mCacheHandleGuidTable
);
966 Retrieve HII package list from ImageHandle and publish to HII database.
968 @param ImageHandle The image handle of the process.
973 InitializeHiiPackage (
974 EFI_HANDLE ImageHandle
978 EFI_HII_PACKAGE_LIST_HEADER
*PackageList
;
979 EFI_HII_HANDLE HiiHandle
;
982 // Retrieve HII package list from ImageHandle
984 Status
= gBS
->OpenProtocol (
986 &gEfiHiiPackageListProtocolGuid
,
987 (VOID
**)&PackageList
,
990 EFI_OPEN_PROTOCOL_GET_PROTOCOL
992 ASSERT_EFI_ERROR (Status
);
993 if (EFI_ERROR (Status
)) {
998 // Publish HII package list to HII Database.
1000 Status
= gHiiDatabase
->NewPackageList (
1006 ASSERT_EFI_ERROR (Status
);
1007 if (EFI_ERROR (Status
)) {