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
)) {
264 FirmwarePerformanceTable
= FindAcpiPtr (
265 (EFI_ACPI_5_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*)AcpiTable
,
266 EFI_ACPI_5_0_FIRMWARE_PERFORMANCE_DATA_TABLE_SIGNATURE
268 if (FirmwarePerformanceTable
== NULL
) {
269 return EFI_NOT_FOUND
;
272 mBootPerformanceTable
= (UINT8
*) (UINTN
)FirmwarePerformanceTable
->BootPointerRecord
.BootPerformanceTablePointer
;
273 mBootPerformanceTableSize
= ((BOOT_PERFORMANCE_TABLE
*) mBootPerformanceTable
)->Header
.Length
;
279 Get Handle form Module Guid.
281 @param ModuleGuid Module Guid.
282 @param Handle The handle to be returned.
286 GetHandleFormModuleGuid (
287 IN EFI_GUID
*ModuleGuid
,
288 IN OUT EFI_HANDLE
*Handle
293 if (IsZeroGuid (ModuleGuid
)) {
297 // Try to get the Handle form the caached array.
299 for (Index
= 0; Index
< mCachePairCount
; Index
++) {
300 if (CompareGuid (ModuleGuid
, &mCacheHandleGuidTable
[Index
].ModuleGuid
)) {
301 *Handle
= mCacheHandleGuidTable
[Index
].Handle
;
305 if (Index
>= mCachePairCount
) {
311 Cache the GUID and handle mapping pairs. In order to save time for searching.
315 BuildCachedGuidHandleTable (
320 EFI_HANDLE
*HandleBuffer
;
323 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
324 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
326 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*FvFilePath
;
328 Status
= gBS
->LocateHandleBuffer (AllHandles
, NULL
, NULL
, &HandleCount
, &HandleBuffer
);
329 if (EFI_ERROR (Status
)) {
330 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_HANDLES_ERROR
), mDpHiiHandle
, Status
);
334 mCacheHandleGuidTable
= AllocateZeroPool (HandleCount
* sizeof (HANDLE_GUID_MAP
));
335 if (mCacheHandleGuidTable
== NULL
) {
336 return EFI_OUT_OF_RESOURCES
;
339 for (Index
= 0; Index
< HandleCount
; Index
++) {
341 // Try Handle as ImageHandle.
343 Status
= gBS
->HandleProtocol (
345 &gEfiLoadedImageProtocolGuid
,
346 (VOID
**) &LoadedImage
348 if (EFI_ERROR (Status
)) {
350 // Try Handle as Controller Handle
352 Status
= gBS
->OpenProtocol (
354 &gEfiDriverBindingProtocolGuid
,
355 (VOID
**) &DriverBinding
,
358 EFI_OPEN_PROTOCOL_GET_PROTOCOL
360 if (!EFI_ERROR (Status
)) {
362 // Get Image protocol from ImageHandle
364 Status
= gBS
->HandleProtocol (
365 DriverBinding
->ImageHandle
,
366 &gEfiLoadedImageProtocolGuid
,
367 (VOID
**) &LoadedImage
372 if (!EFI_ERROR (Status
) && LoadedImage
!= NULL
) {
374 // Get Module Guid from DevicePath.
376 if (LoadedImage
->FilePath
!= NULL
&&
377 LoadedImage
->FilePath
->Type
== MEDIA_DEVICE_PATH
&&
378 LoadedImage
->FilePath
->SubType
== MEDIA_PIWG_FW_FILE_DP
380 FvFilePath
= (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*) LoadedImage
->FilePath
;
381 TempGuid
= &FvFilePath
->FvFileName
;
383 mCacheHandleGuidTable
[mCachePairCount
].Handle
= HandleBuffer
[Index
];
384 CopyGuid (&mCacheHandleGuidTable
[mCachePairCount
].ModuleGuid
, TempGuid
);
389 if (HandleBuffer
!= NULL
) {
390 FreePool (HandleBuffer
);
397 Get Measurement form Fpdt records.
399 @param RecordHeader Pointer to the start record.
400 @param IsStart Is start record or End record.
401 @param Measurement Pointer to the measurement which need to be filled.
406 IN EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER
*RecordHeader
,
408 IN OUT MEASUREMENT_RECORD
*Measurement
412 EFI_HANDLE StartHandle
;
414 switch (RecordHeader
->Type
) {
415 case FPDT_GUID_EVENT_TYPE
:
416 ModuleGuid
= &(((FPDT_GUID_EVENT_RECORD
*)RecordHeader
)->Guid
);
417 Measurement
->Identifier
= ((UINT32
)((FPDT_GUID_EVENT_RECORD
*)RecordHeader
)->ProgressID
);
419 Measurement
->StartTimeStamp
= ((FPDT_GUID_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
421 Measurement
->EndTimeStamp
= ((FPDT_GUID_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
423 switch (Measurement
->Identifier
) {
424 case MODULE_START_ID
:
427 Measurement
->Token
= ALit_PEIM
;
428 Measurement
->Module
= ALit_PEIM
;
429 } else if (mDxePhase
) {
430 Measurement
->Token
= ALit_START_IMAGE
;
431 Measurement
->Module
= ALit_START_IMAGE
;
438 if (AsciiStrCmp (Measurement
->Token
, ALit_PEIM
) == 0) {
439 Measurement
->Handle
= &(((FPDT_GUID_EVENT_RECORD
*)RecordHeader
)->Guid
);
441 GetHandleFormModuleGuid(ModuleGuid
, &StartHandle
);
442 Measurement
->Handle
= StartHandle
;
446 case FPDT_DYNAMIC_STRING_EVENT_TYPE
:
447 ModuleGuid
= &(((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->Guid
);
448 Measurement
->Identifier
= ((UINT32
)((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->ProgressID
);
450 Measurement
->StartTimeStamp
= ((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
452 Measurement
->EndTimeStamp
= ((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
454 switch (Measurement
->Identifier
) {
455 case MODULE_START_ID
:
458 Measurement
->Token
= ALit_PEIM
;
459 } else if (mDxePhase
) {
460 Measurement
->Token
= ALit_START_IMAGE
;
464 case MODULE_LOADIMAGE_START_ID
:
465 case MODULE_LOADIMAGE_END_ID
:
466 Measurement
->Token
= ALit_LOAD_IMAGE
;
469 case MODULE_DB_START_ID
:
470 case MODULE_DB_END_ID
:
471 Measurement
->Token
= ALit_DB_START
;
474 case MODULE_DB_SUPPORT_START_ID
:
475 case MODULE_DB_SUPPORT_END_ID
:
476 Measurement
->Token
= ALit_DB_SUPPORT
;
479 case MODULE_DB_STOP_START_ID
:
480 case MODULE_DB_STOP_END_ID
:
481 Measurement
->Token
= ALit_DB_STOP
;
485 Measurement
->Token
= ((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->String
;
489 Measurement
->Module
= ((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->String
;
491 if (AsciiStrCmp (Measurement
->Token
, ALit_PEIM
) == 0) {
492 Measurement
->Handle
= &(((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->Guid
);
494 GetHandleFormModuleGuid(ModuleGuid
, &StartHandle
);
495 Measurement
->Handle
= StartHandle
;
499 case FPDT_GUID_QWORD_EVENT_TYPE
:
500 ModuleGuid
= &(((FPDT_GUID_QWORD_EVENT_RECORD
*)RecordHeader
)->Guid
);
501 Measurement
->Identifier
= ((UINT32
)((FPDT_GUID_QWORD_EVENT_RECORD
*)RecordHeader
)->ProgressID
);
503 Measurement
->StartTimeStamp
= ((FPDT_GUID_QWORD_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
505 Measurement
->EndTimeStamp
= ((FPDT_GUID_QWORD_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
507 switch (Measurement
->Identifier
) {
508 case MODULE_DB_START_ID
:
509 Measurement
->Token
= ALit_DB_START
;
510 Measurement
->Module
= ALit_DB_START
;
513 case MODULE_DB_SUPPORT_START_ID
:
514 case MODULE_DB_SUPPORT_END_ID
:
515 Measurement
->Token
= ALit_DB_SUPPORT
;
516 Measurement
->Module
= ALit_DB_SUPPORT
;
519 case MODULE_DB_STOP_START_ID
:
520 case MODULE_DB_STOP_END_ID
:
521 Measurement
->Token
= ALit_DB_STOP
;
522 Measurement
->Module
= ALit_DB_STOP
;
525 case MODULE_LOADIMAGE_START_ID
:
526 case MODULE_LOADIMAGE_END_ID
:
527 Measurement
->Token
= ALit_LOAD_IMAGE
;
528 Measurement
->Module
= ALit_LOAD_IMAGE
;
534 GetHandleFormModuleGuid(ModuleGuid
, &StartHandle
);
535 Measurement
->Handle
= StartHandle
;
538 case FPDT_GUID_QWORD_STRING_EVENT_TYPE
:
539 ModuleGuid
= &(((FPDT_GUID_QWORD_STRING_EVENT_RECORD
*)RecordHeader
)->Guid
);
540 Measurement
->Identifier
= ((UINT32
)((FPDT_GUID_QWORD_STRING_EVENT_RECORD
*)RecordHeader
)->ProgressID
);
542 Measurement
->StartTimeStamp
= ((FPDT_GUID_QWORD_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
544 Measurement
->EndTimeStamp
= ((FPDT_GUID_QWORD_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
547 // Currently only "DB:Start:" end record with FPDT_GUID_QWORD_STRING_EVENT_TYPE.
549 switch (Measurement
->Identifier
) {
550 case MODULE_DB_END_ID
:
551 Measurement
->Token
= ALit_DB_START
;
552 Measurement
->Module
= ALit_DB_START
;
557 GetHandleFormModuleGuid(ModuleGuid
, &StartHandle
);
558 Measurement
->Handle
= StartHandle
;
567 Search the start measurement in the mMeasurementList for the end measurement.
569 @param EndMeasureMent Measurement for end record.
574 IN MEASUREMENT_RECORD
*EndMeasureMent
579 for (Index
= mMeasurementNum
- 1; Index
>= 0; Index
--) {
580 if (AsciiStrCmp (EndMeasureMent
->Token
, ALit_PEIM
) == 0) {
581 if (mMeasurementList
[Index
].EndTimeStamp
== 0 && EndMeasureMent
->Handle
!= NULL
&& mMeasurementList
[Index
].Handle
!= NULL
&&
582 CompareGuid(mMeasurementList
[Index
].Handle
, EndMeasureMent
->Handle
) &&
583 (AsciiStrCmp (mMeasurementList
[Index
].Token
, EndMeasureMent
->Token
) == 0) &&
584 (AsciiStrCmp (mMeasurementList
[Index
].Module
, EndMeasureMent
->Module
) == 0)) {
585 mMeasurementList
[Index
].EndTimeStamp
= EndMeasureMent
->EndTimeStamp
;
589 if (mMeasurementList
[Index
].EndTimeStamp
== 0 && mMeasurementList
[Index
].Handle
== EndMeasureMent
->Handle
&&
590 (AsciiStrCmp (mMeasurementList
[Index
].Token
, EndMeasureMent
->Token
) == 0) &&
591 (AsciiStrCmp (mMeasurementList
[Index
].Module
, EndMeasureMent
->Module
) == 0)) {
592 mMeasurementList
[Index
].EndTimeStamp
= EndMeasureMent
->EndTimeStamp
;
600 Generate the measure record array.
604 BuildMeasurementList (
607 EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER
*RecordHeader
;
608 UINT8
*PerformanceTablePtr
;
609 UINT16 StartProgressId
;
611 UINT8
*StartRecordEvent
;
612 MEASUREMENT_RECORD MeasureMent
;
614 mMeasurementList
= AllocateZeroPool (mBootPerformanceTableSize
);
615 if (mMeasurementList
== NULL
) {
616 return EFI_OUT_OF_RESOURCES
;
619 TableLength
= sizeof (BOOT_PERFORMANCE_TABLE
);
620 PerformanceTablePtr
= (mBootPerformanceTable
+ TableLength
);
622 while (TableLength
< mBootPerformanceTableSize
) {
623 RecordHeader
= (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER
*) PerformanceTablePtr
;
624 StartRecordEvent
= (UINT8
*)RecordHeader
;
625 StartProgressId
= ((FPDT_GUID_EVENT_RECORD
*)StartRecordEvent
)->ProgressID
;
628 // If the record is the start record, fill the info to the measurement in the mMeasurementList.
629 // If the record is the end record, find the related start measurement in the mMeasurementList and fill the EndTimeStamp.
631 if (((StartProgressId
>= PERF_EVENTSIGNAL_START_ID
&& ((StartProgressId
& 0x000F) == 0)) ||
632 (StartProgressId
< PERF_EVENTSIGNAL_START_ID
&& ((StartProgressId
& 0x0001) != 0)))) {
634 // Since PEIM and StartImage has same Type and ID when PCD PcdEdkiiFpdtStringRecordEnableOnly = FALSE
635 // So we need to identify these two kinds of record through different phase.
637 if (AsciiStrCmp (((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)StartRecordEvent
)->String
, ALit_PEI
) == 0) {
639 } else if (AsciiStrCmp (((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)StartRecordEvent
)->String
, ALit_DXE
) == 0) {
643 // Get measurement info form the start record to the mMeasurementList.
644 GetMeasurementInfo (RecordHeader
, TRUE
, &(mMeasurementList
[mMeasurementNum
]));
647 GetMeasurementInfo (RecordHeader
, FALSE
, &MeasureMent
);
648 SearchMeasurement (&MeasureMent
);
650 TableLength
+= RecordHeader
->Length
;
651 PerformanceTablePtr
+= RecordHeader
->Length
;
657 Initialize the cumulative data.
667 for (Index
= 0; Index
< NumCum
; ++Index
) {
668 CumData
[Index
].Count
= 0;
669 CumData
[Index
].MinDur
= PERF_MAXDUR
;
670 CumData
[Index
].MaxDur
= 0;
671 CumData
[Index
].Duration
= 0;
676 Dump performance data.
678 @param[in] ImageHandle The image handle.
679 @param[in] SystemTable The system table.
681 @retval SHELL_SUCCESS Command completed successfully.
682 @retval SHELL_INVALID_PARAMETER Command usage error.
683 @retval SHELL_ABORTED The user aborts the operation.
684 @retval value Unknown error.
688 IN EFI_HANDLE ImageHandle
,
689 IN EFI_SYSTEM_TABLE
*SystemTable
692 LIST_ENTRY
*ParamPackage
;
693 CONST CHAR16
*CmdLineArg
;
696 PERFORMANCE_PROPERTY
*PerformanceProperty
;
697 UINTN Number2Display
;
699 EFI_STRING StringPtr
;
707 BOOLEAN CumulativeMode
;
708 CONST CHAR16
*CustomCumulativeToken
;
709 PERF_CUM_DATA
*CustomCumulativeData
;
711 SHELL_STATUS ShellStatus
;
712 TIMER_INFO TimerInfo
;
722 CumulativeMode
= FALSE
;
723 CustomCumulativeData
= NULL
;
724 ShellStatus
= SHELL_SUCCESS
;
727 // initialize the shell lib (we must be in non-auto-init...)
729 Status
= ShellInitialize();
730 ASSERT_EFI_ERROR(Status
);
733 // DP dump performance data by parsing FPDT table in ACPI table.
734 // Folloing 3 steps are to get the measurement form the FPDT table.
738 //1. Get FPDT from ACPI table.
740 Status
= GetBootPerformanceTable ();
741 if (EFI_ERROR(Status
)) {
742 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_GET_BOOT_PERFORMANCE_TABLE_FAIL
), mDpHiiHandle
);
747 //2. Cache the ModuleGuid and hanlde mapping table.
749 Status
= BuildCachedGuidHandleTable();
750 if (EFI_ERROR (Status
)) {
755 //3. Build the measurement array form the FPDT records.
757 Status
= BuildMeasurementList ();
758 if (EFI_ERROR(Status
)) {
763 // Process Command Line arguments
765 Status
= ShellCommandLineParse (ParamList
, &ParamPackage
, NULL
, TRUE
);
766 if (EFI_ERROR(Status
)) {
767 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_INVALID_ARG
), mDpHiiHandle
);
768 return SHELL_INVALID_PARAMETER
;
774 VerboseMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-v");
775 SummaryMode
= (BOOLEAN
) (ShellCommandLineGetFlag (ParamPackage
, L
"-S") || ShellCommandLineGetFlag (ParamPackage
, L
"-s"));
776 AllMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-A");
777 RawMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-R");
778 #if PROFILING_IMPLEMENTED
779 TraceMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-T");
780 ProfileMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-P");
781 #endif // PROFILING_IMPLEMENTED
782 ExcludeMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-x");
783 mShowId
= ShellCommandLineGetFlag (ParamPackage
, L
"-i");
784 CumulativeMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-c");
786 // Options with Values
787 CmdLineArg
= ShellCommandLineGetValue (ParamPackage
, L
"-n");
788 if (CmdLineArg
== NULL
) {
789 Number2Display
= DEFAULT_DISPLAYCOUNT
;
791 Number2Display
= StrDecimalToUintn(CmdLineArg
);
792 if (Number2Display
== 0) {
793 Number2Display
= MAXIMUM_DISPLAYCOUNT
;
797 CmdLineArg
= ShellCommandLineGetValue (ParamPackage
, L
"-t");
798 if (CmdLineArg
== NULL
) {
799 mInterestThreshold
= DEFAULT_THRESHOLD
; // 1ms := 1,000 us
801 mInterestThreshold
= StrDecimalToUint64(CmdLineArg
);
804 // Handle Flag combinations and default behaviors
805 // If both TraceMode and ProfileMode are FALSE, set them both to TRUE
806 if ((! TraceMode
) && (! ProfileMode
)) {
808 #if PROFILING_IMPLEMENTED
810 #endif // PROFILING_IMPLEMENTED
814 // Initialize the pre-defined cumulative data.
816 InitCumulativeData ();
819 // Init the custom cumulative data.
821 CustomCumulativeToken
= ShellCommandLineGetValue (ParamPackage
, L
"-c");
822 if (CustomCumulativeToken
!= NULL
) {
823 CustomCumulativeData
= AllocateZeroPool (sizeof (PERF_CUM_DATA
));
824 if (CustomCumulativeData
== NULL
) {
825 return SHELL_OUT_OF_RESOURCES
;
827 CustomCumulativeData
->MinDur
= PERF_MAXDUR
;
828 CustomCumulativeData
->MaxDur
= 0;
829 CustomCumulativeData
->Count
= 0;
830 CustomCumulativeData
->Duration
= 0;
831 NameSize
= StrLen (CustomCumulativeToken
) + 1;
832 CustomCumulativeData
->Name
= AllocateZeroPool (NameSize
);
833 if (CustomCumulativeData
->Name
== NULL
) {
834 FreePool (CustomCumulativeData
);
835 return SHELL_OUT_OF_RESOURCES
;
837 UnicodeStrToAsciiStrS (CustomCumulativeToken
, CustomCumulativeData
->Name
, NameSize
);
841 // Timer specific processing
843 // Get the Performance counter characteristics:
844 // Freq = Frequency in Hz
845 // StartCount = Value loaded into the counter when it starts counting
846 // EndCount = Value counter counts to before it needs to be reset
848 Status
= EfiGetSystemConfigurationTable (&gPerformanceProtocolGuid
, (VOID
**) &PerformanceProperty
);
849 if (EFI_ERROR (Status
) || (PerformanceProperty
== NULL
)) {
850 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_PERF_PROPERTY_NOT_FOUND
), mDpHiiHandle
);
854 TimerInfo
.Frequency
= (UINT32
)DivU64x32 (PerformanceProperty
->Frequency
, 1000);
855 TimerInfo
.StartCount
= 0;
856 TimerInfo
.EndCount
= 0xFFFF;
857 TimerInfo
.CountUp
= TRUE
;
862 // print DP's build version
863 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_BUILD_REVISION
), mDpHiiHandle
, DP_MAJOR_VERSION
, DP_MINOR_VERSION
);
865 // print performance timer characteristics
866 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_KHZ
), mDpHiiHandle
, TimerInfo
.Frequency
);
868 if (VerboseMode
&& !RawMode
) {
869 StringPtr
= HiiGetString (mDpHiiHandle
,
870 (EFI_STRING_ID
) (TimerInfo
.CountUp
? STRING_TOKEN (STR_DP_UP
) : STRING_TOKEN (STR_DP_DOWN
)), NULL
);
871 ASSERT (StringPtr
!= NULL
);
872 // Print Timer count range and direction
873 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_TIMER_PROPERTIES
), mDpHiiHandle
,
875 TimerInfo
.StartCount
,
878 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_VERBOSE_THRESHOLD
), mDpHiiHandle
, mInterestThreshold
);
881 /****************************************************************************
882 **** Print Sections based on command line options
884 **** Option modes have the following priority:
885 **** v Verbose -- Valid in combination with any other options
886 **** t Threshold -- Modifies All, Raw, and Cooked output
887 **** Default is 0 for All and Raw mode
888 **** Default is DEFAULT_THRESHOLD for "Cooked" mode
889 **** n Number2Display Used by All and Raw mode. Otherwise ignored.
890 **** A All -- R and S options are ignored
891 **** R Raw -- S option is ignored
892 **** s Summary -- Modifies "Cooked" output only
893 **** Cooked (Default)
895 **** The All, Raw, and Cooked modes are modified by the Trace and Profile
897 **** !T && !P := (0) Default, Both are displayed
898 **** T && !P := (1) Only Trace records are displayed
899 **** !T && P := (2) Only Profile records are displayed
900 **** T && P := (3) Same as Default, both are displayed
901 ****************************************************************************/
902 GatherStatistics (CustomCumulativeData
);
903 if (CumulativeMode
) {
904 ProcessCumulative (CustomCumulativeData
);
905 } else if (AllMode
) {
907 Status
= DumpAllTrace( Number2Display
, ExcludeMode
);
908 if (Status
== EFI_ABORTED
) {
909 ShellStatus
= SHELL_ABORTED
;
914 DumpAllProfile( Number2Display
, ExcludeMode
);
916 } else if (RawMode
) {
918 Status
= DumpRawTrace( Number2Display
, ExcludeMode
);
919 if (Status
== EFI_ABORTED
) {
920 ShellStatus
= SHELL_ABORTED
;
925 DumpRawProfile( Number2Display
, ExcludeMode
);
928 //------------- Begin Cooked Mode Processing
931 if ( ! SummaryMode
) {
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
);
954 DumpAllProfile( Number2Display
, ExcludeMode
);
956 } //------------- End of Cooked Mode Processing
957 if ( VerboseMode
|| SummaryMode
) {
962 if (ParamPackage
!= NULL
) {
963 ShellCommandLineFreeVarList (ParamPackage
);
965 SHELL_FREE_NON_NULL (StringPtr
);
966 if (CustomCumulativeData
!= NULL
) {
967 SHELL_FREE_NON_NULL (CustomCumulativeData
->Name
);
969 SHELL_FREE_NON_NULL (CustomCumulativeData
);
971 SHELL_FREE_NON_NULL (mMeasurementList
);
973 SHELL_FREE_NON_NULL (mCacheHandleGuidTable
);
982 Retrive HII package list from ImageHandle and publish to HII database.
984 @param ImageHandle The image handle of the process.
989 InitializeHiiPackage (
990 EFI_HANDLE ImageHandle
994 EFI_HII_PACKAGE_LIST_HEADER
*PackageList
;
995 EFI_HANDLE HiiHandle
;
998 // Retrieve HII package list from ImageHandle
1000 Status
= gBS
->OpenProtocol (
1002 &gEfiHiiPackageListProtocolGuid
,
1003 (VOID
**)&PackageList
,
1006 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1008 ASSERT_EFI_ERROR (Status
);
1009 if (EFI_ERROR (Status
)) {
1014 // Publish HII package list to HII Database.
1016 Status
= gHiiDatabase
->NewPackageList (
1022 ASSERT_EFI_ERROR (Status
);
1023 if (EFI_ERROR (Status
)) {