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 This program and the accompanying materials
19 are licensed and made available under the terms and conditions of the BSD License
20 which accompanies this distribution. The full text of the license may be found at
21 http://opensource.org/licenses/bsd-license.php
23 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
24 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
29 #include "DpInternal.h"
34 EFI_ACPI_DESCRIPTION_HEADER Header
;
39 EFI_ACPI_DESCRIPTION_HEADER Header
;
45 EFI_HANDLE mDpHiiHandle
;
52 HANDLE_GUID_MAP
*mCacheHandleGuidTable
;
53 UINTN mCachePairCount
= 0;
56 /// Module-Global Variables
58 CHAR16 mGaugeString
[DP_GAUGE_STRING_LENGTH
+ 1];
59 CHAR16 mUnicodeToken
[DXE_PERFORMANCE_STRING_SIZE
];
60 UINT64 mInterestThreshold
;
61 BOOLEAN mShowId
= FALSE
;
62 UINT8
*mBootPerformanceTable
;
63 UINTN mBootPerformanceTableSize
;
64 BOOLEAN mPeiPhase
= FALSE
;
65 BOOLEAN mDxePhase
= FALSE
;
67 PERF_SUMMARY_DATA SummaryData
= { 0 }; ///< Create the SummaryData structure and init. to ZERO.
68 MEASUREMENT_RECORD
*mMeasurementList
= NULL
;
69 UINTN mMeasurementNum
= 0;
71 /// Items for which to gather cumulative statistics.
72 PERF_CUM_DATA CumData
[] = {
73 PERF_INIT_CUM_DATA (LOAD_IMAGE_TOK
),
74 PERF_INIT_CUM_DATA (START_IMAGE_TOK
),
75 PERF_INIT_CUM_DATA (DRIVERBINDING_START_TOK
),
76 PERF_INIT_CUM_DATA (DRIVERBINDING_SUPPORT_TOK
)
79 /// Number of items for which we are gathering cumulative statistics.
80 UINT32
const NumCum
= sizeof(CumData
) / sizeof(PERF_CUM_DATA
);
82 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
83 {L
"-v", TypeFlag
}, // -v Verbose Mode
84 {L
"-A", TypeFlag
}, // -A All, Cooked
85 {L
"-R", TypeFlag
}, // -R RAW All
86 {L
"-s", TypeFlag
}, // -s Summary
87 #if PROFILING_IMPLEMENTED
88 {L
"-P", TypeFlag
}, // -P Dump Profile Data
89 {L
"-T", TypeFlag
}, // -T Dump Trace Data
90 #endif // PROFILING_IMPLEMENTED
91 {L
"-x", TypeFlag
}, // -x eXclude Cumulative Items
92 {L
"-i", TypeFlag
}, // -i Display Identifier
93 {L
"-c", TypeValue
}, // -c Display cumulative data.
94 {L
"-n", TypeValue
}, // -n # Number of records to display for A and R
95 {L
"-t", TypeValue
}, // -t # Threshold of interest
102 Display the trailing Verbose information.
105 DumpStatistics( void )
107 EFI_STRING StringPtr
;
108 EFI_STRING StringPtrUnknown
;
109 StringPtr
= HiiGetString (mDpHiiHandle
, STRING_TOKEN (STR_DP_SECTION_STATISTICS
), NULL
);
110 StringPtrUnknown
= HiiGetString (mDpHiiHandle
, STRING_TOKEN (STR_ALIT_UNKNOWN
), NULL
);
111 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_SECTION_HEADER
), mDpHiiHandle
,
112 (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 #if PROFILING_IMPLEMENTED
120 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_STATS_NUMPROFILE
), mDpHiiHandle
, SummaryData
.NumProfile
);
121 #endif // PROFILING_IMPLEMENTED
122 SHELL_FREE_NON_NULL (StringPtr
);
123 SHELL_FREE_NON_NULL (StringPtrUnknown
);
127 This function scan ACPI table in RSDT.
129 @param Rsdt ACPI RSDT
130 @param Signature ACPI table signature
143 EFI_ACPI_DESCRIPTION_HEADER
*Table
;
145 EntryCount
= (Rsdt
->Header
.Length
- sizeof (EFI_ACPI_DESCRIPTION_HEADER
)) / sizeof(UINT32
);
147 EntryPtr
= &Rsdt
->Entry
;
148 for (Index
= 0; Index
< EntryCount
; Index
++, EntryPtr
++) {
149 Table
= (EFI_ACPI_DESCRIPTION_HEADER
*)((UINTN
)(*EntryPtr
));
150 if (Table
->Signature
== Signature
) {
159 This function scan ACPI table in XSDT.
161 @param Xsdt ACPI XSDT
162 @param Signature ACPI table signature
176 EFI_ACPI_DESCRIPTION_HEADER
*Table
;
178 EntryCount
= (Xsdt
->Header
.Length
- sizeof (EFI_ACPI_DESCRIPTION_HEADER
)) / sizeof(UINT64
);
180 BasePtr
= (UINTN
)(&(Xsdt
->Entry
));
181 for (Index
= 0; Index
< EntryCount
; Index
++) {
182 CopyMem (&EntryPtr
, (VOID
*)(BasePtr
+ Index
* sizeof(UINT64
)), sizeof(UINT64
));
183 Table
= (EFI_ACPI_DESCRIPTION_HEADER
*)((UINTN
)(EntryPtr
));
184 if (Table
->Signature
== Signature
) {
193 This function scan ACPI table in RSDP.
195 @param Rsdp ACPI RSDP
196 @param Signature ACPI table signature
202 IN EFI_ACPI_5_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*Rsdp
,
206 EFI_ACPI_DESCRIPTION_HEADER
*AcpiTable
;
213 // Check ACPI2.0 table
215 Rsdt
= (RSDT_TABLE
*)(UINTN
)Rsdp
->RsdtAddress
;
217 if ((Rsdp
->Revision
>= 2) && (Rsdp
->XsdtAddress
< (UINT64
)(UINTN
)-1)) {
218 Xsdt
= (XSDT_TABLE
*)(UINTN
)Rsdp
->XsdtAddress
;
224 AcpiTable
= ScanTableInXSDT (Xsdt
, Signature
);
229 if ((AcpiTable
== NULL
) && (Rsdt
!= NULL
)) {
230 AcpiTable
= ScanTableInRSDT (Rsdt
, Signature
);
237 Get Boot performance table form Acpi table.
241 GetBootPerformanceTable (
246 FIRMWARE_PERFORMANCE_TABLE
*FirmwarePerformanceTable
;
250 Status
= EfiGetSystemConfigurationTable (
251 &gEfiAcpi20TableGuid
,
254 if (EFI_ERROR (Status
)) {
255 Status
= EfiGetSystemConfigurationTable (
256 &gEfiAcpi10TableGuid
,
260 if (EFI_ERROR(Status
) || AcpiTable
== NULL
) {
261 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_GET_ACPI_TABLE_FAIL
), mDpHiiHandle
);
265 FirmwarePerformanceTable
= FindAcpiPtr (
266 (EFI_ACPI_5_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*)AcpiTable
,
267 EFI_ACPI_5_0_FIRMWARE_PERFORMANCE_DATA_TABLE_SIGNATURE
269 if (FirmwarePerformanceTable
== NULL
) {
270 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_GET_ACPI_FPDT_FAIL
), mDpHiiHandle
);
271 return EFI_NOT_FOUND
;
274 mBootPerformanceTable
= (UINT8
*) (UINTN
)FirmwarePerformanceTable
->BootPointerRecord
.BootPerformanceTablePointer
;
275 mBootPerformanceTableSize
= ((BOOT_PERFORMANCE_TABLE
*) mBootPerformanceTable
)->Header
.Length
;
281 Get Handle form Module Guid.
283 @param ModuleGuid Module Guid.
284 @param Handle The handle to be returned.
288 GetHandleFormModuleGuid (
289 IN EFI_GUID
*ModuleGuid
,
290 IN OUT EFI_HANDLE
*Handle
295 if (IsZeroGuid (ModuleGuid
)) {
299 // Try to get the Handle form the caached array.
301 for (Index
= 0; Index
< mCachePairCount
; Index
++) {
302 if (CompareGuid (ModuleGuid
, &mCacheHandleGuidTable
[Index
].ModuleGuid
)) {
303 *Handle
= mCacheHandleGuidTable
[Index
].Handle
;
307 if (Index
>= mCachePairCount
) {
313 Cache the GUID and handle mapping pairs. In order to save time for searching.
317 BuildCachedGuidHandleTable (
322 EFI_HANDLE
*HandleBuffer
;
325 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
326 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
328 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*FvFilePath
;
330 Status
= gBS
->LocateHandleBuffer (AllHandles
, NULL
, NULL
, &HandleCount
, &HandleBuffer
);
331 if (EFI_ERROR (Status
)) {
332 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_HANDLES_ERROR
), mDpHiiHandle
, Status
);
336 mCacheHandleGuidTable
= AllocateZeroPool (HandleCount
* sizeof (HANDLE_GUID_MAP
));
337 if (mCacheHandleGuidTable
== NULL
) {
338 return EFI_OUT_OF_RESOURCES
;
341 for (Index
= 0; Index
< HandleCount
; Index
++) {
343 // Try Handle as ImageHandle.
345 Status
= gBS
->HandleProtocol (
347 &gEfiLoadedImageProtocolGuid
,
348 (VOID
**) &LoadedImage
350 if (EFI_ERROR (Status
)) {
352 // Try Handle as Controller Handle
354 Status
= gBS
->OpenProtocol (
356 &gEfiDriverBindingProtocolGuid
,
357 (VOID
**) &DriverBinding
,
360 EFI_OPEN_PROTOCOL_GET_PROTOCOL
362 if (!EFI_ERROR (Status
)) {
364 // Get Image protocol from ImageHandle
366 Status
= gBS
->HandleProtocol (
367 DriverBinding
->ImageHandle
,
368 &gEfiLoadedImageProtocolGuid
,
369 (VOID
**) &LoadedImage
374 if (!EFI_ERROR (Status
) && LoadedImage
!= NULL
) {
376 // Get Module Guid from DevicePath.
378 if (LoadedImage
->FilePath
!= NULL
&&
379 LoadedImage
->FilePath
->Type
== MEDIA_DEVICE_PATH
&&
380 LoadedImage
->FilePath
->SubType
== MEDIA_PIWG_FW_FILE_DP
382 FvFilePath
= (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*) LoadedImage
->FilePath
;
383 TempGuid
= &FvFilePath
->FvFileName
;
385 mCacheHandleGuidTable
[mCachePairCount
].Handle
= HandleBuffer
[Index
];
386 CopyGuid (&mCacheHandleGuidTable
[mCachePairCount
].ModuleGuid
, TempGuid
);
391 if (HandleBuffer
!= NULL
) {
392 FreePool (HandleBuffer
);
399 Get Measurement form Fpdt records.
401 @param RecordHeader Pointer to the start record.
402 @param IsStart Is start record or End record.
403 @param Measurement Pointer to the measurement which need to be filled.
408 IN EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER
*RecordHeader
,
410 IN OUT MEASUREMENT_RECORD
*Measurement
414 EFI_HANDLE StartHandle
;
416 switch (RecordHeader
->Type
) {
417 case FPDT_GUID_EVENT_TYPE
:
418 ModuleGuid
= &(((FPDT_GUID_EVENT_RECORD
*)RecordHeader
)->Guid
);
419 Measurement
->Identifier
= ((UINT32
)((FPDT_GUID_EVENT_RECORD
*)RecordHeader
)->ProgressID
);
421 Measurement
->StartTimeStamp
= ((FPDT_GUID_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
423 Measurement
->EndTimeStamp
= ((FPDT_GUID_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
425 switch (Measurement
->Identifier
) {
426 case MODULE_START_ID
:
429 Measurement
->Token
= ALit_PEIM
;
430 Measurement
->Module
= ALit_PEIM
;
431 } else if (mDxePhase
) {
432 Measurement
->Token
= ALit_START_IMAGE
;
433 Measurement
->Module
= ALit_START_IMAGE
;
440 if (AsciiStrCmp (Measurement
->Token
, ALit_PEIM
) == 0) {
441 Measurement
->Handle
= &(((FPDT_GUID_EVENT_RECORD
*)RecordHeader
)->Guid
);
443 GetHandleFormModuleGuid(ModuleGuid
, &StartHandle
);
444 Measurement
->Handle
= StartHandle
;
448 case FPDT_DYNAMIC_STRING_EVENT_TYPE
:
449 ModuleGuid
= &(((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->Guid
);
450 Measurement
->Identifier
= ((UINT32
)((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->ProgressID
);
452 Measurement
->StartTimeStamp
= ((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
454 Measurement
->EndTimeStamp
= ((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
456 switch (Measurement
->Identifier
) {
457 case MODULE_START_ID
:
460 Measurement
->Token
= ALit_PEIM
;
461 } else if (mDxePhase
) {
462 Measurement
->Token
= ALit_START_IMAGE
;
466 case MODULE_LOADIMAGE_START_ID
:
467 case MODULE_LOADIMAGE_END_ID
:
468 Measurement
->Token
= ALit_LOAD_IMAGE
;
471 case MODULE_DB_START_ID
:
472 case MODULE_DB_END_ID
:
473 Measurement
->Token
= ALit_DB_START
;
476 case MODULE_DB_SUPPORT_START_ID
:
477 case MODULE_DB_SUPPORT_END_ID
:
478 Measurement
->Token
= ALit_DB_SUPPORT
;
481 case MODULE_DB_STOP_START_ID
:
482 case MODULE_DB_STOP_END_ID
:
483 Measurement
->Token
= ALit_DB_STOP
;
487 Measurement
->Token
= ((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->String
;
491 Measurement
->Module
= ((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->String
;
493 if (AsciiStrCmp (Measurement
->Token
, ALit_PEIM
) == 0) {
494 Measurement
->Handle
= &(((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->Guid
);
496 GetHandleFormModuleGuid(ModuleGuid
, &StartHandle
);
497 Measurement
->Handle
= StartHandle
;
501 case FPDT_GUID_QWORD_EVENT_TYPE
:
502 ModuleGuid
= &(((FPDT_GUID_QWORD_EVENT_RECORD
*)RecordHeader
)->Guid
);
503 Measurement
->Identifier
= ((UINT32
)((FPDT_GUID_QWORD_EVENT_RECORD
*)RecordHeader
)->ProgressID
);
505 Measurement
->StartTimeStamp
= ((FPDT_GUID_QWORD_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
507 Measurement
->EndTimeStamp
= ((FPDT_GUID_QWORD_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
509 switch (Measurement
->Identifier
) {
510 case MODULE_DB_START_ID
:
511 Measurement
->Token
= ALit_DB_START
;
512 Measurement
->Module
= ALit_DB_START
;
515 case MODULE_DB_SUPPORT_START_ID
:
516 case MODULE_DB_SUPPORT_END_ID
:
517 Measurement
->Token
= ALit_DB_SUPPORT
;
518 Measurement
->Module
= ALit_DB_SUPPORT
;
521 case MODULE_DB_STOP_START_ID
:
522 case MODULE_DB_STOP_END_ID
:
523 Measurement
->Token
= ALit_DB_STOP
;
524 Measurement
->Module
= ALit_DB_STOP
;
527 case MODULE_LOADIMAGE_START_ID
:
528 case MODULE_LOADIMAGE_END_ID
:
529 Measurement
->Token
= ALit_LOAD_IMAGE
;
530 Measurement
->Module
= ALit_LOAD_IMAGE
;
536 GetHandleFormModuleGuid(ModuleGuid
, &StartHandle
);
537 Measurement
->Handle
= StartHandle
;
540 case FPDT_GUID_QWORD_STRING_EVENT_TYPE
:
541 ModuleGuid
= &(((FPDT_GUID_QWORD_STRING_EVENT_RECORD
*)RecordHeader
)->Guid
);
542 Measurement
->Identifier
= ((UINT32
)((FPDT_GUID_QWORD_STRING_EVENT_RECORD
*)RecordHeader
)->ProgressID
);
544 Measurement
->StartTimeStamp
= ((FPDT_GUID_QWORD_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
546 Measurement
->EndTimeStamp
= ((FPDT_GUID_QWORD_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
549 // Currently only "DB:Start:" end record with FPDT_GUID_QWORD_STRING_EVENT_TYPE.
551 switch (Measurement
->Identifier
) {
552 case MODULE_DB_END_ID
:
553 Measurement
->Token
= ALit_DB_START
;
554 Measurement
->Module
= ALit_DB_START
;
559 GetHandleFormModuleGuid(ModuleGuid
, &StartHandle
);
560 Measurement
->Handle
= StartHandle
;
569 Search the start measurement in the mMeasurementList for the end measurement.
571 @param EndMeasureMent Measurement for end record.
576 IN MEASUREMENT_RECORD
*EndMeasureMent
581 for (Index
= mMeasurementNum
- 1; Index
>= 0; Index
--) {
582 if (AsciiStrCmp (EndMeasureMent
->Token
, ALit_PEIM
) == 0) {
583 if (mMeasurementList
[Index
].EndTimeStamp
== 0 && EndMeasureMent
->Handle
!= NULL
&& mMeasurementList
[Index
].Handle
!= NULL
&&
584 CompareGuid(mMeasurementList
[Index
].Handle
, EndMeasureMent
->Handle
) &&
585 (AsciiStrCmp (mMeasurementList
[Index
].Token
, EndMeasureMent
->Token
) == 0) &&
586 (AsciiStrCmp (mMeasurementList
[Index
].Module
, EndMeasureMent
->Module
) == 0)) {
587 mMeasurementList
[Index
].EndTimeStamp
= EndMeasureMent
->EndTimeStamp
;
591 if (mMeasurementList
[Index
].EndTimeStamp
== 0 && mMeasurementList
[Index
].Handle
== EndMeasureMent
->Handle
&&
592 (AsciiStrCmp (mMeasurementList
[Index
].Token
, EndMeasureMent
->Token
) == 0) &&
593 (AsciiStrCmp (mMeasurementList
[Index
].Module
, EndMeasureMent
->Module
) == 0)) {
594 mMeasurementList
[Index
].EndTimeStamp
= EndMeasureMent
->EndTimeStamp
;
602 Generate the measure record array.
606 BuildMeasurementList (
609 EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER
*RecordHeader
;
610 UINT8
*PerformanceTablePtr
;
611 UINT16 StartProgressId
;
613 UINT8
*StartRecordEvent
;
614 MEASUREMENT_RECORD MeasureMent
;
616 mMeasurementList
= AllocateZeroPool (mBootPerformanceTableSize
);
617 if (mMeasurementList
== NULL
) {
618 return EFI_OUT_OF_RESOURCES
;
621 TableLength
= sizeof (BOOT_PERFORMANCE_TABLE
);
622 PerformanceTablePtr
= (mBootPerformanceTable
+ TableLength
);
624 while (TableLength
< mBootPerformanceTableSize
) {
625 RecordHeader
= (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER
*) PerformanceTablePtr
;
626 StartRecordEvent
= (UINT8
*)RecordHeader
;
627 StartProgressId
= ((FPDT_GUID_EVENT_RECORD
*)StartRecordEvent
)->ProgressID
;
630 // If the record is the start record, fill the info to the measurement in the mMeasurementList.
631 // If the record is the end record, find the related start measurement in the mMeasurementList and fill the EndTimeStamp.
633 if (((StartProgressId
>= PERF_EVENTSIGNAL_START_ID
&& ((StartProgressId
& 0x000F) == 0)) ||
634 (StartProgressId
< PERF_EVENTSIGNAL_START_ID
&& ((StartProgressId
& 0x0001) != 0)))) {
636 // Since PEIM and StartImage has same Type and ID when PCD PcdEdkiiFpdtStringRecordEnableOnly = FALSE
637 // So we need to identify these two kinds of record through different phase.
639 if (AsciiStrCmp (((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)StartRecordEvent
)->String
, ALit_PEI
) == 0) {
641 } else if (AsciiStrCmp (((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)StartRecordEvent
)->String
, ALit_DXE
) == 0) {
645 // Get measurement info form the start record to the mMeasurementList.
646 GetMeasurementInfo (RecordHeader
, TRUE
, &(mMeasurementList
[mMeasurementNum
]));
649 GetMeasurementInfo (RecordHeader
, FALSE
, &MeasureMent
);
650 SearchMeasurement (&MeasureMent
);
652 TableLength
+= RecordHeader
->Length
;
653 PerformanceTablePtr
+= RecordHeader
->Length
;
659 Initialize the cumulative data.
669 for (Index
= 0; Index
< NumCum
; ++Index
) {
670 CumData
[Index
].Count
= 0;
671 CumData
[Index
].MinDur
= PERF_MAXDUR
;
672 CumData
[Index
].MaxDur
= 0;
673 CumData
[Index
].Duration
= 0;
678 Dump performance data.
680 @param[in] ImageHandle The image handle.
681 @param[in] SystemTable The system table.
683 @retval SHELL_SUCCESS Command completed successfully.
684 @retval SHELL_INVALID_PARAMETER Command usage error.
685 @retval SHELL_ABORTED The user aborts the operation.
686 @retval value Unknown error.
690 IN EFI_HANDLE ImageHandle
,
691 IN EFI_SYSTEM_TABLE
*SystemTable
694 LIST_ENTRY
*ParamPackage
;
695 CONST CHAR16
*CmdLineArg
;
698 PERFORMANCE_PROPERTY
*PerformanceProperty
;
699 UINTN Number2Display
;
701 EFI_STRING StringPtr
;
709 BOOLEAN CumulativeMode
;
710 CONST CHAR16
*CustomCumulativeToken
;
711 PERF_CUM_DATA
*CustomCumulativeData
;
713 SHELL_STATUS ShellStatus
;
714 TIMER_INFO TimerInfo
;
724 CumulativeMode
= FALSE
;
725 CustomCumulativeData
= NULL
;
726 ShellStatus
= SHELL_SUCCESS
;
729 // initialize the shell lib (we must be in non-auto-init...)
731 Status
= ShellInitialize();
732 ASSERT_EFI_ERROR(Status
);
735 // DP dump performance data by parsing FPDT table in ACPI table.
736 // Folloing 3 steps are to get the measurement form the FPDT table.
740 //1. Get FPDT from ACPI table.
742 Status
= GetBootPerformanceTable ();
743 if (EFI_ERROR(Status
)) {
748 //2. Cache the ModuleGuid and hanlde mapping table.
750 Status
= BuildCachedGuidHandleTable();
751 if (EFI_ERROR (Status
)) {
756 //3. Build the measurement array form the FPDT records.
758 Status
= BuildMeasurementList ();
759 if (EFI_ERROR(Status
)) {
764 // Process Command Line arguments
766 Status
= ShellCommandLineParse (ParamList
, &ParamPackage
, NULL
, TRUE
);
767 if (EFI_ERROR(Status
)) {
768 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_INVALID_ARG
), mDpHiiHandle
);
769 return SHELL_INVALID_PARAMETER
;
775 VerboseMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-v");
776 SummaryMode
= (BOOLEAN
) (ShellCommandLineGetFlag (ParamPackage
, L
"-S") || ShellCommandLineGetFlag (ParamPackage
, L
"-s"));
777 AllMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-A");
778 RawMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-R");
779 #if PROFILING_IMPLEMENTED
780 TraceMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-T");
781 ProfileMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-P");
782 #endif // PROFILING_IMPLEMENTED
783 ExcludeMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-x");
784 mShowId
= ShellCommandLineGetFlag (ParamPackage
, L
"-i");
785 CumulativeMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-c");
787 // Options with Values
788 CmdLineArg
= ShellCommandLineGetValue (ParamPackage
, L
"-n");
789 if (CmdLineArg
== NULL
) {
790 Number2Display
= DEFAULT_DISPLAYCOUNT
;
792 Number2Display
= StrDecimalToUintn(CmdLineArg
);
793 if (Number2Display
== 0) {
794 Number2Display
= MAXIMUM_DISPLAYCOUNT
;
798 CmdLineArg
= ShellCommandLineGetValue (ParamPackage
, L
"-t");
799 if (CmdLineArg
== NULL
) {
800 mInterestThreshold
= DEFAULT_THRESHOLD
; // 1ms := 1,000 us
802 mInterestThreshold
= StrDecimalToUint64(CmdLineArg
);
805 // Handle Flag combinations and default behaviors
806 // If both TraceMode and ProfileMode are FALSE, set them both to TRUE
807 if ((! TraceMode
) && (! ProfileMode
)) {
809 #if PROFILING_IMPLEMENTED
811 #endif // PROFILING_IMPLEMENTED
815 // Initialize the pre-defined cumulative data.
817 InitCumulativeData ();
820 // Init the custom cumulative data.
822 CustomCumulativeToken
= ShellCommandLineGetValue (ParamPackage
, L
"-c");
823 if (CustomCumulativeToken
!= NULL
) {
824 CustomCumulativeData
= AllocateZeroPool (sizeof (PERF_CUM_DATA
));
825 if (CustomCumulativeData
== NULL
) {
826 return SHELL_OUT_OF_RESOURCES
;
828 CustomCumulativeData
->MinDur
= PERF_MAXDUR
;
829 CustomCumulativeData
->MaxDur
= 0;
830 CustomCumulativeData
->Count
= 0;
831 CustomCumulativeData
->Duration
= 0;
832 NameSize
= StrLen (CustomCumulativeToken
) + 1;
833 CustomCumulativeData
->Name
= AllocateZeroPool (NameSize
);
834 if (CustomCumulativeData
->Name
== NULL
) {
835 FreePool (CustomCumulativeData
);
836 return SHELL_OUT_OF_RESOURCES
;
838 UnicodeStrToAsciiStrS (CustomCumulativeToken
, CustomCumulativeData
->Name
, NameSize
);
842 // Timer specific processing
844 // Get the Performance counter characteristics:
845 // Freq = Frequency in Hz
846 // StartCount = Value loaded into the counter when it starts counting
847 // EndCount = Value counter counts to before it needs to be reset
849 Status
= EfiGetSystemConfigurationTable (&gPerformanceProtocolGuid
, (VOID
**) &PerformanceProperty
);
850 if (EFI_ERROR (Status
) || (PerformanceProperty
== NULL
)) {
851 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_PERF_PROPERTY_NOT_FOUND
), mDpHiiHandle
);
855 TimerInfo
.Frequency
= (UINT32
)DivU64x32 (PerformanceProperty
->Frequency
, 1000);
856 TimerInfo
.StartCount
= 0;
857 TimerInfo
.EndCount
= 0xFFFF;
858 TimerInfo
.CountUp
= TRUE
;
863 // print DP's build version
864 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_BUILD_REVISION
), mDpHiiHandle
, DP_MAJOR_VERSION
, DP_MINOR_VERSION
);
866 // print performance timer characteristics
867 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_KHZ
), mDpHiiHandle
, TimerInfo
.Frequency
);
869 if (VerboseMode
&& !RawMode
) {
870 StringPtr
= HiiGetString (mDpHiiHandle
,
871 (EFI_STRING_ID
) (TimerInfo
.CountUp
? STRING_TOKEN (STR_DP_UP
) : STRING_TOKEN (STR_DP_DOWN
)), NULL
);
872 ASSERT (StringPtr
!= NULL
);
873 // Print Timer count range and direction
874 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_TIMER_PROPERTIES
), mDpHiiHandle
,
876 TimerInfo
.StartCount
,
879 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_VERBOSE_THRESHOLD
), mDpHiiHandle
, mInterestThreshold
);
882 /****************************************************************************
883 **** Print Sections based on command line options
885 **** Option modes have the following priority:
886 **** v Verbose -- Valid in combination with any other options
887 **** t Threshold -- Modifies All, Raw, and Cooked output
888 **** Default is 0 for All and Raw mode
889 **** Default is DEFAULT_THRESHOLD for "Cooked" mode
890 **** n Number2Display Used by All and Raw mode. Otherwise ignored.
891 **** A All -- R and S options are ignored
892 **** R Raw -- S option is ignored
893 **** s Summary -- Modifies "Cooked" output only
894 **** Cooked (Default)
896 **** The All, Raw, and Cooked modes are modified by the Trace and Profile
898 **** !T && !P := (0) Default, Both are displayed
899 **** T && !P := (1) Only Trace records are displayed
900 **** !T && P := (2) Only Profile records are displayed
901 **** T && P := (3) Same as Default, both are displayed
902 ****************************************************************************/
903 GatherStatistics (CustomCumulativeData
);
904 if (CumulativeMode
) {
905 ProcessCumulative (CustomCumulativeData
);
906 } else if (AllMode
) {
908 Status
= DumpAllTrace( Number2Display
, ExcludeMode
);
909 if (Status
== EFI_ABORTED
) {
910 ShellStatus
= SHELL_ABORTED
;
915 DumpAllProfile( Number2Display
, ExcludeMode
);
917 } else if (RawMode
) {
919 Status
= DumpRawTrace( Number2Display
, ExcludeMode
);
920 if (Status
== EFI_ABORTED
) {
921 ShellStatus
= SHELL_ABORTED
;
926 DumpRawProfile( Number2Display
, ExcludeMode
);
929 //------------- Begin Cooked Mode Processing
932 if ( ! SummaryMode
) {
933 Status
= ProcessHandles ( ExcludeMode
);
934 if (Status
== EFI_ABORTED
) {
935 ShellStatus
= SHELL_ABORTED
;
939 Status
= ProcessPeims ();
940 if (Status
== EFI_ABORTED
) {
941 ShellStatus
= SHELL_ABORTED
;
945 Status
= ProcessGlobal ();
946 if (Status
== EFI_ABORTED
) {
947 ShellStatus
= SHELL_ABORTED
;
951 ProcessCumulative (NULL
);
955 DumpAllProfile( Number2Display
, ExcludeMode
);
957 } //------------- End of Cooked Mode Processing
958 if ( VerboseMode
|| SummaryMode
) {
963 if (ParamPackage
!= NULL
) {
964 ShellCommandLineFreeVarList (ParamPackage
);
966 SHELL_FREE_NON_NULL (StringPtr
);
967 if (CustomCumulativeData
!= NULL
) {
968 SHELL_FREE_NON_NULL (CustomCumulativeData
->Name
);
970 SHELL_FREE_NON_NULL (CustomCumulativeData
);
972 SHELL_FREE_NON_NULL (mMeasurementList
);
974 SHELL_FREE_NON_NULL (mCacheHandleGuidTable
);
983 Retrive HII package list from ImageHandle and publish to HII database.
985 @param ImageHandle The image handle of the process.
990 InitializeHiiPackage (
991 EFI_HANDLE ImageHandle
995 EFI_HII_PACKAGE_LIST_HEADER
*PackageList
;
996 EFI_HANDLE HiiHandle
;
999 // Retrieve HII package list from ImageHandle
1001 Status
= gBS
->OpenProtocol (
1003 &gEfiHiiPackageListProtocolGuid
,
1004 (VOID
**)&PackageList
,
1007 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1009 ASSERT_EFI_ERROR (Status
);
1010 if (EFI_ERROR (Status
)) {
1015 // Publish HII package list to HII Database.
1017 Status
= gHiiDatabase
->NewPackageList (
1023 ASSERT_EFI_ERROR (Status
);
1024 if (EFI_ERROR (Status
)) {