Since performance library instances have been updated to create new FPDT records for new Perf macros. So enhance dp tool to parse the new FPDT records. Enhancement mainly includes: 1. parse the single records for PERF_EVENT macro 2. Parse the new added FPDT_DUAL_GUID_STRING_EVENT_RECORD
Cc: Liming Gao <liming....@intel.com> Cc: Ruiyu Ni <ruiyu...@intel.com> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Dandan Bi <dandan...@intel.com> --- ShellPkg/DynamicCommand/DpDynamicCommand/Dp.c | 75 +++++++++++++++++++--- ShellPkg/DynamicCommand/DpDynamicCommand/Dp.h | 1 + .../DynamicCommand/DpDynamicCommand/DpInternal.h | 14 ++++ ShellPkg/DynamicCommand/DpDynamicCommand/DpTrace.c | 4 +- .../DynamicCommand/DpDynamicCommand/DpUtilities.c | 31 +++++++++ 5 files changed, 113 insertions(+), 12 deletions(-) diff --git a/ShellPkg/DynamicCommand/DpDynamicCommand/Dp.c b/ShellPkg/DynamicCommand/DpDynamicCommand/Dp.c index 38766613175..925341303a4 100644 --- a/ShellPkg/DynamicCommand/DpDynamicCommand/Dp.c +++ b/ShellPkg/DynamicCommand/DpDynamicCommand/Dp.c @@ -428,15 +428,29 @@ GetMeasurementInfo ( break; default: ASSERT(FALSE); } - if (AsciiStrCmp (Measurement->Token, ALit_PEIM) == 0) { - Measurement->Handle = &(((FPDT_GUID_EVENT_RECORD *)RecordHeader)->Guid); + 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; + 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); @@ -481,15 +495,27 @@ GetMeasurementInfo ( break; } Measurement->Module = ((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->String; - if (AsciiStrCmp (Measurement->Token, ALit_PEIM) == 0) { + 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); @@ -551,10 +577,24 @@ GetMeasurementInfo ( } 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; } } @@ -578,10 +618,18 @@ SearchMeasurement ( (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; @@ -618,29 +666,36 @@ BuildMeasurementList ( 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 >= PERF_EVENTSIGNAL_START_ID && ((StartProgressId & 0x000F) == 0)) || + 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 (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; + 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; diff --git a/ShellPkg/DynamicCommand/DpDynamicCommand/Dp.h b/ShellPkg/DynamicCommand/DpDynamicCommand/Dp.h index aae021334d6..96bc89db8dc 100644 --- a/ShellPkg/DynamicCommand/DpDynamicCommand/Dp.h +++ b/ShellPkg/DynamicCommand/DpDynamicCommand/Dp.h @@ -39,10 +39,11 @@ #include <Library/PcdLib.h> #include <Library/SortLib.h> #include <Library/HiiLib.h> #include <Library/FileHandleLib.h> #include <Library/UefiHiiServicesLib.h> +#include <Library/Performancelib.h> extern EFI_HANDLE mDpHiiHandle; #define DP_MAJOR_VERSION 2 #define DP_MINOR_VERSION 5 diff --git a/ShellPkg/DynamicCommand/DpDynamicCommand/DpInternal.h b/ShellPkg/DynamicCommand/DpDynamicCommand/DpInternal.h index 8dd3076cc71..d8bc7453d2d 100644 --- a/ShellPkg/DynamicCommand/DpDynamicCommand/DpInternal.h +++ b/ShellPkg/DynamicCommand/DpDynamicCommand/DpInternal.h @@ -83,10 +83,24 @@ GetDuration ( BOOLEAN IsPhase( IN MEASUREMENT_RECORD *Measurement ); +/** + Determine whether the Measurement record is for core code. + + @param[in] Measurement A pointer to the Measurement record to test. + + @retval TRUE The measurement record is used for core. + @retval FALSE The measurement record is NOT used for core. + +**/ +BOOLEAN +IsCorePerf( + IN MEASUREMENT_RECORD *Measurement + ); + /** Get the file name portion of the Pdb File Name. The portion of the Pdb File Name between the last backslash and either a following period or the end of the string is converted diff --git a/ShellPkg/DynamicCommand/DpDynamicCommand/DpTrace.c b/ShellPkg/DynamicCommand/DpDynamicCommand/DpTrace.c index 7f7d296946f..675cbc3fd14 100644 --- a/ShellPkg/DynamicCommand/DpDynamicCommand/DpTrace.c +++ b/ShellPkg/DynamicCommand/DpDynamicCommand/DpTrace.c @@ -602,11 +602,11 @@ ProcessHandles( Count++; Duration = GetDuration (&Measurement); ElapsedTime = DurationInMicroSeconds ( Duration ); if ((ElapsedTime < mInterestThreshold) || (Measurement.EndTimeStamp == 0) || - (Measurement.Handle == NULL) || + (!IsCorePerf (&Measurement)) || ((ExcludeFlag) && (GetCumulativeItem(&Measurement) >= 0)) ) { // Ignore "uninteresting" or excluded records continue; } mGaugeString[0] = 0; // Empty driver name by default @@ -792,11 +792,11 @@ ProcessGlobal( AsciiStrToUnicodeStrS (Measurement.Module, mGaugeString, ARRAY_SIZE (mGaugeString)); AsciiStrToUnicodeStrS (Measurement.Token, mUnicodeToken, ARRAY_SIZE (mUnicodeToken)); mGaugeString[25] = 0; mUnicodeToken[31] = 0; if ( ! ( IsPhase( &Measurement) || - (Measurement.Handle != NULL) || + IsCorePerf (&Measurement) || (Measurement.EndTimeStamp == 0) )) { Duration = GetDuration (&Measurement); ElapsedTime = DurationInMicroSeconds ( Duration ); diff --git a/ShellPkg/DynamicCommand/DpDynamicCommand/DpUtilities.c b/ShellPkg/DynamicCommand/DpDynamicCommand/DpUtilities.c index 39f71a044c3..5c6ab209d5a 100644 --- a/ShellPkg/DynamicCommand/DpDynamicCommand/DpUtilities.c +++ b/ShellPkg/DynamicCommand/DpDynamicCommand/DpUtilities.c @@ -106,10 +106,41 @@ IsPhase( (AsciiStrCmp (Measurement->Token, ALit_BDS) == 0)) ); return RetVal; } +/** + Determine whether the Measurement record is for core code. + + @param[in] Measurement A pointer to the Measurement record to test. + + @retval TRUE The measurement record is used for core. + @retval FALSE The measurement record is NOT used for core. + +**/ +BOOLEAN +IsCorePerf( + IN MEASUREMENT_RECORD *Measurement + ) +{ + BOOLEAN RetVal; + + RetVal = (BOOLEAN)( + ((Measurement->Identifier == MODULE_START_ID) || + (Measurement->Identifier == MODULE_END_ID) || + (Measurement->Identifier == MODULE_LOADIMAGE_START_ID) || + (Measurement->Identifier == MODULE_LOADIMAGE_END_ID) || + (Measurement->Identifier == MODULE_DB_START_ID) || + (Measurement->Identifier == MODULE_DB_END_ID) || + (Measurement->Identifier == MODULE_DB_SUPPORT_START_ID) || + (Measurement->Identifier == MODULE_DB_SUPPORT_END_ID) || + (Measurement->Identifier == MODULE_DB_STOP_START_ID) || + (Measurement->Identifier == MODULE_DB_STOP_START_ID)) + ); + return RetVal; +} + /** Get the file name portion of the Pdb File Name. The portion of the Pdb File Name between the last backslash and either a following period or the end of the string is converted -- 2.14.3.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel