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
),
77 PERF_INIT_CUM_DATA (DRIVERBINDING_STOP_TOK
)
80 /// Number of items for which we are gathering cumulative statistics.
81 UINT32
const NumCum
= sizeof(CumData
) / sizeof(PERF_CUM_DATA
);
83 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
84 {L
"-v", TypeFlag
}, // -v Verbose Mode
85 {L
"-A", TypeFlag
}, // -A All, Cooked
86 {L
"-R", TypeFlag
}, // -R RAW All
87 {L
"-s", TypeFlag
}, // -s Summary
88 {L
"-x", TypeFlag
}, // -x eXclude Cumulative Items
89 {L
"-i", TypeFlag
}, // -i Display Identifier
90 {L
"-c", TypeValue
}, // -c Display cumulative data.
91 {L
"-n", TypeValue
}, // -n # Number of records to display for A and R
92 {L
"-t", TypeValue
}, // -t # Threshold of interest
99 Display the trailing Verbose information.
102 DumpStatistics( void )
104 EFI_STRING StringPtr
;
105 EFI_STRING StringPtrUnknown
;
106 StringPtr
= HiiGetString (mDpHiiHandle
, STRING_TOKEN (STR_DP_SECTION_STATISTICS
), NULL
);
107 StringPtrUnknown
= HiiGetString (mDpHiiHandle
, STRING_TOKEN (STR_ALIT_UNKNOWN
), NULL
);
108 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_SECTION_HEADER
), mDpHiiHandle
,
109 (StringPtr
== NULL
) ? StringPtrUnknown
: StringPtr
);
110 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_STATS_NUMTRACE
), mDpHiiHandle
, SummaryData
.NumTrace
);
111 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_STATS_NUMINCOMPLETE
), mDpHiiHandle
, SummaryData
.NumIncomplete
);
112 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_STATS_NUMPHASES
), mDpHiiHandle
, SummaryData
.NumSummary
);
113 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_STATS_NUMHANDLES
), mDpHiiHandle
, SummaryData
.NumHandles
, SummaryData
.NumTrace
- SummaryData
.NumHandles
);
114 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_STATS_NUMPEIMS
), mDpHiiHandle
, SummaryData
.NumPEIMs
);
115 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_STATS_NUMGLOBALS
), mDpHiiHandle
, SummaryData
.NumGlobal
);
116 SHELL_FREE_NON_NULL (StringPtr
);
117 SHELL_FREE_NON_NULL (StringPtrUnknown
);
121 Get Boot performance table form Acpi table.
125 GetBootPerformanceTable (
128 FIRMWARE_PERFORMANCE_TABLE
*FirmwarePerformanceTable
;
130 FirmwarePerformanceTable
= (FIRMWARE_PERFORMANCE_TABLE
*) EfiLocateFirstAcpiTable (
131 EFI_ACPI_5_0_FIRMWARE_PERFORMANCE_DATA_TABLE_SIGNATURE
133 if (FirmwarePerformanceTable
== NULL
) {
134 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_GET_ACPI_FPDT_FAIL
), mDpHiiHandle
);
135 return EFI_NOT_FOUND
;
138 mBootPerformanceTable
= (UINT8
*) (UINTN
)FirmwarePerformanceTable
->BootPointerRecord
.BootPerformanceTablePointer
;
139 mBootPerformanceTableSize
= ((BOOT_PERFORMANCE_TABLE
*) mBootPerformanceTable
)->Header
.Length
;
145 Get Handle form Module Guid.
147 @param ModuleGuid Module Guid.
148 @param Handle The handle to be returned.
152 GetHandleFormModuleGuid (
153 IN EFI_GUID
*ModuleGuid
,
154 IN OUT EFI_HANDLE
*Handle
159 if (IsZeroGuid (ModuleGuid
)) {
163 // Try to get the Handle form the caached array.
165 for (Index
= 0; Index
< mCachePairCount
; Index
++) {
166 if (CompareGuid (ModuleGuid
, &mCacheHandleGuidTable
[Index
].ModuleGuid
)) {
167 *Handle
= mCacheHandleGuidTable
[Index
].Handle
;
171 if (Index
>= mCachePairCount
) {
177 Cache the GUID and handle mapping pairs. In order to save time for searching.
181 BuildCachedGuidHandleTable (
186 EFI_HANDLE
*HandleBuffer
;
189 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
190 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
192 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*FvFilePath
;
194 Status
= gBS
->LocateHandleBuffer (AllHandles
, NULL
, NULL
, &HandleCount
, &HandleBuffer
);
195 if (EFI_ERROR (Status
)) {
196 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_HANDLES_ERROR
), mDpHiiHandle
, Status
);
200 mCacheHandleGuidTable
= AllocateZeroPool (HandleCount
* sizeof (HANDLE_GUID_MAP
));
201 if (mCacheHandleGuidTable
== NULL
) {
202 return EFI_OUT_OF_RESOURCES
;
205 for (Index
= 0; Index
< HandleCount
; Index
++) {
207 // Try Handle as ImageHandle.
209 Status
= gBS
->HandleProtocol (
211 &gEfiLoadedImageProtocolGuid
,
212 (VOID
**) &LoadedImage
214 if (EFI_ERROR (Status
)) {
216 // Try Handle as Controller Handle
218 Status
= gBS
->OpenProtocol (
220 &gEfiDriverBindingProtocolGuid
,
221 (VOID
**) &DriverBinding
,
224 EFI_OPEN_PROTOCOL_GET_PROTOCOL
226 if (!EFI_ERROR (Status
)) {
228 // Get Image protocol from ImageHandle
230 Status
= gBS
->HandleProtocol (
231 DriverBinding
->ImageHandle
,
232 &gEfiLoadedImageProtocolGuid
,
233 (VOID
**) &LoadedImage
238 if (!EFI_ERROR (Status
) && LoadedImage
!= NULL
) {
240 // Get Module Guid from DevicePath.
242 if (LoadedImage
->FilePath
!= NULL
&&
243 LoadedImage
->FilePath
->Type
== MEDIA_DEVICE_PATH
&&
244 LoadedImage
->FilePath
->SubType
== MEDIA_PIWG_FW_FILE_DP
246 FvFilePath
= (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*) LoadedImage
->FilePath
;
247 TempGuid
= &FvFilePath
->FvFileName
;
249 mCacheHandleGuidTable
[mCachePairCount
].Handle
= HandleBuffer
[Index
];
250 CopyGuid (&mCacheHandleGuidTable
[mCachePairCount
].ModuleGuid
, TempGuid
);
255 if (HandleBuffer
!= NULL
) {
256 FreePool (HandleBuffer
);
263 Get Measurement form Fpdt records.
265 @param RecordHeader Pointer to the start record.
266 @param IsStart Is start record or End record.
267 @param Measurement Pointer to the measurement which need to be filled.
272 IN EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER
*RecordHeader
,
274 IN OUT MEASUREMENT_RECORD
*Measurement
278 EFI_HANDLE StartHandle
;
280 switch (RecordHeader
->Type
) {
281 case FPDT_GUID_EVENT_TYPE
:
282 ModuleGuid
= &(((FPDT_GUID_EVENT_RECORD
*)RecordHeader
)->Guid
);
283 Measurement
->Identifier
= ((UINT32
)((FPDT_GUID_EVENT_RECORD
*)RecordHeader
)->ProgressID
);
285 Measurement
->StartTimeStamp
= ((FPDT_GUID_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
287 Measurement
->EndTimeStamp
= ((FPDT_GUID_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
289 switch (Measurement
->Identifier
) {
290 case MODULE_START_ID
:
293 Measurement
->Token
= ALit_PEIM
;
294 Measurement
->Module
= ALit_PEIM
;
295 } else if (mDxePhase
) {
296 Measurement
->Token
= ALit_START_IMAGE
;
297 Measurement
->Module
= ALit_START_IMAGE
;
304 if (Measurement
->Token
!= NULL
&& AsciiStrCmp (Measurement
->Token
, ALit_PEIM
) == 0) {
305 Measurement
->Handle
= &(((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->Guid
);
307 GetHandleFormModuleGuid(ModuleGuid
, &StartHandle
);
308 Measurement
->Handle
= StartHandle
;
310 // When no perf entry to record the PEI and DXE phase,
311 // For start image, we need detect the PEIM and non PEIM here.
313 if (Measurement
->Token
== NULL
) {
314 if (StartHandle
== NULL
&& !IsZeroGuid (ModuleGuid
)) {
315 Measurement
->Token
= ALit_PEIM
;
316 Measurement
->Module
= ALit_PEIM
;
317 Measurement
->Handle
= ModuleGuid
;
319 Measurement
->Token
= ALit_START_IMAGE
;
320 Measurement
->Module
= ALit_START_IMAGE
;
326 case FPDT_DYNAMIC_STRING_EVENT_TYPE
:
327 ModuleGuid
= &(((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->Guid
);
328 Measurement
->Identifier
= ((UINT32
)((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->ProgressID
);
330 Measurement
->StartTimeStamp
= ((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
332 Measurement
->EndTimeStamp
= ((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
334 switch (Measurement
->Identifier
) {
335 case MODULE_START_ID
:
338 Measurement
->Token
= ALit_PEIM
;
339 } else if (mDxePhase
) {
340 Measurement
->Token
= ALit_START_IMAGE
;
344 case MODULE_LOADIMAGE_START_ID
:
345 case MODULE_LOADIMAGE_END_ID
:
346 Measurement
->Token
= ALit_LOAD_IMAGE
;
349 case MODULE_DB_START_ID
:
350 case MODULE_DB_END_ID
:
351 Measurement
->Token
= ALit_DB_START
;
354 case MODULE_DB_SUPPORT_START_ID
:
355 case MODULE_DB_SUPPORT_END_ID
:
356 Measurement
->Token
= ALit_DB_SUPPORT
;
359 case MODULE_DB_STOP_START_ID
:
360 case MODULE_DB_STOP_END_ID
:
361 Measurement
->Token
= ALit_DB_STOP
;
365 Measurement
->Token
= ((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->String
;
369 Measurement
->Module
= ((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->String
;
371 if (Measurement
->Token
!= NULL
&& AsciiStrCmp (Measurement
->Token
, ALit_PEIM
) == 0) {
372 Measurement
->Handle
= &(((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->Guid
);
374 GetHandleFormModuleGuid(ModuleGuid
, &StartHandle
);
375 Measurement
->Handle
= StartHandle
;
377 // When no perf entry to record the PEI and DXE phase,
378 // For start image, we need detect the PEIM and non PEIM here.
380 if (Measurement
->Token
== NULL
&& (Measurement
->Identifier
== MODULE_START_ID
|| Measurement
->Identifier
== MODULE_END_ID
)) {
381 if (StartHandle
== NULL
&& !IsZeroGuid (ModuleGuid
)) {
382 Measurement
->Token
= ALit_PEIM
;
383 Measurement
->Handle
= ModuleGuid
;
385 Measurement
->Token
= ALit_START_IMAGE
;
391 case FPDT_GUID_QWORD_EVENT_TYPE
:
392 ModuleGuid
= &(((FPDT_GUID_QWORD_EVENT_RECORD
*)RecordHeader
)->Guid
);
393 Measurement
->Identifier
= ((UINT32
)((FPDT_GUID_QWORD_EVENT_RECORD
*)RecordHeader
)->ProgressID
);
395 Measurement
->StartTimeStamp
= ((FPDT_GUID_QWORD_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
397 Measurement
->EndTimeStamp
= ((FPDT_GUID_QWORD_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
399 switch (Measurement
->Identifier
) {
400 case MODULE_DB_START_ID
:
401 Measurement
->Token
= ALit_DB_START
;
402 Measurement
->Module
= ALit_DB_START
;
405 case MODULE_DB_SUPPORT_START_ID
:
406 case MODULE_DB_SUPPORT_END_ID
:
407 Measurement
->Token
= ALit_DB_SUPPORT
;
408 Measurement
->Module
= ALit_DB_SUPPORT
;
411 case MODULE_DB_STOP_START_ID
:
412 case MODULE_DB_STOP_END_ID
:
413 Measurement
->Token
= ALit_DB_STOP
;
414 Measurement
->Module
= ALit_DB_STOP
;
417 case MODULE_LOADIMAGE_START_ID
:
418 case MODULE_LOADIMAGE_END_ID
:
419 Measurement
->Token
= ALit_LOAD_IMAGE
;
420 Measurement
->Module
= ALit_LOAD_IMAGE
;
426 GetHandleFormModuleGuid(ModuleGuid
, &StartHandle
);
427 Measurement
->Handle
= StartHandle
;
430 case FPDT_GUID_QWORD_STRING_EVENT_TYPE
:
431 ModuleGuid
= &(((FPDT_GUID_QWORD_STRING_EVENT_RECORD
*)RecordHeader
)->Guid
);
432 Measurement
->Identifier
= ((UINT32
)((FPDT_GUID_QWORD_STRING_EVENT_RECORD
*)RecordHeader
)->ProgressID
);
434 Measurement
->StartTimeStamp
= ((FPDT_GUID_QWORD_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
436 Measurement
->EndTimeStamp
= ((FPDT_GUID_QWORD_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
439 // Currently only "DB:Start:" end record with FPDT_GUID_QWORD_STRING_EVENT_TYPE.
441 switch (Measurement
->Identifier
) {
442 case MODULE_DB_END_ID
:
443 Measurement
->Token
= ALit_DB_START
;
444 Measurement
->Module
= ALit_DB_START
;
449 GetHandleFormModuleGuid(ModuleGuid
, &StartHandle
);
450 Measurement
->Handle
= StartHandle
;
453 case FPDT_DUAL_GUID_STRING_EVENT_TYPE
:
454 ModuleGuid
= &(((FPDT_DUAL_GUID_STRING_EVENT_RECORD
*)RecordHeader
)->Guid1
);
455 Measurement
->Identifier
= ((UINT32
)((FPDT_DUAL_GUID_STRING_EVENT_RECORD
*)RecordHeader
)->ProgressID
);
457 Measurement
->StartTimeStamp
= ((FPDT_DUAL_GUID_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
459 Measurement
->EndTimeStamp
= ((FPDT_DUAL_GUID_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
461 Measurement
->Token
= ((FPDT_DUAL_GUID_STRING_EVENT_RECORD
*)RecordHeader
)->String
;
462 Measurement
->Module
= ((FPDT_DUAL_GUID_STRING_EVENT_RECORD
*)RecordHeader
)->String
;
463 GetHandleFormModuleGuid(ModuleGuid
, &StartHandle
);
464 Measurement
->Handle
= StartHandle
;
473 Search the start measurement in the mMeasurementList for the end measurement.
475 @param EndMeasureMent Measurement for end record.
480 IN MEASUREMENT_RECORD
*EndMeasureMent
485 for (Index
= mMeasurementNum
- 1; Index
>= 0; Index
--) {
486 if (AsciiStrCmp (EndMeasureMent
->Token
, ALit_PEIM
) == 0) {
487 if (mMeasurementList
[Index
].EndTimeStamp
== 0 && EndMeasureMent
->Handle
!= NULL
&& mMeasurementList
[Index
].Handle
!= NULL
&&
488 CompareGuid(mMeasurementList
[Index
].Handle
, EndMeasureMent
->Handle
) &&
489 (AsciiStrCmp (mMeasurementList
[Index
].Token
, EndMeasureMent
->Token
) == 0) &&
490 (AsciiStrCmp (mMeasurementList
[Index
].Module
, EndMeasureMent
->Module
) == 0)) {
491 mMeasurementList
[Index
].EndTimeStamp
= EndMeasureMent
->EndTimeStamp
;
494 } else if (EndMeasureMent
->Identifier
== PERF_CROSSMODULE_END_ID
) {
495 if (mMeasurementList
[Index
].EndTimeStamp
== 0 &&
496 (AsciiStrCmp (mMeasurementList
[Index
].Token
, EndMeasureMent
->Token
) == 0) &&
497 (AsciiStrCmp (mMeasurementList
[Index
].Module
, EndMeasureMent
->Module
) == 0) &&
498 mMeasurementList
[Index
].Identifier
== PERF_CROSSMODULE_START_ID
) {
499 mMeasurementList
[Index
].EndTimeStamp
= EndMeasureMent
->EndTimeStamp
;
503 if (mMeasurementList
[Index
].EndTimeStamp
== 0 && mMeasurementList
[Index
].Handle
== EndMeasureMent
->Handle
&&
504 (AsciiStrCmp (mMeasurementList
[Index
].Token
, EndMeasureMent
->Token
) == 0) &&
505 (AsciiStrCmp (mMeasurementList
[Index
].Module
, EndMeasureMent
->Module
) == 0)) {
506 mMeasurementList
[Index
].EndTimeStamp
= EndMeasureMent
->EndTimeStamp
;
514 Generate the measure record array.
518 BuildMeasurementList (
521 EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER
*RecordHeader
;
522 UINT8
*PerformanceTablePtr
;
523 UINT16 StartProgressId
;
525 UINT8
*StartRecordEvent
;
526 MEASUREMENT_RECORD MeasureMent
;
528 mMeasurementList
= AllocateZeroPool (mBootPerformanceTableSize
);
529 if (mMeasurementList
== NULL
) {
530 return EFI_OUT_OF_RESOURCES
;
533 TableLength
= sizeof (BOOT_PERFORMANCE_TABLE
);
534 PerformanceTablePtr
= (mBootPerformanceTable
+ TableLength
);
536 while (TableLength
< mBootPerformanceTableSize
) {
537 RecordHeader
= (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER
*) PerformanceTablePtr
;
538 StartRecordEvent
= (UINT8
*)RecordHeader
;
539 StartProgressId
= ((FPDT_GUID_EVENT_RECORD
*)StartRecordEvent
)->ProgressID
;
542 // 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.
543 // If the record is the start record, fill the info to the measurement in the mMeasurementList.
544 // If the record is the end record, find the related start measurement in the mMeasurementList and fill the EndTimeStamp.
546 if (StartProgressId
== 0) {
547 GetMeasurementInfo (RecordHeader
, FALSE
, &(mMeasurementList
[mMeasurementNum
]));
549 } else if (((StartProgressId
>= PERF_EVENTSIGNAL_START_ID
&& ((StartProgressId
& 0x000F) == 0)) ||
550 (StartProgressId
< PERF_EVENTSIGNAL_START_ID
&& ((StartProgressId
& 0x0001) != 0)))) {
552 // Since PEIM and StartImage has same Type and ID when PCD PcdEdkiiFpdtStringRecordEnableOnly = FALSE
553 // So we need to identify these two kinds of record through different phase.
555 if(StartProgressId
== PERF_CROSSMODULE_START_ID
){
556 if (AsciiStrCmp (((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)StartRecordEvent
)->String
, ALit_PEI
) == 0) {
558 } else if (AsciiStrCmp (((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)StartRecordEvent
)->String
, ALit_DXE
) == 0) {
563 // Get measurement info form the start record to the mMeasurementList.
564 GetMeasurementInfo (RecordHeader
, TRUE
, &(mMeasurementList
[mMeasurementNum
]));
567 ZeroMem(&MeasureMent
, sizeof(MEASUREMENT_RECORD
));
568 GetMeasurementInfo (RecordHeader
, FALSE
, &MeasureMent
);
569 SearchMeasurement (&MeasureMent
);
571 TableLength
+= RecordHeader
->Length
;
572 PerformanceTablePtr
+= RecordHeader
->Length
;
578 Initialize the cumulative data.
588 for (Index
= 0; Index
< NumCum
; ++Index
) {
589 CumData
[Index
].Count
= 0;
590 CumData
[Index
].MinDur
= PERF_MAXDUR
;
591 CumData
[Index
].MaxDur
= 0;
592 CumData
[Index
].Duration
= 0;
597 Initialize the Summary data.
605 SummaryData
.NumTrace
= 0;
606 SummaryData
.NumIncomplete
= 0;
607 SummaryData
.NumSummary
= 0;
608 SummaryData
.NumHandles
= 0;
609 SummaryData
.NumPEIMs
= 0;
610 SummaryData
.NumGlobal
= 0;
614 Dump performance data.
616 @param[in] ImageHandle The image handle.
617 @param[in] SystemTable The system table.
619 @retval SHELL_SUCCESS Command completed successfully.
620 @retval SHELL_INVALID_PARAMETER Command usage error.
621 @retval SHELL_ABORTED The user aborts the operation.
622 @retval value Unknown error.
626 IN EFI_HANDLE ImageHandle
,
627 IN EFI_SYSTEM_TABLE
*SystemTable
630 LIST_ENTRY
*ParamPackage
;
631 CONST CHAR16
*CmdLineArg
;
634 PERFORMANCE_PROPERTY
*PerformanceProperty
;
635 UINTN Number2Display
;
637 EFI_STRING StringPtr
;
643 BOOLEAN CumulativeMode
;
644 CONST CHAR16
*CustomCumulativeToken
;
645 PERF_CUM_DATA
*CustomCumulativeData
;
647 SHELL_STATUS ShellStatus
;
648 TIMER_INFO TimerInfo
;
657 CumulativeMode
= FALSE
;
658 CustomCumulativeData
= NULL
;
659 ShellStatus
= SHELL_SUCCESS
;
662 // initialize the shell lib (we must be in non-auto-init...)
664 Status
= ShellInitialize();
665 ASSERT_EFI_ERROR(Status
);
668 // Process Command Line arguments
670 Status
= ShellCommandLineParse (ParamList
, &ParamPackage
, NULL
, TRUE
);
671 if (EFI_ERROR(Status
)) {
672 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_INVALID_ARG
), mDpHiiHandle
);
673 return SHELL_INVALID_PARAMETER
;
674 } else if (ShellCommandLineGetCount(ParamPackage
) > 1){
675 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_TOO_MANY
), mDpHiiHandle
);
676 return SHELL_INVALID_PARAMETER
;
682 VerboseMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-v");
683 SummaryMode
= (BOOLEAN
) (ShellCommandLineGetFlag (ParamPackage
, L
"-S") || ShellCommandLineGetFlag (ParamPackage
, L
"-s"));
684 AllMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-A");
685 RawMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-R");
686 ExcludeMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-x");
687 mShowId
= ShellCommandLineGetFlag (ParamPackage
, L
"-i");
688 CumulativeMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-c");
690 if (AllMode
&& RawMode
) {
691 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_CONFLICT_ARG
), mDpHiiHandle
, L
"-A", L
"-R");
692 return SHELL_INVALID_PARAMETER
;
695 // Options with Values
696 if (ShellCommandLineGetFlag (ParamPackage
, L
"-n")) {
697 CmdLineArg
= ShellCommandLineGetValue (ParamPackage
, L
"-n");
698 if (CmdLineArg
== NULL
) {
699 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_TOO_FEW
), mDpHiiHandle
);
700 return SHELL_INVALID_PARAMETER
;
702 if (!(RawMode
|| AllMode
)) {
703 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_NO_RAW_ALL
), mDpHiiHandle
);
704 return SHELL_INVALID_PARAMETER
;
706 Status
= ShellConvertStringToUint64(CmdLineArg
, &Intermediate
, FALSE
, TRUE
);
707 if (EFI_ERROR (Status
)) {
708 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_INVALID_NUM_ARG
), mDpHiiHandle
, L
"-n");
709 return SHELL_INVALID_PARAMETER
;
711 Number2Display
= (UINTN
)Intermediate
;
712 if (Number2Display
== 0 || Number2Display
> MAXIMUM_DISPLAYCOUNT
) {
713 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_INVALID_RANGE
), mDpHiiHandle
, L
"-n", 0, MAXIMUM_DISPLAYCOUNT
);
714 return SHELL_INVALID_PARAMETER
;
719 Number2Display
= DEFAULT_DISPLAYCOUNT
;
722 if (ShellCommandLineGetFlag (ParamPackage
, L
"-t")) {
723 CmdLineArg
= ShellCommandLineGetValue (ParamPackage
, L
"-t");
724 if (CmdLineArg
== NULL
) {
725 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_TOO_FEW
), mDpHiiHandle
);
726 return SHELL_INVALID_PARAMETER
;
728 Status
= ShellConvertStringToUint64(CmdLineArg
, &Intermediate
, FALSE
, TRUE
);
729 if (EFI_ERROR (Status
)) {
730 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_INVALID_NUM_ARG
), mDpHiiHandle
, L
"-t");
731 return SHELL_INVALID_PARAMETER
;
733 mInterestThreshold
= Intermediate
;
737 mInterestThreshold
= DEFAULT_THRESHOLD
; // 1ms := 1,000 us
740 if (ShellCommandLineGetFlag (ParamPackage
, L
"-c")) {
741 CustomCumulativeToken
= ShellCommandLineGetValue (ParamPackage
, L
"-c");
742 if (CustomCumulativeToken
== NULL
) {
743 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_TOO_FEW
), mDpHiiHandle
);
744 return SHELL_INVALID_PARAMETER
;
746 CustomCumulativeData
= AllocateZeroPool (sizeof (PERF_CUM_DATA
));
747 if (CustomCumulativeData
== NULL
) {
748 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
751 CustomCumulativeData
->MinDur
= PERF_MAXDUR
;
752 CustomCumulativeData
->MaxDur
= 0;
753 CustomCumulativeData
->Count
= 0;
754 CustomCumulativeData
->Duration
= 0;
755 NameSize
= StrLen (CustomCumulativeToken
) + 1;
756 CustomCumulativeData
->Name
= AllocateZeroPool (NameSize
);
757 if (CustomCumulativeData
->Name
== NULL
) {
758 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
761 UnicodeStrToAsciiStrS (CustomCumulativeToken
, CustomCumulativeData
->Name
, NameSize
);
766 // DP dump performance data by parsing FPDT table in ACPI table.
767 // Folloing 3 steps are to get the measurement form the FPDT table.
771 //1. Get FPDT from ACPI table.
773 Status
= GetBootPerformanceTable ();
774 if (EFI_ERROR (Status
)) {
775 ShellStatus
= Status
;
780 //2. Cache the ModuleGuid and hanlde mapping table.
782 Status
= BuildCachedGuidHandleTable();
783 if (EFI_ERROR (Status
)) {
784 ShellStatus
= Status
;
789 //3. Build the measurement array form the FPDT records.
791 Status
= BuildMeasurementList ();
792 if (EFI_ERROR (Status
)) {
793 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
798 // Initialize the pre-defined cumulative data.
800 InitCumulativeData ();
803 // Initialize the Summary data.
808 // Timer specific processing
810 // Get the Performance counter characteristics:
811 // Freq = Frequency in Hz
812 // StartCount = Value loaded into the counter when it starts counting
813 // EndCount = Value counter counts to before it needs to be reset
815 Status
= EfiGetSystemConfigurationTable (&gPerformanceProtocolGuid
, (VOID
**) &PerformanceProperty
);
816 if (EFI_ERROR (Status
) || (PerformanceProperty
== NULL
)) {
817 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_PERF_PROPERTY_NOT_FOUND
), mDpHiiHandle
);
821 TimerInfo
.Frequency
= (UINT32
)DivU64x32 (PerformanceProperty
->Frequency
, 1000);
822 TimerInfo
.StartCount
= 0;
823 TimerInfo
.EndCount
= 0xFFFF;
824 TimerInfo
.CountUp
= TRUE
;
829 // print DP's build version
830 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_BUILD_REVISION
), mDpHiiHandle
, DP_MAJOR_VERSION
, DP_MINOR_VERSION
);
832 // print performance timer characteristics
833 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_KHZ
), mDpHiiHandle
, TimerInfo
.Frequency
);
835 if (VerboseMode
&& !RawMode
) {
836 StringPtr
= HiiGetString (mDpHiiHandle
,
837 (EFI_STRING_ID
) (TimerInfo
.CountUp
? STRING_TOKEN (STR_DP_UP
) : STRING_TOKEN (STR_DP_DOWN
)), NULL
);
838 ASSERT (StringPtr
!= NULL
);
839 // Print Timer count range and direction
840 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_TIMER_PROPERTIES
), mDpHiiHandle
,
842 TimerInfo
.StartCount
,
845 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_VERBOSE_THRESHOLD
), mDpHiiHandle
, mInterestThreshold
);
848 /****************************************************************************
849 **** Print Sections based on command line options
851 **** Option modes have the following priority:
852 **** v Verbose -- Valid in combination with any other options
853 **** t Threshold -- Modifies All, Raw, and Cooked output
854 **** Default is 0 for All and Raw mode
855 **** Default is DEFAULT_THRESHOLD for "Cooked" mode
856 **** n Number2Display Used by All and Raw mode. Otherwise ignored.
857 **** A All -- R and S options are ignored
858 **** R Raw -- S option is ignored
859 **** s Summary -- Modifies "Cooked" output only
860 **** Cooked (Default)
861 ****************************************************************************/
862 GatherStatistics (CustomCumulativeData
);
863 if (CumulativeMode
) {
864 ProcessCumulative (CustomCumulativeData
);
865 } else if (AllMode
) {
866 Status
= DumpAllTrace( Number2Display
, ExcludeMode
);
867 if (Status
== EFI_ABORTED
) {
868 ShellStatus
= SHELL_ABORTED
;
871 } else if (RawMode
) {
872 Status
= DumpRawTrace( Number2Display
, ExcludeMode
);
873 if (Status
== EFI_ABORTED
) {
874 ShellStatus
= SHELL_ABORTED
;
878 //------------- Begin Cooked Mode Processing
880 if ( ! SummaryMode
) {
881 Status
= ProcessHandles ( ExcludeMode
);
882 if (Status
== EFI_ABORTED
) {
883 ShellStatus
= SHELL_ABORTED
;
887 Status
= ProcessPeims ();
888 if (Status
== EFI_ABORTED
) {
889 ShellStatus
= SHELL_ABORTED
;
893 Status
= ProcessGlobal ();
894 if (Status
== EFI_ABORTED
) {
895 ShellStatus
= SHELL_ABORTED
;
899 ProcessCumulative (NULL
);
901 } //------------- End of Cooked Mode Processing
902 if ( VerboseMode
|| SummaryMode
) {
907 if (ParamPackage
!= NULL
) {
908 ShellCommandLineFreeVarList (ParamPackage
);
910 SHELL_FREE_NON_NULL (StringPtr
);
911 if (CustomCumulativeData
!= NULL
) {
912 SHELL_FREE_NON_NULL (CustomCumulativeData
->Name
);
914 SHELL_FREE_NON_NULL (CustomCumulativeData
);
916 SHELL_FREE_NON_NULL (mMeasurementList
);
918 SHELL_FREE_NON_NULL (mCacheHandleGuidTable
);
927 Retrive HII package list from ImageHandle and publish to HII database.
929 @param ImageHandle The image handle of the process.
934 InitializeHiiPackage (
935 EFI_HANDLE ImageHandle
939 EFI_HII_PACKAGE_LIST_HEADER
*PackageList
;
940 EFI_HANDLE HiiHandle
;
943 // Retrieve HII package list from ImageHandle
945 Status
= gBS
->OpenProtocol (
947 &gEfiHiiPackageListProtocolGuid
,
948 (VOID
**)&PackageList
,
951 EFI_OPEN_PROTOCOL_GET_PROTOCOL
953 ASSERT_EFI_ERROR (Status
);
954 if (EFI_ERROR (Status
)) {
959 // Publish HII package list to HII Database.
961 Status
= gHiiDatabase
->NewPackageList (
967 ASSERT_EFI_ERROR (Status
);
968 if (EFI_ERROR (Status
)) {