alder_lake_bios/Intel/AlderLake/ClientOneSiliconPkg/Cpu/LibraryPrivate/PeiCpuPowerMgmtLib/PowerMgmtInitPeim.c

800 lines
25 KiB
C

/** @file
Processor Power Management initialization code. This code determines current
user configuration and modifies and loads ASL as well as initializing chipset
and processor features to enable the proper power management.
Acronyms:
PPM - Processor Power Management
TM - Thermal Monitor
IST - Intel(R) Speedstep technology
HT - Hyper-Threading Technology
ITBM - Intel(R) Turbo Boost Max Technology 3.0
@copyright
INTEL CONFIDENTIAL
Copyright 1999 - 2021 Intel Corporation.
The source code contained or described herein and all documents related to the
source code ("Material") are owned by Intel Corporation or its suppliers or
licensors. Title to the Material remains with Intel Corporation or its suppliers
and licensors. The Material may contain trade secrets and proprietary and
confidential information of Intel Corporation and its suppliers and licensors,
and is protected by worldwide copyright and trade secret laws and treaty
provisions. No part of the Material may be used, copied, reproduced, modified,
published, uploaded, posted, transmitted, distributed, or disclosed in any way
without Intel's prior express written permission.
No license under any patent, copyright, trade secret or other intellectual
property right is granted to or conferred upon you by disclosure or delivery
of the Materials, either expressly, by implication, inducement, estoppel or
otherwise. Any license under such intellectual property rights must be
express and approved by Intel in writing.
Unless otherwise agreed by Intel in writing, you may not remove or alter
this notice or any other notice embedded in Materials by Intel or
Intel's suppliers or licensors in any way.
This file contains an 'Intel Peripheral Driver' and is uniquely identified as
"Intel Reference Module" and is licensed for Intel CPUs and chipsets under
the terms of your license agreement with Intel or your vendor. This file may
be modified by the user, subject to additional terms of the license agreement.
@par Specification
**/
#include "PowerMgmtInitPeim.h"
#include <Library/PciSegmentLib.h>
#include <Library/ConfigBlockLib.h>
#include <Library/PostCodeLib.h>
#include <Library/PreSiliconEnvDetectLib.h>
#if FixedPcdGetBool(PcdITbtEnable) == 1
#include <TcssDataHob.h>
#endif
#include <Library/MsrFruLib.h>
extern EFI_GUID gCpuInitDataHobGuid;
//
// Global variables
//
///
/// Power Managment policy configurations
///
SI_POLICY_PPI *gSiCpuPolicy = NULL;
SI_PREMEM_POLICY_PPI *gSiPreMemPolicy = NULL;
CPU_POWER_MGMT_BASIC_CONFIG *gCpuPowerMgmtBasicConfig = NULL;
CPU_POWER_MGMT_CUSTOM_CONFIG *gCpuPowerMgmtCustomConfig = NULL;
CPU_POWER_MGMT_PSYS_CONFIG *gCpuPowerMgmtPsysConfig = NULL;
CPU_POWER_MGMT_TEST_CONFIG *gCpuPowerMgmtTestConfig = NULL;
OVERCLOCKING_PREMEM_CONFIG *gOverClockingPreMemConfig = NULL;
CPU_CONFIG_LIB_PREMEM_CONFIG *gCpuConfigLibPreMemConfig = NULL;
CPU_POWER_MGMT_VR_CONFIG *gCpuPowerMgmtVrConfig = NULL;
CPU_INIT_DATA_HOB *mCpuInitDataHob = NULL;
//
// Values for FVID table calculate.
//
UINT32 mPpmFlags = 0;
UINT16 mTurboBusRatio = 0;
UINT8 mMaxBusRatio = 0;
UINT8 mMinBusRatio = 0;
UINT16 mProcessorFlavor = 0;
UINT16 mPackageTdp = 0; ///< Processor TDP value in MSR_PACKAGE_POWER_SKU.
UINT16 mPackageTdpWatt = 0; ///< Processor TDP value in Watts.
UINT16 mCpuConfigTdpBootRatio = 0; ///< Config TDP Boot settings
UINT16 mCustomPowerUnit = 1;
UINT8 mCtdpCtc[TDP_MAX_LEVEL]; /// CTDP Levels CTC
UINT8 mCtdpPpc[TDP_MAX_LEVEL]; /// CTDP Levels PPC
UINT8 mCtdpTar[TDP_MAX_LEVEL]; /// CTDP Levels TAR
UINT8 mConfigTdpBootModeIndex;
UINT8 mLowestMaxPerf = 0;
UINT8 mCtdpLevelsSupported;
UINT8 mConfigurablePpc;
UINT8 mCtdpPowerLimitWindow[TDP_MAX_LEVEL];
UINT16 mCtdpPowerLimit1[TDP_MAX_LEVEL];
UINT16 mCtdpPowerLimit2[TDP_MAX_LEVEL];
UINT8 mEnableItbm;
///
/// Fractional part of Processor Power Unit in Watts. (i.e. Unit is 1/mProcessorPowerUnit)
///
UINT8 mProcessorPowerUnit = 0;
///
/// Maximum allowed power limit value in TURBO_POWER_LIMIT_MSR and PRIMARY_PLANE_POWER_LIMIT_MSR
/// in units specified by PACKAGE_POWER_SKU_UNIT_MSR
///
UINT16 mPackageMaxPower = 0;
///
/// Minimum allowed power limit value in TURBO_POWER_LIMIT_MSR and PRIMARY_PLANE_POWER_LIMIT_MSR
/// in units specified by PACKAGE_POWER_SKU_UNIT_MSR
///
UINT16 mPackageMinPower = 0;
UINT8 mRatioLimitProgrammble = 0; ///< Programmable Ratio Limit
UINT8 mTdpLimitProgrammable = 0; ///< Programmable TDP Limit
///
/// Cpu Identifier used for PM overrides
///
UINT32 mCpuIdentifier;
//
// FVID Table Information
// Default FVID table
// One header field plus states
//
FVID_TABLE *mFvidPointer = NULL;
/**
Power Management init after memory PEI module
@retval EFI_SUCCESS The driver installes/initialized correctly.
@retval Driver will ASSERT in debug builds on error. PPM functionality is considered critical for mobile systems.
**/
EFI_STATUS
CpuPowerMgmtInit (
VOID
)
{
EFI_STATUS Status;
VOID *Hob;
DEBUG ((DEBUG_INFO, "CpuPowerMgmtInit Start \n"));
PostCode (0xC6A);
DEBUG ((DEBUG_INFO, " PeimInitializePowerMgmt Entry\n"));
///
/// Locate platform configuration information
///
Status = PeiServicesLocatePpi (
&gSiPolicyPpiGuid,
0,
NULL,
(VOID **) &gSiCpuPolicy);
ASSERT_EFI_ERROR (Status);
Status = PeiServicesLocatePpi (
&gSiPreMemPolicyPpiGuid,
0,
NULL,
(VOID **) &gSiPreMemPolicy);
ASSERT_EFI_ERROR (Status);
///
/// Initialize the Global pointer for Power Managment Policy
///
Status = GetConfigBlock ((VOID *) gSiCpuPolicy, &gCpuPowerMgmtBasicConfigGuid, (VOID *) &gCpuPowerMgmtBasicConfig);
ASSERT_EFI_ERROR (Status);
Status = GetConfigBlock ((VOID *) gSiCpuPolicy, &gCpuPowerMgmtCustomConfigGuid, (VOID *) &gCpuPowerMgmtCustomConfig);
ASSERT_EFI_ERROR (Status);
Status = GetConfigBlock ((VOID *) gSiCpuPolicy, &gCpuPowerMgmtPsysConfigGuid, (VOID *) &gCpuPowerMgmtPsysConfig);
ASSERT_EFI_ERROR (Status);
Status = GetConfigBlock ((VOID *) gSiCpuPolicy, &gCpuPowerMgmtTestConfigGuid, (VOID *) &gCpuPowerMgmtTestConfig);
ASSERT_EFI_ERROR (Status);
Status = GetConfigBlock ((VOID *) gSiPreMemPolicy, &gOverclockingPreMemConfigGuid, (VOID *) &gOverClockingPreMemConfig);
ASSERT_EFI_ERROR (Status);
Status = GetConfigBlock ((VOID *) gSiPreMemPolicy, &gCpuConfigLibPreMemConfigGuid, (VOID *) &gCpuConfigLibPreMemConfig);
ASSERT_EFI_ERROR (Status);
Status = GetConfigBlock ((VOID *) gSiCpuPolicy, &gCpuConfigGuid, (VOID *) &mCpuConfig);
ASSERT_EFI_ERROR (Status);
Status = GetConfigBlock ((VOID*) gSiCpuPolicy, &gCpuPowerMgmtVrConfigGuid, (VOID*) &gCpuPowerMgmtVrConfig);
ASSERT_EFI_ERROR (Status);
if (mCpuConfig->SkipMpInit == 0) {
///
/// Locate MpService Ppi
///
Status = PeiServicesLocatePpi (
&gEdkiiPeiMpServices2PpiGuid,
0,
NULL,
(VOID **) &mMpServices2Ppi);
ASSERT_EFI_ERROR (Status);
///
/// Get CPU Init Data Hob
///
Hob = GetFirstGuidHob (&gCpuInitDataHobGuid);
if (Hob == NULL) {
DEBUG ((DEBUG_ERROR, "CPU Data HOB not available\n"));
return EFI_NOT_FOUND;
}
mCpuInitDataHob = (CPU_INIT_DATA_HOB *) ((UINTN) Hob + sizeof (EFI_HOB_GUID_TYPE));
///
/// Initialize FVID table pointer
///
DEBUG((DEBUG_INFO, "Initialize FVID table pointer\n"));
mFvidPointer = (FVID_TABLE *) &(mCpuInitDataHob->FvidTable);
}
///
/// Initialize Power management Global variables
///
InitPowerManagementGlobalVariables ();
///
/// Initialize CPU Power management code (determine HW and configured state, configure hardware and software accordingly)
///
Status = InitPpm ();
ASSERT_EFI_ERROR (Status);
DEBUG((DEBUG_INFO, "CpuPowerMgmtInit Done \n"));
DEBUG((DEBUG_INFO, "CPU Post-Mem Exit \n"));
PostCode (0xC7F);
return EFI_SUCCESS;
}
/**
Initializes the platform power management global variable.
This must be called prior to any of the functions being used.
**/
VOID
InitPowerManagementGlobalVariables (
VOID
)
{
MSR_PACKAGE_POWER_SKU_REGISTER PackagePowerSkuMsr;
MSR_PACKAGE_POWER_SKU_UNIT_REGISTER PackagePowerSkuUnitMsr;
CPU_SKU CpuSku;
///
/// Get Platform ID by reading System Agent's Device ID (B0:D0:F0:R02)
///
mProcessorFlavor = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS (SA_SEG_NUM, SA_MC_BUS, SA_MC_DEV, SA_MC_FUN, R_SA_MC_DEVICE_ID));
///
/// Get Maximum Non-Turbo bus ratio (HFM) from Platform Info MSR Bits[15:8]
/// Get Maximum Efficiency bus ratio (LFM) from Platform Info MSR Bits[47:40]
///
MsrGetBusRatio (&mMaxBusRatio, &mMinBusRatio);
mTurboBusRatio = MsrGetMaxTurboRatio ();
///
/// Check if Turbo Ratio Limit is programmable
/// Platform Info MSR (0xCE) [28]
///
mRatioLimitProgrammble = (UINT8) MsrIsTurboRatioLimitProgrammable ();
///
/// Check if TDP Limit is programmable
/// Platform Info MSR (0xCE) [29]
///
mTdpLimitProgrammable = (UINT8) MsrIsTdpLimitProgrammable ();
if (mTdpLimitProgrammable) {
mConfigTdpBootModeIndex = (UINT8) gCpuConfigLibPreMemConfig->ConfigTdpLevel;
} else {
mConfigTdpBootModeIndex = 0;
}
///
/// Get Processor TDP
/// Get Maximum Power from Turbo Power Limit MSR Bits[46:32]
/// and convert it to units specified by Package Power SKU
/// Unit MSR [3:0]
///
PackagePowerSkuMsr.Uint64 = AsmReadMsr64 (MSR_PACKAGE_POWER_SKU);
PackagePowerSkuUnitMsr.Uint64 = AsmReadMsr64 (MSR_PACKAGE_POWER_SKU_UNIT);
mProcessorPowerUnit = (UINT8) PackagePowerSkuUnitMsr.Bits.PwrUnit;
if (mProcessorPowerUnit == 0) {
mProcessorPowerUnit = 1;
} else {
mProcessorPowerUnit = (UINT8) LShiftU64 (2, (mProcessorPowerUnit - 1));
if (IsSimicsEnvironment()) {
if (mProcessorPowerUnit == 0) {
mProcessorPowerUnit = 1;
}
}
}
mPackageTdp = (UINT16) PackagePowerSkuMsr.Bits.PkgTdp;
mPackageTdpWatt = (UINT16) DivU64x32 (mPackageTdp , mProcessorPowerUnit);
mPackageMaxPower = (UINT16) PackagePowerSkuMsr.Bits.PkgMaxPwr;
mPackageMinPower = (UINT16) PackagePowerSkuMsr.Bits.PkgMinPwr;
///
/// Set mCustomPowerUnit to user selected Power unit
///
mCustomPowerUnit = 1;
if (gCpuPowerMgmtTestConfig->CustomPowerUnit == PowerUnit125MilliWatts) {
mCustomPowerUnit = 8; ///< Unit is 125 milli watt
}
if (mCpuConfig->SkipMpInit == 0) {
///
/// Intel Turbo Boost Max Technology 3.0
///
mEnableItbm = gCpuPowerMgmtBasicConfig->EnableItbm;
if (mTdpLimitProgrammable) {
mCpuIdentifier = GetCpuIdentifierWithCtdp (mConfigTdpBootModeIndex);
} else {
mCpuIdentifier = GetCpuIdentifier ();
}
///
/// Initialize the CpuIdentifier when Vr Power Delivery design is enabled.
///
CpuSku = GetCpuSku ();
if ((CpuSku == EnumCpuHalo) || (CpuSku == EnumCpuTrad)) {
if (gCpuPowerMgmtVrConfig->VrPowerDeliveryDesign != 0) {
mCpuIdentifier = gCpuPowerMgmtVrConfig->VrPowerDeliveryDesign;
DEBUG ((DEBUG_INFO, "CPU Identifier from VR Power Design - %x \n", mCpuIdentifier));
} else {
DEBUG ((DEBUG_ERROR, "VR ERROR: VrPowerDeliveryDesign is missing! VR override values may take effect !\n"));
}
}
///
/// Initialize flags based on processor capablities
///
SetPpmFlags ();
///
/// Determine current user configuration
///
SetUserConfigurationPpmFlags ();
///
/// Set Misc PPM flags based on other configuration status
///
MiscSetPpmFlags ();
}
return;
}
/**
Set the PPM flags
**/
VOID
SetPpmFlags (
VOID
)
{
MSR_MISC_ENABLES_REGISTER MiscEnable;
MSR_FLEX_RATIO_REGISTER FlexRatioMsr;
CPUID_VERSION_INFO_ECX VersionInfoEcx;
CPUID_VERSION_INFO_EDX VersionInfoEdx;
CPUID_MONITOR_MWAIT_ECX MonitorMwaitEcx;
CPUID_MONITOR_MWAIT_EDX MonitorMwaitEdx;
CPUID_THERMAL_POWER_MANAGEMENT_EAX PowerEax;
UINT8 Threads;
UINT8 OverclockingBins;
UINTN States;
BOOLEAN CpuidLimitingEnabled;
UINT32 PpmFlags;
PpmFlags = 0;
///
/// Check if the processor has multiple threads.
/// @todo CMP should only be set if the processor has multiple cores,
/// but current usage expects it to be set based on threads.
///
GetEnabledCoreThreadCount (NULL, &Threads);
if ((Threads) > 1) {
PpmFlags |= PPM_CMP;
}
///
/// Disable CPUID limiting (and save current setting) if enabled
/// and enable MONITOR/MWAIT support
///
MiscEnable.Uint64 = AsmReadMsr64 (MSR_IA32_MISC_ENABLE);
CpuidLimitingEnabled = (BOOLEAN) MiscEnable.Bits.BootNt4;
if (CpuidLimitingEnabled) {
MiscEnable.Bits.BootNt4 = 0;
AsmWriteMsr64 (MSR_IA32_MISC_ENABLE, MiscEnable.Uint64);
}
///
/// Read the CPUID values we care about. To get the correct MONITOR/MWAIT-related values,
/// we need to read after we have disabled limiting and enabled MONITOR/MWAIT
///
AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, &VersionInfoEcx.Uint32, &VersionInfoEdx.Uint32);
AsmCpuid (CPUID_MONITOR_MWAIT, NULL, NULL, &MonitorMwaitEcx.Uint32, &MonitorMwaitEdx.Uint32);
AsmCpuid (CPUID_THERMAL_POWER_MANAGEMENT, &PowerEax.Uint32, NULL, NULL, NULL);
///
/// Check Thermal Monitor capable and update the flag.
///
if (VersionInfoEdx.Bits.TM == 1) {
PpmFlags |= PPM_TM;
}
///
/// Check Enhanced Intel SpeedStep(R) technology capable.
///
if (VersionInfoEcx.Bits.EIST == 1) {
PpmFlags |= (PPM_EIST);
DEBUG ((DEBUG_INFO, "EIST capable\n"));
}
///
/// Determine if the MONITOR/MWAIT instructions are supported.
///
if ((VersionInfoEcx.Bits.MONITOR == 1) && (MonitorMwaitEcx.Bits.ExtensionsSupported == 1)) {
PpmFlags |= PPM_MWAIT_EXT;
}
///
/// Determine the C-State and Enhanced C-State support present.
/// Monitor/MWAIT parameters function describes the numbers supported.
///
States = MonitorMwaitEdx.Bits.C1States;
if (States >= ENHANCED_CSTATE_SUPPORTED) {
PpmFlags |= (PPM_C1 | PPM_C1E);
} else if (States == CSTATE_SUPPORTED) {
PpmFlags |= PPM_C1;
}
States = MonitorMwaitEdx.Bits.C3States;
if (States >= C6_C7_LONG_LATENCY_SUPPORTED) { // Both Long and Short Latency C6 supported
PpmFlags |= (PPM_C6 | C6_LONG_LATENCY_ENABLE);
} else if (States >= C6_C7_SHORT_LATENCY_SUPPORTED) { // Only Short Latency C6 supported.
PpmFlags |= PPM_C6;
}
States = MonitorMwaitEdx.Bits.C4States;
switch (States) {
case C7s_LONG_LATENCY_SUPPORTED:
//
// C7 & C7s Long and Short supported
//
PpmFlags |= (PPM_C7S | C7s_LONG_LATENCY_ENABLE | PPM_C7 | C7_LONG_LATENCY_ENABLE);
break;
case C7s_SHORT_LATENCY_SUPPORTED:
//
// C7s Long Latency is not supported.
//
PpmFlags |= (PPM_C7S | PPM_C7 | C7_LONG_LATENCY_ENABLE);
break;
case C6_C7_LONG_LATENCY_SUPPORTED:
//
// C7 Long and Short supported
//
PpmFlags |= (PPM_C7 | C7_LONG_LATENCY_ENABLE);
break;
case C6_C7_SHORT_LATENCY_SUPPORTED:
//
// C7 Long Latency is not supported.
//
PpmFlags |= PPM_C7;
break;
default:
break;
}
States = MonitorMwaitEdx.Bits.C5States;
if (States >= CSTATE_SUPPORTED) {
PpmFlags |= PPM_C8;
}
States = MonitorMwaitEdx.Bits.C6States;
if (States >= CSTATE_SUPPORTED) {
PpmFlags |= PPM_C9;
}
States = MonitorMwaitEdx.Bits.C7States;
if (States >= CSTATE_SUPPORTED) {
PpmFlags |= PPM_C10;
}
///
/// Check if TimedMwait is supported and update the flag
///
if (MsrIsTimedMwaitSupported ()) {
PpmFlags |= PPM_TIMED_MWAIT;
}
if (PpmFlags & (PPM_C8 |PPM_C9 | PPM_C10)) {
PpmFlags |= PPM_CD;
}
///
/// Check if turbo mode is supported and update the flag
///
if ((PowerEax.Bits.TurboBoostTechnology == 0) &&
(MiscEnable.Bits.TurboModeDisable == 0)
) {
///
/// Turbo Mode is not available in this physical processor package.
/// BIOS should not attempt to enable Turbo Mode via IA32_MISC_ENABLE MSR.
/// BIOS should show Turbo Mode as Disabled and Not Configurable.
///
} else if (PowerEax.Bits.TurboBoostTechnology == 0) {
///
/// Turbo Mode is available but globally disabled for the all logical
/// processors in this processor package.
/// BIOS can enable Turbo Mode by IA32_MISC_ENABLE MSR 1A0h bit [38] = 0.
///
PpmFlags |= PPM_TURBO;
} else if (PowerEax.Bits.TurboBoostTechnology == 1) {
///
/// Turbo Mode is factory-configured as available and enabled for all logical processors in this processor package.
/// This case handles the cases where turbo mode is enabled before PPM gets chance to enable it
///
PpmFlags |= PPM_TURBO;
}
///
/// Restore the CPUID limit setting.
///
if (CpuidLimitingEnabled) {
MiscEnable.Bits.BootNt4 = 1;
AsmWriteMsr64 (MSR_IA32_MISC_ENABLE, MiscEnable.Uint64);
}
///
/// Set the T-states flag
///
PpmFlags |= PPM_TSTATES;
///
/// Determine if Clock modulation duty cycle extension is supported
///
if (PowerEax.Bits.ECMD == 1) {
PpmFlags |= PPM_TSTATE_FINE_GRAINED;
}
PpmFlags |= PPM_EEPST; ///< Energy Efficient P-state feature is supported
///
/// Check HWP support
///
if (PowerEax.Bits.HWP == 1) {
PpmFlags |= PPM_HWP;
DEBUG ((DEBUG_INFO, "HWP capable\n"));
}
///
/// Check if overclocking is fully unlocked
///
FlexRatioMsr.Uint64 = AsmReadMsr64 (MSR_FLEX_RATIO);
OverclockingBins = (UINT8) FlexRatioMsr.Bits.OcBins;
if (OverclockingBins == MAX_OVERCLOCKING_BINS) {
PpmFlags |= PPM_OC_UNLOCKED;
}
///
/// Check Intel Turbo Boost Max Technology 3.0 support.
///
if (IsItbmSupported ()) {
PpmFlags |= PPM_TURBO_BOOST_MAX;
DEBUG ((DEBUG_INFO, "Itbm: Intel Turbo Boost Max Technology 3.0 supported\n"));
}
mPpmFlags = PpmFlags;
return;
}
/**
Set the PPM flags based on current user configuration
**/
VOID
SetUserConfigurationPpmFlags (
VOID
)
{
UINT32 UserPpmFlag;
//
// In advance to clear following PPM flags which are related with policies that user can enabled/disabled.
//
UserPpmFlag = (UINT32) ~(PPM_EIST | PPM_C1 | PPM_C1E | PPM_TM | PPM_TURBO | PPM_TSTATES |
PPM_TSTATE_FINE_GRAINED | PPM_EEPST | PPM_TIMED_MWAIT | PPM_HWP | PPM_OC_UNLOCKED);
///
/// Configure flag based on user selections
///
if (gCpuPowerMgmtTestConfig->Eist) {
UserPpmFlag |= PPM_EIST;
}
if (gCpuPowerMgmtTestConfig->Cx) {
UserPpmFlag |= PPM_C1;
if (gCpuPowerMgmtTestConfig->C1e) {
UserPpmFlag |= PPM_C1E;
}
} else {
UserPpmFlag &= ~( PPM_C6 | C6_LONG_LATENCY_ENABLE |
PPM_C7S | PPM_C7 | C7_LONG_LATENCY_ENABLE | C7s_LONG_LATENCY_ENABLE | PPM_CD |
PPM_C8 | PPM_C9 | PPM_C10);
}
if (gCpuPowerMgmtTestConfig->ThermalMonitor) {
UserPpmFlag |= PPM_TM;
}
if (gCpuPowerMgmtBasicConfig->TurboMode) {
UserPpmFlag |= PPM_TURBO;
}
if (gCpuPowerMgmtTestConfig->TStates) {
UserPpmFlag |= (PPM_TSTATES | PPM_TSTATE_FINE_GRAINED);
}
if (gCpuPowerMgmtTestConfig->EnergyEfficientPState) {
UserPpmFlag |= PPM_EEPST;
}
if (gCpuPowerMgmtTestConfig->TimedMwait) {
UserPpmFlag |= PPM_TIMED_MWAIT;
}
if (gCpuPowerMgmtBasicConfig->Hwp) {
UserPpmFlag |= PPM_HWP;
}
if (gOverClockingPreMemConfig->OcSupport) {
UserPpmFlag |= PPM_OC_UNLOCKED;
}
mPpmFlags &= UserPpmFlag;
}
/**
Tranfer CPU NVS Variables to Hob.
**/
VOID
CpuNvsDataHob (
VOID
)
{
UINT16 Index;
mCpuInitDataHob->ConfigTdpBootModeIndex = mConfigTdpBootModeIndex; /// CTDP Boot Mode Index
mCpuInitDataHob->LowestMaxPerf = mLowestMaxPerf; /// Max ratio of the slowest core.
mCpuInitDataHob->CtdpLevelsSupported = mCtdpLevelsSupported; /// ConfigTdp Number Of Levels
mCpuInitDataHob->ConfigTdpLevel = (UINT8) gCpuConfigLibPreMemConfig->ConfigTdpLevel; /// Configuration for boot TDP selection; <b>0: TDP Nominal</b>; 1: TDP Down; 2: TDP Up.
mCpuInitDataHob->ApplyConfigTdp = (UINT8) gCpuPowerMgmtBasicConfig->ApplyConfigTdp; /// Enable Configurable TDP
mCpuInitDataHob->ConfigurablePpc = mConfigurablePpc; /// Boot Mode vlues for _PPC
mCpuInitDataHob->LowestMaxPerf = mLowestMaxPerf; /// Max ratio of the slowest core.
mCpuInitDataHob->PpmFlags = mPpmFlags;
mCpuInitDataHob->EnableItbm = mEnableItbm;
for (Index = 0; Index < 3; Index++) {
mCpuInitDataHob->CtdpPpc[Index] = mCtdpPpc[Index]; /// CTDP Levels PPC
mCpuInitDataHob->CtdpCtc[Index] = mCtdpCtc [Index];
mCpuInitDataHob->CtdpTar[Index] = mCtdpTar[Index]; /// CTDP Levels TAR
mCpuInitDataHob->CtdpPowerLimitWindow[Index] = mCtdpPowerLimitWindow[Index]; /// CTDP Levels Power Limits Time Window
mCpuInitDataHob->CtdpPowerLimit1[Index] = mCtdpPowerLimit1[Index]; /// CTDP Levels Power Limit1
mCpuInitDataHob->CtdpPowerLimit2[Index] = mCtdpPowerLimit2[Index]; /// CTDP Levels Power Limit2
}
}
/**
Set Misc PPM flags based on other configuration status
**/
VOID
MiscSetPpmFlags (
VOID
)
{
#if FixedPcdGetBool(PcdITbtEnable) == 1
TCSS_DATA_HOB *TcssHob;
TcssHob = NULL;
///
/// Locate HOB for TCSS Data
///
TcssHob = (TCSS_DATA_HOB *) GetFirstGuidHob (&gTcssHobGuid);
if (TcssHob == NULL) {
DEBUG ((DEBUG_ERROR, "SA TSCC Data HOB not found\n"));
return;
}
///
/// Check IOM ready state
/// - Limit Package C state to PC2 when IOM is not ready
///
if (TcssHob->TcssData.IOMReady == 0) {
DEBUG ((DEBUG_INFO, "PkgC warning: Limit Package C state to PC2 when IOM is not ready\n"));
///
/// Update PpmFlags
///
mPpmFlags &= ~( PPM_C6 | C6_LONG_LATENCY_ENABLE |
PPM_C7S | PPM_C7 | C7_LONG_LATENCY_ENABLE | C7s_LONG_LATENCY_ENABLE | PPM_CD |
PPM_C8 | PPM_C9 | PPM_C10);
}
#endif
}
/**
Initialize the processor power management based on hardware capabilities
and user configuration settings.
@retval EFI_SUCCESS - on success
@retval Appropiate failure code on error
**/
EFI_STATUS
InitPpm (
VOID
)
{
EFI_STATUS Status;
EFI_STATUS CtdpSupport;
UINT16 NumberOfStates;
UINTN Index;
Status = EFI_SUCCESS;
CtdpSupport = EFI_UNSUPPORTED;
DEBUG((DEBUG_INFO, "InitPpm \n"));
PostCode (0xC71);
if (mCpuConfig->SkipMpInit == 0) {
///
/// Initialize Config TDP
///
CtdpSupport = InitializeConfigurableTdp ();
///
/// Initialize P states
///
InitPStates ();
///
/// Initialize Hwp
///
InitializeHwp ();
///
/// Initialize Hwp misc features
///
InitializeHwpMiscFeatures ();
///
/// Initalize Intel Turbo Boost Max Technology 3.0
///
InitializeItbm ();
///
/// Initialize C State (IdleStates)
///
InitCState ();
//
// Dump FVID table for LPSS and TPSS
//
NumberOfStates = mFvidPointer[0].FvidHeader.EistStates;
//
// Dump FVID table for LPSS and TPSS
//
DumpFvidTable (mFvidPointer, LPSS_FVID_MAX_STATES, NumberOfStates);
if (!EFI_ERROR(CtdpSupport)) {
CtdpPatchFvidTable (mFvidPointer);
CtdpPatchFvidTableforLimit16Pstate (mFvidPointer);
//
// Print Ctdp TAR and PPC patch table
//
DEBUG ((DEBUG_INFO, "CPU Ctdp is supported\n"));
DEBUG ((DEBUG_INFO, "mCtdpTar:(%d)\n", mCtdpLevelsSupported));
DEBUG ((DEBUG_INFO, "Level\tRatio\n"));
for (Index = 0; Index < mCtdpLevelsSupported; Index++) {
DEBUG ((DEBUG_INFO, " %d\t%d\n", Index, mCtdpTar[Index]));
}
DEBUG ((DEBUG_INFO, "mCtdpPpc:(%d)\n", mCtdpLevelsSupported));
DEBUG ((DEBUG_INFO, "Level\tState\n"));
for (Index = 0; Index < mCtdpLevelsSupported; Index++) {
DEBUG ((DEBUG_INFO, " %d\t%d\n", Index, mCtdpPpc[Index]));
}
DumpFvidTable (mFvidPointer, LPSS_FVID_MAX_STATES, NumberOfStates);
}
///
/// Initialize thermal features
///
InitThermal ();
}
///
/// Initialise Miscellaneous features
///
InitMiscFeatures (CtdpSupport);
if (mCpuConfig->SkipMpInit == 0) {
///
/// Lock down all settings
///
PpmLockDown ();
}
CpuNvsDataHob ();
return Status;
}