summaryrefslogtreecommitdiff
path: root/ShellPkg/DynamicCommand/DpDynamicCommand/Dp.c
diff options
context:
space:
mode:
Diffstat (limited to 'ShellPkg/DynamicCommand/DpDynamicCommand/Dp.c')
-rw-r--r--ShellPkg/DynamicCommand/DpDynamicCommand/Dp.c2062
1 files changed, 1031 insertions, 1031 deletions
diff --git a/ShellPkg/DynamicCommand/DpDynamicCommand/Dp.c b/ShellPkg/DynamicCommand/DpDynamicCommand/Dp.c
index 98c84d2ef9..c1d194ab03 100644
--- a/ShellPkg/DynamicCommand/DpDynamicCommand/Dp.c
+++ b/ShellPkg/DynamicCommand/DpDynamicCommand/Dp.c
@@ -1,1031 +1,1031 @@
-/** @file
- Shell command for Displaying Performance Metrics.
-
- The Dp command reads performance data and presents it in several
- different formats depending upon the needs of the user. Both
- Trace and Measured Profiling information is processed and presented.
-
- Dp uses the "PerformanceLib" to read the measurement records.
- The "TimerLib" provides information about the timer, such as frequency,
- beginning, and ending counter values.
- Measurement records contain identifying information (Handle, Token, Module)
- and start and end time values.
- Dp uses this information to group records in different ways. It also uses
- timer information to calculate elapsed time for each measurement.
-
- Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
- (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-**/
-
-#include "Dp.h"
-#include "Literals.h"
-#include "DpInternal.h"
-
-#pragma pack(1)
-
-typedef struct {
- EFI_ACPI_DESCRIPTION_HEADER Header;
- UINT32 Entry;
-} RSDT_TABLE;
-
-typedef struct {
- EFI_ACPI_DESCRIPTION_HEADER Header;
- UINT64 Entry;
-} XSDT_TABLE;
-
-#pragma pack()
-
-EFI_HII_HANDLE mDpHiiHandle;
-
-typedef struct {
- EFI_HANDLE Handle;
- EFI_GUID ModuleGuid;
-} HANDLE_GUID_MAP;
-
-HANDLE_GUID_MAP *mCacheHandleGuidTable;
-UINTN mCachePairCount = 0;
-
-//
-/// Module-Global Variables
-///@{
-CHAR16 mGaugeString[DP_GAUGE_STRING_LENGTH + 1];
-CHAR16 mUnicodeToken[DXE_PERFORMANCE_STRING_SIZE];
-UINT64 mInterestThreshold;
-BOOLEAN mShowId = FALSE;
-UINT8 *mBootPerformanceTable;
-UINTN mBootPerformanceTableSize;
-BOOLEAN mPeiPhase = FALSE;
-BOOLEAN mDxePhase = FALSE;
-UINT64 mResetEnd = 0;
-
-PERF_SUMMARY_DATA SummaryData = { 0 }; ///< Create the SummaryData structure and init. to ZERO.
-MEASUREMENT_RECORD *mMeasurementList = NULL;
-UINTN mMeasurementNum = 0;
-
-/// Items for which to gather cumulative statistics.
-PERF_CUM_DATA CumData[] = {
- PERF_INIT_CUM_DATA (LOAD_IMAGE_TOK),
- PERF_INIT_CUM_DATA (START_IMAGE_TOK),
- PERF_INIT_CUM_DATA (DRIVERBINDING_START_TOK),
- PERF_INIT_CUM_DATA (DRIVERBINDING_SUPPORT_TOK),
- PERF_INIT_CUM_DATA (DRIVERBINDING_STOP_TOK)
-};
-
-/// Number of items for which we are gathering cumulative statistics.
-UINT32 const NumCum = sizeof (CumData) / sizeof (PERF_CUM_DATA);
-
-STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
- { L"-v", TypeFlag }, // -v Verbose Mode
- { L"-A", TypeFlag }, // -A All, Cooked
- { L"-R", TypeFlag }, // -R RAW All
- { L"-s", TypeFlag }, // -s Summary
- { L"-x", TypeFlag }, // -x eXclude Cumulative Items
- { L"-i", TypeFlag }, // -i Display Identifier
- { L"-c", TypeValue }, // -c Display cumulative data.
- { L"-n", TypeValue }, // -n # Number of records to display for A and R
- { L"-t", TypeValue }, // -t # Threshold of interest
- { NULL, TypeMax }
-};
-
-///@}
-
-/**
- Display the trailing Verbose information.
-**/
-VOID
-DumpStatistics (
- void
- )
-{
- EFI_STRING StringPtr;
- EFI_STRING StringPtrUnknown;
-
- StringPtr = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_STATISTICS), NULL);
- StringPtrUnknown = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_DP_SECTION_HEADER),
- mDpHiiHandle,
- (StringPtr == NULL) ? StringPtrUnknown : StringPtr
- );
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMTRACE), mDpHiiHandle, SummaryData.NumTrace);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMINCOMPLETE), mDpHiiHandle, SummaryData.NumIncomplete);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMPHASES), mDpHiiHandle, SummaryData.NumSummary);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMHANDLES), mDpHiiHandle, SummaryData.NumHandles, SummaryData.NumTrace - SummaryData.NumHandles);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMPEIMS), mDpHiiHandle, SummaryData.NumPEIMs);
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMGLOBALS), mDpHiiHandle, SummaryData.NumGlobal);
- SHELL_FREE_NON_NULL (StringPtr);
- SHELL_FREE_NON_NULL (StringPtrUnknown);
-}
-
-/**
- Get Boot performance table form Acpi table.
-
-**/
-EFI_STATUS
-GetBootPerformanceTable (
- )
-{
- EFI_STATUS Status;
- FIRMWARE_PERFORMANCE_TABLE *FirmwarePerformanceTable;
-
- FirmwarePerformanceTable = (FIRMWARE_PERFORMANCE_TABLE *)EfiLocateFirstAcpiTable (
- EFI_ACPI_5_0_FIRMWARE_PERFORMANCE_DATA_TABLE_SIGNATURE
- );
- if (FirmwarePerformanceTable == NULL) {
- Status = EfiGetSystemConfigurationTable (&gEdkiiFpdtExtendedFirmwarePerformanceGuid, (VOID **)&mBootPerformanceTable);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GET_ACPI_FPDT_FAIL), mDpHiiHandle);
- return EFI_NOT_FOUND;
- }
- } else {
- mBootPerformanceTable = (UINT8 *)(UINTN)FirmwarePerformanceTable->BootPointerRecord.BootPerformanceTablePointer;
- }
-
- mBootPerformanceTableSize = ((BOOT_PERFORMANCE_TABLE *)mBootPerformanceTable)->Header.Length;
-
- return EFI_SUCCESS;
-}
-
-/**
- Get Handle form Module Guid.
-
- @param ModuleGuid Module Guid.
- @param Handle The handle to be returned.
-
-**/
-VOID
-GetHandleFormModuleGuid (
- IN EFI_GUID *ModuleGuid,
- IN OUT EFI_HANDLE *Handle
- )
-{
- UINTN Index;
-
- if (IsZeroGuid (ModuleGuid)) {
- *Handle = NULL;
- }
-
- //
- // Try to get the Handle from the cached array.
- //
- for (Index = 0; Index < mCachePairCount; Index++) {
- if (CompareGuid (ModuleGuid, &mCacheHandleGuidTable[Index].ModuleGuid)) {
- *Handle = mCacheHandleGuidTable[Index].Handle;
- break;
- }
- }
-
- if (Index >= mCachePairCount) {
- *Handle = NULL;
- }
-}
-
-/**
-Cache the GUID and handle mapping pairs. In order to save time for searching.
-
-**/
-EFI_STATUS
-BuildCachedGuidHandleTable (
- VOID
- )
-{
- EFI_STATUS Status;
- EFI_HANDLE *HandleBuffer;
- UINTN HandleCount;
- UINTN Index;
- EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
- EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
- EFI_GUID *TempGuid;
- MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFilePath;
-
- Status = gBS->LocateHandleBuffer (AllHandles, NULL, NULL, &HandleCount, &HandleBuffer);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLES_ERROR), mDpHiiHandle, Status);
- return Status;
- }
-
- mCacheHandleGuidTable = AllocateZeroPool (HandleCount * sizeof (HANDLE_GUID_MAP));
- if (mCacheHandleGuidTable == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- for (Index = 0; Index < HandleCount; Index++) {
- //
- // Try Handle as ImageHandle.
- //
- Status = gBS->HandleProtocol (
- HandleBuffer[Index],
- &gEfiLoadedImageProtocolGuid,
- (VOID **)&LoadedImage
- );
- if (EFI_ERROR (Status)) {
- //
- // Try Handle as Controller Handle
- //
- Status = gBS->OpenProtocol (
- HandleBuffer[Index],
- &gEfiDriverBindingProtocolGuid,
- (VOID **)&DriverBinding,
- NULL,
- NULL,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- if (!EFI_ERROR (Status)) {
- //
- // Get Image protocol from ImageHandle
- //
- Status = gBS->HandleProtocol (
- DriverBinding->ImageHandle,
- &gEfiLoadedImageProtocolGuid,
- (VOID **)&LoadedImage
- );
- }
- }
-
- if (!EFI_ERROR (Status) && (LoadedImage != NULL)) {
- //
- // Get Module Guid from DevicePath.
- //
- if ((LoadedImage->FilePath != NULL) &&
- (LoadedImage->FilePath->Type == MEDIA_DEVICE_PATH) &&
- (LoadedImage->FilePath->SubType == MEDIA_PIWG_FW_FILE_DP)
- )
- {
- FvFilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)LoadedImage->FilePath;
- TempGuid = &FvFilePath->FvFileName;
-
- mCacheHandleGuidTable[mCachePairCount].Handle = HandleBuffer[Index];
- CopyGuid (&mCacheHandleGuidTable[mCachePairCount].ModuleGuid, TempGuid);
- mCachePairCount++;
- }
- }
- }
-
- if (HandleBuffer != NULL) {
- FreePool (HandleBuffer);
- HandleBuffer = NULL;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Get Measurement form Fpdt records.
-
- @param RecordHeader Pointer to the start record.
- @param IsStart Is start record or End record.
- @param Measurement Pointer to the measurement which need to be filled.
-
-**/
-VOID
-GetMeasurementInfo (
- IN EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *RecordHeader,
- IN BOOLEAN IsStart,
- IN OUT MEASUREMENT_RECORD *Measurement
- )
-{
- VOID *ModuleGuid;
- EFI_HANDLE StartHandle;
-
- switch (RecordHeader->Type) {
- case FPDT_GUID_EVENT_TYPE:
- ModuleGuid = &(((FPDT_GUID_EVENT_RECORD *)RecordHeader)->Guid);
- Measurement->Identifier = ((UINT32)((FPDT_GUID_EVENT_RECORD *)RecordHeader)->ProgressID);
- if (IsStart) {
- Measurement->StartTimeStamp = ((FPDT_GUID_EVENT_RECORD *)RecordHeader)->Timestamp;
- } else {
- Measurement->EndTimeStamp = ((FPDT_GUID_EVENT_RECORD *)RecordHeader)->Timestamp;
- }
-
- switch (Measurement->Identifier) {
- case MODULE_START_ID:
- case MODULE_END_ID:
- if (mPeiPhase) {
- Measurement->Token = ALit_PEIM;
- Measurement->Module = ALit_PEIM;
- } else if (mDxePhase) {
- Measurement->Token = ALit_START_IMAGE;
- Measurement->Module = ALit_START_IMAGE;
- }
-
- break;
- default:
- ASSERT (FALSE);
- }
-
- if ((Measurement->Token != NULL) && (AsciiStrCmp (Measurement->Token, ALit_PEIM) == 0)) {
- Measurement->Handle = &(((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Guid);
- } else {
- GetHandleFormModuleGuid (ModuleGuid, &StartHandle);
- Measurement->Handle = StartHandle;
- //
- // When no perf entry to record the PEI and DXE phase,
- // For start image, we need detect the PEIM and non PEIM here.
- //
- if (Measurement->Token == NULL) {
- if ((StartHandle == NULL) && !IsZeroGuid (ModuleGuid)) {
- Measurement->Token = ALit_PEIM;
- Measurement->Module = ALit_PEIM;
- Measurement->Handle = ModuleGuid;
- } else {
- Measurement->Token = ALit_START_IMAGE;
- Measurement->Module = ALit_START_IMAGE;
- }
- }
- }
-
- break;
-
- case FPDT_DYNAMIC_STRING_EVENT_TYPE:
- ModuleGuid = &(((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Guid);
- Measurement->Identifier = ((UINT32)((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->ProgressID);
- if (IsStart) {
- Measurement->StartTimeStamp = ((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;
- } else {
- Measurement->EndTimeStamp = ((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;
- }
-
- switch (Measurement->Identifier) {
- case MODULE_START_ID:
- case MODULE_END_ID:
- if (mPeiPhase) {
- Measurement->Token = ALit_PEIM;
- } else if (mDxePhase) {
- Measurement->Token = ALit_START_IMAGE;
- }
-
- break;
-
- case MODULE_LOADIMAGE_START_ID:
- case MODULE_LOADIMAGE_END_ID:
- Measurement->Token = ALit_LOAD_IMAGE;
- break;
-
- case MODULE_DB_START_ID:
- case MODULE_DB_END_ID:
- Measurement->Token = ALit_DB_START;
- break;
-
- case MODULE_DB_SUPPORT_START_ID:
- case MODULE_DB_SUPPORT_END_ID:
- Measurement->Token = ALit_DB_SUPPORT;
- break;
-
- case MODULE_DB_STOP_START_ID:
- case MODULE_DB_STOP_END_ID:
- Measurement->Token = ALit_DB_STOP;
- break;
-
- default:
- Measurement->Token = ((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->String;
- break;
- }
-
- Measurement->Module = ((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->String;
-
- if ((Measurement->Token != NULL) && (AsciiStrCmp (Measurement->Token, ALit_PEIM) == 0)) {
- Measurement->Handle = &(((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Guid);
- } else {
- GetHandleFormModuleGuid (ModuleGuid, &StartHandle);
- Measurement->Handle = StartHandle;
- //
- // When no perf entry to record the PEI and DXE phase,
- // For start image, we need detect the PEIM and non PEIM here.
- //
- if ((Measurement->Token == NULL) && ((Measurement->Identifier == MODULE_START_ID) || (Measurement->Identifier == MODULE_END_ID))) {
- if ((StartHandle == NULL) && !IsZeroGuid (ModuleGuid)) {
- Measurement->Token = ALit_PEIM;
- Measurement->Handle = ModuleGuid;
- } else {
- Measurement->Token = ALit_START_IMAGE;
- }
- }
- }
-
- break;
-
- case FPDT_GUID_QWORD_EVENT_TYPE:
- ModuleGuid = &(((FPDT_GUID_QWORD_EVENT_RECORD *)RecordHeader)->Guid);
- Measurement->Identifier = ((UINT32)((FPDT_GUID_QWORD_EVENT_RECORD *)RecordHeader)->ProgressID);
- if (IsStart) {
- Measurement->StartTimeStamp = ((FPDT_GUID_QWORD_EVENT_RECORD *)RecordHeader)->Timestamp;
- } else {
- Measurement->EndTimeStamp = ((FPDT_GUID_QWORD_EVENT_RECORD *)RecordHeader)->Timestamp;
- }
-
- switch (Measurement->Identifier) {
- case MODULE_DB_START_ID:
- Measurement->Token = ALit_DB_START;
- Measurement->Module = ALit_DB_START;
- break;
-
- case MODULE_DB_SUPPORT_START_ID:
- case MODULE_DB_SUPPORT_END_ID:
- Measurement->Token = ALit_DB_SUPPORT;
- Measurement->Module = ALit_DB_SUPPORT;
- break;
-
- case MODULE_DB_STOP_START_ID:
- case MODULE_DB_STOP_END_ID:
- Measurement->Token = ALit_DB_STOP;
- Measurement->Module = ALit_DB_STOP;
- break;
-
- case MODULE_LOADIMAGE_START_ID:
- case MODULE_LOADIMAGE_END_ID:
- Measurement->Token = ALit_LOAD_IMAGE;
- Measurement->Module = ALit_LOAD_IMAGE;
- break;
-
- default:
- ASSERT (FALSE);
- }
-
- GetHandleFormModuleGuid (ModuleGuid, &StartHandle);
- Measurement->Handle = StartHandle;
- break;
-
- case FPDT_GUID_QWORD_STRING_EVENT_TYPE:
- ModuleGuid = &(((FPDT_GUID_QWORD_STRING_EVENT_RECORD *)RecordHeader)->Guid);
- Measurement->Identifier = ((UINT32)((FPDT_GUID_QWORD_STRING_EVENT_RECORD *)RecordHeader)->ProgressID);
- if (IsStart) {
- Measurement->StartTimeStamp = ((FPDT_GUID_QWORD_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;
- } else {
- Measurement->EndTimeStamp = ((FPDT_GUID_QWORD_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;
- }
-
- //
- // Currently only "DB:Start:" end record with FPDT_GUID_QWORD_STRING_EVENT_TYPE.
- //
- switch (Measurement->Identifier) {
- case MODULE_DB_END_ID:
- Measurement->Token = ALit_DB_START;
- Measurement->Module = ALit_DB_START;
- break;
- default:
- ASSERT (FALSE);
- }
-
- GetHandleFormModuleGuid (ModuleGuid, &StartHandle);
- Measurement->Handle = StartHandle;
- break;
-
- case FPDT_DUAL_GUID_STRING_EVENT_TYPE:
- ModuleGuid = &(((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->Guid1);
- Measurement->Identifier = ((UINT32)((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->ProgressID);
- if (IsStart) {
- Measurement->StartTimeStamp = ((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;
- } else {
- Measurement->EndTimeStamp = ((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;
- }
-
- Measurement->Token = ((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->String;
- Measurement->Module = ((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->String;
- GetHandleFormModuleGuid (ModuleGuid, &StartHandle);
- Measurement->Handle = StartHandle;
- break;
-
- default:
- break;
- }
-}
-
-/**
- Search the start measurement in the mMeasurementList for the end measurement.
-
- @param EndMeasureMent Measurement for end record.
-
-**/
-VOID
-SearchMeasurement (
- IN MEASUREMENT_RECORD *EndMeasureMent
- )
-{
- INTN Index;
-
- for (Index = mMeasurementNum - 1; Index >= 0; Index--) {
- if (AsciiStrCmp (EndMeasureMent->Token, ALit_PEIM) == 0) {
- if ((mMeasurementList[Index].EndTimeStamp == 0) && (EndMeasureMent->Handle != NULL) && (mMeasurementList[Index].Handle != NULL) &&
- CompareGuid (mMeasurementList[Index].Handle, EndMeasureMent->Handle) &&
- (AsciiStrCmp (mMeasurementList[Index].Token, EndMeasureMent->Token) == 0) &&
- (AsciiStrCmp (mMeasurementList[Index].Module, EndMeasureMent->Module) == 0))
- {
- mMeasurementList[Index].EndTimeStamp = EndMeasureMent->EndTimeStamp;
- break;
- }
- } else if (EndMeasureMent->Identifier == PERF_CROSSMODULE_END_ID) {
- if ((mMeasurementList[Index].EndTimeStamp == 0) &&
- (AsciiStrCmp (mMeasurementList[Index].Token, EndMeasureMent->Token) == 0) &&
- (AsciiStrCmp (mMeasurementList[Index].Module, EndMeasureMent->Module) == 0) &&
- (mMeasurementList[Index].Identifier == PERF_CROSSMODULE_START_ID))
- {
- mMeasurementList[Index].EndTimeStamp = EndMeasureMent->EndTimeStamp;
- break;
- }
- } else {
- if ((mMeasurementList[Index].EndTimeStamp == 0) && (mMeasurementList[Index].Handle == EndMeasureMent->Handle) &&
- (AsciiStrCmp (mMeasurementList[Index].Token, EndMeasureMent->Token) == 0) &&
- (AsciiStrCmp (mMeasurementList[Index].Module, EndMeasureMent->Module) == 0))
- {
- mMeasurementList[Index].EndTimeStamp = EndMeasureMent->EndTimeStamp;
- break;
- }
- }
- }
-}
-
-/**
- Generate the measure record array.
-
-**/
-EFI_STATUS
-BuildMeasurementList (
- )
-{
- EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *RecordHeader;
- UINT8 *PerformanceTablePtr;
- UINT8 *BasicBootTablePtr;
- UINT64 ResetEnd;
- UINT16 StartProgressId;
- UINTN TableLength;
- UINT8 *StartRecordEvent;
- MEASUREMENT_RECORD MeasureMent;
-
- mMeasurementList = AllocateZeroPool (mBootPerformanceTableSize);
- if (mMeasurementList == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Update the ResetEnd which was logged at the beginning of firmware image execution
- //
- TableLength = sizeof (EFI_ACPI_5_0_FPDT_PERFORMANCE_TABLE_HEADER);
- BasicBootTablePtr = (mBootPerformanceTable + TableLength);
- ResetEnd = ((EFI_ACPI_5_0_FPDT_FIRMWARE_BASIC_BOOT_RECORD *)BasicBootTablePtr)->ResetEnd;
-
- if (ResetEnd > 0) {
- mResetEnd = ResetEnd;
- }
-
- TableLength = sizeof (BOOT_PERFORMANCE_TABLE);
- PerformanceTablePtr = (mBootPerformanceTable + TableLength);
-
- while (TableLength < mBootPerformanceTableSize) {
- RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)PerformanceTablePtr;
- StartRecordEvent = (UINT8 *)RecordHeader;
- StartProgressId = ((FPDT_GUID_EVENT_RECORD *)StartRecordEvent)->ProgressID;
-
- //
- // 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.
- // If the record is the start record, fill the info to the measurement in the mMeasurementList.
- // If the record is the end record, find the related start measurement in the mMeasurementList and fill the EndTimeStamp.
- //
- if (StartProgressId == 0) {
- GetMeasurementInfo (RecordHeader, FALSE, &(mMeasurementList[mMeasurementNum]));
- mMeasurementNum++;
- } else if ((((StartProgressId >= PERF_EVENTSIGNAL_START_ID) && ((StartProgressId & 0x000F) == 0)) ||
- ((StartProgressId < PERF_EVENTSIGNAL_START_ID) && ((StartProgressId & 0x0001) != 0))))
- {
- //
- // Since PEIM and StartImage has same Type and ID when PCD PcdEdkiiFpdtStringRecordEnableOnly = FALSE
- // So we need to identify these two kinds of record through different phase.
- //
- if (StartProgressId == PERF_CROSSMODULE_START_ID ) {
- if (AsciiStrCmp (((FPDT_DYNAMIC_STRING_EVENT_RECORD *)StartRecordEvent)->String, ALit_PEI) == 0) {
- mPeiPhase = TRUE;
- } else if (AsciiStrCmp (((FPDT_DYNAMIC_STRING_EVENT_RECORD *)StartRecordEvent)->String, ALit_DXE) == 0) {
- mDxePhase = TRUE;
- mPeiPhase = FALSE;
- }
- }
-
- // Get measurement info form the start record to the mMeasurementList.
- GetMeasurementInfo (RecordHeader, TRUE, &(mMeasurementList[mMeasurementNum]));
- mMeasurementNum++;
- } else {
- ZeroMem (&MeasureMent, sizeof (MEASUREMENT_RECORD));
- GetMeasurementInfo (RecordHeader, FALSE, &MeasureMent);
- SearchMeasurement (&MeasureMent);
- }
-
- TableLength += RecordHeader->Length;
- PerformanceTablePtr += RecordHeader->Length;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Initialize the cumulative data.
-
-**/
-VOID
-InitCumulativeData (
- VOID
- )
-{
- UINTN Index;
-
- for (Index = 0; Index < NumCum; ++Index) {
- CumData[Index].Count = 0;
- CumData[Index].MinDur = PERF_MAXDUR;
- CumData[Index].MaxDur = 0;
- CumData[Index].Duration = 0;
- }
-}
-
-/**
- Initialize the Summary data.
-
-**/
-VOID
-InitSummaryData (
- VOID
- )
-{
- SummaryData.NumTrace = 0;
- SummaryData.NumIncomplete = 0;
- SummaryData.NumSummary = 0;
- SummaryData.NumHandles = 0;
- SummaryData.NumPEIMs = 0;
- SummaryData.NumGlobal = 0;
-}
-
-/**
- Dump performance data.
-
- @param[in] ImageHandle The image handle.
- @param[in] SystemTable The system table.
-
- @retval SHELL_SUCCESS Command completed successfully.
- @retval SHELL_INVALID_PARAMETER Command usage error.
- @retval SHELL_ABORTED The user aborts the operation.
- @retval value Unknown error.
-**/
-SHELL_STATUS
-RunDp (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- LIST_ENTRY *ParamPackage;
- CONST CHAR16 *CmdLineArg;
- EFI_STATUS Status;
-
- PERFORMANCE_PROPERTY *PerformanceProperty;
- UINTN Number2Display;
-
- EFI_STRING StringPtr;
- BOOLEAN SummaryMode;
- BOOLEAN VerboseMode;
- BOOLEAN AllMode;
- BOOLEAN RawMode;
- BOOLEAN ExcludeMode;
- BOOLEAN CumulativeMode;
- CONST CHAR16 *CustomCumulativeToken;
- PERF_CUM_DATA *CustomCumulativeData;
- UINTN NameSize;
- SHELL_STATUS ShellStatus;
- TIMER_INFO TimerInfo;
- UINT64 Intermediate;
-
- StringPtr = NULL;
- SummaryMode = FALSE;
- VerboseMode = FALSE;
- AllMode = FALSE;
- RawMode = FALSE;
- ExcludeMode = FALSE;
- CumulativeMode = FALSE;
- CustomCumulativeData = NULL;
- ShellStatus = SHELL_SUCCESS;
-
- //
- // initialize the shell lib (we must be in non-auto-init...)
- //
- Status = ShellInitialize ();
- ASSERT_EFI_ERROR (Status);
-
- //
- // Process Command Line arguments
- //
- Status = ShellCommandLineParse (ParamList, &ParamPackage, NULL, TRUE);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_INVALID_ARG), mDpHiiHandle);
- return SHELL_INVALID_PARAMETER;
- } else if (ShellCommandLineGetCount (ParamPackage) > 1) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TOO_MANY), mDpHiiHandle);
- return SHELL_INVALID_PARAMETER;
- }
-
- //
- // Boolean options
- //
- VerboseMode = ShellCommandLineGetFlag (ParamPackage, L"-v");
- SummaryMode = (BOOLEAN)(ShellCommandLineGetFlag (ParamPackage, L"-S") || ShellCommandLineGetFlag (ParamPackage, L"-s"));
- AllMode = ShellCommandLineGetFlag (ParamPackage, L"-A");
- RawMode = ShellCommandLineGetFlag (ParamPackage, L"-R");
- ExcludeMode = ShellCommandLineGetFlag (ParamPackage, L"-x");
- mShowId = ShellCommandLineGetFlag (ParamPackage, L"-i");
- CumulativeMode = ShellCommandLineGetFlag (ParamPackage, L"-c");
-
- if (AllMode && RawMode) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_CONFLICT_ARG), mDpHiiHandle, L"-A", L"-R");
- return SHELL_INVALID_PARAMETER;
- }
-
- // Options with Values
- if (ShellCommandLineGetFlag (ParamPackage, L"-n")) {
- CmdLineArg = ShellCommandLineGetValue (ParamPackage, L"-n");
- if (CmdLineArg == NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TOO_FEW), mDpHiiHandle);
- return SHELL_INVALID_PARAMETER;
- } else {
- if (!(RawMode || AllMode)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_NO_RAW_ALL), mDpHiiHandle);
- return SHELL_INVALID_PARAMETER;
- }
-
- Status = ShellConvertStringToUint64 (CmdLineArg, &Intermediate, FALSE, TRUE);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_INVALID_NUM_ARG), mDpHiiHandle, L"-n");
- return SHELL_INVALID_PARAMETER;
- } else {
- Number2Display = (UINTN)Intermediate;
- if ((Number2Display == 0) || (Number2Display > MAXIMUM_DISPLAYCOUNT)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_INVALID_RANGE), mDpHiiHandle, L"-n", 0, MAXIMUM_DISPLAYCOUNT);
- return SHELL_INVALID_PARAMETER;
- }
- }
- }
- } else {
- Number2Display = DEFAULT_DISPLAYCOUNT;
- }
-
- if (ShellCommandLineGetFlag (ParamPackage, L"-t")) {
- CmdLineArg = ShellCommandLineGetValue (ParamPackage, L"-t");
- if (CmdLineArg == NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TOO_FEW), mDpHiiHandle);
- return SHELL_INVALID_PARAMETER;
- } else {
- Status = ShellConvertStringToUint64 (CmdLineArg, &Intermediate, FALSE, TRUE);
- if (EFI_ERROR (Status)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_INVALID_NUM_ARG), mDpHiiHandle, L"-t");
- return SHELL_INVALID_PARAMETER;
- } else {
- mInterestThreshold = Intermediate;
- }
- }
- } else {
- mInterestThreshold = DEFAULT_THRESHOLD; // 1ms := 1,000 us
- }
-
- if (ShellCommandLineGetFlag (ParamPackage, L"-c")) {
- CustomCumulativeToken = ShellCommandLineGetValue (ParamPackage, L"-c");
- if (CustomCumulativeToken == NULL) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TOO_FEW), mDpHiiHandle);
- return SHELL_INVALID_PARAMETER;
- } else {
- CustomCumulativeData = AllocateZeroPool (sizeof (PERF_CUM_DATA));
- if (CustomCumulativeData == NULL) {
- ShellStatus = SHELL_OUT_OF_RESOURCES;
- goto Done;
- }
-
- CustomCumulativeData->MinDur = PERF_MAXDUR;
- CustomCumulativeData->MaxDur = 0;
- CustomCumulativeData->Count = 0;
- CustomCumulativeData->Duration = 0;
- NameSize = StrLen (CustomCumulativeToken) + 1;
- CustomCumulativeData->Name = AllocateZeroPool (NameSize);
- if (CustomCumulativeData->Name == NULL) {
- ShellStatus = SHELL_OUT_OF_RESOURCES;
- goto Done;
- }
-
- UnicodeStrToAsciiStrS (CustomCumulativeToken, CustomCumulativeData->Name, NameSize);
- }
- }
-
- //
- // DP dump performance data by parsing FPDT table in ACPI table.
- // Folloing 3 steps are to get the measurement form the FPDT table.
- //
-
- //
- // 1. Get FPDT from ACPI table.
- //
- Status = GetBootPerformanceTable ();
- if (EFI_ERROR (Status)) {
- ShellStatus = Status;
- goto Done;
- }
-
- //
- // 2. Cache the ModuleGuid and hanlde mapping table.
- //
- Status = BuildCachedGuidHandleTable ();
- if (EFI_ERROR (Status)) {
- ShellStatus = Status;
- goto Done;
- }
-
- //
- // 3. Build the measurement array form the FPDT records.
- //
- Status = BuildMeasurementList ();
- if (EFI_ERROR (Status)) {
- ShellStatus = SHELL_OUT_OF_RESOURCES;
- goto Done;
- }
-
- //
- // Initialize the pre-defined cumulative data.
- //
- InitCumulativeData ();
-
- //
- // Initialize the Summary data.
- //
- InitSummaryData ();
-
- //
- // Timer specific processing
- //
- // Get the Performance counter characteristics:
- // Freq = Frequency in Hz
- // StartCount = Value loaded into the counter when it starts counting
- // EndCount = Value counter counts to before it needs to be reset
- //
- Status = EfiGetSystemConfigurationTable (&gPerformanceProtocolGuid, (VOID **)&PerformanceProperty);
- if (EFI_ERROR (Status) || (PerformanceProperty == NULL)) {
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PERF_PROPERTY_NOT_FOUND), mDpHiiHandle);
- goto Done;
- }
-
- TimerInfo.Frequency = (UINT32)DivU64x32 (PerformanceProperty->Frequency, 1000);
- TimerInfo.StartCount = 0;
- TimerInfo.EndCount = 0xFFFF;
- TimerInfo.CountUp = TRUE;
-
- //
- // Print header
- //
- // print DP's build version
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_BUILD_REVISION), mDpHiiHandle, DP_MAJOR_VERSION, DP_MINOR_VERSION);
-
- // print performance timer characteristics
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_KHZ), mDpHiiHandle, TimerInfo.Frequency);
-
- if (VerboseMode && !RawMode) {
- StringPtr = HiiGetString (
- mDpHiiHandle,
- (EFI_STRING_ID)(TimerInfo.CountUp ? STRING_TOKEN (STR_DP_UP) : STRING_TOKEN (STR_DP_DOWN)),
- NULL
- );
- ASSERT (StringPtr != NULL);
- // Print Timer count range and direction
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_DP_TIMER_PROPERTIES),
- mDpHiiHandle,
- StringPtr,
- TimerInfo.StartCount,
- TimerInfo.EndCount
- );
- ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_VERBOSE_THRESHOLD), mDpHiiHandle, mInterestThreshold);
- }
-
- /****************************************************************************
- **** Print Sections based on command line options
- ****
- **** Option modes have the following priority:
- **** v Verbose -- Valid in combination with any other options
- **** t Threshold -- Modifies All, Raw, and Cooked output
- **** Default is 0 for All and Raw mode
- **** Default is DEFAULT_THRESHOLD for "Cooked" mode
- **** n Number2Display Used by All and Raw mode. Otherwise ignored.
- **** A All -- R and S options are ignored
- **** R Raw -- S option is ignored
- **** s Summary -- Modifies "Cooked" output only
- **** Cooked (Default)
- ****************************************************************************/
- GatherStatistics (CustomCumulativeData);
- if (CumulativeMode) {
- ProcessCumulative (CustomCumulativeData);
- } else if (AllMode) {
- Status = DumpAllTrace (Number2Display, ExcludeMode);
- if (Status == EFI_ABORTED) {
- ShellStatus = SHELL_ABORTED;
- goto Done;
- }
- } else if (RawMode) {
- Status = DumpRawTrace (Number2Display, ExcludeMode);
- if (Status == EFI_ABORTED) {
- ShellStatus = SHELL_ABORTED;
- goto Done;
- }
- } else {
- // ------------- Begin Cooked Mode Processing
- ProcessPhases ();
- if ( !SummaryMode) {
- Status = ProcessHandles (ExcludeMode);
- if (Status == EFI_ABORTED) {
- ShellStatus = SHELL_ABORTED;
- goto Done;
- }
-
- Status = ProcessPeims ();
- if (Status == EFI_ABORTED) {
- ShellStatus = SHELL_ABORTED;
- goto Done;
- }
-
- Status = ProcessGlobal ();
- if (Status == EFI_ABORTED) {
- ShellStatus = SHELL_ABORTED;
- goto Done;
- }
-
- ProcessCumulative (NULL);
- }
- } // ------------- End of Cooked Mode Processing
-
- if ( VerboseMode || SummaryMode) {
- DumpStatistics ();
- }
-
-Done:
- if (ParamPackage != NULL) {
- ShellCommandLineFreeVarList (ParamPackage);
- }
-
- SHELL_FREE_NON_NULL (StringPtr);
- if (CustomCumulativeData != NULL) {
- SHELL_FREE_NON_NULL (CustomCumulativeData->Name);
- }
-
- SHELL_FREE_NON_NULL (CustomCumulativeData);
-
- SHELL_FREE_NON_NULL (mMeasurementList);
-
- SHELL_FREE_NON_NULL (mCacheHandleGuidTable);
-
- mMeasurementNum = 0;
- mCachePairCount = 0;
- return ShellStatus;
-}
-
-/**
- Retrieve HII package list from ImageHandle and publish to HII database.
-
- @param ImageHandle The image handle of the process.
-
- @return HII handle.
-**/
-EFI_HII_HANDLE
-InitializeHiiPackage (
- EFI_HANDLE ImageHandle
- )
-{
- EFI_STATUS Status;
- EFI_HII_PACKAGE_LIST_HEADER *PackageList;
- EFI_HII_HANDLE HiiHandle;
-
- //
- // Retrieve HII package list from ImageHandle
- //
- Status = gBS->OpenProtocol (
- ImageHandle,
- &gEfiHiiPackageListProtocolGuid,
- (VOID **)&PackageList,
- ImageHandle,
- NULL,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- ASSERT_EFI_ERROR (Status);
- if (EFI_ERROR (Status)) {
- return NULL;
- }
-
- //
- // Publish HII package list to HII Database.
- //
- Status = gHiiDatabase->NewPackageList (
- gHiiDatabase,
- PackageList,
- NULL,
- &HiiHandle
- );
- ASSERT_EFI_ERROR (Status);
- if (EFI_ERROR (Status)) {
- return NULL;
- }
-
- return HiiHandle;
-}
+/** @file
+ Shell command for Displaying Performance Metrics.
+
+ The Dp command reads performance data and presents it in several
+ different formats depending upon the needs of the user. Both
+ Trace and Measured Profiling information is processed and presented.
+
+ Dp uses the "PerformanceLib" to read the measurement records.
+ The "TimerLib" provides information about the timer, such as frequency,
+ beginning, and ending counter values.
+ Measurement records contain identifying information (Handle, Token, Module)
+ and start and end time values.
+ Dp uses this information to group records in different ways. It also uses
+ timer information to calculate elapsed time for each measurement.
+
+ Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
+ (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "Dp.h"
+#include "Literals.h"
+#include "DpInternal.h"
+
+#pragma pack(1)
+
+typedef struct {
+ EFI_ACPI_DESCRIPTION_HEADER Header;
+ UINT32 Entry;
+} RSDT_TABLE;
+
+typedef struct {
+ EFI_ACPI_DESCRIPTION_HEADER Header;
+ UINT64 Entry;
+} XSDT_TABLE;
+
+#pragma pack()
+
+EFI_HII_HANDLE mDpHiiHandle;
+
+typedef struct {
+ EFI_HANDLE Handle;
+ EFI_GUID ModuleGuid;
+} HANDLE_GUID_MAP;
+
+HANDLE_GUID_MAP *mCacheHandleGuidTable;
+UINTN mCachePairCount = 0;
+
+//
+/// Module-Global Variables
+///@{
+CHAR16 mGaugeString[DP_GAUGE_STRING_LENGTH + 1];
+CHAR16 mUnicodeToken[DXE_PERFORMANCE_STRING_SIZE];
+UINT64 mInterestThreshold;
+BOOLEAN mShowId = FALSE;
+UINT8 *mBootPerformanceTable;
+UINTN mBootPerformanceTableSize;
+BOOLEAN mPeiPhase = FALSE;
+BOOLEAN mDxePhase = FALSE;
+UINT64 mResetEnd = 0;
+
+PERF_SUMMARY_DATA SummaryData = { 0 }; ///< Create the SummaryData structure and init. to ZERO.
+MEASUREMENT_RECORD *mMeasurementList = NULL;
+UINTN mMeasurementNum = 0;
+
+/// Items for which to gather cumulative statistics.
+PERF_CUM_DATA CumData[] = {
+ PERF_INIT_CUM_DATA (LOAD_IMAGE_TOK),
+ PERF_INIT_CUM_DATA (START_IMAGE_TOK),
+ PERF_INIT_CUM_DATA (DRIVERBINDING_START_TOK),
+ PERF_INIT_CUM_DATA (DRIVERBINDING_SUPPORT_TOK),
+ PERF_INIT_CUM_DATA (DRIVERBINDING_STOP_TOK)
+};
+
+/// Number of items for which we are gathering cumulative statistics.
+UINT32 const NumCum = sizeof (CumData) / sizeof (PERF_CUM_DATA);
+
+STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
+ { L"-v", TypeFlag }, // -v Verbose Mode
+ { L"-A", TypeFlag }, // -A All, Cooked
+ { L"-R", TypeFlag }, // -R RAW All
+ { L"-s", TypeFlag }, // -s Summary
+ { L"-x", TypeFlag }, // -x eXclude Cumulative Items
+ { L"-i", TypeFlag }, // -i Display Identifier
+ { L"-c", TypeValue }, // -c Display cumulative data.
+ { L"-n", TypeValue }, // -n # Number of records to display for A and R
+ { L"-t", TypeValue }, // -t # Threshold of interest
+ { NULL, TypeMax }
+};
+
+///@}
+
+/**
+ Display the trailing Verbose information.
+**/
+VOID
+DumpStatistics (
+ void
+ )
+{
+ EFI_STRING StringPtr;
+ EFI_STRING StringPtrUnknown;
+
+ StringPtr = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_STATISTICS), NULL);
+ StringPtrUnknown = HiiGetString (mDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_DP_SECTION_HEADER),
+ mDpHiiHandle,
+ (StringPtr == NULL) ? StringPtrUnknown : StringPtr
+ );
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMTRACE), mDpHiiHandle, SummaryData.NumTrace);
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMINCOMPLETE), mDpHiiHandle, SummaryData.NumIncomplete);
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMPHASES), mDpHiiHandle, SummaryData.NumSummary);
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMHANDLES), mDpHiiHandle, SummaryData.NumHandles, SummaryData.NumTrace - SummaryData.NumHandles);
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMPEIMS), mDpHiiHandle, SummaryData.NumPEIMs);
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMGLOBALS), mDpHiiHandle, SummaryData.NumGlobal);
+ SHELL_FREE_NON_NULL (StringPtr);
+ SHELL_FREE_NON_NULL (StringPtrUnknown);
+}
+
+/**
+ Get Boot performance table form Acpi table.
+
+**/
+EFI_STATUS
+GetBootPerformanceTable (
+ )
+{
+ EFI_STATUS Status;
+ FIRMWARE_PERFORMANCE_TABLE *FirmwarePerformanceTable;
+
+ FirmwarePerformanceTable = (FIRMWARE_PERFORMANCE_TABLE *)EfiLocateFirstAcpiTable (
+ EFI_ACPI_5_0_FIRMWARE_PERFORMANCE_DATA_TABLE_SIGNATURE
+ );
+ if (FirmwarePerformanceTable == NULL) {
+ Status = EfiGetSystemConfigurationTable (&gEdkiiFpdtExtendedFirmwarePerformanceGuid, (VOID **)&mBootPerformanceTable);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GET_ACPI_FPDT_FAIL), mDpHiiHandle);
+ return EFI_NOT_FOUND;
+ }
+ } else {
+ mBootPerformanceTable = (UINT8 *)(UINTN)FirmwarePerformanceTable->BootPointerRecord.BootPerformanceTablePointer;
+ }
+
+ mBootPerformanceTableSize = ((BOOT_PERFORMANCE_TABLE *)mBootPerformanceTable)->Header.Length;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Get Handle form Module Guid.
+
+ @param ModuleGuid Module Guid.
+ @param Handle The handle to be returned.
+
+**/
+VOID
+GetHandleFormModuleGuid (
+ IN EFI_GUID *ModuleGuid,
+ IN OUT EFI_HANDLE *Handle
+ )
+{
+ UINTN Index;
+
+ if (IsZeroGuid (ModuleGuid)) {
+ *Handle = NULL;
+ }
+
+ //
+ // Try to get the Handle from the cached array.
+ //
+ for (Index = 0; Index < mCachePairCount; Index++) {
+ if (CompareGuid (ModuleGuid, &mCacheHandleGuidTable[Index].ModuleGuid)) {
+ *Handle = mCacheHandleGuidTable[Index].Handle;
+ break;
+ }
+ }
+
+ if (Index >= mCachePairCount) {
+ *Handle = NULL;
+ }
+}
+
+/**
+Cache the GUID and handle mapping pairs. In order to save time for searching.
+
+**/
+EFI_STATUS
+BuildCachedGuidHandleTable (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *HandleBuffer;
+ UINTN HandleCount;
+ UINTN Index;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
+ EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
+ EFI_GUID *TempGuid;
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFilePath;
+
+ Status = gBS->LocateHandleBuffer (AllHandles, NULL, NULL, &HandleCount, &HandleBuffer);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLES_ERROR), mDpHiiHandle, Status);
+ return Status;
+ }
+
+ mCacheHandleGuidTable = AllocateZeroPool (HandleCount * sizeof (HANDLE_GUID_MAP));
+ if (mCacheHandleGuidTable == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ for (Index = 0; Index < HandleCount; Index++) {
+ //
+ // Try Handle as ImageHandle.
+ //
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gEfiLoadedImageProtocolGuid,
+ (VOID **)&LoadedImage
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // Try Handle as Controller Handle
+ //
+ Status = gBS->OpenProtocol (
+ HandleBuffer[Index],
+ &gEfiDriverBindingProtocolGuid,
+ (VOID **)&DriverBinding,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Get Image protocol from ImageHandle
+ //
+ Status = gBS->HandleProtocol (
+ DriverBinding->ImageHandle,
+ &gEfiLoadedImageProtocolGuid,
+ (VOID **)&LoadedImage
+ );
+ }
+ }
+
+ if (!EFI_ERROR (Status) && (LoadedImage != NULL)) {
+ //
+ // Get Module Guid from DevicePath.
+ //
+ if ((LoadedImage->FilePath != NULL) &&
+ (LoadedImage->FilePath->Type == MEDIA_DEVICE_PATH) &&
+ (LoadedImage->FilePath->SubType == MEDIA_PIWG_FW_FILE_DP)
+ )
+ {
+ FvFilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)LoadedImage->FilePath;
+ TempGuid = &FvFilePath->FvFileName;
+
+ mCacheHandleGuidTable[mCachePairCount].Handle = HandleBuffer[Index];
+ CopyGuid (&mCacheHandleGuidTable[mCachePairCount].ModuleGuid, TempGuid);
+ mCachePairCount++;
+ }
+ }
+ }
+
+ if (HandleBuffer != NULL) {
+ FreePool (HandleBuffer);
+ HandleBuffer = NULL;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Get Measurement form Fpdt records.
+
+ @param RecordHeader Pointer to the start record.
+ @param IsStart Is start record or End record.
+ @param Measurement Pointer to the measurement which need to be filled.
+
+**/
+VOID
+GetMeasurementInfo (
+ IN EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *RecordHeader,
+ IN BOOLEAN IsStart,
+ IN OUT MEASUREMENT_RECORD *Measurement
+ )
+{
+ VOID *ModuleGuid;
+ EFI_HANDLE StartHandle;
+
+ switch (RecordHeader->Type) {
+ case FPDT_GUID_EVENT_TYPE:
+ ModuleGuid = &(((FPDT_GUID_EVENT_RECORD *)RecordHeader)->Guid);
+ Measurement->Identifier = ((UINT32)((FPDT_GUID_EVENT_RECORD *)RecordHeader)->ProgressID);
+ if (IsStart) {
+ Measurement->StartTimeStamp = ((FPDT_GUID_EVENT_RECORD *)RecordHeader)->Timestamp;
+ } else {
+ Measurement->EndTimeStamp = ((FPDT_GUID_EVENT_RECORD *)RecordHeader)->Timestamp;
+ }
+
+ switch (Measurement->Identifier) {
+ case MODULE_START_ID:
+ case MODULE_END_ID:
+ if (mPeiPhase) {
+ Measurement->Token = ALit_PEIM;
+ Measurement->Module = ALit_PEIM;
+ } else if (mDxePhase) {
+ Measurement->Token = ALit_START_IMAGE;
+ Measurement->Module = ALit_START_IMAGE;
+ }
+
+ break;
+ default:
+ ASSERT (FALSE);
+ }
+
+ if ((Measurement->Token != NULL) && (AsciiStrCmp (Measurement->Token, ALit_PEIM) == 0)) {
+ Measurement->Handle = &(((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Guid);
+ } else {
+ GetHandleFormModuleGuid (ModuleGuid, &StartHandle);
+ Measurement->Handle = StartHandle;
+ //
+ // When no perf entry to record the PEI and DXE phase,
+ // For start image, we need detect the PEIM and non PEIM here.
+ //
+ if (Measurement->Token == NULL) {
+ if ((StartHandle == NULL) && !IsZeroGuid (ModuleGuid)) {
+ Measurement->Token = ALit_PEIM;
+ Measurement->Module = ALit_PEIM;
+ Measurement->Handle = ModuleGuid;
+ } else {
+ Measurement->Token = ALit_START_IMAGE;
+ Measurement->Module = ALit_START_IMAGE;
+ }
+ }
+ }
+
+ break;
+
+ case FPDT_DYNAMIC_STRING_EVENT_TYPE:
+ ModuleGuid = &(((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Guid);
+ Measurement->Identifier = ((UINT32)((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->ProgressID);
+ if (IsStart) {
+ Measurement->StartTimeStamp = ((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;
+ } else {
+ Measurement->EndTimeStamp = ((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;
+ }
+
+ switch (Measurement->Identifier) {
+ case MODULE_START_ID:
+ case MODULE_END_ID:
+ if (mPeiPhase) {
+ Measurement->Token = ALit_PEIM;
+ } else if (mDxePhase) {
+ Measurement->Token = ALit_START_IMAGE;
+ }
+
+ break;
+
+ case MODULE_LOADIMAGE_START_ID:
+ case MODULE_LOADIMAGE_END_ID:
+ Measurement->Token = ALit_LOAD_IMAGE;
+ break;
+
+ case MODULE_DB_START_ID:
+ case MODULE_DB_END_ID:
+ Measurement->Token = ALit_DB_START;
+ break;
+
+ case MODULE_DB_SUPPORT_START_ID:
+ case MODULE_DB_SUPPORT_END_ID:
+ Measurement->Token = ALit_DB_SUPPORT;
+ break;
+
+ case MODULE_DB_STOP_START_ID:
+ case MODULE_DB_STOP_END_ID:
+ Measurement->Token = ALit_DB_STOP;
+ break;
+
+ default:
+ Measurement->Token = ((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->String;
+ break;
+ }
+
+ Measurement->Module = ((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->String;
+
+ if ((Measurement->Token != NULL) && (AsciiStrCmp (Measurement->Token, ALit_PEIM) == 0)) {
+ Measurement->Handle = &(((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Guid);
+ } else {
+ GetHandleFormModuleGuid (ModuleGuid, &StartHandle);
+ Measurement->Handle = StartHandle;
+ //
+ // When no perf entry to record the PEI and DXE phase,
+ // For start image, we need detect the PEIM and non PEIM here.
+ //
+ if ((Measurement->Token == NULL) && ((Measurement->Identifier == MODULE_START_ID) || (Measurement->Identifier == MODULE_END_ID))) {
+ if ((StartHandle == NULL) && !IsZeroGuid (ModuleGuid)) {
+ Measurement->Token = ALit_PEIM;
+ Measurement->Handle = ModuleGuid;
+ } else {
+ Measurement->Token = ALit_START_IMAGE;
+ }
+ }
+ }
+
+ break;
+
+ case FPDT_GUID_QWORD_EVENT_TYPE:
+ ModuleGuid = &(((FPDT_GUID_QWORD_EVENT_RECORD *)RecordHeader)->Guid);
+ Measurement->Identifier = ((UINT32)((FPDT_GUID_QWORD_EVENT_RECORD *)RecordHeader)->ProgressID);
+ if (IsStart) {
+ Measurement->StartTimeStamp = ((FPDT_GUID_QWORD_EVENT_RECORD *)RecordHeader)->Timestamp;
+ } else {
+ Measurement->EndTimeStamp = ((FPDT_GUID_QWORD_EVENT_RECORD *)RecordHeader)->Timestamp;
+ }
+
+ switch (Measurement->Identifier) {
+ case MODULE_DB_START_ID:
+ Measurement->Token = ALit_DB_START;
+ Measurement->Module = ALit_DB_START;
+ break;
+
+ case MODULE_DB_SUPPORT_START_ID:
+ case MODULE_DB_SUPPORT_END_ID:
+ Measurement->Token = ALit_DB_SUPPORT;
+ Measurement->Module = ALit_DB_SUPPORT;
+ break;
+
+ case MODULE_DB_STOP_START_ID:
+ case MODULE_DB_STOP_END_ID:
+ Measurement->Token = ALit_DB_STOP;
+ Measurement->Module = ALit_DB_STOP;
+ break;
+
+ case MODULE_LOADIMAGE_START_ID:
+ case MODULE_LOADIMAGE_END_ID:
+ Measurement->Token = ALit_LOAD_IMAGE;
+ Measurement->Module = ALit_LOAD_IMAGE;
+ break;
+
+ default:
+ ASSERT (FALSE);
+ }
+
+ GetHandleFormModuleGuid (ModuleGuid, &StartHandle);
+ Measurement->Handle = StartHandle;
+ break;
+
+ case FPDT_GUID_QWORD_STRING_EVENT_TYPE:
+ ModuleGuid = &(((FPDT_GUID_QWORD_STRING_EVENT_RECORD *)RecordHeader)->Guid);
+ Measurement->Identifier = ((UINT32)((FPDT_GUID_QWORD_STRING_EVENT_RECORD *)RecordHeader)->ProgressID);
+ if (IsStart) {
+ Measurement->StartTimeStamp = ((FPDT_GUID_QWORD_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;
+ } else {
+ Measurement->EndTimeStamp = ((FPDT_GUID_QWORD_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;
+ }
+
+ //
+ // Currently only "DB:Start:" end record with FPDT_GUID_QWORD_STRING_EVENT_TYPE.
+ //
+ switch (Measurement->Identifier) {
+ case MODULE_DB_END_ID:
+ Measurement->Token = ALit_DB_START;
+ Measurement->Module = ALit_DB_START;
+ break;
+ default:
+ ASSERT (FALSE);
+ }
+
+ GetHandleFormModuleGuid (ModuleGuid, &StartHandle);
+ Measurement->Handle = StartHandle;
+ break;
+
+ case FPDT_DUAL_GUID_STRING_EVENT_TYPE:
+ ModuleGuid = &(((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->Guid1);
+ Measurement->Identifier = ((UINT32)((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->ProgressID);
+ if (IsStart) {
+ Measurement->StartTimeStamp = ((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;
+ } else {
+ Measurement->EndTimeStamp = ((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;
+ }
+
+ Measurement->Token = ((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->String;
+ Measurement->Module = ((FPDT_DUAL_GUID_STRING_EVENT_RECORD *)RecordHeader)->String;
+ GetHandleFormModuleGuid (ModuleGuid, &StartHandle);
+ Measurement->Handle = StartHandle;
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ Search the start measurement in the mMeasurementList for the end measurement.
+
+ @param EndMeasureMent Measurement for end record.
+
+**/
+VOID
+SearchMeasurement (
+ IN MEASUREMENT_RECORD *EndMeasureMent
+ )
+{
+ INTN Index;
+
+ for (Index = mMeasurementNum - 1; Index >= 0; Index--) {
+ if (AsciiStrCmp (EndMeasureMent->Token, ALit_PEIM) == 0) {
+ if ((mMeasurementList[Index].EndTimeStamp == 0) && (EndMeasureMent->Handle != NULL) && (mMeasurementList[Index].Handle != NULL) &&
+ CompareGuid (mMeasurementList[Index].Handle, EndMeasureMent->Handle) &&
+ (AsciiStrCmp (mMeasurementList[Index].Token, EndMeasureMent->Token) == 0) &&
+ (AsciiStrCmp (mMeasurementList[Index].Module, EndMeasureMent->Module) == 0))
+ {
+ mMeasurementList[Index].EndTimeStamp = EndMeasureMent->EndTimeStamp;
+ break;
+ }
+ } else if (EndMeasureMent->Identifier == PERF_CROSSMODULE_END_ID) {
+ if ((mMeasurementList[Index].EndTimeStamp == 0) &&
+ (AsciiStrCmp (mMeasurementList[Index].Token, EndMeasureMent->Token) == 0) &&
+ (AsciiStrCmp (mMeasurementList[Index].Module, EndMeasureMent->Module) == 0) &&
+ (mMeasurementList[Index].Identifier == PERF_CROSSMODULE_START_ID))
+ {
+ mMeasurementList[Index].EndTimeStamp = EndMeasureMent->EndTimeStamp;
+ break;
+ }
+ } else {
+ if ((mMeasurementList[Index].EndTimeStamp == 0) && (mMeasurementList[Index].Handle == EndMeasureMent->Handle) &&
+ (AsciiStrCmp (mMeasurementList[Index].Token, EndMeasureMent->Token) == 0) &&
+ (AsciiStrCmp (mMeasurementList[Index].Module, EndMeasureMent->Module) == 0))
+ {
+ mMeasurementList[Index].EndTimeStamp = EndMeasureMent->EndTimeStamp;
+ break;
+ }
+ }
+ }
+}
+
+/**
+ Generate the measure record array.
+
+**/
+EFI_STATUS
+BuildMeasurementList (
+ )
+{
+ EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *RecordHeader;
+ UINT8 *PerformanceTablePtr;
+ UINT8 *BasicBootTablePtr;
+ UINT64 ResetEnd;
+ UINT16 StartProgressId;
+ UINTN TableLength;
+ UINT8 *StartRecordEvent;
+ MEASUREMENT_RECORD MeasureMent;
+
+ mMeasurementList = AllocateZeroPool (mBootPerformanceTableSize);
+ if (mMeasurementList == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Update the ResetEnd which was logged at the beginning of firmware image execution
+ //
+ TableLength = sizeof (EFI_ACPI_5_0_FPDT_PERFORMANCE_TABLE_HEADER);
+ BasicBootTablePtr = (mBootPerformanceTable + TableLength);
+ ResetEnd = ((EFI_ACPI_5_0_FPDT_FIRMWARE_BASIC_BOOT_RECORD *)BasicBootTablePtr)->ResetEnd;
+
+ if (ResetEnd > 0) {
+ mResetEnd = ResetEnd;
+ }
+
+ TableLength = sizeof (BOOT_PERFORMANCE_TABLE);
+ PerformanceTablePtr = (mBootPerformanceTable + TableLength);
+
+ while (TableLength < mBootPerformanceTableSize) {
+ RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)PerformanceTablePtr;
+ StartRecordEvent = (UINT8 *)RecordHeader;
+ StartProgressId = ((FPDT_GUID_EVENT_RECORD *)StartRecordEvent)->ProgressID;
+
+ //
+ // 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.
+ // If the record is the start record, fill the info to the measurement in the mMeasurementList.
+ // If the record is the end record, find the related start measurement in the mMeasurementList and fill the EndTimeStamp.
+ //
+ if (StartProgressId == 0) {
+ GetMeasurementInfo (RecordHeader, FALSE, &(mMeasurementList[mMeasurementNum]));
+ mMeasurementNum++;
+ } else if ((((StartProgressId >= PERF_EVENTSIGNAL_START_ID) && ((StartProgressId & 0x000F) == 0)) ||
+ ((StartProgressId < PERF_EVENTSIGNAL_START_ID) && ((StartProgressId & 0x0001) != 0))))
+ {
+ //
+ // Since PEIM and StartImage has same Type and ID when PCD PcdEdkiiFpdtStringRecordEnableOnly = FALSE
+ // So we need to identify these two kinds of record through different phase.
+ //
+ if (StartProgressId == PERF_CROSSMODULE_START_ID ) {
+ if (AsciiStrCmp (((FPDT_DYNAMIC_STRING_EVENT_RECORD *)StartRecordEvent)->String, ALit_PEI) == 0) {
+ mPeiPhase = TRUE;
+ } else if (AsciiStrCmp (((FPDT_DYNAMIC_STRING_EVENT_RECORD *)StartRecordEvent)->String, ALit_DXE) == 0) {
+ mDxePhase = TRUE;
+ mPeiPhase = FALSE;
+ }
+ }
+
+ // Get measurement info form the start record to the mMeasurementList.
+ GetMeasurementInfo (RecordHeader, TRUE, &(mMeasurementList[mMeasurementNum]));
+ mMeasurementNum++;
+ } else {
+ ZeroMem (&MeasureMent, sizeof (MEASUREMENT_RECORD));
+ GetMeasurementInfo (RecordHeader, FALSE, &MeasureMent);
+ SearchMeasurement (&MeasureMent);
+ }
+
+ TableLength += RecordHeader->Length;
+ PerformanceTablePtr += RecordHeader->Length;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Initialize the cumulative data.
+
+**/
+VOID
+InitCumulativeData (
+ VOID
+ )
+{
+ UINTN Index;
+
+ for (Index = 0; Index < NumCum; ++Index) {
+ CumData[Index].Count = 0;
+ CumData[Index].MinDur = PERF_MAXDUR;
+ CumData[Index].MaxDur = 0;
+ CumData[Index].Duration = 0;
+ }
+}
+
+/**
+ Initialize the Summary data.
+
+**/
+VOID
+InitSummaryData (
+ VOID
+ )
+{
+ SummaryData.NumTrace = 0;
+ SummaryData.NumIncomplete = 0;
+ SummaryData.NumSummary = 0;
+ SummaryData.NumHandles = 0;
+ SummaryData.NumPEIMs = 0;
+ SummaryData.NumGlobal = 0;
+}
+
+/**
+ Dump performance data.
+
+ @param[in] ImageHandle The image handle.
+ @param[in] SystemTable The system table.
+
+ @retval SHELL_SUCCESS Command completed successfully.
+ @retval SHELL_INVALID_PARAMETER Command usage error.
+ @retval SHELL_ABORTED The user aborts the operation.
+ @retval value Unknown error.
+**/
+SHELL_STATUS
+RunDp (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ LIST_ENTRY *ParamPackage;
+ CONST CHAR16 *CmdLineArg;
+ EFI_STATUS Status;
+
+ PERFORMANCE_PROPERTY *PerformanceProperty;
+ UINTN Number2Display;
+
+ EFI_STRING StringPtr;
+ BOOLEAN SummaryMode;
+ BOOLEAN VerboseMode;
+ BOOLEAN AllMode;
+ BOOLEAN RawMode;
+ BOOLEAN ExcludeMode;
+ BOOLEAN CumulativeMode;
+ CONST CHAR16 *CustomCumulativeToken;
+ PERF_CUM_DATA *CustomCumulativeData;
+ UINTN NameSize;
+ SHELL_STATUS ShellStatus;
+ TIMER_INFO TimerInfo;
+ UINT64 Intermediate;
+
+ StringPtr = NULL;
+ SummaryMode = FALSE;
+ VerboseMode = FALSE;
+ AllMode = FALSE;
+ RawMode = FALSE;
+ ExcludeMode = FALSE;
+ CumulativeMode = FALSE;
+ CustomCumulativeData = NULL;
+ ShellStatus = SHELL_SUCCESS;
+
+ //
+ // initialize the shell lib (we must be in non-auto-init...)
+ //
+ Status = ShellInitialize ();
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Process Command Line arguments
+ //
+ Status = ShellCommandLineParse (ParamList, &ParamPackage, NULL, TRUE);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_INVALID_ARG), mDpHiiHandle);
+ return SHELL_INVALID_PARAMETER;
+ } else if (ShellCommandLineGetCount (ParamPackage) > 1) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TOO_MANY), mDpHiiHandle);
+ return SHELL_INVALID_PARAMETER;
+ }
+
+ //
+ // Boolean options
+ //
+ VerboseMode = ShellCommandLineGetFlag (ParamPackage, L"-v");
+ SummaryMode = (BOOLEAN)(ShellCommandLineGetFlag (ParamPackage, L"-S") || ShellCommandLineGetFlag (ParamPackage, L"-s"));
+ AllMode = ShellCommandLineGetFlag (ParamPackage, L"-A");
+ RawMode = ShellCommandLineGetFlag (ParamPackage, L"-R");
+ ExcludeMode = ShellCommandLineGetFlag (ParamPackage, L"-x");
+ mShowId = ShellCommandLineGetFlag (ParamPackage, L"-i");
+ CumulativeMode = ShellCommandLineGetFlag (ParamPackage, L"-c");
+
+ if (AllMode && RawMode) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_CONFLICT_ARG), mDpHiiHandle, L"-A", L"-R");
+ return SHELL_INVALID_PARAMETER;
+ }
+
+ // Options with Values
+ if (ShellCommandLineGetFlag (ParamPackage, L"-n")) {
+ CmdLineArg = ShellCommandLineGetValue (ParamPackage, L"-n");
+ if (CmdLineArg == NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TOO_FEW), mDpHiiHandle);
+ return SHELL_INVALID_PARAMETER;
+ } else {
+ if (!(RawMode || AllMode)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_NO_RAW_ALL), mDpHiiHandle);
+ return SHELL_INVALID_PARAMETER;
+ }
+
+ Status = ShellConvertStringToUint64 (CmdLineArg, &Intermediate, FALSE, TRUE);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_INVALID_NUM_ARG), mDpHiiHandle, L"-n");
+ return SHELL_INVALID_PARAMETER;
+ } else {
+ Number2Display = (UINTN)Intermediate;
+ if ((Number2Display == 0) || (Number2Display > MAXIMUM_DISPLAYCOUNT)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_INVALID_RANGE), mDpHiiHandle, L"-n", 0, MAXIMUM_DISPLAYCOUNT);
+ return SHELL_INVALID_PARAMETER;
+ }
+ }
+ }
+ } else {
+ Number2Display = DEFAULT_DISPLAYCOUNT;
+ }
+
+ if (ShellCommandLineGetFlag (ParamPackage, L"-t")) {
+ CmdLineArg = ShellCommandLineGetValue (ParamPackage, L"-t");
+ if (CmdLineArg == NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TOO_FEW), mDpHiiHandle);
+ return SHELL_INVALID_PARAMETER;
+ } else {
+ Status = ShellConvertStringToUint64 (CmdLineArg, &Intermediate, FALSE, TRUE);
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_INVALID_NUM_ARG), mDpHiiHandle, L"-t");
+ return SHELL_INVALID_PARAMETER;
+ } else {
+ mInterestThreshold = Intermediate;
+ }
+ }
+ } else {
+ mInterestThreshold = DEFAULT_THRESHOLD; // 1ms := 1,000 us
+ }
+
+ if (ShellCommandLineGetFlag (ParamPackage, L"-c")) {
+ CustomCumulativeToken = ShellCommandLineGetValue (ParamPackage, L"-c");
+ if (CustomCumulativeToken == NULL) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TOO_FEW), mDpHiiHandle);
+ return SHELL_INVALID_PARAMETER;
+ } else {
+ CustomCumulativeData = AllocateZeroPool (sizeof (PERF_CUM_DATA));
+ if (CustomCumulativeData == NULL) {
+ ShellStatus = SHELL_OUT_OF_RESOURCES;
+ goto Done;
+ }
+
+ CustomCumulativeData->MinDur = PERF_MAXDUR;
+ CustomCumulativeData->MaxDur = 0;
+ CustomCumulativeData->Count = 0;
+ CustomCumulativeData->Duration = 0;
+ NameSize = StrLen (CustomCumulativeToken) + 1;
+ CustomCumulativeData->Name = AllocateZeroPool (NameSize);
+ if (CustomCumulativeData->Name == NULL) {
+ ShellStatus = SHELL_OUT_OF_RESOURCES;
+ goto Done;
+ }
+
+ UnicodeStrToAsciiStrS (CustomCumulativeToken, CustomCumulativeData->Name, NameSize);
+ }
+ }
+
+ //
+ // DP dump performance data by parsing FPDT table in ACPI table.
+ // Folloing 3 steps are to get the measurement form the FPDT table.
+ //
+
+ //
+ // 1. Get FPDT from ACPI table.
+ //
+ Status = GetBootPerformanceTable ();
+ if (EFI_ERROR (Status)) {
+ ShellStatus = Status;
+ goto Done;
+ }
+
+ //
+ // 2. Cache the ModuleGuid and hanlde mapping table.
+ //
+ Status = BuildCachedGuidHandleTable ();
+ if (EFI_ERROR (Status)) {
+ ShellStatus = Status;
+ goto Done;
+ }
+
+ //
+ // 3. Build the measurement array form the FPDT records.
+ //
+ Status = BuildMeasurementList ();
+ if (EFI_ERROR (Status)) {
+ ShellStatus = SHELL_OUT_OF_RESOURCES;
+ goto Done;
+ }
+
+ //
+ // Initialize the pre-defined cumulative data.
+ //
+ InitCumulativeData ();
+
+ //
+ // Initialize the Summary data.
+ //
+ InitSummaryData ();
+
+ //
+ // Timer specific processing
+ //
+ // Get the Performance counter characteristics:
+ // Freq = Frequency in Hz
+ // StartCount = Value loaded into the counter when it starts counting
+ // EndCount = Value counter counts to before it needs to be reset
+ //
+ Status = EfiGetSystemConfigurationTable (&gPerformanceProtocolGuid, (VOID **)&PerformanceProperty);
+ if (EFI_ERROR (Status) || (PerformanceProperty == NULL)) {
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_PERF_PROPERTY_NOT_FOUND), mDpHiiHandle);
+ goto Done;
+ }
+
+ TimerInfo.Frequency = (UINT32)DivU64x32 (PerformanceProperty->Frequency, 1000);
+ TimerInfo.StartCount = 0;
+ TimerInfo.EndCount = 0xFFFF;
+ TimerInfo.CountUp = TRUE;
+
+ //
+ // Print header
+ //
+ // print DP's build version
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_BUILD_REVISION), mDpHiiHandle, DP_MAJOR_VERSION, DP_MINOR_VERSION);
+
+ // print performance timer characteristics
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_KHZ), mDpHiiHandle, TimerInfo.Frequency);
+
+ if (VerboseMode && !RawMode) {
+ StringPtr = HiiGetString (
+ mDpHiiHandle,
+ (EFI_STRING_ID)(TimerInfo.CountUp ? STRING_TOKEN (STR_DP_UP) : STRING_TOKEN (STR_DP_DOWN)),
+ NULL
+ );
+ ASSERT (StringPtr != NULL);
+ // Print Timer count range and direction
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_DP_TIMER_PROPERTIES),
+ mDpHiiHandle,
+ StringPtr,
+ TimerInfo.StartCount,
+ TimerInfo.EndCount
+ );
+ ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_VERBOSE_THRESHOLD), mDpHiiHandle, mInterestThreshold);
+ }
+
+ /****************************************************************************
+ **** Print Sections based on command line options
+ ****
+ **** Option modes have the following priority:
+ **** v Verbose -- Valid in combination with any other options
+ **** t Threshold -- Modifies All, Raw, and Cooked output
+ **** Default is 0 for All and Raw mode
+ **** Default is DEFAULT_THRESHOLD for "Cooked" mode
+ **** n Number2Display Used by All and Raw mode. Otherwise ignored.
+ **** A All -- R and S options are ignored
+ **** R Raw -- S option is ignored
+ **** s Summary -- Modifies "Cooked" output only
+ **** Cooked (Default)
+ ****************************************************************************/
+ GatherStatistics (CustomCumulativeData);
+ if (CumulativeMode) {
+ ProcessCumulative (CustomCumulativeData);
+ } else if (AllMode) {
+ Status = DumpAllTrace (Number2Display, ExcludeMode);
+ if (Status == EFI_ABORTED) {
+ ShellStatus = SHELL_ABORTED;
+ goto Done;
+ }
+ } else if (RawMode) {
+ Status = DumpRawTrace (Number2Display, ExcludeMode);
+ if (Status == EFI_ABORTED) {
+ ShellStatus = SHELL_ABORTED;
+ goto Done;
+ }
+ } else {
+ // ------------- Begin Cooked Mode Processing
+ ProcessPhases ();
+ if ( !SummaryMode) {
+ Status = ProcessHandles (ExcludeMode);
+ if (Status == EFI_ABORTED) {
+ ShellStatus = SHELL_ABORTED;
+ goto Done;
+ }
+
+ Status = ProcessPeims ();
+ if (Status == EFI_ABORTED) {
+ ShellStatus = SHELL_ABORTED;
+ goto Done;
+ }
+
+ Status = ProcessGlobal ();
+ if (Status == EFI_ABORTED) {
+ ShellStatus = SHELL_ABORTED;
+ goto Done;
+ }
+
+ ProcessCumulative (NULL);
+ }
+ } // ------------- End of Cooked Mode Processing
+
+ if ( VerboseMode || SummaryMode) {
+ DumpStatistics ();
+ }
+
+Done:
+ if (ParamPackage != NULL) {
+ ShellCommandLineFreeVarList (ParamPackage);
+ }
+
+ SHELL_FREE_NON_NULL (StringPtr);
+ if (CustomCumulativeData != NULL) {
+ SHELL_FREE_NON_NULL (CustomCumulativeData->Name);
+ }
+
+ SHELL_FREE_NON_NULL (CustomCumulativeData);
+
+ SHELL_FREE_NON_NULL (mMeasurementList);
+
+ SHELL_FREE_NON_NULL (mCacheHandleGuidTable);
+
+ mMeasurementNum = 0;
+ mCachePairCount = 0;
+ return ShellStatus;
+}
+
+/**
+ Retrieve HII package list from ImageHandle and publish to HII database.
+
+ @param ImageHandle The image handle of the process.
+
+ @return HII handle.
+**/
+EFI_HII_HANDLE
+InitializeHiiPackage (
+ EFI_HANDLE ImageHandle
+ )
+{
+ EFI_STATUS Status;
+ EFI_HII_PACKAGE_LIST_HEADER *PackageList;
+ EFI_HII_HANDLE HiiHandle;
+
+ //
+ // Retrieve HII package list from ImageHandle
+ //
+ Status = gBS->OpenProtocol (
+ ImageHandle,
+ &gEfiHiiPackageListProtocolGuid,
+ (VOID **)&PackageList,
+ ImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ }
+
+ //
+ // Publish HII package list to HII Database.
+ //
+ Status = gHiiDatabase->NewPackageList (
+ gHiiDatabase,
+ PackageList,
+ NULL,
+ &HiiHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ }
+
+ return HiiHandle;
+}