/** * Sets up PSI_L operation. * * This function implements the LowPowerThreshold parameter. * * @param[in] FamilySpecificServices The current Family Specific Services. * @param[in] CpuEarlyParams Contains VrmLowPowerThreshold parameter. * @param[in] PciAddress PCI address of the executing core's config space. * @param[in] StdHeader Config handle for library and services. * */ VOID STATIC F10PmVrmLowPowerModeEnable ( IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams, IN PCI_ADDR PciAddress, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 Pstate; UINT32 PstateCurrent; UINT32 NextPstateCurrent; UINT32 AndMask; UINT32 OrMask; UINT32 PreviousVID; UINT32 PstateVID; UINT32 HwPsMaxVal; UINT64 PstateMsr; BOOLEAN EnablePsi; if (CpuEarlyParams->PlatformConfig.VrmProperties[CoreVrm].LowPowerThreshold != 0) { EnablePsi = FALSE; PreviousVID = 0x7F; // Initialize to invalid zero volt VID code PstateVID = 0x7F; PciAddress.Address.Function = FUNC_3; PciAddress.Address.Register = CPTC2_REG; LibAmdPciRead (AccessWidth32, PciAddress, &HwPsMaxVal, StdHeader); for (Pstate = 0; Pstate <= (UINT32) ((CLK_PWR_TIMING_CTRL2_REGISTER *) &HwPsMaxVal)->PstateMaxVal; Pstate++) { if (FamilySpecificServices->GetProcIddMax (FamilySpecificServices, (UINT8) Pstate, &PstateCurrent, StdHeader)) { LibAmdMsrRead ((UINT32) (Pstate + PS_REG_BASE), &PstateMsr, StdHeader); PstateVID = (UINT32) (((PSTATE_MSR *) &PstateMsr)->CpuVid); if ((Pstate + 1) > (UINT32) ((CLK_PWR_TIMING_CTRL2_REGISTER *) &HwPsMaxVal)->PstateMaxVal) { NextPstateCurrent = 0; } else if (FamilySpecificServices->GetProcIddMax (FamilySpecificServices, (UINT8) (Pstate + 1), &NextPstateCurrent, StdHeader)) { NextPstateCurrent = CpuEarlyParams->PlatformConfig.VrmProperties[CoreVrm].InrushCurrentLimit + NextPstateCurrent; } if ((PstateCurrent <= CpuEarlyParams->PlatformConfig.VrmProperties[CoreVrm].LowPowerThreshold) && (NextPstateCurrent <= CpuEarlyParams->PlatformConfig.VrmProperties[CoreVrm].LowPowerThreshold) && (PstateVID != PreviousVID)) { EnablePsi = TRUE; break; } PreviousVID = PstateVID; } } PciAddress.Address.Function = FUNC_3; PciAddress.Address.Register = PW_CTL_MISC_REG; AndMask = 0xFFFFFFFF; OrMask = 0x00000000; ((POWER_CTRL_MISC_REGISTER *) &AndMask)->PsiVid = 0; if (EnablePsi) { ((POWER_CTRL_MISC_REGISTER *) &OrMask)->PsiVid = PstateVID; ((POWER_CTRL_MISC_REGISTER *) &OrMask)->PsiVidEn = 1; } else { ((POWER_CTRL_MISC_REGISTER *) &AndMask)->PsiVidEn = 0; } ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader); } }
/** * Family 10h core 0 entry point for performing the necessary steps after * a warm reset has occurred. * * The steps are as follows: * 1. Modify F3xDC[PstateMaxVal] to reflect the lowest performance P-state * supported, as indicated in MSRC001_00[68:64][PstateEn] * 2. If MSRC001_0071[CurNbDid] = 0, set MSRC001_001F[GfxNbPstateDis] * 3. If MSRC001_0071[CurPstate] != F3xDC[PstateMaxVal], go to step 20 * 4. If F3xDC[PstateMaxVal] = 0 or F3xDC[PstateMaxVal] != 4, go to step 7 * 5. If MSRC001_0061[CurPstateLimit] <= F3xDC[PstateMaxVal]-1, go to step 17 * 6. Exit the sequence * 7. Copy the P-state register pointed to by F3xDC[PstateMaxVal] to the P-state * register pointed to by F3xDC[PstateMaxVal]+1 * 8. Write F3xDC[PstateMaxVal]+1 to F3xDC[PstateMaxVal] * 9. Write (the new) F3xDC[PstateMaxVal] to MSRC001_0062[PstateCmd] * 10. Wait for MSRC001_0071[CurCpuFid/CurCpuDid] = CpuFid/CpuDid from the P-state * register pointed to by (the new) F3xDC[PstateMaxVal] * 11. Copy (the new) F3xDC[PstateMaxVal]-1 to MSRC001_0062[PstateCmd] * 12. Wait for MSRC001_0071[CurCpuFid/CurCpuDid] = CpuFid/CpuDid from the P-state * register pointed to by (the new) F3xDC[PstateMaxVal]-1 * 13. If MSRC001_0071[CurNbDid] = 1, set MSRC001_001F[GfxNbPstateDis] * 14. If required, transition the NB COF and VID to the NbDid and NbVid from the * P-state register pointed to by MSRC001_0061[CurPstateLimit] using the NB COF * and VID transition sequence after a warm reset * 15. Write MSRC001_00[68:64][PstateEn]=0 for the P-state pointed to by F3xDC[PstateMaxVal] * 16. Write (the new) F3xDC[PstateMaxVal]-1 to F3xDC[PstateMaxVal] and exit the sequence * 17. Copy F3xDC[PstateMaxVal]-1 to MSRC001_0062[PstateCmd] * 18. Wait for MSRC001_0071[CurCpuFid/CurCpuDid] = CpuFid/CpuDid from the P-state * register pointed to by F3xDC[PstateMaxVal]-1 * 19. If MSRC001_0071[CurNbDid] = 0, set MSRC001_001F[GfxNbPstateDis] * 20. Copy F3xDC[PstateMaxVal] to MSRC001_0062[PstateCmd] * 21. Wait for MSRC001_0071[CurCpuFid/CurCpuDid] = CpuFid/CpuDid from the P-state * register pointed to by F3xDC[PstateMaxVal] * 22. If MSRC001_0071[CurNbDid] = 1, set MSRC001_001F[GfxNbPstateDis] * 23. Issue an LDTSTOP assertion in the IO hub and exit sequence * 24. If required, transition the NB COF and VID to the NbDid and NbVid from the * P-state register pointed to by F3xDC[PstateMaxVal] using the NB COF and VID * transition sequence after a warm reset * * @param[in] FamilySpecificServices The current Family Specific Services. * @param[in] CpuEarlyParamsPtr Service parameters * @param[in] StdHeader Config handle for library and services. * */ VOID F10PmAfterReset ( IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 Socket; UINT32 Module; UINT32 PsMaxVal; UINT32 CoreNum; UINT32 MsrAddr; UINT32 Core; UINT32 AndMask; UINT32 OrMask; UINT64 LocalMsrRegister; PCI_ADDR PciAddress; AP_TASK TaskPtr; AGESA_STATUS IgnoredSts; IdentifyCore (StdHeader, &Socket, &Module, &Core, &IgnoredSts); GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts); GetActiveCoresInCurrentSocket (&CoreNum, StdHeader); ASSERT (Core == 0); // Step 1 Modify F3xDC[PstateMaxVal] to reflect the lowest performance // P-state supported, as indicated in MSRC001_00[68:64][PstateEn] for (MsrAddr = PS_MAX_REG; MsrAddr > PS_REG_BASE; --MsrAddr) { LibAmdMsrRead (MsrAddr, &LocalMsrRegister, StdHeader); if (((PSTATE_MSR *) &LocalMsrRegister)->PsEnable == 1) { break; } } PsMaxVal = MsrAddr - PS_REG_BASE; PciAddress.Address.Function = FUNC_3; PciAddress.Address.Register = CPTC2_REG; AndMask = 0xFFFFFFFF; OrMask = 0x00000000; ((CLK_PWR_TIMING_CTRL2_REGISTER *) &AndMask)->PstateMaxVal = 0; ((CLK_PWR_TIMING_CTRL2_REGISTER *) &OrMask)->PstateMaxVal = PsMaxVal; ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader); // Launch each local core to perform the remaining steps. TaskPtr.FuncAddress.PfApTask = F10PmAfterResetCore; TaskPtr.DataTransfer.DataSizeInDwords = 0; TaskPtr.ExeFlags = WAIT_FOR_CORE; ApUtilRunCodeOnAllLocalCoresAtEarly (&TaskPtr, StdHeader, CpuEarlyParamsPtr); }
/** * Enable BL-C Cpu Cache Flush On Halt Function * * @param[in] FamilySpecificServices The current Family Specific Services. * @param[in] EntryPoint Timepoint designator. * @param[in] PlatformConfig Contains the runtime modifiable feature input data. * @param[in] StdHeader Config Handle for library, services. */ VOID SetF10BlCacheFlushOnHaltRegister ( IN CPU_CFOH_FAMILY_SERVICES *FamilySpecificServices, IN UINT64 EntryPoint, IN PLATFORM_CONFIGURATION *PlatformConfig, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 AndMask; UINT32 OrMask; UINT32 CoreCount; PCI_ADDR PciAddress; CPU_LOGICAL_ID CpuFamilyRevision; if ((EntryPoint & CPU_FEAT_AFTER_POST_MTRR_SYNC) != 0) { GetLogicalIdOfCurrentCore (&CpuFamilyRevision, StdHeader); PciAddress.Address.Function = FUNC_3; PciAddress.Address.Register = CLOCK_POWER_TIMING_CTRL2_REG; if (CpuFamilyRevision.Revision == AMD_F10_BL_C3) { // F3xDC[25:19] = 04h // F3xDC[18:16] = 111b AndMask = 0xFC00FFFF; OrMask = 0x00270000; } else { // F3xDC[25:19] = 28h // F3xDC[18:16] = 111b AndMask = 0xFC00FFFF; OrMask = 0x01470000; //For BL_C2 single Core, F3xDC[18:16] = 0 GetActiveCoresInCurrentSocket (&CoreCount, StdHeader); if (CoreCount == 1) { if (CpuFamilyRevision.Revision == AMD_F10_BL_C2) { OrMask = 0x01400000; } } } // Get the Or Mask value from IDS IDS_OPTION_HOOK (IDS_CACHE_FLUSH_HLT, &OrMask, StdHeader); ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader); // F3xDC } }
/** * Enable Cpu Cache Flush On Halt Function * * @param[in] FamilySpecificServices The current Family Specific Services. * @param[in] EntryPoint Timepoint designator. * @param[in] PlatformConfig Contains the runtime modifiable feature input data. * @param[in] StdHeader Config Handle for library, services. */ VOID SetF10CacheFlushOnHaltRegister ( IN CPU_CFOH_FAMILY_SERVICES *FamilySpecificServices, IN UINT64 EntryPoint, IN PLATFORM_CONFIGURATION *PlatformConfig, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 AndMask; UINT32 OrMask; UINT32 CoreCount; CPU_LOGICAL_ID LogicalId; PCI_ADDR PciAddress; if ((EntryPoint & CPU_FEAT_AFTER_POST_MTRR_SYNC) != 0) { // Initialize F3xDC // bits[25:19] CacheFlushOnHaltTmr = 28h // bits[18:16] CacheFlushOnHaltCtl = 111b PciAddress.Address.Function = FUNC_3; PciAddress.Address.Register = CLOCK_POWER_TIMING_CTRL2_REG; AndMask = 0xFC00FFFF; OrMask = 0x01470000; GetLogicalIdOfCurrentCore (&LogicalId, StdHeader); if ((LogicalId.Revision & AMD_F10_C2) != 0) { //For F10_C2 single Core, F3xDC[18:16] = 0 GetActiveCoresInCurrentSocket (&CoreCount, StdHeader); if (CoreCount == 1) { OrMask = 0x01400000; } } IDS_OPTION_HOOK (IDS_CACHE_FLUSH_HLT, &OrMask, StdHeader); ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader); // F3xDC } }
/** * Family 10h core 0 entry point for performing power plane initialization. * * The steps are as follows: * 1. If single plane, program lower VID code of CpuVid & NbVid for all * enabled P-States. * 2. Configure F3xA0[SlamMode] & F3xD8[VsRampTime & VsSlamTime] based on * platform requirements. * 3. Configure F3xD4[PowerStepUp & PowerStepDown] * 4. Optionally configure F3xA0[PsiVidEn & PsiVid] * * @param[in] FamilySpecificServices The current Family Specific Services. * @param[in] CpuEarlyParams Service parameters * @param[in] StdHeader Config handle for library and services. * */ VOID F10CpuAmdPmPwrPlaneInit ( IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams, IN AMD_CONFIG_PARAMS *StdHeader ) { BOOLEAN PviModeFlag; PCI_ADDR PciAddress; UINT16 PowerStepTime; UINT32 PowerStepEncoded; UINT32 PciRegister; UINT32 VsSlamTime; UINT32 Socket; UINT32 Module; UINT32 Core; UINT32 NumOfCores; UINT32 LowCore; UINT32 AndMask; UINT32 OrMask; UINT64 MsrRegister; AP_TASK TaskPtr; AGESA_STATUS IgnoredSts; PLATFORM_FEATS Features; CPU_LOGICAL_ID LogicalId; // Initialize the union Features.PlatformValue = 0; GetPlatformFeatures (&Features, &CpuEarlyParams->PlatformConfig, StdHeader); IdentifyCore (StdHeader, &Socket, &Module, &Core, &IgnoredSts); GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts); ASSERT (Core == 0); GetLogicalIdOfCurrentCore (&LogicalId, StdHeader); // Set SlamVidMode PciAddress.Address.Function = FUNC_3; PciAddress.Address.Register = PW_CTL_MISC_REG; LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); AndMask = 0xFFFFFFFF; OrMask = 0x00000000; if (((POWER_CTRL_MISC_REGISTER *) &PciRegister)->PviMode == 1) { PviModeFlag = TRUE; ((POWER_CTRL_MISC_REGISTER *) &AndMask)->SlamVidMode = 0; // Have all single plane cores adjust their NB and CPU VID fields TaskPtr.FuncAddress.PfApTask = F10PmPwrPlaneInitPviCore; TaskPtr.DataTransfer.DataSizeInDwords = 0; TaskPtr.ExeFlags = WAIT_FOR_CORE; ApUtilRunCodeOnAllLocalCoresAtEarly (&TaskPtr, StdHeader, CpuEarlyParams); } else { PviModeFlag = FALSE; ((POWER_CTRL_MISC_REGISTER *) &OrMask)->SlamVidMode = 1; } ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader); F10ProgramVSSlamTimeOnSocket (&PciAddress, CpuEarlyParams, StdHeader); // Configure PowerStepUp/PowerStepDown PciAddress.Address.Register = CPTC0_REG; if ((Features.PlatformFeatures.PlatformSingleLink == 1) || (Features.PlatformFeatures.PlatformUma == 1) || (Features.PlatformFeatures.PlatformUmaIfcm == 1) || (Features.PlatformFeatures.PlatformIfcm == 1) || (Features.PlatformFeatures.PlatformIommu == 1)) { PowerStepEncoded = 0x8; } else { GetGivenModuleCoreRange ((UINT32) Socket, (UINT32) Module, &LowCore, &NumOfCores, StdHeader); NumOfCores = ((NumOfCores - LowCore) + 1); PowerStepTime = (UINT16) (400 / NumOfCores); for (PowerStepEncoded = 0xF; PowerStepEncoded > 0; PowerStepEncoded--) { if (PowerStepTime <= PowerStepEncodings[PowerStepEncoded]) { break; } } } AndMask = 0xFFFFFFFF; ((CLK_PWR_TIMING_CTRL_REGISTER *) &AndMask)->PowerStepUp = 0; ((CLK_PWR_TIMING_CTRL_REGISTER *) &AndMask)->PowerStepDown = 0; OrMask = 0x00000000; ((CLK_PWR_TIMING_CTRL_REGISTER *) &OrMask)->PowerStepUp = PowerStepEncoded; ((CLK_PWR_TIMING_CTRL_REGISTER *) &OrMask)->PowerStepDown = PowerStepEncoded; ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader); if ((LogicalId.Revision & AMD_F10_C3) != 0) { // Set up Pop up P-state register PciAddress.Address.Register = CPTC2_REG; LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); AndMask = 0xFFFFFFFF; ((POPUP_PSTATE_REGISTER *) &AndMask)->PopupPstate = 0; ((POPUP_PSTATE_REGISTER *) &AndMask)->PopupCpuVid = 0; ((POPUP_PSTATE_REGISTER *) &AndMask)->PopupCpuFid = 0; ((POPUP_PSTATE_REGISTER *) &AndMask)->PopupCpuDid = 0; OrMask = 0x00000000; ((POPUP_PSTATE_REGISTER *) &OrMask)->PopupEn = 0; ((POPUP_PSTATE_REGISTER *) &OrMask)->PopupPstate = ((CLK_PWR_TIMING_CTRL2_REGISTER *) &PciRegister)->PstateMaxVal; LibAmdMsrRead ((((CLK_PWR_TIMING_CTRL2_REGISTER *) &PciRegister)->PstateMaxVal + PS_REG_BASE), &MsrRegister, StdHeader); ((POPUP_PSTATE_REGISTER *) &OrMask)->PopupCpuVid = (UINT32) ((PSTATE_MSR *) &MsrRegister)->CpuVid; ((POPUP_PSTATE_REGISTER *) &OrMask)->PopupCpuFid = (UINT32) ((PSTATE_MSR *) &MsrRegister)->CpuFid; ((POPUP_PSTATE_REGISTER *) &OrMask)->PopupCpuDid = (UINT32) ((PSTATE_MSR *) &MsrRegister)->CpuDid; PciAddress.Address.Register = POPUP_PSTATE_REG; ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader); // Set AltVidStart PciAddress.Address.Register = CPTC1_REG; AndMask = 0xFFFFFFFF; ((CLK_PWR_TIMING_CTRL1_REGISTER *) &AndMask)->AltVidStart = 0; OrMask = 0x00000000; ((CLK_PWR_TIMING_CTRL1_REGISTER *) &OrMask)->AltVidStart = (UINT32) ((PSTATE_MSR *) &MsrRegister)->CpuVid; ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader); // Set up Altvid slam time PciAddress.Address.Register = CPTC2_REG; VsSlamTime = F10CalculateAltvidVSSlamTimeOnCore (PviModeFlag, &PciAddress, CpuEarlyParams, StdHeader); AndMask = 0xFFFFFFFF; ((CLK_PWR_TIMING_CTRL2_REGISTER *) &AndMask)->AltvidVSSlamTime = 0; ((CLK_PWR_TIMING_CTRL2_REGISTER *) &AndMask)->SlamTimeMode = 0; OrMask = 0x00000000; ((CLK_PWR_TIMING_CTRL2_REGISTER *) &OrMask)->AltvidVSSlamTime = VsSlamTime; ((CLK_PWR_TIMING_CTRL2_REGISTER *) &OrMask)->SlamTimeMode = 2; ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader); } if (IsWarmReset (StdHeader) && !PviModeFlag) { // Configure PsiVid F10PmVrmLowPowerModeEnable (FamilySpecificServices, CpuEarlyParams, StdHeader); } }
/** * Family 10h core 0 entry point for performing the family 10h Processor- * Systemboard Power Delivery Check. * * The steps are as follows: * 1. Starting with P0, loop through all P-states until a passing state is * found. A passing state is one in which the current required by the * CPU is less than the maximum amount of current that the system can * provide to the CPU. If P0 is under the limit, no further action is * necessary. * 2. If at least one P-State is under the limit & at least one P-State is * over the limit, the BIOS must: * a. If the processor's current P-State is disabled by the power check, * then the BIOS must request a transition to an enabled P-state * using MSRC001_0062[PstateCmd] and wait for MSRC001_0063[CurPstate] * to reflect the new value. * b. Copy the contents of the enabled P-state MSRs to the highest * performance P-state locations. * c. Request a P-state transition to the P-state MSR containing the * COF/VID values currently applied. * d. On revision E systems with CPUID Fn8000_0007[CPB]=1, if P0 is disabled then * program F4x15C[BoostSrc]=0. This step uses hardware P-state numbering. * e. Adjust the following P-state parameters affected by the P-state * MSR copy by subtracting the number of P-states that are disabled * by the power check. * 1. F3x64[HtcPstateLimit] * 2. F3x68[StcPstateLimit] * 3. F3xDC[PstateMaxVal] * 3. If all P-States are over the limit, the BIOS must: * a. If the processor's current P-State is !=F3xDC[PstateMaxVal], then * write F3xDC[PstateMaxVal] to MSRC001_0062[PstateCmd] and wait for * MSRC001_0063[CurPstate] to reflect the new value. * b. If F3xDC[PstateMaxVal]!= 000b, copy the contents of the P-state * MSR pointed to by F3xDC[PstateMaxVal] to MSRC001_0064 and set * MSRC001_0064[PstateEn] * c. Write 000b to MSRC001_0062[PstateCmd] and wait for MSRC001_0063 * [CurPstate] to reflect the new value. * d. Adjust the following P-state parameters to zero on revision D and earlier processors. * On revision E processors adjust the following fields to F4x15C[NumBoostStates]: * 1. F3x64[HtcPstateLimit] * 2. F3x68[StcPstateLimit] * 3. F3xDC[PstateMaxVal] * e. For revision E systems with CPUID Fn8000_0007[CPB]=1, program F4x15C[BoostSrc]=0. * * @param[in] FamilySpecificServices The current Family Specific Services. * @param[in] CpuEarlyParams Service parameters * @param[in] StdHeader Config handle for library and services. * */ VOID F10PmPwrCheck ( IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT8 DisPsNum; UINT8 PsMaxVal; UINT8 Pstate; UINT32 ProcIddMax; UINT32 LocalPciRegister; UINT32 Socket; UINT32 Module; UINT32 Core; UINT32 AndMask; UINT32 OrMask; UINT32 PstateLimit; PCI_ADDR PciAddress; UINT64 LocalMsrRegister; AP_TASK TaskPtr; AGESA_STATUS IgnoredSts; PWRCHK_ERROR_DATA ErrorData; // get the socket number IdentifyCore (StdHeader, &Socket, &Module, &Core, &IgnoredSts); ErrorData.SocketNumber = (UINT8)Socket; ASSERT (Core == 0); // get the Max P-state value for (PsMaxVal = NM_PS_REG - 1; PsMaxVal != 0; --PsMaxVal) { LibAmdMsrRead (PS_REG_BASE + PsMaxVal, &LocalMsrRegister, StdHeader); if (((PSTATE_MSR *) &LocalMsrRegister)->PsEnable == 1) { break; } } ErrorData.HwPstateNumber = (UINT8) (PsMaxVal + 1); DisPsNum = 0; for (Pstate = 0; Pstate < ErrorData.HwPstateNumber; Pstate++) { if (FamilySpecificServices->GetProcIddMax (FamilySpecificServices, Pstate, &ProcIddMax, StdHeader)) { if (ProcIddMax > CpuEarlyParams->PlatformConfig.VrmProperties[CoreVrm].CurrentLimit) { // Add to event log the Pstate that exceeded the current limit PutEventLog (AGESA_WARNING, CPU_EVENT_PM_PSTATE_OVERCURRENT, Socket, Pstate, 0, 0, StdHeader); DisPsNum++; } else { break; } } } // If all P-state registers are disabled, move P[PsMaxVal] to P0 // and transition to P0, then wait for CurPstate = 0 ErrorData.AllowablePstateNumber = ((PsMaxVal + 1) - DisPsNum); // We only need to log this event on the BSC if (ErrorData.AllowablePstateNumber == 0) { PutEventLog (AGESA_FATAL, CPU_EVENT_PM_ALL_PSTATE_OVERCURRENT, Socket, 0, 0, 0, StdHeader); } if (DisPsNum != 0) { GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts); // Check if CPB is supported. if yes, get the number of boost states. ErrorData.NumberofBoostStates = F10GetNumberOfBoostedPstatesOnCore (StdHeader); TaskPtr.FuncAddress.PfApTaskI = F10PmPwrCheckCore; TaskPtr.DataTransfer.DataSizeInDwords = SIZE_IN_DWORDS (PWRCHK_ERROR_DATA); TaskPtr.DataTransfer.DataPtr = &ErrorData; TaskPtr.DataTransfer.DataTransferFlags = 0; TaskPtr.ExeFlags = WAIT_FOR_CORE; ApUtilRunCodeOnAllLocalCoresAtEarly (&TaskPtr, StdHeader, CpuEarlyParams); // Final Step 1 // For revision E systems with CPUID Fn8000_0007[CPB]=1, if P0 is disabled then // program F4x15C[BoostSrc]=0. This step uses hardware P-state numbering. if (ErrorData.NumberofBoostStates == 1) { PciAddress.Address.Function = FUNC_4; PciAddress.Address.Register = CPB_CTRL_REG; LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); ((CPB_CTRL_REGISTER *) &LocalPciRegister)->BoostSrc = 0; LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); } // Final Step 2 // F3x64[HtPstatelimit] -= disPsNum // F3x68[StcPstateLimit]-= disPsNum // F3xDC[PstateMaxVal]-= disPsNum PciAddress.Address.Function = FUNC_3; PciAddress.Address.Register = HTC_REG; AndMask = 0xFFFFFFFF; ((HTC_REGISTER *) &AndMask)->HtcPstateLimit = 0; OrMask = 0x00000000; LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); // F3x64 PstateLimit = ((HTC_REGISTER *) &LocalPciRegister)->HtcPstateLimit; if (ErrorData.AllowablePstateNumber != 0) { if (PstateLimit > DisPsNum) { PstateLimit -= DisPsNum; ((HTC_REGISTER *) &OrMask)->HtcPstateLimit = PstateLimit; } } else { ((HTC_REGISTER *) &OrMask)->HtcPstateLimit = ErrorData.NumberofBoostStates; } ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader); // F3x64 PciAddress.Address.Register = STC_REG; AndMask = 0xFFFFFFFF; ((STC_REGISTER *) &AndMask)->StcPstateLimit = 0; OrMask = 0x00000000; LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); // F3x68 PstateLimit = ((STC_REGISTER *) &LocalPciRegister)->StcPstateLimit; if (ErrorData.AllowablePstateNumber != 0) { if (PstateLimit > DisPsNum) { PstateLimit -= DisPsNum; ((STC_REGISTER *) &OrMask)->StcPstateLimit = PstateLimit; } } else { ((STC_REGISTER *) &OrMask)->StcPstateLimit = ErrorData.NumberofBoostStates; } ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader); // F3x68 PciAddress.Address.Register = CPTC2_REG; AndMask = 0xFFFFFFFF; ((CLK_PWR_TIMING_CTRL2_REGISTER *) &AndMask)->PstateMaxVal = 0; OrMask = 0x00000000; LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); // F3xDC PstateLimit = ((CLK_PWR_TIMING_CTRL2_REGISTER *) &LocalPciRegister)->PstateMaxVal; if (ErrorData.AllowablePstateNumber != 0) { if (PstateLimit > DisPsNum) { PstateLimit -= DisPsNum; ((CLK_PWR_TIMING_CTRL2_REGISTER *) &OrMask)->PstateMaxVal = PstateLimit; } } else { ((CLK_PWR_TIMING_CTRL2_REGISTER *) &OrMask)->PstateMaxVal = ErrorData.NumberofBoostStates; } ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader); // F3xDC // Now that P0 has changed, recalculate VSSlamTime F10ProgramVSSlamTimeOnSocket (&PciAddress, CpuEarlyParams, StdHeader); } }
/** * Core 0 task to enable message-based C1e on a family 10h CPU. * * @param[in] MsgBasedC1eServices Pointer to this CPU's HW C1e family services. * @param[in] EntryPoint Timepoint designator. * @param[in] PlatformConfig Contains the runtime modifiable feature input data. * @param[in] StdHeader Config Handle for library, services. * * @return AGESA_SUCCESS Always succeeds. * */ AGESA_STATUS STATIC F10InitializeMsgBasedC1e ( IN MSG_BASED_C1E_FAMILY_SERVICES *MsgBasedC1eServices, IN UINT64 EntryPoint, IN PLATFORM_CONFIGURATION *PlatformConfig, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 AndMask; UINT32 Core; UINT32 Module; UINT32 OrMask; UINT32 PciRegister; UINT32 Socket; AP_TASK TaskPtr; PCI_ADDR PciAddress; AGESA_STATUS IgnoredSts; if ((EntryPoint & (CPU_FEAT_AFTER_POST_MTRR_SYNC | CPU_FEAT_AFTER_RESUME_MTRR_SYNC)) != 0) { // Note that this core 0 does NOT have the ability to launch // any of its cores. Attempting to do so could lead to a system // hang. // Set F3xA0[IdleExitEn] = 1 PciAddress.Address.Function = FUNC_3; PciAddress.Address.Register = PW_CTL_MISC_REG; AndMask = 0xFFFFFFFF; OrMask = 0; ((POWER_CTRL_MISC_REGISTER *) &OrMask)->IdleExitEn = 1; ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader); // F3xA0 // Set F3x188[EnStpGntOnFlushMaskWakeup] = 1 PciAddress.Address.Register = NB_EXT_CFG_LO_REG; OrMask = 0; ((NB_EXT_CFG_LO_REGISTER *) &OrMask)->EnStpGntOnFlushMaskWakeup = 1; ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader); // F3x188 // Set F3xD4[MTC1eEn] = 1, F3xD4[CacheFlushImmOnAllHalt] = 1 // Set F3xD4[StutterScrubEn] = 1 if scrubbing is enabled ((CLK_PWR_TIMING_CTRL_REGISTER *) &AndMask)->StutterScrubEn = 0; OrMask = 0; ((CLK_PWR_TIMING_CTRL_REGISTER *) &OrMask)->MTC1eEn = 1; ((CLK_PWR_TIMING_CTRL_REGISTER *) &OrMask)->CacheFlushImmOnAllHalt = 1; IdentifyCore (StdHeader, &Socket, &Module, &Core, &IgnoredSts); for (Module = 0; Module < (UINT8)GetPlatformNumberOfModules (); Module++) { if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts)) { PciAddress.Address.Function = FUNC_3; PciAddress.Address.Register = CPTC0_REG; if (IsDramScrubberEnabled (PciAddress, StdHeader)) { ((CLK_PWR_TIMING_CTRL_REGISTER *) &OrMask)->StutterScrubEn = 1; } else { ((CLK_PWR_TIMING_CTRL_REGISTER *) &OrMask)->StutterScrubEn = 0; } LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); PciRegister &= AndMask; PciRegister |= OrMask; LibAmdPciWrite (AccessWidth32, PciAddress, &PciRegister, StdHeader); } } } else if (EntryPoint == CPU_FEAT_AFTER_PM_INIT) { // At early, this core 0 can launch its subordinate cores. TaskPtr.FuncAddress.PfApTaskI = F10InitializeMsgBasedC1eOnCore; TaskPtr.DataTransfer.DataSizeInDwords = 1; TaskPtr.DataTransfer.DataPtr = &PlatformConfig->C1ePlatformData; TaskPtr.DataTransfer.DataTransferFlags = 0; TaskPtr.ExeFlags = WAIT_FOR_CORE; ApUtilRunCodeOnAllLocalCoresAtEarly (&TaskPtr, StdHeader, NULL); } return AGESA_SUCCESS; }
/** * Family 10h core 0 entry point for performing the "Northbridge COF and * VID Configuration" algorithm. * * The steps are as follows: * 1. Determine if the algorithm is necessary by checking if all NB FIDs * match in the coherent fabric. If so, check to see if NbCofVidUpdate * is zero for all CPUs. If that is also true, no further steps are * necessary. If not + cold reset, proceed to step 2. If not + warm * reset, proceed to step 8. * 2. Determine NewNbVid & NewNbFid. * 3. Copy Startup Pstate settings to P0/P1 MSRs on all local cores. * 4. Copy NewNbVid to P0 NbVid on all local cores. * 5. Transition to P1 on all local cores. * 6. Transition to P0 on local core 0 only. * 7. Copy NewNbFid to F3xD4[NbFid], set NbFidEn, and issue a warm reset. * 8. Update all enabled Pstate MSRs' NbVids according to NbVidUpdateAll * on all local cores. * 9. Transition to Startup Pstate on all local cores. * * @param[in] FamilySpecificServices The current Family Specific Services. * @param[in] CpuEarlyParamsPtr Service related parameters (unused). * @param[in] StdHeader Config handle for library and services. * */ VOID F10PmNbCofVidInit ( IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr, IN AMD_CONFIG_PARAMS *StdHeader ) { BOOLEAN PerformNbCofVidCfg; BOOLEAN SystemNbCofsMatch; UINT8 NewNbFid; UINT8 NewNbVid; UINT32 Socket; UINT32 Module; UINT32 Core; UINT32 SystemNbCof; UINT32 AndMask; UINT32 OrMask; UINT32 Ignored; UINT32 NewNbVoltage; WARM_RESET_REQUEST Request; AP_TASK TaskPtr; PCI_ADDR PciAddress; AGESA_STATUS IgnoredSts; NB_COF_VID_INIT_WARM FunctionData; PerformNbCofVidCfg = TRUE; OptionMultiSocketConfiguration.GetSystemNbCof (&SystemNbCof, &SystemNbCofsMatch, StdHeader); if (SystemNbCofsMatch) { if (!OptionMultiSocketConfiguration.GetSystemNbCofVidUpdate (StdHeader)) { PerformNbCofVidCfg = FALSE; } } if (PerformNbCofVidCfg) { // get the local node ID IdentifyCore (StdHeader, &Socket, &Module, &Core, &IgnoredSts); GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts); ASSERT (Core == 0); // get NewNbVid FamilySpecificServices->GetNbFrequency (FamilySpecificServices, &PciAddress, &Ignored, &NewNbVoltage, StdHeader); ASSERT (((1550000 - NewNbVoltage) % 12500) == 0); NewNbVid = (UINT8) ((1550000 - NewNbVoltage) / 12500); ASSERT (NewNbVid < 0x80); if (!(IsWarmReset (StdHeader))) { // determine NewNbFid NewNbFid = (UINT8) ((SystemNbCof / 200) - 4); TaskPtr.FuncAddress.PfApTaskI = PmNbCofVidInitP0P1Core; TaskPtr.DataTransfer.DataSizeInDwords = 1; TaskPtr.DataTransfer.DataPtr = &NewNbVid; TaskPtr.DataTransfer.DataTransferFlags = 0; TaskPtr.ExeFlags = 0; ApUtilRunCodeOnAllLocalCoresAtEarly (&TaskPtr, StdHeader, CpuEarlyParamsPtr); // Transition core 0 to P0 and wait for change to complete FamilySpecificServices->TransitionPstate (FamilySpecificServices, (UINT8) 0, (BOOLEAN) TRUE, StdHeader); PciAddress.Address.Register = CPTC0_REG; AndMask = 0xFFFFFFFF; ((CLK_PWR_TIMING_CTRL_REGISTER *) &AndMask)->NbFid = 0; OrMask = 0x00000000; ((CLK_PWR_TIMING_CTRL_REGISTER *) &OrMask)->NbFid = NewNbFid; ((CLK_PWR_TIMING_CTRL_REGISTER *) &OrMask)->NbFidEn = 1; ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader); // warm reset request FamilySpecificServices->GetWarmResetFlag (FamilySpecificServices, StdHeader, &Request); Request.RequestBit = TRUE; FamilySpecificServices->SetWarmResetFlag (FamilySpecificServices, StdHeader, &Request); } else { // warm reset path FunctionData.NewNbVid = NewNbVid; FamilySpecificServices->IsNbCofInitNeeded (FamilySpecificServices, &PciAddress, &FunctionData.NbVidUpdateAll, StdHeader); TaskPtr.FuncAddress.PfApTaskI = PmNbCofVidInitWarmCore; TaskPtr.DataTransfer.DataSizeInDwords = SIZE_IN_DWORDS (NB_COF_VID_INIT_WARM); TaskPtr.DataTransfer.DataPtr = &FunctionData; TaskPtr.DataTransfer.DataTransferFlags = 0; TaskPtr.ExeFlags = WAIT_FOR_CORE; ApUtilRunCodeOnAllLocalCoresAtEarly (&TaskPtr, StdHeader, CpuEarlyParamsPtr); } } // skip whole algorithm }