/** * Family 16h Mullins core 0 entry point for performing the necessary steps for core * P-states after a warm reset has occurred. * * The steps are as follows: * 1. If MSRC001_0071[CurPstate] = MSRC001_0071[CurPstateLimit], then skip step 3 for that core. * 2. Write 0 to MSRC001_0062[PstateCmd] on all cores in the processor. * 3. Wait for MSRC001_0071[CurCpuFid, CurCpuDid] = [CpuFid, CpuDid] from * MSRC001_00[6B:64] indexed by MSRC001_0071[CurPstateLimit]. * 4. Write MSRC001_0061[PstateMaxVal] to MSRC001_0062[PstateCmd] on all * cores in the processor. * 5. Wait for MSRC001_0071[CurCpuFid, CurCpuDid] = [CpuFid, CpuDid] from * MSRC001_00[6B:64] indexed by MSRC001_0061[PstateMaxVal]. * 6. If MSRC001_0071[CurPstateLimit] != MSRC001_0071[CurPstate], wait for * MSRC001_0071[CurCpuVid] = [CpuVid] from MSRC001_00[6B:64] indexed by * MSRC001_0061[PstateMaxVal]. * 7. Wait for MSRC001_0063[CurPstate] = MSRC001_0062[PstateCmd]. * * @param[in] FamilySpecificServices The current Family Specific Services. * @param[in] CpuEarlyParamsPtr Service parameters * @param[in] StdHeader Config handle for library and services. * */ VOID F16MlPmCoreAfterReset ( IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 Core; UINT32 HwPsMaxVal; PCI_ADDR PciAddress; AP_TASK TaskPtr; IDS_HDT_CONSOLE (CPU_TRACE, " F16MlPmCoreAfterReset\n"); GetCurrentCore (&Core, StdHeader); ASSERT (Core == 0); PciAddress.AddressValue = MAKE_SBDFO (0, 0, 24, FUNC_3, CPTC2_REG); LibAmdPciRead (AccessWidth32, PciAddress, &HwPsMaxVal, StdHeader); HwPsMaxVal = ((CLK_PWR_TIMING_CTRL2_REGISTER *) &HwPsMaxVal)->HwPstateMaxVal; // Launch each local core to perform steps 1 through 4. TaskPtr.FuncAddress.PfApTask = F16MlPmCoreAfterResetPhase1OnCore; TaskPtr.DataTransfer.DataSizeInDwords = 0; TaskPtr.ExeFlags = WAIT_FOR_CORE; ApUtilRunCodeOnAllLocalCoresAtEarly (&TaskPtr, StdHeader, CpuEarlyParamsPtr); // Launch each local core to perform steps 5 through 7. TaskPtr.FuncAddress.PfApTaskI = F16MlPmCoreAfterResetPhase2OnCore; TaskPtr.DataTransfer.DataSizeInDwords = 1; TaskPtr.DataTransfer.DataPtr = &HwPsMaxVal; TaskPtr.DataTransfer.DataTransferFlags = 0; TaskPtr.ExeFlags = WAIT_FOR_CORE; ApUtilRunCodeOnAllLocalCoresAtEarly (&TaskPtr, StdHeader, CpuEarlyParamsPtr); }
/** * Enable Hardware C1e on a family 10h CPU. * * @param[in] HwC1eServices 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 F10InitializeHwC1e ( IN HW_C1E_FAMILY_SERVICES *HwC1eServices, IN UINT64 EntryPoint, IN PLATFORM_CONFIGURATION *PlatformConfig, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT64 MsrRegister; AP_TASK TaskPtr; MsrRegister = 0; ((INTPEND_MSR *) &MsrRegister)->IoMsgAddr = PlatformConfig->C1ePlatformData; ((INTPEND_MSR *) &MsrRegister)->IoMsgData = 0xC1; ((INTPEND_MSR *) &MsrRegister)->IoRd = 1; ((INTPEND_MSR *) &MsrRegister)->C1eOnCmpHalt = 1; ((INTPEND_MSR *) &MsrRegister)->SmiOnCmpHalt = 0; TaskPtr.FuncAddress.PfApTaskI = F10InitializeHwC1eOnCore; TaskPtr.DataTransfer.DataSizeInDwords = 2; TaskPtr.DataTransfer.DataPtr = &MsrRegister; TaskPtr.DataTransfer.DataTransferFlags = 0; TaskPtr.ExeFlags = WAIT_FOR_CORE; ApUtilRunCodeOnAllLocalCoresAtEarly (&TaskPtr, StdHeader, NULL); return AGESA_SUCCESS; }
/** * Enable IO Cstate on a family 14h CPU. * Implement steps 1 to 3 of BKDG section 2.5.4.2.9 BIOS Requirements for Initialization * * @param[in] IoCstateServices Pointer to this CPU's IO Cstate 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 F14InitializeIoCstate ( IN IO_CSTATE_FAMILY_SERVICES *IoCstateServices, IN UINT64 EntryPoint, IN PLATFORM_CONFIGURATION *PlatformConfig, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 i; UINT32 MaxEnabledPstate; UINT32 PciRegister; UINT64 MsrRegister; AP_TASK TaskPtr; PCI_ADDR PciAddress; if ((EntryPoint & CPU_FEAT_AFTER_PM_INIT) != 0) { for (i = MSR_PSTATE_7; i > MSR_PSTATE_0; i--) { LibAmdMsrRead (i, &MsrRegister, StdHeader); if (((PSTATE_MSR *) &MsrRegister)->PsEnable == 1) { break; } } MaxEnabledPstate = i - MSR_PSTATE_0; // Initialize MSRC001_0073[CstateAddr] on each core to a region of // the IO address map with 8 consecutive available addresses. MsrRegister = 0; ((CSTATE_ADDRESS_MSR *) &MsrRegister)->CstateAddr = PlatformConfig->CStateIoBaseAddress; ASSERT ((((CSTATE_ADDRESS_MSR *) &MsrRegister)->CstateAddr != 0) && (((CSTATE_ADDRESS_MSR *) &MsrRegister)->CstateAddr <= 0xFFF8)); TaskPtr.FuncAddress.PfApTaskI = F14InitializeIoCstateOnCore; TaskPtr.DataTransfer.DataSizeInDwords = 2; TaskPtr.DataTransfer.DataPtr = &MsrRegister; TaskPtr.DataTransfer.DataTransferFlags = 0; TaskPtr.ExeFlags = WAIT_FOR_CORE; ApUtilRunCodeOnAllLocalCoresAtEarly (&TaskPtr, StdHeader, NULL); // Program D18F4x1A8[PService] to the index of lowest-performance // P-state with MSRC001_00[6B:64][PstateEn]==1 on core 0. PciAddress.AddressValue = CPU_STATE_PM_CTRL0_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); ((CPU_STATE_PM_CTRL0_REGISTER *) &PciRegister)->PService = MaxEnabledPstate; LibAmdPciWrite (AccessWidth32, PciAddress, &PciRegister, StdHeader); // Program D18F4x1AC[CstPminEn] to 1. PciAddress.AddressValue = CPU_STATE_PM_CTRL1_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); ((CPU_STATE_PM_CTRL1_REGISTER *) &PciRegister)->CstPminEn = 1; LibAmdPciWrite (AccessWidth32, PciAddress, &PciRegister, StdHeader); } return AGESA_SUCCESS; }
/** * Transitions the executing processor to the desired P-state. * * This function implements the AMD_CPU_EARLY_PARAMS.MemInitPState parameter, and is * run by all processor core 0s. * * @param[in] StdHeader Config handle for library and services * @param[in] CpuEarlyParamsPtr Required input parameters for early CPU initialization * */ VOID STATIC GoToMemInitPstateCore0 ( IN AMD_CONFIG_PARAMS *StdHeader, IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr ) { AP_TASK TaskPtr; TaskPtr.FuncAddress.PfApTaskC = GoToMemInitPstateCore; TaskPtr.DataTransfer.DataSizeInDwords = 0; TaskPtr.ExeFlags = WAIT_FOR_CORE | PASS_EARLY_PARAMS; ApUtilRunCodeOnAllLocalCoresAtEarly (&TaskPtr, StdHeader, CpuEarlyParamsPtr); }
/** * 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); }
/** * 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 }