diff --git a/UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeaturesLib.inf b/UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeaturesLib.inf index d803012ce2..1b823155b1 100644 --- a/UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeaturesLib.inf +++ b/UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeaturesLib.inf @@ -58,8 +58,9 @@ LocalApicLib [Pcd] - gUefiCpuPkgTokenSpaceGuid.PcdCpuClockModulationDutyCycle ## SOMETIMES_CONSUMES - gUefiCpuPkgTokenSpaceGuid.PcdIsPowerOnReset ## SOMETIMES_CONSUMES - gUefiCpuPkgTokenSpaceGuid.PcdCpuProcTraceOutputScheme ## SOMETIMES_CONSUMES - gUefiCpuPkgTokenSpaceGuid.PcdCpuProcTraceMemSize ## SOMETIMES_CONSUMES - gUefiCpuPkgTokenSpaceGuid.PcdCpuProcTraceBspOnly ## SOMETIMES_CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuClockModulationDutyCycle ## SOMETIMES_CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdIsPowerOnReset ## SOMETIMES_CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuProcTraceOutputScheme ## SOMETIMES_CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuProcTraceMemSize ## SOMETIMES_CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuProcTraceBspOnly ## SOMETIMES_CONSUMES + gUefiCpuPkgTokenSpaceGuid.PcdCpuProcTracePerformanceCollecting ## SOMETIMES_CONSUMES diff --git a/UefiCpuPkg/Library/CpuCommonFeaturesLib/ProcTrace.c b/UefiCpuPkg/Library/CpuCommonFeaturesLib/ProcTrace.c index 92d6f54b42..a4510eb802 100644 --- a/UefiCpuPkg/Library/CpuCommonFeaturesLib/ProcTrace.c +++ b/UefiCpuPkg/Library/CpuCommonFeaturesLib/ProcTrace.c @@ -33,6 +33,7 @@ typedef struct { MSR_IA32_RTIT_CTL_REGISTER RtitCtrl; MSR_IA32_RTIT_OUTPUT_BASE_REGISTER RtitOutputBase; MSR_IA32_RTIT_OUTPUT_MASK_PTRS_REGISTER RtitOutputMaskPtrs; + BOOLEAN CycPacketSupported; } PROC_TRACE_PROCESSOR_DATA; typedef struct { @@ -47,6 +48,7 @@ typedef struct { UINTN *TopaMemArray; BOOLEAN EnableOnBspOnly; + BOOLEAN EnablePerformanceCollecting; PROC_TRACE_PROCESSOR_DATA *ProcessorData; } PROC_TRACE_DATA; @@ -76,10 +78,11 @@ ProcTraceGetConfigData ( ASSERT (ConfigData != NULL); ConfigData->ProcessorData = (PROC_TRACE_PROCESSOR_DATA *)((UINT8 *)ConfigData + sizeof (PROC_TRACE_DATA)); - ConfigData->NumberOfProcessors = (UINT32)NumberOfProcessors; - ConfigData->ProcTraceMemSize = PcdGet32 (PcdCpuProcTraceMemSize); - ConfigData->ProcTraceOutputScheme = PcdGet8 (PcdCpuProcTraceOutputScheme); - ConfigData->EnableOnBspOnly = PcdGetBool (PcdCpuProcTraceBspOnly); + ConfigData->NumberOfProcessors = (UINT32)NumberOfProcessors; + ConfigData->ProcTraceMemSize = PcdGet32 (PcdCpuProcTraceMemSize); + ConfigData->ProcTraceOutputScheme = PcdGet8 (PcdCpuProcTraceOutputScheme); + ConfigData->EnableOnBspOnly = PcdGetBool (PcdCpuProcTraceBspOnly); + ConfigData->EnablePerformanceCollecting = PcdGetBool (PcdCpuProcTracePerformanceCollecting); return ConfigData; } @@ -111,7 +114,8 @@ ProcTraceSupport ( { PROC_TRACE_DATA *ProcTraceData; CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_EBX Ebx; - CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF_ECX Ecx; + CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF_ECX ProcTraceEcx; + CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF_EBX ProcTraceEbx; // // Check if ProcTraceMemorySize option is enabled (0xFF means disable by user) @@ -132,15 +136,17 @@ ProcTraceSupport ( return FALSE; } - AsmCpuidEx (CPUID_INTEL_PROCESSOR_TRACE, CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF, NULL, NULL, &Ecx.Uint32, NULL); - ProcTraceData->ProcessorData[ProcessorNumber].TopaSupported = (BOOLEAN)(Ecx.Bits.RTIT == 1); - ProcTraceData->ProcessorData[ProcessorNumber].SingleRangeSupported = (BOOLEAN)(Ecx.Bits.SingleRangeOutput == 1); + AsmCpuidEx (CPUID_INTEL_PROCESSOR_TRACE, CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF, NULL, &ProcTraceEbx.Uint32, &ProcTraceEcx.Uint32, NULL); + ProcTraceData->ProcessorData[ProcessorNumber].TopaSupported = (BOOLEAN)(ProcTraceEcx.Bits.RTIT == 1); + ProcTraceData->ProcessorData[ProcessorNumber].SingleRangeSupported = (BOOLEAN)(ProcTraceEcx.Bits.SingleRangeOutput == 1); if ((ProcTraceData->ProcessorData[ProcessorNumber].TopaSupported && (ProcTraceData->ProcTraceOutputScheme == RtitOutputSchemeToPA)) || (ProcTraceData->ProcessorData[ProcessorNumber].SingleRangeSupported && (ProcTraceData->ProcTraceOutputScheme == RtitOutputSchemeSingleRange))) { ProcTraceData->ProcessorData[ProcessorNumber].RtitCtrl.Uint64 = AsmReadMsr64 (MSR_IA32_RTIT_CTL); ProcTraceData->ProcessorData[ProcessorNumber].RtitOutputBase.Uint64 = AsmReadMsr64 (MSR_IA32_RTIT_OUTPUT_BASE); ProcTraceData->ProcessorData[ProcessorNumber].RtitOutputMaskPtrs.Uint64 = AsmReadMsr64 (MSR_IA32_RTIT_OUTPUT_MASK_PTRS); + ProcTraceData->ProcessorData[ProcessorNumber].CycPacketSupported = (BOOLEAN)(ProcTraceEbx.Bits.ConfigurablePsb == 1); + return TRUE; } @@ -517,6 +523,22 @@ ProcTraceInitialize ( CtrlReg.Bits.User = 1; CtrlReg.Bits.BranchEn = 1; CtrlReg.Bits.TraceEn = 1; + + // + // Generate CYC/TSC timing packets to collect performance data. + // + if (ProcTraceData->EnablePerformanceCollecting) { + if (ProcTraceData->ProcessorData[ProcessorNumber].CycPacketSupported) { + CtrlReg.Bits.CYCEn = 1; + CtrlReg.Bits.CYCThresh = 5; + } + + // + // Write to TSCEn is always supported + // + CtrlReg.Bits.TSCEn = 1; + } + CPU_REGISTER_TABLE_WRITE64 ( ProcessorNumber, Msr, diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec index 6845e80706..d31c3b127c 100644 --- a/UefiCpuPkg/UefiCpuPkg.dec +++ b/UefiCpuPkg/UefiCpuPkg.dec @@ -345,6 +345,14 @@ # @Prompt Enable CPU processor trace only on BSP. gUefiCpuPkgTokenSpaceGuid.PcdCpuProcTraceBspOnly|FALSE|BOOLEAN|0x60000019 + ## This PCD indicates if enable performance collecting when CPU processor trace is enabled.

+ # CYC/TSC timing packets will be generated to collect performance data if this PCD is TRUE. + # This PCD is ignored if CPU processor trace is disabled.

+ # TRUE - Performance collecting will be enabled in processor trace.
+ # FASLE - Performance collecting will be disabled in processor trace.
+ # @Prompt Enable performance collecting when processor trace is enabled. + gUefiCpuPkgTokenSpaceGuid.PcdCpuProcTracePerformanceCollecting|FALSE|BOOLEAN|0x60000020 + [PcdsFixedAtBuild.X64, PcdsPatchableInModule.X64, PcdsDynamic.X64, PcdsDynamicEx.X64] ## Indicate access to non-SMRAM memory is restricted to reserved, runtime and ACPI NVS type after SmmReadyToLock. # MMIO access is always allowed regardless of the value of this PCD.