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 {L
"-x", TypeFlag
}, // -x eXclude Cumulative Items
88 {L
"-i", TypeFlag
}, // -i Display Identifier
89 {L
"-c", TypeValue
}, // -c Display cumulative data.
90 {L
"-n", TypeValue
}, // -n # Number of records to display for A and R
91 {L
"-t", TypeValue
}, // -t # Threshold of interest
98 Display the trailing Verbose information.
101 DumpStatistics( void )
103 EFI_STRING StringPtr
;
104 EFI_STRING StringPtrUnknown
;
105 StringPtr
= HiiGetString (mDpHiiHandle
, STRING_TOKEN (STR_DP_SECTION_STATISTICS
), NULL
);
106 StringPtrUnknown
= HiiGetString (mDpHiiHandle
, STRING_TOKEN (STR_ALIT_UNKNOWN
), NULL
);
107 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_SECTION_HEADER
), mDpHiiHandle
,
108 (StringPtr
== NULL
) ? StringPtrUnknown
: StringPtr
);
109 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_STATS_NUMTRACE
), mDpHiiHandle
, SummaryData
.NumTrace
);
110 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_STATS_NUMINCOMPLETE
), mDpHiiHandle
, SummaryData
.NumIncomplete
);
111 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_STATS_NUMPHASES
), mDpHiiHandle
, SummaryData
.NumSummary
);
112 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_STATS_NUMHANDLES
), mDpHiiHandle
, SummaryData
.NumHandles
, SummaryData
.NumTrace
- SummaryData
.NumHandles
);
113 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_STATS_NUMPEIMS
), mDpHiiHandle
, SummaryData
.NumPEIMs
);
114 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_STATS_NUMGLOBALS
), mDpHiiHandle
, SummaryData
.NumGlobal
);
115 SHELL_FREE_NON_NULL (StringPtr
);
116 SHELL_FREE_NON_NULL (StringPtrUnknown
);
120 This function scan ACPI table in RSDT.
122 @param Rsdt ACPI RSDT
123 @param Signature ACPI table signature
136 EFI_ACPI_DESCRIPTION_HEADER
*Table
;
138 EntryCount
= (Rsdt
->Header
.Length
- sizeof (EFI_ACPI_DESCRIPTION_HEADER
)) / sizeof(UINT32
);
140 EntryPtr
= &Rsdt
->Entry
;
141 for (Index
= 0; Index
< EntryCount
; Index
++, EntryPtr
++) {
142 Table
= (EFI_ACPI_DESCRIPTION_HEADER
*)((UINTN
)(*EntryPtr
));
143 if (Table
->Signature
== Signature
) {
152 This function scan ACPI table in XSDT.
154 @param Xsdt ACPI XSDT
155 @param Signature ACPI table signature
169 EFI_ACPI_DESCRIPTION_HEADER
*Table
;
171 EntryCount
= (Xsdt
->Header
.Length
- sizeof (EFI_ACPI_DESCRIPTION_HEADER
)) / sizeof(UINT64
);
173 BasePtr
= (UINTN
)(&(Xsdt
->Entry
));
174 for (Index
= 0; Index
< EntryCount
; Index
++) {
175 CopyMem (&EntryPtr
, (VOID
*)(BasePtr
+ Index
* sizeof(UINT64
)), sizeof(UINT64
));
176 Table
= (EFI_ACPI_DESCRIPTION_HEADER
*)((UINTN
)(EntryPtr
));
177 if (Table
->Signature
== Signature
) {
186 This function scan ACPI table in RSDP.
188 @param Rsdp ACPI RSDP
189 @param Signature ACPI table signature
195 IN EFI_ACPI_5_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*Rsdp
,
199 EFI_ACPI_DESCRIPTION_HEADER
*AcpiTable
;
206 // Check ACPI2.0 table
208 Rsdt
= (RSDT_TABLE
*)(UINTN
)Rsdp
->RsdtAddress
;
210 if ((Rsdp
->Revision
>= 2) && (Rsdp
->XsdtAddress
< (UINT64
)(UINTN
)-1)) {
211 Xsdt
= (XSDT_TABLE
*)(UINTN
)Rsdp
->XsdtAddress
;
217 AcpiTable
= ScanTableInXSDT (Xsdt
, Signature
);
222 if ((AcpiTable
== NULL
) && (Rsdt
!= NULL
)) {
223 AcpiTable
= ScanTableInRSDT (Rsdt
, Signature
);
230 Get Boot performance table form Acpi table.
234 GetBootPerformanceTable (
239 FIRMWARE_PERFORMANCE_TABLE
*FirmwarePerformanceTable
;
243 Status
= EfiGetSystemConfigurationTable (
244 &gEfiAcpi20TableGuid
,
247 if (EFI_ERROR (Status
)) {
248 Status
= EfiGetSystemConfigurationTable (
249 &gEfiAcpi10TableGuid
,
253 if (EFI_ERROR(Status
) || AcpiTable
== NULL
) {
254 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_GET_ACPI_TABLE_FAIL
), mDpHiiHandle
);
258 FirmwarePerformanceTable
= FindAcpiPtr (
259 (EFI_ACPI_5_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*)AcpiTable
,
260 EFI_ACPI_5_0_FIRMWARE_PERFORMANCE_DATA_TABLE_SIGNATURE
262 if (FirmwarePerformanceTable
== NULL
) {
263 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_GET_ACPI_FPDT_FAIL
), mDpHiiHandle
);
264 return EFI_NOT_FOUND
;
267 mBootPerformanceTable
= (UINT8
*) (UINTN
)FirmwarePerformanceTable
->BootPointerRecord
.BootPerformanceTablePointer
;
268 mBootPerformanceTableSize
= ((BOOT_PERFORMANCE_TABLE
*) mBootPerformanceTable
)->Header
.Length
;
274 Get Handle form Module Guid.
276 @param ModuleGuid Module Guid.
277 @param Handle The handle to be returned.
281 GetHandleFormModuleGuid (
282 IN EFI_GUID
*ModuleGuid
,
283 IN OUT EFI_HANDLE
*Handle
288 if (IsZeroGuid (ModuleGuid
)) {
292 // Try to get the Handle form the caached array.
294 for (Index
= 0; Index
< mCachePairCount
; Index
++) {
295 if (CompareGuid (ModuleGuid
, &mCacheHandleGuidTable
[Index
].ModuleGuid
)) {
296 *Handle
= mCacheHandleGuidTable
[Index
].Handle
;
300 if (Index
>= mCachePairCount
) {
306 Cache the GUID and handle mapping pairs. In order to save time for searching.
310 BuildCachedGuidHandleTable (
315 EFI_HANDLE
*HandleBuffer
;
318 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
319 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
321 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*FvFilePath
;
323 Status
= gBS
->LocateHandleBuffer (AllHandles
, NULL
, NULL
, &HandleCount
, &HandleBuffer
);
324 if (EFI_ERROR (Status
)) {
325 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_HANDLES_ERROR
), mDpHiiHandle
, Status
);
329 mCacheHandleGuidTable
= AllocateZeroPool (HandleCount
* sizeof (HANDLE_GUID_MAP
));
330 if (mCacheHandleGuidTable
== NULL
) {
331 return EFI_OUT_OF_RESOURCES
;
334 for (Index
= 0; Index
< HandleCount
; Index
++) {
336 // Try Handle as ImageHandle.
338 Status
= gBS
->HandleProtocol (
340 &gEfiLoadedImageProtocolGuid
,
341 (VOID
**) &LoadedImage
343 if (EFI_ERROR (Status
)) {
345 // Try Handle as Controller Handle
347 Status
= gBS
->OpenProtocol (
349 &gEfiDriverBindingProtocolGuid
,
350 (VOID
**) &DriverBinding
,
353 EFI_OPEN_PROTOCOL_GET_PROTOCOL
355 if (!EFI_ERROR (Status
)) {
357 // Get Image protocol from ImageHandle
359 Status
= gBS
->HandleProtocol (
360 DriverBinding
->ImageHandle
,
361 &gEfiLoadedImageProtocolGuid
,
362 (VOID
**) &LoadedImage
367 if (!EFI_ERROR (Status
) && LoadedImage
!= NULL
) {
369 // Get Module Guid from DevicePath.
371 if (LoadedImage
->FilePath
!= NULL
&&
372 LoadedImage
->FilePath
->Type
== MEDIA_DEVICE_PATH
&&
373 LoadedImage
->FilePath
->SubType
== MEDIA_PIWG_FW_FILE_DP
375 FvFilePath
= (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*) LoadedImage
->FilePath
;
376 TempGuid
= &FvFilePath
->FvFileName
;
378 mCacheHandleGuidTable
[mCachePairCount
].Handle
= HandleBuffer
[Index
];
379 CopyGuid (&mCacheHandleGuidTable
[mCachePairCount
].ModuleGuid
, TempGuid
);
384 if (HandleBuffer
!= NULL
) {
385 FreePool (HandleBuffer
);
392 Get Measurement form Fpdt records.
394 @param RecordHeader Pointer to the start record.
395 @param IsStart Is start record or End record.
396 @param Measurement Pointer to the measurement which need to be filled.
401 IN EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER
*RecordHeader
,
403 IN OUT MEASUREMENT_RECORD
*Measurement
407 EFI_HANDLE StartHandle
;
409 switch (RecordHeader
->Type
) {
410 case FPDT_GUID_EVENT_TYPE
:
411 ModuleGuid
= &(((FPDT_GUID_EVENT_RECORD
*)RecordHeader
)->Guid
);
412 Measurement
->Identifier
= ((UINT32
)((FPDT_GUID_EVENT_RECORD
*)RecordHeader
)->ProgressID
);
414 Measurement
->StartTimeStamp
= ((FPDT_GUID_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
416 Measurement
->EndTimeStamp
= ((FPDT_GUID_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
418 switch (Measurement
->Identifier
) {
419 case MODULE_START_ID
:
422 Measurement
->Token
= ALit_PEIM
;
423 Measurement
->Module
= ALit_PEIM
;
424 } else if (mDxePhase
) {
425 Measurement
->Token
= ALit_START_IMAGE
;
426 Measurement
->Module
= ALit_START_IMAGE
;
433 if (Measurement
->Token
!= NULL
&& AsciiStrCmp (Measurement
->Token
, ALit_PEIM
) == 0) {
434 Measurement
->Handle
= &(((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->Guid
);
436 GetHandleFormModuleGuid(ModuleGuid
, &StartHandle
);
437 Measurement
->Handle
= StartHandle
;
439 // When no perf entry to record the PEI and DXE phase,
440 // For start image, we need detect the PEIM and non PEIM here.
442 if (Measurement
->Token
== NULL
) {
443 if (StartHandle
== NULL
&& !IsZeroGuid (ModuleGuid
)) {
444 Measurement
->Token
= ALit_PEIM
;
445 Measurement
->Module
= ALit_PEIM
;
446 Measurement
->Handle
= ModuleGuid
;
448 Measurement
->Token
= ALit_START_IMAGE
;
449 Measurement
->Module
= ALit_START_IMAGE
;
455 case FPDT_DYNAMIC_STRING_EVENT_TYPE
:
456 ModuleGuid
= &(((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->Guid
);
457 Measurement
->Identifier
= ((UINT32
)((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->ProgressID
);
459 Measurement
->StartTimeStamp
= ((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
461 Measurement
->EndTimeStamp
= ((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
463 switch (Measurement
->Identifier
) {
464 case MODULE_START_ID
:
467 Measurement
->Token
= ALit_PEIM
;
468 } else if (mDxePhase
) {
469 Measurement
->Token
= ALit_START_IMAGE
;
473 case MODULE_LOADIMAGE_START_ID
:
474 case MODULE_LOADIMAGE_END_ID
:
475 Measurement
->Token
= ALit_LOAD_IMAGE
;
478 case MODULE_DB_START_ID
:
479 case MODULE_DB_END_ID
:
480 Measurement
->Token
= ALit_DB_START
;
483 case MODULE_DB_SUPPORT_START_ID
:
484 case MODULE_DB_SUPPORT_END_ID
:
485 Measurement
->Token
= ALit_DB_SUPPORT
;
488 case MODULE_DB_STOP_START_ID
:
489 case MODULE_DB_STOP_END_ID
:
490 Measurement
->Token
= ALit_DB_STOP
;
494 Measurement
->Token
= ((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->String
;
498 Measurement
->Module
= ((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->String
;
500 if (Measurement
->Token
!= NULL
&& AsciiStrCmp (Measurement
->Token
, ALit_PEIM
) == 0) {
501 Measurement
->Handle
= &(((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->Guid
);
503 GetHandleFormModuleGuid(ModuleGuid
, &StartHandle
);
504 Measurement
->Handle
= StartHandle
;
506 // When no perf entry to record the PEI and DXE phase,
507 // For start image, we need detect the PEIM and non PEIM here.
509 if (Measurement
->Token
== NULL
&& (Measurement
->Identifier
== MODULE_START_ID
|| Measurement
->Identifier
== MODULE_END_ID
)) {
510 if (StartHandle
== NULL
&& !IsZeroGuid (ModuleGuid
)) {
511 Measurement
->Token
= ALit_PEIM
;
512 Measurement
->Handle
= ModuleGuid
;
514 Measurement
->Token
= ALit_START_IMAGE
;
520 case FPDT_GUID_QWORD_EVENT_TYPE
:
521 ModuleGuid
= &(((FPDT_GUID_QWORD_EVENT_RECORD
*)RecordHeader
)->Guid
);
522 Measurement
->Identifier
= ((UINT32
)((FPDT_GUID_QWORD_EVENT_RECORD
*)RecordHeader
)->ProgressID
);
524 Measurement
->StartTimeStamp
= ((FPDT_GUID_QWORD_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
526 Measurement
->EndTimeStamp
= ((FPDT_GUID_QWORD_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
528 switch (Measurement
->Identifier
) {
529 case MODULE_DB_START_ID
:
530 Measurement
->Token
= ALit_DB_START
;
531 Measurement
->Module
= ALit_DB_START
;
534 case MODULE_DB_SUPPORT_START_ID
:
535 case MODULE_DB_SUPPORT_END_ID
:
536 Measurement
->Token
= ALit_DB_SUPPORT
;
537 Measurement
->Module
= ALit_DB_SUPPORT
;
540 case MODULE_DB_STOP_START_ID
:
541 case MODULE_DB_STOP_END_ID
:
542 Measurement
->Token
= ALit_DB_STOP
;
543 Measurement
->Module
= ALit_DB_STOP
;
546 case MODULE_LOADIMAGE_START_ID
:
547 case MODULE_LOADIMAGE_END_ID
:
548 Measurement
->Token
= ALit_LOAD_IMAGE
;
549 Measurement
->Module
= ALit_LOAD_IMAGE
;
555 GetHandleFormModuleGuid(ModuleGuid
, &StartHandle
);
556 Measurement
->Handle
= StartHandle
;
559 case FPDT_GUID_QWORD_STRING_EVENT_TYPE
:
560 ModuleGuid
= &(((FPDT_GUID_QWORD_STRING_EVENT_RECORD
*)RecordHeader
)->Guid
);
561 Measurement
->Identifier
= ((UINT32
)((FPDT_GUID_QWORD_STRING_EVENT_RECORD
*)RecordHeader
)->ProgressID
);
563 Measurement
->StartTimeStamp
= ((FPDT_GUID_QWORD_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
565 Measurement
->EndTimeStamp
= ((FPDT_GUID_QWORD_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
568 // Currently only "DB:Start:" end record with FPDT_GUID_QWORD_STRING_EVENT_TYPE.
570 switch (Measurement
->Identifier
) {
571 case MODULE_DB_END_ID
:
572 Measurement
->Token
= ALit_DB_START
;
573 Measurement
->Module
= ALit_DB_START
;
578 GetHandleFormModuleGuid(ModuleGuid
, &StartHandle
);
579 Measurement
->Handle
= StartHandle
;
582 case FPDT_DUAL_GUID_STRING_EVENT_TYPE
:
583 ModuleGuid
= &(((FPDT_DUAL_GUID_STRING_EVENT_RECORD
*)RecordHeader
)->Guid1
);
584 Measurement
->Identifier
= ((UINT32
)((FPDT_DUAL_GUID_STRING_EVENT_RECORD
*)RecordHeader
)->ProgressID
);
586 Measurement
->StartTimeStamp
= ((FPDT_DUAL_GUID_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
588 Measurement
->EndTimeStamp
= ((FPDT_DUAL_GUID_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
590 Measurement
->Token
= ((FPDT_DUAL_GUID_STRING_EVENT_RECORD
*)RecordHeader
)->String
;
591 Measurement
->Module
= ((FPDT_DUAL_GUID_STRING_EVENT_RECORD
*)RecordHeader
)->String
;
592 GetHandleFormModuleGuid(ModuleGuid
, &StartHandle
);
593 Measurement
->Handle
= StartHandle
;
602 Search the start measurement in the mMeasurementList for the end measurement.
604 @param EndMeasureMent Measurement for end record.
609 IN MEASUREMENT_RECORD
*EndMeasureMent
614 for (Index
= mMeasurementNum
- 1; Index
>= 0; Index
--) {
615 if (AsciiStrCmp (EndMeasureMent
->Token
, ALit_PEIM
) == 0) {
616 if (mMeasurementList
[Index
].EndTimeStamp
== 0 && EndMeasureMent
->Handle
!= NULL
&& mMeasurementList
[Index
].Handle
!= NULL
&&
617 CompareGuid(mMeasurementList
[Index
].Handle
, EndMeasureMent
->Handle
) &&
618 (AsciiStrCmp (mMeasurementList
[Index
].Token
, EndMeasureMent
->Token
) == 0) &&
619 (AsciiStrCmp (mMeasurementList
[Index
].Module
, EndMeasureMent
->Module
) == 0)) {
620 mMeasurementList
[Index
].EndTimeStamp
= EndMeasureMent
->EndTimeStamp
;
623 } else if (EndMeasureMent
->Identifier
== PERF_CROSSMODULE_END_ID
) {
624 if (mMeasurementList
[Index
].EndTimeStamp
== 0 &&
625 (AsciiStrCmp (mMeasurementList
[Index
].Token
, EndMeasureMent
->Token
) == 0) &&
626 (AsciiStrCmp (mMeasurementList
[Index
].Module
, EndMeasureMent
->Module
) == 0) &&
627 mMeasurementList
[Index
].Identifier
== PERF_CROSSMODULE_START_ID
) {
628 mMeasurementList
[Index
].EndTimeStamp
= EndMeasureMent
->EndTimeStamp
;
632 if (mMeasurementList
[Index
].EndTimeStamp
== 0 && mMeasurementList
[Index
].Handle
== EndMeasureMent
->Handle
&&
633 (AsciiStrCmp (mMeasurementList
[Index
].Token
, EndMeasureMent
->Token
) == 0) &&
634 (AsciiStrCmp (mMeasurementList
[Index
].Module
, EndMeasureMent
->Module
) == 0)) {
635 mMeasurementList
[Index
].EndTimeStamp
= EndMeasureMent
->EndTimeStamp
;
643 Generate the measure record array.
647 BuildMeasurementList (
650 EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER
*RecordHeader
;
651 UINT8
*PerformanceTablePtr
;
652 UINT16 StartProgressId
;
654 UINT8
*StartRecordEvent
;
655 MEASUREMENT_RECORD MeasureMent
;
657 mMeasurementList
= AllocateZeroPool (mBootPerformanceTableSize
);
658 if (mMeasurementList
== NULL
) {
659 return EFI_OUT_OF_RESOURCES
;
662 TableLength
= sizeof (BOOT_PERFORMANCE_TABLE
);
663 PerformanceTablePtr
= (mBootPerformanceTable
+ TableLength
);
665 while (TableLength
< mBootPerformanceTableSize
) {
666 RecordHeader
= (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER
*) PerformanceTablePtr
;
667 StartRecordEvent
= (UINT8
*)RecordHeader
;
668 StartProgressId
= ((FPDT_GUID_EVENT_RECORD
*)StartRecordEvent
)->ProgressID
;
671 // 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.
672 // If the record is the start record, fill the info to the measurement in the mMeasurementList.
673 // If the record is the end record, find the related start measurement in the mMeasurementList and fill the EndTimeStamp.
675 if (StartProgressId
== 0) {
676 GetMeasurementInfo (RecordHeader
, FALSE
, &(mMeasurementList
[mMeasurementNum
]));
678 } else if (((StartProgressId
>= PERF_EVENTSIGNAL_START_ID
&& ((StartProgressId
& 0x000F) == 0)) ||
679 (StartProgressId
< PERF_EVENTSIGNAL_START_ID
&& ((StartProgressId
& 0x0001) != 0)))) {
681 // Since PEIM and StartImage has same Type and ID when PCD PcdEdkiiFpdtStringRecordEnableOnly = FALSE
682 // So we need to identify these two kinds of record through different phase.
684 if(StartProgressId
== PERF_CROSSMODULE_START_ID
){
685 if (AsciiStrCmp (((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)StartRecordEvent
)->String
, ALit_PEI
) == 0) {
687 } else if (AsciiStrCmp (((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)StartRecordEvent
)->String
, ALit_DXE
) == 0) {
692 // Get measurement info form the start record to the mMeasurementList.
693 GetMeasurementInfo (RecordHeader
, TRUE
, &(mMeasurementList
[mMeasurementNum
]));
696 ZeroMem(&MeasureMent
, sizeof(MEASUREMENT_RECORD
));
697 GetMeasurementInfo (RecordHeader
, FALSE
, &MeasureMent
);
698 SearchMeasurement (&MeasureMent
);
700 TableLength
+= RecordHeader
->Length
;
701 PerformanceTablePtr
+= RecordHeader
->Length
;
707 Initialize the cumulative data.
717 for (Index
= 0; Index
< NumCum
; ++Index
) {
718 CumData
[Index
].Count
= 0;
719 CumData
[Index
].MinDur
= PERF_MAXDUR
;
720 CumData
[Index
].MaxDur
= 0;
721 CumData
[Index
].Duration
= 0;
726 Initialize the Summary data.
734 SummaryData
.NumTrace
= 0;
735 SummaryData
.NumIncomplete
= 0;
736 SummaryData
.NumSummary
= 0;
737 SummaryData
.NumHandles
= 0;
738 SummaryData
.NumPEIMs
= 0;
739 SummaryData
.NumGlobal
= 0;
743 Dump performance data.
745 @param[in] ImageHandle The image handle.
746 @param[in] SystemTable The system table.
748 @retval SHELL_SUCCESS Command completed successfully.
749 @retval SHELL_INVALID_PARAMETER Command usage error.
750 @retval SHELL_ABORTED The user aborts the operation.
751 @retval value Unknown error.
755 IN EFI_HANDLE ImageHandle
,
756 IN EFI_SYSTEM_TABLE
*SystemTable
759 LIST_ENTRY
*ParamPackage
;
760 CONST CHAR16
*CmdLineArg
;
763 PERFORMANCE_PROPERTY
*PerformanceProperty
;
764 UINTN Number2Display
;
766 EFI_STRING StringPtr
;
772 BOOLEAN CumulativeMode
;
773 CONST CHAR16
*CustomCumulativeToken
;
774 PERF_CUM_DATA
*CustomCumulativeData
;
776 SHELL_STATUS ShellStatus
;
777 TIMER_INFO TimerInfo
;
785 CumulativeMode
= FALSE
;
786 CustomCumulativeData
= NULL
;
787 ShellStatus
= SHELL_SUCCESS
;
790 // initialize the shell lib (we must be in non-auto-init...)
792 Status
= ShellInitialize();
793 ASSERT_EFI_ERROR(Status
);
796 // Process Command Line arguments
798 Status
= ShellCommandLineParse (ParamList
, &ParamPackage
, NULL
, TRUE
);
799 if (EFI_ERROR(Status
)) {
800 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_INVALID_ARG
), mDpHiiHandle
);
801 return SHELL_INVALID_PARAMETER
;
807 VerboseMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-v");
808 SummaryMode
= (BOOLEAN
) (ShellCommandLineGetFlag (ParamPackage
, L
"-S") || ShellCommandLineGetFlag (ParamPackage
, L
"-s"));
809 AllMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-A");
810 RawMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-R");
811 ExcludeMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-x");
812 mShowId
= ShellCommandLineGetFlag (ParamPackage
, L
"-i");
813 CumulativeMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-c");
815 // Options with Values
816 CmdLineArg
= ShellCommandLineGetValue (ParamPackage
, L
"-n");
817 if (CmdLineArg
== NULL
) {
818 Number2Display
= DEFAULT_DISPLAYCOUNT
;
820 Number2Display
= StrDecimalToUintn(CmdLineArg
);
821 if (Number2Display
== 0) {
822 Number2Display
= MAXIMUM_DISPLAYCOUNT
;
826 CmdLineArg
= ShellCommandLineGetValue (ParamPackage
, L
"-t");
827 if (CmdLineArg
== NULL
) {
828 mInterestThreshold
= DEFAULT_THRESHOLD
; // 1ms := 1,000 us
830 mInterestThreshold
= StrDecimalToUint64(CmdLineArg
);
835 // DP dump performance data by parsing FPDT table in ACPI table.
836 // Folloing 3 steps are to get the measurement form the FPDT table.
840 //1. Get FPDT from ACPI table.
842 Status
= GetBootPerformanceTable ();
843 if (EFI_ERROR (Status
)) {
844 ShellStatus
= Status
;
849 //2. Cache the ModuleGuid and hanlde mapping table.
851 Status
= BuildCachedGuidHandleTable();
852 if (EFI_ERROR (Status
)) {
853 ShellStatus
= Status
;
858 //3. Build the measurement array form the FPDT records.
860 Status
= BuildMeasurementList ();
861 if (EFI_ERROR (Status
)) {
862 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
867 // Initialize the pre-defined cumulative data.
869 InitCumulativeData ();
872 // Initialize the Summary data.
877 // Init the custom cumulative data.
879 CustomCumulativeToken
= ShellCommandLineGetValue (ParamPackage
, L
"-c");
880 if (CustomCumulativeToken
!= NULL
) {
881 CustomCumulativeData
= AllocateZeroPool (sizeof (PERF_CUM_DATA
));
882 if (CustomCumulativeData
== NULL
) {
883 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
886 CustomCumulativeData
->MinDur
= PERF_MAXDUR
;
887 CustomCumulativeData
->MaxDur
= 0;
888 CustomCumulativeData
->Count
= 0;
889 CustomCumulativeData
->Duration
= 0;
890 NameSize
= StrLen (CustomCumulativeToken
) + 1;
891 CustomCumulativeData
->Name
= AllocateZeroPool (NameSize
);
892 if (CustomCumulativeData
->Name
== NULL
) {
893 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
896 UnicodeStrToAsciiStrS (CustomCumulativeToken
, CustomCumulativeData
->Name
, NameSize
);
900 // Timer specific processing
902 // Get the Performance counter characteristics:
903 // Freq = Frequency in Hz
904 // StartCount = Value loaded into the counter when it starts counting
905 // EndCount = Value counter counts to before it needs to be reset
907 Status
= EfiGetSystemConfigurationTable (&gPerformanceProtocolGuid
, (VOID
**) &PerformanceProperty
);
908 if (EFI_ERROR (Status
) || (PerformanceProperty
== NULL
)) {
909 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_PERF_PROPERTY_NOT_FOUND
), mDpHiiHandle
);
913 TimerInfo
.Frequency
= (UINT32
)DivU64x32 (PerformanceProperty
->Frequency
, 1000);
914 TimerInfo
.StartCount
= 0;
915 TimerInfo
.EndCount
= 0xFFFF;
916 TimerInfo
.CountUp
= TRUE
;
921 // print DP's build version
922 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_BUILD_REVISION
), mDpHiiHandle
, DP_MAJOR_VERSION
, DP_MINOR_VERSION
);
924 // print performance timer characteristics
925 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_KHZ
), mDpHiiHandle
, TimerInfo
.Frequency
);
927 if (VerboseMode
&& !RawMode
) {
928 StringPtr
= HiiGetString (mDpHiiHandle
,
929 (EFI_STRING_ID
) (TimerInfo
.CountUp
? STRING_TOKEN (STR_DP_UP
) : STRING_TOKEN (STR_DP_DOWN
)), NULL
);
930 ASSERT (StringPtr
!= NULL
);
931 // Print Timer count range and direction
932 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_TIMER_PROPERTIES
), mDpHiiHandle
,
934 TimerInfo
.StartCount
,
937 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_VERBOSE_THRESHOLD
), mDpHiiHandle
, mInterestThreshold
);
940 /****************************************************************************
941 **** Print Sections based on command line options
943 **** Option modes have the following priority:
944 **** v Verbose -- Valid in combination with any other options
945 **** t Threshold -- Modifies All, Raw, and Cooked output
946 **** Default is 0 for All and Raw mode
947 **** Default is DEFAULT_THRESHOLD for "Cooked" mode
948 **** n Number2Display Used by All and Raw mode. Otherwise ignored.
949 **** A All -- R and S options are ignored
950 **** R Raw -- S option is ignored
951 **** s Summary -- Modifies "Cooked" output only
952 **** Cooked (Default)
953 ****************************************************************************/
954 GatherStatistics (CustomCumulativeData
);
955 if (CumulativeMode
) {
956 ProcessCumulative (CustomCumulativeData
);
957 } else if (AllMode
) {
958 Status
= DumpAllTrace( Number2Display
, ExcludeMode
);
959 if (Status
== EFI_ABORTED
) {
960 ShellStatus
= SHELL_ABORTED
;
963 } else if (RawMode
) {
964 Status
= DumpRawTrace( Number2Display
, ExcludeMode
);
965 if (Status
== EFI_ABORTED
) {
966 ShellStatus
= SHELL_ABORTED
;
970 //------------- Begin Cooked Mode Processing
972 if ( ! SummaryMode
) {
973 Status
= ProcessHandles ( ExcludeMode
);
974 if (Status
== EFI_ABORTED
) {
975 ShellStatus
= SHELL_ABORTED
;
979 Status
= ProcessPeims ();
980 if (Status
== EFI_ABORTED
) {
981 ShellStatus
= SHELL_ABORTED
;
985 Status
= ProcessGlobal ();
986 if (Status
== EFI_ABORTED
) {
987 ShellStatus
= SHELL_ABORTED
;
991 ProcessCumulative (NULL
);
993 } //------------- End of Cooked Mode Processing
994 if ( VerboseMode
|| SummaryMode
) {
999 if (ParamPackage
!= NULL
) {
1000 ShellCommandLineFreeVarList (ParamPackage
);
1002 SHELL_FREE_NON_NULL (StringPtr
);
1003 if (CustomCumulativeData
!= NULL
) {
1004 SHELL_FREE_NON_NULL (CustomCumulativeData
->Name
);
1006 SHELL_FREE_NON_NULL (CustomCumulativeData
);
1008 SHELL_FREE_NON_NULL (mMeasurementList
);
1010 SHELL_FREE_NON_NULL (mCacheHandleGuidTable
);
1012 mMeasurementNum
= 0;
1013 mCachePairCount
= 0;
1019 Retrive HII package list from ImageHandle and publish to HII database.
1021 @param ImageHandle The image handle of the process.
1026 InitializeHiiPackage (
1027 EFI_HANDLE ImageHandle
1031 EFI_HII_PACKAGE_LIST_HEADER
*PackageList
;
1032 EFI_HANDLE HiiHandle
;
1035 // Retrieve HII package list from ImageHandle
1037 Status
= gBS
->OpenProtocol (
1039 &gEfiHiiPackageListProtocolGuid
,
1040 (VOID
**)&PackageList
,
1043 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1045 ASSERT_EFI_ERROR (Status
);
1046 if (EFI_ERROR (Status
)) {
1051 // Publish HII package list to HII Database.
1053 Status
= gHiiDatabase
->NewPackageList (
1059 ASSERT_EFI_ERROR (Status
);
1060 if (EFI_ERROR (Status
)) {