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 This function scan ACPI table in RSDT.
123 @param Rsdt ACPI RSDT
124 @param Signature ACPI table signature
137 EFI_ACPI_DESCRIPTION_HEADER
*Table
;
139 EntryCount
= (Rsdt
->Header
.Length
- sizeof (EFI_ACPI_DESCRIPTION_HEADER
)) / sizeof(UINT32
);
141 EntryPtr
= &Rsdt
->Entry
;
142 for (Index
= 0; Index
< EntryCount
; Index
++, EntryPtr
++) {
143 Table
= (EFI_ACPI_DESCRIPTION_HEADER
*)((UINTN
)(*EntryPtr
));
144 if (Table
->Signature
== Signature
) {
153 This function scan ACPI table in XSDT.
155 @param Xsdt ACPI XSDT
156 @param Signature ACPI table signature
170 EFI_ACPI_DESCRIPTION_HEADER
*Table
;
172 EntryCount
= (Xsdt
->Header
.Length
- sizeof (EFI_ACPI_DESCRIPTION_HEADER
)) / sizeof(UINT64
);
174 BasePtr
= (UINTN
)(&(Xsdt
->Entry
));
175 for (Index
= 0; Index
< EntryCount
; Index
++) {
176 CopyMem (&EntryPtr
, (VOID
*)(BasePtr
+ Index
* sizeof(UINT64
)), sizeof(UINT64
));
177 Table
= (EFI_ACPI_DESCRIPTION_HEADER
*)((UINTN
)(EntryPtr
));
178 if (Table
->Signature
== Signature
) {
187 This function scan ACPI table in RSDP.
189 @param Rsdp ACPI RSDP
190 @param Signature ACPI table signature
196 IN EFI_ACPI_5_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*Rsdp
,
200 EFI_ACPI_DESCRIPTION_HEADER
*AcpiTable
;
207 // Check ACPI2.0 table
209 Rsdt
= (RSDT_TABLE
*)(UINTN
)Rsdp
->RsdtAddress
;
211 if ((Rsdp
->Revision
>= 2) && (Rsdp
->XsdtAddress
< (UINT64
)(UINTN
)-1)) {
212 Xsdt
= (XSDT_TABLE
*)(UINTN
)Rsdp
->XsdtAddress
;
218 AcpiTable
= ScanTableInXSDT (Xsdt
, Signature
);
223 if ((AcpiTable
== NULL
) && (Rsdt
!= NULL
)) {
224 AcpiTable
= ScanTableInRSDT (Rsdt
, Signature
);
231 Get Boot performance table form Acpi table.
235 GetBootPerformanceTable (
240 FIRMWARE_PERFORMANCE_TABLE
*FirmwarePerformanceTable
;
244 Status
= EfiGetSystemConfigurationTable (
245 &gEfiAcpi20TableGuid
,
248 if (EFI_ERROR (Status
)) {
249 Status
= EfiGetSystemConfigurationTable (
250 &gEfiAcpi10TableGuid
,
254 if (EFI_ERROR(Status
) || AcpiTable
== NULL
) {
255 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_GET_ACPI_TABLE_FAIL
), mDpHiiHandle
);
259 FirmwarePerformanceTable
= FindAcpiPtr (
260 (EFI_ACPI_5_0_ROOT_SYSTEM_DESCRIPTION_POINTER
*)AcpiTable
,
261 EFI_ACPI_5_0_FIRMWARE_PERFORMANCE_DATA_TABLE_SIGNATURE
263 if (FirmwarePerformanceTable
== NULL
) {
264 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_GET_ACPI_FPDT_FAIL
), mDpHiiHandle
);
265 return EFI_NOT_FOUND
;
268 mBootPerformanceTable
= (UINT8
*) (UINTN
)FirmwarePerformanceTable
->BootPointerRecord
.BootPerformanceTablePointer
;
269 mBootPerformanceTableSize
= ((BOOT_PERFORMANCE_TABLE
*) mBootPerformanceTable
)->Header
.Length
;
275 Get Handle form Module Guid.
277 @param ModuleGuid Module Guid.
278 @param Handle The handle to be returned.
282 GetHandleFormModuleGuid (
283 IN EFI_GUID
*ModuleGuid
,
284 IN OUT EFI_HANDLE
*Handle
289 if (IsZeroGuid (ModuleGuid
)) {
293 // Try to get the Handle form the caached array.
295 for (Index
= 0; Index
< mCachePairCount
; Index
++) {
296 if (CompareGuid (ModuleGuid
, &mCacheHandleGuidTable
[Index
].ModuleGuid
)) {
297 *Handle
= mCacheHandleGuidTable
[Index
].Handle
;
301 if (Index
>= mCachePairCount
) {
307 Cache the GUID and handle mapping pairs. In order to save time for searching.
311 BuildCachedGuidHandleTable (
316 EFI_HANDLE
*HandleBuffer
;
319 EFI_LOADED_IMAGE_PROTOCOL
*LoadedImage
;
320 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
322 MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*FvFilePath
;
324 Status
= gBS
->LocateHandleBuffer (AllHandles
, NULL
, NULL
, &HandleCount
, &HandleBuffer
);
325 if (EFI_ERROR (Status
)) {
326 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_HANDLES_ERROR
), mDpHiiHandle
, Status
);
330 mCacheHandleGuidTable
= AllocateZeroPool (HandleCount
* sizeof (HANDLE_GUID_MAP
));
331 if (mCacheHandleGuidTable
== NULL
) {
332 return EFI_OUT_OF_RESOURCES
;
335 for (Index
= 0; Index
< HandleCount
; Index
++) {
337 // Try Handle as ImageHandle.
339 Status
= gBS
->HandleProtocol (
341 &gEfiLoadedImageProtocolGuid
,
342 (VOID
**) &LoadedImage
344 if (EFI_ERROR (Status
)) {
346 // Try Handle as Controller Handle
348 Status
= gBS
->OpenProtocol (
350 &gEfiDriverBindingProtocolGuid
,
351 (VOID
**) &DriverBinding
,
354 EFI_OPEN_PROTOCOL_GET_PROTOCOL
356 if (!EFI_ERROR (Status
)) {
358 // Get Image protocol from ImageHandle
360 Status
= gBS
->HandleProtocol (
361 DriverBinding
->ImageHandle
,
362 &gEfiLoadedImageProtocolGuid
,
363 (VOID
**) &LoadedImage
368 if (!EFI_ERROR (Status
) && LoadedImage
!= NULL
) {
370 // Get Module Guid from DevicePath.
372 if (LoadedImage
->FilePath
!= NULL
&&
373 LoadedImage
->FilePath
->Type
== MEDIA_DEVICE_PATH
&&
374 LoadedImage
->FilePath
->SubType
== MEDIA_PIWG_FW_FILE_DP
376 FvFilePath
= (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH
*) LoadedImage
->FilePath
;
377 TempGuid
= &FvFilePath
->FvFileName
;
379 mCacheHandleGuidTable
[mCachePairCount
].Handle
= HandleBuffer
[Index
];
380 CopyGuid (&mCacheHandleGuidTable
[mCachePairCount
].ModuleGuid
, TempGuid
);
385 if (HandleBuffer
!= NULL
) {
386 FreePool (HandleBuffer
);
393 Get Measurement form Fpdt records.
395 @param RecordHeader Pointer to the start record.
396 @param IsStart Is start record or End record.
397 @param Measurement Pointer to the measurement which need to be filled.
402 IN EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER
*RecordHeader
,
404 IN OUT MEASUREMENT_RECORD
*Measurement
408 EFI_HANDLE StartHandle
;
410 switch (RecordHeader
->Type
) {
411 case FPDT_GUID_EVENT_TYPE
:
412 ModuleGuid
= &(((FPDT_GUID_EVENT_RECORD
*)RecordHeader
)->Guid
);
413 Measurement
->Identifier
= ((UINT32
)((FPDT_GUID_EVENT_RECORD
*)RecordHeader
)->ProgressID
);
415 Measurement
->StartTimeStamp
= ((FPDT_GUID_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
417 Measurement
->EndTimeStamp
= ((FPDT_GUID_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
419 switch (Measurement
->Identifier
) {
420 case MODULE_START_ID
:
423 Measurement
->Token
= ALit_PEIM
;
424 Measurement
->Module
= ALit_PEIM
;
425 } else if (mDxePhase
) {
426 Measurement
->Token
= ALit_START_IMAGE
;
427 Measurement
->Module
= ALit_START_IMAGE
;
434 if (Measurement
->Token
!= NULL
&& AsciiStrCmp (Measurement
->Token
, ALit_PEIM
) == 0) {
435 Measurement
->Handle
= &(((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->Guid
);
437 GetHandleFormModuleGuid(ModuleGuid
, &StartHandle
);
438 Measurement
->Handle
= StartHandle
;
440 // When no perf entry to record the PEI and DXE phase,
441 // For start image, we need detect the PEIM and non PEIM here.
443 if (Measurement
->Token
== NULL
) {
444 if (StartHandle
== NULL
&& !IsZeroGuid (ModuleGuid
)) {
445 Measurement
->Token
= ALit_PEIM
;
446 Measurement
->Module
= ALit_PEIM
;
447 Measurement
->Handle
= ModuleGuid
;
449 Measurement
->Token
= ALit_START_IMAGE
;
450 Measurement
->Module
= ALit_START_IMAGE
;
456 case FPDT_DYNAMIC_STRING_EVENT_TYPE
:
457 ModuleGuid
= &(((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->Guid
);
458 Measurement
->Identifier
= ((UINT32
)((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->ProgressID
);
460 Measurement
->StartTimeStamp
= ((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
462 Measurement
->EndTimeStamp
= ((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
464 switch (Measurement
->Identifier
) {
465 case MODULE_START_ID
:
468 Measurement
->Token
= ALit_PEIM
;
469 } else if (mDxePhase
) {
470 Measurement
->Token
= ALit_START_IMAGE
;
474 case MODULE_LOADIMAGE_START_ID
:
475 case MODULE_LOADIMAGE_END_ID
:
476 Measurement
->Token
= ALit_LOAD_IMAGE
;
479 case MODULE_DB_START_ID
:
480 case MODULE_DB_END_ID
:
481 Measurement
->Token
= ALit_DB_START
;
484 case MODULE_DB_SUPPORT_START_ID
:
485 case MODULE_DB_SUPPORT_END_ID
:
486 Measurement
->Token
= ALit_DB_SUPPORT
;
489 case MODULE_DB_STOP_START_ID
:
490 case MODULE_DB_STOP_END_ID
:
491 Measurement
->Token
= ALit_DB_STOP
;
495 Measurement
->Token
= ((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->String
;
499 Measurement
->Module
= ((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->String
;
501 if (Measurement
->Token
!= NULL
&& AsciiStrCmp (Measurement
->Token
, ALit_PEIM
) == 0) {
502 Measurement
->Handle
= &(((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)RecordHeader
)->Guid
);
504 GetHandleFormModuleGuid(ModuleGuid
, &StartHandle
);
505 Measurement
->Handle
= StartHandle
;
507 // When no perf entry to record the PEI and DXE phase,
508 // For start image, we need detect the PEIM and non PEIM here.
510 if (Measurement
->Token
== NULL
&& (Measurement
->Identifier
== MODULE_START_ID
|| Measurement
->Identifier
== MODULE_END_ID
)) {
511 if (StartHandle
== NULL
&& !IsZeroGuid (ModuleGuid
)) {
512 Measurement
->Token
= ALit_PEIM
;
513 Measurement
->Handle
= ModuleGuid
;
515 Measurement
->Token
= ALit_START_IMAGE
;
521 case FPDT_GUID_QWORD_EVENT_TYPE
:
522 ModuleGuid
= &(((FPDT_GUID_QWORD_EVENT_RECORD
*)RecordHeader
)->Guid
);
523 Measurement
->Identifier
= ((UINT32
)((FPDT_GUID_QWORD_EVENT_RECORD
*)RecordHeader
)->ProgressID
);
525 Measurement
->StartTimeStamp
= ((FPDT_GUID_QWORD_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
527 Measurement
->EndTimeStamp
= ((FPDT_GUID_QWORD_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
529 switch (Measurement
->Identifier
) {
530 case MODULE_DB_START_ID
:
531 Measurement
->Token
= ALit_DB_START
;
532 Measurement
->Module
= ALit_DB_START
;
535 case MODULE_DB_SUPPORT_START_ID
:
536 case MODULE_DB_SUPPORT_END_ID
:
537 Measurement
->Token
= ALit_DB_SUPPORT
;
538 Measurement
->Module
= ALit_DB_SUPPORT
;
541 case MODULE_DB_STOP_START_ID
:
542 case MODULE_DB_STOP_END_ID
:
543 Measurement
->Token
= ALit_DB_STOP
;
544 Measurement
->Module
= ALit_DB_STOP
;
547 case MODULE_LOADIMAGE_START_ID
:
548 case MODULE_LOADIMAGE_END_ID
:
549 Measurement
->Token
= ALit_LOAD_IMAGE
;
550 Measurement
->Module
= ALit_LOAD_IMAGE
;
556 GetHandleFormModuleGuid(ModuleGuid
, &StartHandle
);
557 Measurement
->Handle
= StartHandle
;
560 case FPDT_GUID_QWORD_STRING_EVENT_TYPE
:
561 ModuleGuid
= &(((FPDT_GUID_QWORD_STRING_EVENT_RECORD
*)RecordHeader
)->Guid
);
562 Measurement
->Identifier
= ((UINT32
)((FPDT_GUID_QWORD_STRING_EVENT_RECORD
*)RecordHeader
)->ProgressID
);
564 Measurement
->StartTimeStamp
= ((FPDT_GUID_QWORD_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
566 Measurement
->EndTimeStamp
= ((FPDT_GUID_QWORD_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
569 // Currently only "DB:Start:" end record with FPDT_GUID_QWORD_STRING_EVENT_TYPE.
571 switch (Measurement
->Identifier
) {
572 case MODULE_DB_END_ID
:
573 Measurement
->Token
= ALit_DB_START
;
574 Measurement
->Module
= ALit_DB_START
;
579 GetHandleFormModuleGuid(ModuleGuid
, &StartHandle
);
580 Measurement
->Handle
= StartHandle
;
583 case FPDT_DUAL_GUID_STRING_EVENT_TYPE
:
584 ModuleGuid
= &(((FPDT_DUAL_GUID_STRING_EVENT_RECORD
*)RecordHeader
)->Guid1
);
585 Measurement
->Identifier
= ((UINT32
)((FPDT_DUAL_GUID_STRING_EVENT_RECORD
*)RecordHeader
)->ProgressID
);
587 Measurement
->StartTimeStamp
= ((FPDT_DUAL_GUID_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
589 Measurement
->EndTimeStamp
= ((FPDT_DUAL_GUID_STRING_EVENT_RECORD
*)RecordHeader
)->Timestamp
;
591 Measurement
->Token
= ((FPDT_DUAL_GUID_STRING_EVENT_RECORD
*)RecordHeader
)->String
;
592 Measurement
->Module
= ((FPDT_DUAL_GUID_STRING_EVENT_RECORD
*)RecordHeader
)->String
;
593 GetHandleFormModuleGuid(ModuleGuid
, &StartHandle
);
594 Measurement
->Handle
= StartHandle
;
603 Search the start measurement in the mMeasurementList for the end measurement.
605 @param EndMeasureMent Measurement for end record.
610 IN MEASUREMENT_RECORD
*EndMeasureMent
615 for (Index
= mMeasurementNum
- 1; Index
>= 0; Index
--) {
616 if (AsciiStrCmp (EndMeasureMent
->Token
, ALit_PEIM
) == 0) {
617 if (mMeasurementList
[Index
].EndTimeStamp
== 0 && EndMeasureMent
->Handle
!= NULL
&& mMeasurementList
[Index
].Handle
!= NULL
&&
618 CompareGuid(mMeasurementList
[Index
].Handle
, EndMeasureMent
->Handle
) &&
619 (AsciiStrCmp (mMeasurementList
[Index
].Token
, EndMeasureMent
->Token
) == 0) &&
620 (AsciiStrCmp (mMeasurementList
[Index
].Module
, EndMeasureMent
->Module
) == 0)) {
621 mMeasurementList
[Index
].EndTimeStamp
= EndMeasureMent
->EndTimeStamp
;
624 } else if (EndMeasureMent
->Identifier
== PERF_CROSSMODULE_END_ID
) {
625 if (mMeasurementList
[Index
].EndTimeStamp
== 0 &&
626 (AsciiStrCmp (mMeasurementList
[Index
].Token
, EndMeasureMent
->Token
) == 0) &&
627 (AsciiStrCmp (mMeasurementList
[Index
].Module
, EndMeasureMent
->Module
) == 0) &&
628 mMeasurementList
[Index
].Identifier
== PERF_CROSSMODULE_START_ID
) {
629 mMeasurementList
[Index
].EndTimeStamp
= EndMeasureMent
->EndTimeStamp
;
633 if (mMeasurementList
[Index
].EndTimeStamp
== 0 && mMeasurementList
[Index
].Handle
== EndMeasureMent
->Handle
&&
634 (AsciiStrCmp (mMeasurementList
[Index
].Token
, EndMeasureMent
->Token
) == 0) &&
635 (AsciiStrCmp (mMeasurementList
[Index
].Module
, EndMeasureMent
->Module
) == 0)) {
636 mMeasurementList
[Index
].EndTimeStamp
= EndMeasureMent
->EndTimeStamp
;
644 Generate the measure record array.
648 BuildMeasurementList (
651 EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER
*RecordHeader
;
652 UINT8
*PerformanceTablePtr
;
653 UINT16 StartProgressId
;
655 UINT8
*StartRecordEvent
;
656 MEASUREMENT_RECORD MeasureMent
;
658 mMeasurementList
= AllocateZeroPool (mBootPerformanceTableSize
);
659 if (mMeasurementList
== NULL
) {
660 return EFI_OUT_OF_RESOURCES
;
663 TableLength
= sizeof (BOOT_PERFORMANCE_TABLE
);
664 PerformanceTablePtr
= (mBootPerformanceTable
+ TableLength
);
666 while (TableLength
< mBootPerformanceTableSize
) {
667 RecordHeader
= (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER
*) PerformanceTablePtr
;
668 StartRecordEvent
= (UINT8
*)RecordHeader
;
669 StartProgressId
= ((FPDT_GUID_EVENT_RECORD
*)StartRecordEvent
)->ProgressID
;
672 // 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.
673 // If the record is the start record, fill the info to the measurement in the mMeasurementList.
674 // If the record is the end record, find the related start measurement in the mMeasurementList and fill the EndTimeStamp.
676 if (StartProgressId
== 0) {
677 GetMeasurementInfo (RecordHeader
, FALSE
, &(mMeasurementList
[mMeasurementNum
]));
679 } else if (((StartProgressId
>= PERF_EVENTSIGNAL_START_ID
&& ((StartProgressId
& 0x000F) == 0)) ||
680 (StartProgressId
< PERF_EVENTSIGNAL_START_ID
&& ((StartProgressId
& 0x0001) != 0)))) {
682 // Since PEIM and StartImage has same Type and ID when PCD PcdEdkiiFpdtStringRecordEnableOnly = FALSE
683 // So we need to identify these two kinds of record through different phase.
685 if(StartProgressId
== PERF_CROSSMODULE_START_ID
){
686 if (AsciiStrCmp (((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)StartRecordEvent
)->String
, ALit_PEI
) == 0) {
688 } else if (AsciiStrCmp (((FPDT_DYNAMIC_STRING_EVENT_RECORD
*)StartRecordEvent
)->String
, ALit_DXE
) == 0) {
693 // Get measurement info form the start record to the mMeasurementList.
694 GetMeasurementInfo (RecordHeader
, TRUE
, &(mMeasurementList
[mMeasurementNum
]));
697 ZeroMem(&MeasureMent
, sizeof(MEASUREMENT_RECORD
));
698 GetMeasurementInfo (RecordHeader
, FALSE
, &MeasureMent
);
699 SearchMeasurement (&MeasureMent
);
701 TableLength
+= RecordHeader
->Length
;
702 PerformanceTablePtr
+= RecordHeader
->Length
;
708 Initialize the cumulative data.
718 for (Index
= 0; Index
< NumCum
; ++Index
) {
719 CumData
[Index
].Count
= 0;
720 CumData
[Index
].MinDur
= PERF_MAXDUR
;
721 CumData
[Index
].MaxDur
= 0;
722 CumData
[Index
].Duration
= 0;
727 Initialize the Summary data.
735 SummaryData
.NumTrace
= 0;
736 SummaryData
.NumIncomplete
= 0;
737 SummaryData
.NumSummary
= 0;
738 SummaryData
.NumHandles
= 0;
739 SummaryData
.NumPEIMs
= 0;
740 SummaryData
.NumGlobal
= 0;
744 Dump performance data.
746 @param[in] ImageHandle The image handle.
747 @param[in] SystemTable The system table.
749 @retval SHELL_SUCCESS Command completed successfully.
750 @retval SHELL_INVALID_PARAMETER Command usage error.
751 @retval SHELL_ABORTED The user aborts the operation.
752 @retval value Unknown error.
756 IN EFI_HANDLE ImageHandle
,
757 IN EFI_SYSTEM_TABLE
*SystemTable
760 LIST_ENTRY
*ParamPackage
;
761 CONST CHAR16
*CmdLineArg
;
764 PERFORMANCE_PROPERTY
*PerformanceProperty
;
765 UINTN Number2Display
;
767 EFI_STRING StringPtr
;
773 BOOLEAN CumulativeMode
;
774 CONST CHAR16
*CustomCumulativeToken
;
775 PERF_CUM_DATA
*CustomCumulativeData
;
777 SHELL_STATUS ShellStatus
;
778 TIMER_INFO TimerInfo
;
787 CumulativeMode
= FALSE
;
788 CustomCumulativeData
= NULL
;
789 ShellStatus
= SHELL_SUCCESS
;
792 // initialize the shell lib (we must be in non-auto-init...)
794 Status
= ShellInitialize();
795 ASSERT_EFI_ERROR(Status
);
798 // Process Command Line arguments
800 Status
= ShellCommandLineParse (ParamList
, &ParamPackage
, NULL
, TRUE
);
801 if (EFI_ERROR(Status
)) {
802 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_INVALID_ARG
), mDpHiiHandle
);
803 return SHELL_INVALID_PARAMETER
;
804 } else if (ShellCommandLineGetCount(ParamPackage
) > 1){
805 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_TOO_MANY
), mDpHiiHandle
);
806 return SHELL_INVALID_PARAMETER
;
812 VerboseMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-v");
813 SummaryMode
= (BOOLEAN
) (ShellCommandLineGetFlag (ParamPackage
, L
"-S") || ShellCommandLineGetFlag (ParamPackage
, L
"-s"));
814 AllMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-A");
815 RawMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-R");
816 ExcludeMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-x");
817 mShowId
= ShellCommandLineGetFlag (ParamPackage
, L
"-i");
818 CumulativeMode
= ShellCommandLineGetFlag (ParamPackage
, L
"-c");
820 if (AllMode
&& RawMode
) {
821 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_CONFLICT_ARG
), mDpHiiHandle
, L
"-A", L
"-R");
822 return SHELL_INVALID_PARAMETER
;
825 // Options with Values
826 if (ShellCommandLineGetFlag (ParamPackage
, L
"-n")) {
827 CmdLineArg
= ShellCommandLineGetValue (ParamPackage
, L
"-n");
828 if (CmdLineArg
== NULL
) {
829 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_TOO_FEW
), mDpHiiHandle
);
830 return SHELL_INVALID_PARAMETER
;
832 if (!(RawMode
|| AllMode
)) {
833 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_NO_RAW_ALL
), mDpHiiHandle
);
834 return SHELL_INVALID_PARAMETER
;
836 Status
= ShellConvertStringToUint64(CmdLineArg
, &Intermediate
, FALSE
, TRUE
);
837 if (EFI_ERROR (Status
)) {
838 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_INVALID_NUM_ARG
), mDpHiiHandle
, L
"-n");
839 return SHELL_INVALID_PARAMETER
;
841 Number2Display
= (UINTN
)Intermediate
;
842 if (Number2Display
== 0 || Number2Display
> MAXIMUM_DISPLAYCOUNT
) {
843 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_INVALID_RANGE
), mDpHiiHandle
, L
"-n", 0, MAXIMUM_DISPLAYCOUNT
);
844 return SHELL_INVALID_PARAMETER
;
849 Number2Display
= DEFAULT_DISPLAYCOUNT
;
852 if (ShellCommandLineGetFlag (ParamPackage
, L
"-t")) {
853 CmdLineArg
= ShellCommandLineGetValue (ParamPackage
, L
"-t");
854 if (CmdLineArg
== NULL
) {
855 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_TOO_FEW
), mDpHiiHandle
);
856 return SHELL_INVALID_PARAMETER
;
858 Status
= ShellConvertStringToUint64(CmdLineArg
, &Intermediate
, FALSE
, TRUE
);
859 if (EFI_ERROR (Status
)) {
860 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_INVALID_NUM_ARG
), mDpHiiHandle
, L
"-t");
861 return SHELL_INVALID_PARAMETER
;
863 mInterestThreshold
= Intermediate
;
867 mInterestThreshold
= DEFAULT_THRESHOLD
; // 1ms := 1,000 us
870 if (ShellCommandLineGetFlag (ParamPackage
, L
"-c")) {
871 CustomCumulativeToken
= ShellCommandLineGetValue (ParamPackage
, L
"-c");
872 if (CustomCumulativeToken
== NULL
) {
873 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_TOO_FEW
), mDpHiiHandle
);
874 return SHELL_INVALID_PARAMETER
;
876 CustomCumulativeData
= AllocateZeroPool (sizeof (PERF_CUM_DATA
));
877 if (CustomCumulativeData
== NULL
) {
878 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
881 CustomCumulativeData
->MinDur
= PERF_MAXDUR
;
882 CustomCumulativeData
->MaxDur
= 0;
883 CustomCumulativeData
->Count
= 0;
884 CustomCumulativeData
->Duration
= 0;
885 NameSize
= StrLen (CustomCumulativeToken
) + 1;
886 CustomCumulativeData
->Name
= AllocateZeroPool (NameSize
);
887 if (CustomCumulativeData
->Name
== NULL
) {
888 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
891 UnicodeStrToAsciiStrS (CustomCumulativeToken
, CustomCumulativeData
->Name
, NameSize
);
896 // DP dump performance data by parsing FPDT table in ACPI table.
897 // Folloing 3 steps are to get the measurement form the FPDT table.
901 //1. Get FPDT from ACPI table.
903 Status
= GetBootPerformanceTable ();
904 if (EFI_ERROR (Status
)) {
905 ShellStatus
= Status
;
910 //2. Cache the ModuleGuid and hanlde mapping table.
912 Status
= BuildCachedGuidHandleTable();
913 if (EFI_ERROR (Status
)) {
914 ShellStatus
= Status
;
919 //3. Build the measurement array form the FPDT records.
921 Status
= BuildMeasurementList ();
922 if (EFI_ERROR (Status
)) {
923 ShellStatus
= SHELL_OUT_OF_RESOURCES
;
928 // Initialize the pre-defined cumulative data.
930 InitCumulativeData ();
933 // Initialize the Summary data.
938 // Timer specific processing
940 // Get the Performance counter characteristics:
941 // Freq = Frequency in Hz
942 // StartCount = Value loaded into the counter when it starts counting
943 // EndCount = Value counter counts to before it needs to be reset
945 Status
= EfiGetSystemConfigurationTable (&gPerformanceProtocolGuid
, (VOID
**) &PerformanceProperty
);
946 if (EFI_ERROR (Status
) || (PerformanceProperty
== NULL
)) {
947 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_PERF_PROPERTY_NOT_FOUND
), mDpHiiHandle
);
951 TimerInfo
.Frequency
= (UINT32
)DivU64x32 (PerformanceProperty
->Frequency
, 1000);
952 TimerInfo
.StartCount
= 0;
953 TimerInfo
.EndCount
= 0xFFFF;
954 TimerInfo
.CountUp
= TRUE
;
959 // print DP's build version
960 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_BUILD_REVISION
), mDpHiiHandle
, DP_MAJOR_VERSION
, DP_MINOR_VERSION
);
962 // print performance timer characteristics
963 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_KHZ
), mDpHiiHandle
, TimerInfo
.Frequency
);
965 if (VerboseMode
&& !RawMode
) {
966 StringPtr
= HiiGetString (mDpHiiHandle
,
967 (EFI_STRING_ID
) (TimerInfo
.CountUp
? STRING_TOKEN (STR_DP_UP
) : STRING_TOKEN (STR_DP_DOWN
)), NULL
);
968 ASSERT (StringPtr
!= NULL
);
969 // Print Timer count range and direction
970 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_TIMER_PROPERTIES
), mDpHiiHandle
,
972 TimerInfo
.StartCount
,
975 ShellPrintHiiEx (-1, -1, NULL
, STRING_TOKEN (STR_DP_VERBOSE_THRESHOLD
), mDpHiiHandle
, mInterestThreshold
);
978 /****************************************************************************
979 **** Print Sections based on command line options
981 **** Option modes have the following priority:
982 **** v Verbose -- Valid in combination with any other options
983 **** t Threshold -- Modifies All, Raw, and Cooked output
984 **** Default is 0 for All and Raw mode
985 **** Default is DEFAULT_THRESHOLD for "Cooked" mode
986 **** n Number2Display Used by All and Raw mode. Otherwise ignored.
987 **** A All -- R and S options are ignored
988 **** R Raw -- S option is ignored
989 **** s Summary -- Modifies "Cooked" output only
990 **** Cooked (Default)
991 ****************************************************************************/
992 GatherStatistics (CustomCumulativeData
);
993 if (CumulativeMode
) {
994 ProcessCumulative (CustomCumulativeData
);
995 } else if (AllMode
) {
996 Status
= DumpAllTrace( Number2Display
, ExcludeMode
);
997 if (Status
== EFI_ABORTED
) {
998 ShellStatus
= SHELL_ABORTED
;
1001 } else if (RawMode
) {
1002 Status
= DumpRawTrace( Number2Display
, ExcludeMode
);
1003 if (Status
== EFI_ABORTED
) {
1004 ShellStatus
= SHELL_ABORTED
;
1008 //------------- Begin Cooked Mode Processing
1010 if ( ! SummaryMode
) {
1011 Status
= ProcessHandles ( ExcludeMode
);
1012 if (Status
== EFI_ABORTED
) {
1013 ShellStatus
= SHELL_ABORTED
;
1017 Status
= ProcessPeims ();
1018 if (Status
== EFI_ABORTED
) {
1019 ShellStatus
= SHELL_ABORTED
;
1023 Status
= ProcessGlobal ();
1024 if (Status
== EFI_ABORTED
) {
1025 ShellStatus
= SHELL_ABORTED
;
1029 ProcessCumulative (NULL
);
1031 } //------------- End of Cooked Mode Processing
1032 if ( VerboseMode
|| SummaryMode
) {
1037 if (ParamPackage
!= NULL
) {
1038 ShellCommandLineFreeVarList (ParamPackage
);
1040 SHELL_FREE_NON_NULL (StringPtr
);
1041 if (CustomCumulativeData
!= NULL
) {
1042 SHELL_FREE_NON_NULL (CustomCumulativeData
->Name
);
1044 SHELL_FREE_NON_NULL (CustomCumulativeData
);
1046 SHELL_FREE_NON_NULL (mMeasurementList
);
1048 SHELL_FREE_NON_NULL (mCacheHandleGuidTable
);
1050 mMeasurementNum
= 0;
1051 mCachePairCount
= 0;
1057 Retrive HII package list from ImageHandle and publish to HII database.
1059 @param ImageHandle The image handle of the process.
1064 InitializeHiiPackage (
1065 EFI_HANDLE ImageHandle
1069 EFI_HII_PACKAGE_LIST_HEADER
*PackageList
;
1070 EFI_HANDLE HiiHandle
;
1073 // Retrieve HII package list from ImageHandle
1075 Status
= gBS
->OpenProtocol (
1077 &gEfiHiiPackageListProtocolGuid
,
1078 (VOID
**)&PackageList
,
1081 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1083 ASSERT_EFI_ERROR (Status
);
1084 if (EFI_ERROR (Status
)) {
1089 // Publish HII package list to HII Database.
1091 Status
= gHiiDatabase
->NewPackageList (
1097 ASSERT_EFI_ERROR (Status
);
1098 if (EFI_ERROR (Status
)) {