/** * Main entry point for initializing the Thermal Control * safety net feature. * * This must be run by all Family 10h core 0s in the system. * * @param[in] FamilySpecificServices The current Family Specific Services. * @param[in] CpuEarlyParamsPtr Service parameters. * @param[in] StdHeader Config handle for library and services. */ VOID F10PmThermalInit ( IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 Core; UINT32 Module; UINT32 LocalPciRegister; UINT32 Socket; PCI_ADDR PciAddress; AGESA_STATUS IgnoredSts; IdentifyCore (StdHeader, &Socket, &Module, &Core, &IgnoredSts); ASSERT (Core == 0); if (GetPciAddress (StdHeader, Socket, 0, &PciAddress, &IgnoredSts)) { PciAddress.Address.Function = FUNC_3; PciAddress.Address.Register = NB_CAPS_REG; LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); if (((NB_CAPS_REGISTER *) &LocalPciRegister)->HtcCapable == 1) { // Enable HTC PciAddress.Address.Register = HTC_REG; LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); ((HTC_REGISTER *) &LocalPciRegister)->HtcSlewSel = 0; ((HTC_REGISTER *) &LocalPciRegister)->HtcEn = 1; LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); } } }
/** * Get NB pstate current. * * @CpuServiceMethod{::F_CPU_GET_NB_IDD_MAX}. * * This function returns the NbIddMax. * * @param[in] FamilySpecificServices The current Family Specific Services. * @param[in] NbPstate The NB P-state to check. * @param[out] NbIddMax NB P-state current in mA. * @param[in] StdHeader Handle of Header for calling lib functions and services. * * @retval TRUE NB P-state is enabled, and NbIddMax is valid. * @retval FALSE NB P-state is disabled */ BOOLEAN F16MlGetNbIddMax ( IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, IN UINT8 NbPstate, OUT UINT32 *NbIddMax, IN AMD_CONFIG_PARAMS *StdHeader ) { BOOLEAN IsNbPsEnabled; PCI_ADDR PciAddress; NB_PSTATE_CTRL_REGISTER NbPstateCtrlReg; NB_PSTATE_REGISTER NbPstateReg; IDS_HDT_CONSOLE (CPU_TRACE, " F16MlGetNbIddMax - NB P%d\n", NbPstate); IsNbPsEnabled = FALSE; PciAddress.AddressValue = NB_PSTATE_CTRL_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &NbPstateCtrlReg, StdHeader); ASSERT (NbPstate < NM_NB_PS_REG); if (NbPstate <= NbPstateCtrlReg.NbPstateMaxVal) { PciAddress.Address.Register = (NB_PSTATE_0 + (sizeof (NB_PSTATE_REGISTER) * NbPstate)); LibAmdPciRead (AccessWidth32, PciAddress, &NbPstateReg, StdHeader); // Ensure that requested NbPstate is enabled if (NbPstateReg.NbPstateEn == 1) { F16MlCmnCalculateCurrentInmA (NbPstateReg.NbIddValue, NbPstateReg.NbIddDiv, NbIddMax, StdHeader); IsNbPsEnabled = TRUE; IDS_HDT_CONSOLE (CPU_TRACE, " NB Pstate %d is Valid. NbIddMax %d\n", NbPstate, *NbIddMax); } } return IsNbPsEnabled; }
/** * Entry point for enabling Hardware Thermal Control * * This function must be run after all P-State routines have been executed * * @param[in] HtcServices The current CPU's family services. * @param[in] EntryPoint Timepoint designator. * @param[in] PlatformConfig Platform profile/build option config structure. * @param[in] StdHeader Config handle for library and services. * * @retval AGESA_SUCCESS Always succeeds. * */ AGESA_STATUS STATIC F15KvInitializeHtc ( IN HTC_FAMILY_SERVICES *HtcServices, IN UINT64 EntryPoint, IN PLATFORM_CONFIGURATION *PlatformConfig, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 LocalPciRegister; PCI_ADDR PciAddress; if ((EntryPoint & (CPU_FEAT_AFTER_POST_MTRR_SYNC | CPU_FEAT_AFTER_RESUME_MTRR_SYNC)) != 0) { PciAddress.AddressValue = NB_CAPS_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); if (((NB_CAPS_REGISTER *) &LocalPciRegister)->HtcCapable == 1) { // Enable HTC PciAddress.Address.Register = HTC_REG; LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); if (((HTC_REGISTER *) &LocalPciRegister)->HtcTmpLmt != 0) { // Enable HTC ((HTC_REGISTER *) &LocalPciRegister)->HtcEn = 1; } else { // Disable HTC ((HTC_REGISTER *) &LocalPciRegister)->HtcEn = 0; } IDS_OPTION_HOOK (IDS_HTC_CTRL, &LocalPciRegister, StdHeader); LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); } } return AGESA_SUCCESS; }
/** * Workaround for Erratum #687 for TN processors. * * AGESA should program F5x88[14] with the fused value from F3x1FC[29] and * program F2x408[CpuElevPrioDis] with inversed fuse value from F3x1FC[29] for all TN parts. * * @param[in] Data The table data value, for example to indicate which CPU and Platform types matched. * @param[in] StdHeader Config handle for library and services. * */ VOID STATIC Erratum687Workaround ( IN UINT32 Data, IN AMD_CONFIG_PARAMS *StdHeader ) { PCI_ADDR PciAddress; PRODUCT_INFO_REGISTER ProductInfo; NB_CFG_4_REGISTER NbCfg4; GMC_TO_DCT_CTL_2_REGISTER GmcToDctCtrl2; UINT32 DctSelCnt; DCT_CFG_SEL_REGISTER DctCfgSel; PciAddress.AddressValue = PRCT_INFO_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, (VOID *)&ProductInfo, StdHeader); PciAddress.AddressValue = NB_CFG_REG4_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, (VOID *)&NbCfg4, StdHeader); NbCfg4.Bit14 = ProductInfo.EnDcqChgPriToHigh; LibAmdPciWrite (AccessWidth32, PciAddress, (VOID *)&NbCfg4, StdHeader); for (DctSelCnt = 0; DctSelCnt <= 1; DctSelCnt++) { PciAddress.AddressValue = GMC_TO_DCT_CTL_2_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, (VOID *)&GmcToDctCtrl2, StdHeader); GmcToDctCtrl2.CpuElevPrioDis = ~ProductInfo.EnDcqChgPriToHigh; LibAmdPciWrite (AccessWidth32, PciAddress, (VOID *)&GmcToDctCtrl2, StdHeader); PciAddress.AddressValue = DCT_CFG_SEL_REG_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, (VOID *)&DctCfgSel, StdHeader); DctCfgSel.DctCfgSel = ~DctCfgSel.DctCfgSel; LibAmdPciWrite (AccessWidth32, PciAddress, (VOID *)&DctCfgSel, StdHeader); } }
/** * Set the Processor Name String register based on F5x194/198 * * This function copies F5x198_x[B:0] to MSR_C001_00[35:30] * * @param[in] FamilyServices The current Family Specific Services. * @param[in] EarlyParams Service parameters. * @param[in] StdHeader Config handle for library and services. * */ VOID F15SetBrandIdRegistersAtEarly ( IN CPU_SPECIFIC_SERVICES *FamilyServices, IN AMD_CPU_EARLY_PARAMS *EarlyParams, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 PciData; UINT32 ExceptionId; UINT32 MsrIndex; UINT64 MsrData; UINT64 *MsrNameStringPtrPtr; PCI_ADDR PciAddress; if (IsCorePairPrimary (FirstCoreIsComputeUnitPrimary, StdHeader)) { if (IsException (&ExceptionId, StdHeader)) { ASSERT (ExceptionId < (sizeof (CpuF15ExceptionBrandIdString) / sizeof (CpuF15ExceptionBrandIdString[0]))); MsrNameStringPtrPtr = (UINT64 *) CpuF15ExceptionBrandIdString[ExceptionId].Stringstart; } else { OptionMultiSocketConfiguration.GetCurrPciAddr (&PciAddress, StdHeader); PciAddress.Address.Function = FUNC_5; PciAddress.Address.Register = NAME_STRING_ADDRESS_PORT; // check if D18F5x198_x0 is 00000000h. PciData = 0; LibAmdPciWrite (AccessWidth32, PciAddress, &PciData, StdHeader); PciAddress.Address.Register = NAME_STRING_DATA_PORT; LibAmdPciRead (AccessWidth32, PciAddress, &PciData, StdHeader); if (PciData != 0) { for (MsrIndex = 0; MsrIndex <= (MSR_CPUID_NAME_STRING5 - MSR_CPUID_NAME_STRING0); MsrIndex++) { PciAddress.Address.Register = NAME_STRING_ADDRESS_PORT; PciData = MsrIndex * 2; LibAmdPciWrite (AccessWidth32, PciAddress, &PciData, StdHeader); PciAddress.Address.Register = NAME_STRING_DATA_PORT; LibAmdPciRead (AccessWidth32, PciAddress, &PciData, StdHeader); ((PROCESSOR_NAME_STRING *) (&MsrData))->lo = PciData; PciAddress.Address.Register = NAME_STRING_ADDRESS_PORT; PciData = (MsrIndex * 2) + 1; LibAmdPciWrite (AccessWidth32, PciAddress, &PciData, StdHeader); PciAddress.Address.Register = NAME_STRING_DATA_PORT; LibAmdPciRead (AccessWidth32, PciAddress, &PciData, StdHeader); ((PROCESSOR_NAME_STRING *) (&MsrData))->hi = PciData; LibAmdMsrWrite ((MsrIndex + MSR_CPUID_NAME_STRING0), &MsrData, StdHeader); } return; } else { // It is unprogrammed (unfused) parts and use a name string of "AMD Unprogrammed Engineering Sample" MsrNameStringPtrPtr = (UINT64 *) str_Unprogrammed_Sample; } } // Put values into name MSRs, Always write the full 48 bytes for (MsrIndex = MSR_CPUID_NAME_STRING0; MsrIndex <= MSR_CPUID_NAME_STRING5; MsrIndex++) { LibAmdMsrWrite (MsrIndex, MsrNameStringPtrPtr, StdHeader); MsrNameStringPtrPtr++; } } }
/** * Family 14h model 0 - 0xF core 0 entry point for programming registers for lower * power consumption. * * Set up D18F6x94[CpuPstateThrEn, CpuPstateThr], and D18F4x134[IntRateCC6DecrRate * according to the BKDG. * * @param[in] FamilySpecificServices The current Family Specific Services. * @param[in] CpuEarlyParams Service parameters * @param[in] StdHeader Config handle for library and services. * */ VOID F14OptimizeForLowPowerInit ( IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT8 NumBoostStates; UINT32 LocalPciRegister; BOOLEAN OptimizeForLowPower; BOOLEAN IsRevC; PCI_ADDR PciAddress; CPU_LOGICAL_ID CpuFamilyRevision; PciAddress.AddressValue = PRODUCT_INFO_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); if ((((PRODUCT_INFO_REGISTER *) &LocalPciRegister)->LowPowerDefault == 1) && (CpuEarlyParams->PlatformConfig.PlatformProfile.PlatformPowerPolicy == BatteryLife)) { OptimizeForLowPower = TRUE; } else { OptimizeForLowPower = FALSE; } // Get F4x15C [4:2] NumBoostStates // Get IsRevC NumBoostStates = 0; IsRevC = FALSE; GetLogicalIdOfCurrentCore (&CpuFamilyRevision, StdHeader); if ((CpuFamilyRevision.Revision & AMD_F14_ON_Cx) != 0) { IsRevC = TRUE; PciAddress.AddressValue = CPB_CTRL_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); NumBoostStates = (UINT8) ((CPB_CTRL_REGISTER *) &LocalPciRegister)->NumBoostStates; } // F6x94[2:0] CpuPstateThr PciAddress.AddressValue = NB_PSTATE_CFG_HIGH_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); if (OptimizeForLowPower) { ((NB_PSTATE_CFG_HIGH_REGISTER *) &LocalPciRegister)->CpuPstateThr = 0; } else { if (NumBoostStates == 0) { ((NB_PSTATE_CFG_HIGH_REGISTER *) &LocalPciRegister)->CpuPstateThr = 1; } else { ((NB_PSTATE_CFG_HIGH_REGISTER *) &LocalPciRegister)->CpuPstateThr = 2; } } // F6x94[3] CpuPstateThrEn = 1 ((NB_PSTATE_CFG_HIGH_REGISTER *) &LocalPciRegister)->CpuPstateThrEn = 1; LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); // F4x134[31:27] IntRateCC6DecrRate PciAddress.AddressValue = CSTATE_MON_CTRL3_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); ((CSTATE_MON_CTRL3_REGISTER *) &LocalPciRegister)->IntRateCC6DecrRate = (OptimizeForLowPower || IsRevC) ? 0x18 : 0x8; LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); }
/** * Determines the NB clock on the desired node. * * @CpuServiceMethod{::F_CPU_GET_NB_PSTATE_INFO}. * * @param[in] FamilySpecificServices The current Family Specific Services. * @param[in] PlatformConfig Platform profile/build option config structure. * @param[in] PciAddress The segment, bus, and device numbers of the CPU in question. * @param[in] NbPstate The NB P-state number to check. * @param[out] FreqNumeratorInMHz The desired node's frequency numerator in megahertz. * @param[out] FreqDivisor The desired node's frequency divisor. * @param[out] VoltageInuV The desired node's voltage in microvolts. * @param[in] StdHeader Handle of Header for calling lib functions and services. * * @retval TRUE NbPstate is valid * @retval FALSE NbPstate is disabled or invalid */ BOOLEAN F16MlGetNbPstateInfo ( IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, IN PLATFORM_CONFIGURATION *PlatformConfig, IN PCI_ADDR *PciAddress, IN UINT32 NbPstate, OUT UINT32 *FreqNumeratorInMHz, OUT UINT32 *FreqDivisor, OUT UINT32 *VoltageInuV, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 NbVid; BOOLEAN PstateIsValid; NB_PSTATE_CTRL_REGISTER NbPstateCtrlReg; NB_PSTATE_REGISTER NbPstateReg; IDS_HDT_CONSOLE (CPU_TRACE, " F16MlGetNbPstateInfo - NB P%d\n", NbPstate); ASSERT ((PciAddress->Address.Segment == 0) && (PciAddress->Address.Bus == 0) && (PciAddress->Address.Device == 0x18)); PstateIsValid = FALSE; // If NB P1, P2, or P3 is requested, make sure that NB Pstate is enabled if ((NbPstate == 0) || (FamilySpecificServices->IsNbPstateEnabled (FamilySpecificServices, PlatformConfig, StdHeader))) { PciAddress->AddressValue = NB_PSTATE_CTRL_PCI_ADDR; LibAmdPciRead (AccessWidth32, *PciAddress, &NbPstateCtrlReg, StdHeader); ASSERT ((NbPstate < NM_NB_PS_REG) && (NbPstateCtrlReg.NbPstateMaxVal < NM_NB_PS_REG)); if (NbPstate <= NbPstateCtrlReg.NbPstateMaxVal) { PciAddress->Address.Register = (NB_PSTATE_0 + (sizeof (NB_PSTATE_REGISTER) * NbPstate)); LibAmdPciRead (AccessWidth32, *PciAddress, &NbPstateReg, StdHeader); IDS_HDT_CONSOLE (CPU_TRACE, " En:%d Fid:%x Did:%x Vid:%x\n", NbPstateReg.NbPstateEn, NbPstateReg.NbFid, NbPstateReg.NbDid, GetF16MlNbVid (&NbPstateReg)); // Check if at least NB P0 is enabled. ASSERT ((NbPstate == 0) ? (NbPstateReg.NbPstateEn == 1) : TRUE); // Ensure that requested NbPstate is enabled if (NbPstateReg.NbPstateEn == 1) { // Check for P-state Bandwidth Requirements on // "All NB P-states must be defined such that D18F5x1[6C:60][NbFid] <= 2Eh" ASSERT (NbPstateReg.NbFid <= 0x2E); F16MlGetNbFreqNumeratorInMHz (NbPstateReg.NbFid, FreqNumeratorInMHz, StdHeader); F16MlGetNbFreqDivisor (NbPstateReg.NbDid, FreqDivisor, StdHeader); // Check for P-state Bandwidth Requirements on // "400MHz <= NBCOF <= 1600MHz" ASSERT ((*FreqNumeratorInMHz / *FreqDivisor) >= 400); ASSERT ((*FreqNumeratorInMHz / *FreqDivisor) <= 1600); NbVid = GetF16MlNbVid (&NbPstateReg); F16MlCovertVidInuV (NbVid, VoltageInuV, StdHeader); PstateIsValid = TRUE; IDS_HDT_CONSOLE (CPU_TRACE, " NB Pstate %d is Valid. NbVid=%d VoltageInuV=%d\n", NbPstate, NbVid, *VoltageInuV); } } } return PstateIsValid; }
/** * Support routine for F15OrPmNbAfterReset to perform MSR initialization on one * core of each die in a family 15h socket. * * This function implements steps 1 - 13 on each core. * * @param[in] StdHeader Config handle for library and services. * */ VOID STATIC F15OrPmNbAfterResetOnCore ( IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 NbPsCtrlOnEntry; UINT32 NbPsCtrlOnExit; UINT64 LocalMsrRegister; PCI_ADDR PciAddress; // 1. Temp1 = D18F5x170[SwNbPstateLoDis]. // 2. Temp2 = D18F5x170[NbPstateDisOnP0]. // 3. Temp3 = D18F5x170[NbPstateThreshold]. OptionMultiSocketConfiguration.GetCurrPciAddr (&PciAddress, StdHeader); PciAddress.Address.Function = FUNC_5; PciAddress.Address.Register = NB_PSTATE_CTRL; LibAmdPciRead (AccessWidth32, PciAddress, &NbPsCtrlOnEntry, StdHeader); // Check if NB P-states were disabled, and if so, prevent any changes from occurring. if (((NB_PSTATE_CTRL_REGISTER *) &NbPsCtrlOnEntry)->NbPstateMaxVal != 0) { // 4. If MSRC001_0070[NbPstate] = 1, go to step 9 LibAmdMsrRead (MSR_COFVID_CTL, &LocalMsrRegister, StdHeader); if (((COFVID_CTRL_MSR *) &LocalMsrRegister)->NbPstate == 0) { // 5. Write 0 to D18F5x170[SwNbPstateLoDis, NbPstateDisOnP0, NbPstateThreshold]. // 6. Wait for D18F5x174[CurNbPstate] = D18F5x170[NbPstateLo] and D18F5x174[CurNbFid, // CurNbDid] = [NbFid, NbDid] from D18F5x1[6C:60] indexed by D18F5x170[NbPstateLo]. TransitionToNbLow (PciAddress, StdHeader); // 7. Set D18F5x170[SwNbPstateLoDis] = 1. // 8. Wait for D18F5x174[CurNbPstate] = D18F5x170[NbPstateHi] and D18F5x174[CurNbFid, // CurNbDid] = [NbFid, NbDid] from D18F5x1[6C:60] indexed by D18F5x170[NbPstateHi]. // Go to step 13. TransitionToNbHigh (PciAddress, StdHeader); } else { // 9. Set D18F5x170[SwNbPstateLoDis] = 1. // 10. Wait for D18F5x174[CurNbPstate] = D18F5x170[NbPstateHi] and D18F5x174[CurNbFid, // CurNbDid] = [NbFid, NbDid] from D18F5x1[6C:60] indexed by D18F5x170[NbPstateHi]. TransitionToNbHigh (PciAddress, StdHeader); // 11. Write 0 to D18F5x170[SwNbPstateLoDis, NbPstateDisOnP0, NbPstateThreshold]. // 12. Wait for D18F5x174[CurNbPstate] = D18F5x170[NbPstateLo] and D18F5x174[CurNbFid, // CurNbDid] = [NbFid, NbDid] from D18F5x1[6C:60] indexed by D18F5x170[NbPstateLo]. TransitionToNbLow (PciAddress, StdHeader); } // 13. Set D18F5x170[SwNbPstateLoDis] = Temp1, D18F5x170[NbPstateDisOnP0] = Temp2, and // D18F5x170[NbPstateThreshold] = Temp3. LibAmdPciRead (AccessWidth32, PciAddress, &NbPsCtrlOnExit, StdHeader); ((NB_PSTATE_CTRL_REGISTER *) &NbPsCtrlOnExit)->SwNbPstateLoDis = ((NB_PSTATE_CTRL_REGISTER *) &NbPsCtrlOnEntry)->SwNbPstateLoDis; ((NB_PSTATE_CTRL_REGISTER *) &NbPsCtrlOnExit)->NbPstateDisOnP0 = ((NB_PSTATE_CTRL_REGISTER *) &NbPsCtrlOnEntry)->NbPstateDisOnP0; ((NB_PSTATE_CTRL_REGISTER *) &NbPsCtrlOnExit)->NbPstateThreshold = ((NB_PSTATE_CTRL_REGISTER *) &NbPsCtrlOnEntry)->NbPstateThreshold; LibAmdPciWrite (AccessWidth32, PciAddress, &NbPsCtrlOnExit, StdHeader); } }
/** * Main entry point for initializing the Thermal Control * safety net feature. * * This must be run by all Family 16h Kabini core 0s in the system. * * @param[in] HtcServices The current CPU's family services. * @param[in] EntryPoint Timepoint designator. * @param[in] PlatformConfig Platform profile/build option config structure. * @param[in] StdHeader Config handle for library and services. * * @retval AGESA_SUCCESS Always succeeds. * */ AGESA_STATUS STATIC F16KbInitializeHtc ( IN HTC_FAMILY_SERVICES *HtcServices, IN UINT64 EntryPoint, IN PLATFORM_CONFIGURATION *PlatformConfig, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 HtcTempLimit; NB_CAPS_REGISTER NbCaps; HTC_REGISTER HtcReg; CLK_PWR_TIMING_CTRL2_REGISTER Cptc2; POPUP_PSTATE_REGISTER PopUpPstate; PCI_ADDR PciAddress; UINT32 D0F0xBC_xC0107097; if ((EntryPoint & (CPU_FEAT_AFTER_POST_MTRR_SYNC | CPU_FEAT_AFTER_RESUME_MTRR_SYNC)) != 0) { PciAddress.AddressValue = NB_CAPS_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &NbCaps, StdHeader); if (NbCaps.HtcCapable == 1) { // Enable HTC PciAddress.Address.Register = HTC_REG; LibAmdPciRead (AccessWidth32, PciAddress, &HtcReg, StdHeader); GnbRegisterReadKB (GnbGetHandle (StdHeader), 0x4, 0xC0107097, &D0F0xBC_xC0107097, 0, StdHeader); HtcReg.HtcTmpLmt = (D0F0xBC_xC0107097 >> 3) & 0x7F; if (HtcReg.HtcTmpLmt != 0) { // Enable HTC HtcReg.HtcEn = 1; PciAddress.Address.Register = CPTC2_REG; LibAmdPciRead (AccessWidth32, PciAddress, &Cptc2, StdHeader); if (HtcReg.HtcPstateLimit > Cptc2.HwPstateMaxVal) { // F3xDC[HwPstateMaxVal] = F3x64[HtcPstateLimit] Cptc2.HwPstateMaxVal = HtcReg.HtcPstateLimit; LibAmdPciWrite (AccessWidth32, PciAddress, &Cptc2, StdHeader); // F3xA8[PopDownPstate] = F3xDC[HwPstateMaxVal] PciAddress.Address.Register = POPUP_PSTATE_REG; LibAmdPciRead (AccessWidth32, PciAddress, &PopUpPstate, StdHeader); PopUpPstate.PopDownPstate = Cptc2.HwPstateMaxVal; LibAmdPciWrite (AccessWidth32, PciAddress, &PopUpPstate, StdHeader); } if ((PlatformConfig->HtcTemperatureLimit >= 520) && (PlatformConfig->LhtcTemperatureLimit != 0)) { HtcTempLimit = ((PlatformConfig->HtcTemperatureLimit - 520) / 5); if (HtcTempLimit < HtcReg.HtcTmpLmt) { HtcReg.HtcTmpLmt = HtcTempLimit; } } } else { // Disable HTC HtcReg.HtcEn = 0; } PciAddress.Address.Register = HTC_REG; IDS_OPTION_HOOK (IDS_HTC_CTRL, &HtcReg, StdHeader); LibAmdPciWrite (AccessWidth32, PciAddress, &HtcReg, StdHeader); }
/** * 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; }
/** * A Family Specific Workaround method, to sync internal node 1 SbiAddr setting. * * @param[in] Data The table data value (unused in this routine) * @param[in] StdHeader Config handle for library and services * *--------------------------------------------------------------------------------------- **/ VOID STATIC F10RevDSyncInternalNode1SbiAddr ( IN UINT32 Data, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 Socket; UINT32 Module; UINT32 DataOr; UINT32 DataAnd; UINT32 ModuleType; PCI_ADDR PciAddress; AGESA_STATUS AgesaStatus; UINT32 SyncToModule; AP_MAIL_INFO ApMailboxInfo; UINT32 LocalPciRegister; ApMailboxInfo.Info = 0; GetApMailbox (&ApMailboxInfo.Info, StdHeader); ASSERT (ApMailboxInfo.Fields.Socket < MAX_SOCKETS); ASSERT (ApMailboxInfo.Fields.Module < MAX_DIES); Socket = ApMailboxInfo.Fields.Socket; Module = ApMailboxInfo.Fields.Module; ModuleType = ApMailboxInfo.Fields.ModuleType; // sync is just needed on multinode cpu if (ModuleType != 0) { // check if it is internal node 0 of every socket if (Module == 0) { if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &AgesaStatus)) { PciAddress.Address.Function = FUNC_3; PciAddress.Address.Register = 0x1E4; // read internal node 0 F3x1E4[6:4] LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); DataOr = LocalPciRegister & ((UINT32) (7 << 4)); DataAnd = ~(UINT32) (7 << 4); for (SyncToModule = 1; SyncToModule < GetPlatformNumberOfModules (); SyncToModule++) { if (GetPciAddress (StdHeader, Socket, SyncToModule, &PciAddress, &AgesaStatus)) { PciAddress.Address.Function = FUNC_3; PciAddress.Address.Register = 0x1E4; // sync the other internal node F3x1E4[6:4] LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); LocalPciRegister &= DataAnd; LocalPciRegister |= DataOr; LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); } } } } } }
/** * Main entry point for initializing the Thermal Control * safety net feature. * * This must be run by all Family 16h Mullins core 0s in the system. * * @param[in] HtcServices The current CPU's family services. * @param[in] EntryPoint Timepoint designator. * @param[in] PlatformConfig Platform profile/build option config structure. * @param[in] StdHeader Config handle for library and services. * * @retval AGESA_SUCCESS Always succeeds. * */ AGESA_STATUS STATIC F16MlInitializeHtc ( IN HTC_FAMILY_SERVICES *HtcServices, IN UINT64 EntryPoint, IN PLATFORM_CONFIGURATION *PlatformConfig, IN AMD_CONFIG_PARAMS *StdHeader ) { NB_CAPS_REGISTER NbCaps; HTC_REGISTER HtcReg; CLK_PWR_TIMING_CTRL2_REGISTER Cptc2; POPUP_PSTATE_REGISTER PopUpPstate; PCI_ADDR PciAddress; D0F0xBC_xC0107097_STRUCT D0F0xBC_xC0107097; if ((EntryPoint & (CPU_FEAT_AFTER_POST_MTRR_SYNC | CPU_FEAT_AFTER_RESUME_MTRR_SYNC)) != 0) { PciAddress.AddressValue = NB_CAPS_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &NbCaps, StdHeader); if (NbCaps.HtcCapable == 1) { // Enable HTC PciAddress.Address.Register = HTC_REG; LibAmdPciRead (AccessWidth32, PciAddress, &HtcReg, StdHeader); GnbRegisterReadML (GnbGetHandle (StdHeader), D0F0xBC_xC0107097_TYPE, D0F0xBC_xC0107097_ADDRESS, &D0F0xBC_xC0107097, 0, StdHeader); HtcReg.HtcTmpLmt = D0F0xBC_xC0107097.Field.HtcTmpLmt; if (HtcReg.HtcTmpLmt != 0) { // Enable HTC HtcReg.HtcEn = 1; PciAddress.Address.Register = CPTC2_REG; LibAmdPciRead (AccessWidth32, PciAddress, &Cptc2, StdHeader); if (HtcReg.HtcPstateLimit > Cptc2.HwPstateMaxVal) { // F3xDC[HwPstateMaxVal] = F3x64[HtcPstateLimit] Cptc2.HwPstateMaxVal = HtcReg.HtcPstateLimit; LibAmdPciWrite (AccessWidth32, PciAddress, &Cptc2, StdHeader); // F3xA8[PopDownPstate] = F3xDC[HwPstateMaxVal] PciAddress.Address.Register = POPUP_PSTATE_REG; LibAmdPciRead (AccessWidth32, PciAddress, &PopUpPstate, StdHeader); PopUpPstate.PopDownPstate = Cptc2.HwPstateMaxVal; LibAmdPciWrite (AccessWidth32, PciAddress, &PopUpPstate, StdHeader); } } else { // Disable HTC HtcReg.HtcEn = 0; } PciAddress.Address.Register = HTC_REG; IDS_OPTION_HOOK (IDS_HTC_CTRL, &HtcReg, StdHeader); LibAmdPciWrite (AccessWidth32, PciAddress, &HtcReg, StdHeader); } } return AGESA_SUCCESS; }
/** * BSC entry point for for enabling Core Performance Boost. * * Set up D18F4x15C[BoostSrc] and start the PDMs according to the BKDG. * * @param[in] CpbServices The current CPU's family services. * @param[in] PlatformConfig Contains the runtime modifiable feature input data. * @param[in] EntryPoint Current CPU feature dispatch point. * @param[in] StdHeader Config handle for library and services. * * @retval AGESA_SUCCESS Always succeeds. * */ AGESA_STATUS STATIC F15CzInitializeCpb ( IN CPB_FAMILY_SERVICES *CpbServices, IN PLATFORM_CONFIGURATION *PlatformConfig, IN UINT64 EntryPoint, IN AMD_CONFIG_PARAMS *StdHeader ) { CPB_CTRL_REGISTER CpbControl; PCI_ADDR PciAddress; PCI_ADDR StcPciAddr; F15_PSTATE_MSR PstateMsrData; SW_PS_LIMIT_REGISTER Stc; UINT32 Pbx; UINT32 PsMax; if ((EntryPoint & CPU_FEAT_MID_INIT) != 0) { PciAddress.AddressValue = CPB_CTRL_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &CpbControl, StdHeader); if (CpbControl.BoostSrc == 0) { // If any boosted P-state is still enabled, set BoostSrc = 1. for (Pbx = 0; Pbx < CpbControl.NumBoostStates; Pbx++) { LibAmdMsrRead (PS_REG_BASE + Pbx, (UINT64 *)&PstateMsrData, StdHeader); if (PstateMsrData.PsEnable == 1) { StcPciAddr.AddressValue = SW_PS_LIMIT_PCI_ADDR; LibAmdPciRead (AccessWidth32, StcPciAddr, &Stc, StdHeader); Stc.SwPstateLimitEn = 1; Stc.SwPstateLimit = CpbControl.NumBoostStates; LibAmdPciWrite (AccessWidth32, StcPciAddr, &Stc, StdHeader); S3_SAVE_PCI_WRITE (StdHeader, StcPciAddr, AccessWidth32, &Stc); CpbControl.BoostSrc = 1; LibAmdPciWrite (AccessWidth32, PciAddress, &CpbControl, StdHeader); S3_SAVE_PCI_WRITE (StdHeader, PciAddress, AccessWidth32, &CpbControl); break; } } } } else if ((EntryPoint & CPU_FEAT_MID_LATE_INIT) != 0) { PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x18, 3, 0xDC); LibAmdPciRead (AccessWidth32, PciAddress, &PsMax, StdHeader); PsMax = ((PsMax & 0x700) << 20); PciAddress.AddressValue = MAKE_SBDFO (0, 0, 0x18, 3, 0x68); LibAmdPciWrite (AccessWidth32, PciAddress, &PsMax, StdHeader); S3_SAVE_PCI_WRITE (StdHeader, PciAddress, AccessWidth32, &PsMax); } return AGESA_SUCCESS; }
/** * 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 SetF15KvCacheFlushOnHaltRegister ( IN CPU_CFOH_FAMILY_SERVICES *FamilySpecificServices, IN UINT64 EntryPoint, IN PLATFORM_CONFIGURATION *PlatformConfig, IN AMD_CONFIG_PARAMS *StdHeader ) { PCI_ADDR PciAddress; F15_KV_CLK_PWR_TIMING_CTRL2_REGISTER ClkPwrTimingCtrl2; CSTATE_POLICY_CTRL1_REGISTER CstatePolicyCtrl1; CSTATE_CTRL1_REGISTER CstateCtrl1; if ((EntryPoint & (CPU_FEAT_AFTER_POST_MTRR_SYNC | CPU_FEAT_AFTER_RESUME_MTRR_SYNC)) != 0) { // Set D18F3xDC[CacheFlushOnHaltCtl] != 0 // Set D18F3xDC[CacheFlushOnHaltTmr] PciAddress.AddressValue = CPTC2_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &ClkPwrTimingCtrl2, StdHeader); ClkPwrTimingCtrl2.CacheFlushOnHaltCtl = 7; ClkPwrTimingCtrl2.CacheFlushOnHaltTmr = 0x32; LibAmdPciWrite (AccessWidth32, PciAddress, &ClkPwrTimingCtrl2, StdHeader); // Set D18F4x128[CacheFlushTmr, CacheFlushSucMonThreshold] PciAddress.AddressValue = CSTATE_POLICY_CTRL1_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &CstatePolicyCtrl1, StdHeader); CstatePolicyCtrl1.CacheFlushTmr = 0x32; CstatePolicyCtrl1.CacheFlushSucMonThreshold = 5; CstatePolicyCtrl1.CacheFlushSucMonMispredictAct = 1; CstatePolicyCtrl1.CacheFlushSucMonTmrSel = 0; LibAmdPciWrite (AccessWidth32, PciAddress, &CstatePolicyCtrl1, StdHeader); // Set cache flush bits in D18F4x118 PciAddress.AddressValue = CSTATE_CTRL1_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &CstateCtrl1, StdHeader); // Set C-state Action Field 0 CstateCtrl1.CacheFlushEnCstAct0 = 1; CstateCtrl1.CacheFlushTmrSelCstAct0 = 2; CstateCtrl1.ClkDivisorCstAct0 = 0; // Set C-state Action Field 1 CstateCtrl1.CacheFlushEnCstAct1 = 1; CstateCtrl1.CacheFlushTmrSelCstAct1 = 1; CstateCtrl1.ClkDivisorCstAct1 = 0; LibAmdPciWrite (AccessWidth32, PciAddress, &CstateCtrl1, StdHeader); //Override the default setting IDS_OPTION_HOOK (IDS_CACHE_FLUSH_HLT, NULL, StdHeader); } }
/** * Check to see if the input CPU is running in the optimal configuration. * * @param[in] HtAssistServices HT Assist family services. * @param[in] Socket Processor socket to check. * @param[in] StdHeader Config Handle for library, services. * * @retval TRUE HT Assist is running sub-optimally. * @retval FALSE HT Assist is running optimally. * */ STATIC BOOLEAN F10IsNonOptimalConfig ( IN HT_ASSIST_FAMILY_SERVICES *HtAssistServices, IN UINT32 Socket, IN AMD_CONFIG_PARAMS *StdHeader ) { BOOLEAN IsNonOptimal; BOOLEAN IsMemoryPresent; UINT32 Module; UINT32 PciRegister; PCI_ADDR PciAddress; AGESA_STATUS IgnoredStatus; IsNonOptimal = FALSE; for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) { if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredStatus)) { IsMemoryPresent = FALSE; PciAddress.Address.Function = FUNC_2; PciAddress.Address.Register = DRAM_CFG_HI_REG0; LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); if (((DRAM_CFG_HI_REGISTER *) &PciRegister)->MemClkFreqVal == 1) { IsMemoryPresent = TRUE; if (((DRAM_CFG_HI_REGISTER *) &PciRegister)->MemClkFreq < 4) { IsNonOptimal = TRUE; break; } } PciAddress.Address.Register = DRAM_CFG_HI_REG1; LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); if (((DRAM_CFG_HI_REGISTER *) &PciRegister)->MemClkFreqVal == 1) { IsMemoryPresent = TRUE; if (((DRAM_CFG_HI_REGISTER *) &PciRegister)->MemClkFreq < 4) { IsNonOptimal = TRUE; break; } } if (!IsMemoryPresent) { IsNonOptimal = TRUE; break; } } } return IsNonOptimal; }
/** * Is C6 supported on this CPU * * @param[in] C6Services Pointer to this CPU's C6 family services. * @param[in] Socket This core's zero-based socket number. * @param[in] StdHeader Config Handle for library, services. * * @retval TRUE C6 state is supported. * @retval FALSE C6 state is not supported. * */ BOOLEAN STATIC F14IsC6Supported ( IN C6_FAMILY_SERVICES *C6Services, IN UINT32 Socket, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 PciRegister; BOOLEAN IsEnabled; PCI_ADDR PciAddress; IsEnabled = TRUE; PciAddress.AddressValue = CPU_STATE_PM_CTRL1_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); if ((((CPU_STATE_PM_CTRL1_REGISTER *) &PciRegister)->CoreC6Cap == 0) && (((CPU_STATE_PM_CTRL1_REGISTER *) &PciRegister)->PkgC6Cap == 0)) { IsEnabled = FALSE; } F14EarlySampleC6Support.F14IsC6SupportedHook (&IsEnabled, StdHeader); return IsEnabled; }
/** * Check to see if the input CPU supports HT Assist. * * @param[in] HtAssistServices HT Assist family services. * @param[in] Socket Processor socket to check. * @param[in] StdHeader Config Handle for library, services. * * @retval TRUE HT Assist is supported. * @retval FALSE HT Assist cannot be enabled. * */ BOOLEAN STATIC F10IsHtAssistSupported ( IN HT_ASSIST_FAMILY_SERVICES *HtAssistServices, IN UINT32 Socket, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 Module; UINT32 PciRegister; BOOLEAN IsSupported; PCI_ADDR PciAddress; AGESA_STATUS IgnoredStatus; IsSupported = FALSE; for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) { if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredStatus)) { PciAddress.Address.Function = FUNC_3; PciAddress.Address.Register = NB_CAPS_REG; LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader); if (((NB_CAPS_REGISTER *) &PciRegister)->L3Capable == 1) { IsSupported = TRUE; } break; } } return IsSupported; }
/** * Workaround for CPUs with a minimum P-state = 800MHz. * * AGESA should change the frequency of 800MHz P-states to 900MHz. * * @param[in] Data The table data value, for example to indicate which CPU and Platform types matched. * @param[in] StdHeader Config handle for library and services. * */ VOID STATIC Update800MHzHtcPstateTo900MHz ( IN UINT32 Data, IN AMD_CONFIG_PARAMS *StdHeader ) { PCI_ADDR PciAddress; PSTATE_MSR HtcPstate; PSTATE_MSR HtcPstateMinus1; HTC_REGISTER HtcRegister; PciAddress.AddressValue = HTC_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, (VOID *) &HtcRegister, StdHeader); LibAmdMsrRead ((HtcRegister.HtcPstateLimit + MSR_PSTATE_0), (UINT64 *) &HtcPstate, StdHeader); if (HtcPstate.CpuFid == 0 && HtcPstate.CpuDid == 1) { if (HtcRegister.HtcPstateLimit == 0) { HtcPstateMinus1 = HtcPstate; } else { LibAmdMsrRead ((HtcRegister.HtcPstateLimit + MSR_PSTATE_0 - 1), (UINT64 *) &HtcPstateMinus1, StdHeader); } HtcPstate.CpuVid = HtcPstateMinus1.CpuVid; HtcPstate.CpuFid = 2; LibAmdMsrWrite ((HtcRegister.HtcPstateLimit + MSR_PSTATE_0), (UINT64 *) &HtcPstate, StdHeader); } }
/** * Determines the NB clock on the desired node. * * @CpuServiceMethod{::F_CPU_GET_NB_FREQ}. * * @param[in] FamilySpecificServices The current Family Specific Services. * @param[out] FrequencyInMHz Northbridge clock frequency in MHz. * @param[in] StdHeader Header for library and services * * @retval AGESA_SUCCESS Always succeeds. */ AGESA_STATUS F14GetCurrentNbFrequency ( IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, OUT UINT32 *FrequencyInMHz, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 PciReg; UINT32 MainPllFid; PCI_ADDR PciAddress; PciAddress.AddressValue = CPTC0_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &PciReg, StdHeader); if (((CLK_PWR_TIMING_CTRL_REGISTER *) &PciReg)->MainPllOpFreqIdEn == 1) { MainPllFid = ((CLK_PWR_TIMING_CTRL_REGISTER *) &PciReg)->MainPllOpFreqId; } else { MainPllFid = 0; } *FrequencyInMHz = ((MainPllFid + 0x10) * 100); ASSERT (*FrequencyInMHz <= 4000); return (AGESA_SUCCESS); }
/** * 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 SetF16KbCacheFlushOnHaltRegister ( IN CPU_CFOH_FAMILY_SERVICES *FamilySpecificServices, IN UINT64 EntryPoint, IN PLATFORM_CONFIGURATION *PlatformConfig, IN AMD_CONFIG_PARAMS *StdHeader ) { PCI_ADDR PciAddress; CSTATE_CTRL1_REGISTER CstateCtrl1; if ((EntryPoint & (CPU_FEAT_AFTER_POST_MTRR_SYNC | CPU_FEAT_AFTER_RESUME_MTRR_SYNC)) != 0) { // Set F4x118 PciAddress.AddressValue = CSTATE_CTRL1_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &CstateCtrl1, StdHeader); // Set C-state Action Field 0 // bits[11] NbClkGate0 = 0x1 // bits[12] SelfRefr0 = 0x1 CstateCtrl1.NbClkGate0 = 1; CstateCtrl1.SelfRefr0 = 1; // Set C-state Action Field 1 // bits[27] NbClkGate1 = 0x1 // bits[28] SelfRefr1 = 0x1 CstateCtrl1.NbClkGate1 = 1; CstateCtrl1.SelfRefr1 = 1; LibAmdPciWrite (AccessWidth32, PciAddress, &CstateCtrl1, StdHeader); //Override the default setting IDS_OPTION_HOOK (IDS_CACHE_FLUSH_HLT, NULL, StdHeader); } }
/** * 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); }
/** * Get CPU pstate current. * * @CpuServiceMethod{::F_CPU_GET_IDD_MAX}. * * This function returns the ProcIddMax. * * @param[in] FamilySpecificServices The current Family Specific Services. * @param[in] Pstate The P-state to check. * @param[out] ProcIddMax P-state current in mA. * @param[in] StdHeader Handle of Header for calling lib functions and services. * * @retval TRUE P-state is enabled * @retval FALSE P-state is disabled */ BOOLEAN F16MlGetProcIddMax ( IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, IN UINT8 Pstate, OUT UINT32 *ProcIddMax, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 MsrAddress; PSTATE_MSR PstateMsr; BOOLEAN IsPstateEnabled; PCI_ADDR PciAddress; NB_CAPS_2_REGISTER NbCap2; UINT32 ProcIddMaxPerCore; IDS_HDT_CONSOLE (CPU_TRACE, " F16MlGetProcIddMax - P%d\n", Pstate); IsPstateEnabled = FALSE; MsrAddress = (UINT32) (Pstate + PS_REG_BASE); ASSERT (MsrAddress <= PS_MAX_REG); LibAmdMsrRead (MsrAddress, (UINT64 *) &PstateMsr, StdHeader); F16MlCmnCalculateCurrentInmA ((UINT32) PstateMsr.IddValue, (UINT32) PstateMsr.IddDiv, &ProcIddMaxPerCore, StdHeader); PciAddress.AddressValue = NB_CAPS_REG2_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &NbCap2, StdHeader); *ProcIddMax = (UINT32) ProcIddMaxPerCore * (NbCap2.CmpCap + 1); IDS_HDT_CONSOLE (CPU_TRACE, " Pstate %d ProcIddMax %d CmpCap %d\n", Pstate, *ProcIddMax, NbCap2.CmpCap); if (PstateMsr.PsEnable == 1) { IsPstateEnabled = TRUE; } return IsPstateEnabled; }
/** * Set HT Frequency register for IO Devices * * Provide a common routine for accessing the HT Link Frequency registers at offset 8 * and 0x10, to enforce not clearing the HT Link error bits. Replaces direct use of * AmdPCIWriteBits(). * * @note This routine is called for IO Devices only!! All comply to the * "HyperTransport I/O Link Specification ". * * @param[in] Reg the PCI config address the control register * @param[in] Hibit the high bit number * @param[in] Lobit the low bit number * @param[in] Value the value to write to that bit range. Bit 0 => loBit. * @param[in] State Our state, config handle for lib */ VOID STATIC SetHtIoFrequencyRegisterBits ( IN PCI_ADDR Reg, IN UINT8 Hibit, IN UINT8 Lobit, IN UINT32 *Value, IN STATE_DATA *State ) { UINT32 Mask; UINT32 Temp; ASSERT ((Hibit < 32) && (Lobit < 32) && (Hibit >= Lobit) && ((Reg.AddressValue & 0x3) == 0)); ASSERT ((Hibit < 12) || (Lobit > 14)); // A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case if ((Hibit - Lobit) != 31) { Mask = (((UINT32)1 << ((Hibit - Lobit) + 1)) - 1); } else { Mask = (UINT32)0xFFFFFFFF; } LibAmdPciRead (AccessWidth32, Reg, &Temp, State->ConfigHandle); Temp &= ~(Mask << Lobit); Temp |= (*Value & Mask) << Lobit; Temp &= (UINT32)HT_FREQUENCY_CLEAR_LINK_ERRORS; LibAmdPciWrite (AccessWidth32, Reg, &Temp, State->ConfigHandle); }
/** * Access HT Link Control Register. * * @HtFeatMethod{::F_SET_HT_CONTROL_REGISTER_BITS} * * Provide a common routine for accessing the HT Link Control registers (84, a4, c4, * e4), to enforce not clearing the HT CRC error bits. Replaces direct use of * AmdPCIWriteBits(). * * @note: This routine is called for CPUs as well as IO Devices! All comply to the * "HyperTransport I/O Link Specification ". * * @param[in] Reg the PCI config address the control register * @param[in] HiBit the high bit number * @param[in] LoBit the low bit number * @param[in] Value the value to write to that bit range. Bit 0 => loBit. * @param[in] State Our state, config handle for lib */ VOID SetHtControlRegisterBits ( IN PCI_ADDR Reg, IN UINT8 HiBit, IN UINT8 LoBit, IN UINT32 *Value, IN STATE_DATA *State ) { UINT32 Temp; UINT32 mask; ASSERT ((HiBit < 32) && (LoBit < 32) && (HiBit >= LoBit) && ((Reg.AddressValue & 0x3) == 0)); ASSERT ((HiBit < 8) || (LoBit > 9)); // A 1 << 32 == 1 << 0 due to x86 SHL instruction, so skip if that is the case if ((HiBit - LoBit) != 31) { mask = (((UINT32)1 << (HiBit - LoBit + 1)) - 1); } else { mask = (UINT32)0xFFFFFFFF; } LibAmdPciRead (AccessWidth32, Reg, &Temp, State->ConfigHandle); Temp &= ~(mask << LoBit); Temp |= (*Value & mask) << LoBit; Temp &= (UINT32)HT_CONTROL_CLEAR_CRC; LibAmdPciWrite (AccessWidth32, Reg, &Temp, State->ConfigHandle); }
/** * BSC entry point for checking whether or not CPB is supported. * * @param[in] CpbServices The current CPU's family services. * @param[in] PlatformConfig Contains the runtime modifiable feature input data. * @param[in] Socket Zero based socket number to check. * @param[in] StdHeader Config handle for library and services. * * @retval TRUE CPB is supported. * @retval FALSE CPB is not supported. * */ BOOLEAN STATIC F15TnIsCpbSupported ( IN CPB_FAMILY_SERVICES *CpbServices, IN PLATFORM_CONFIGURATION *PlatformConfig, IN UINT32 Socket, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT64 MsrData; BOOLEAN CpbSupported; CPB_CTRL_REGISTER CpbControl; PCI_ADDR PciAddress; CpbSupported = FALSE; PciAddress.AddressValue = CPB_CTRL_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &CpbControl, StdHeader); if (CpbControl.NumBoostStates != 0) { LibAmdMsrRead (MSR_PSTATE_0, &MsrData, StdHeader); if (((PSTATE_MSR *) &MsrData)->PsEnable == 1) { CpbSupported = TRUE; } } return CpbSupported; }
/** * BSC entry point for for enabling Core Performance Boost. * * Set up D18F4x15C[BoostSrc] and start the PDMs according to the BKDG. * * @param[in] CpbServices The current CPU's family services. * @param[in] PlatformConfig Contains the runtime modifiable feature input data. * @param[in] EntryPoint Current CPU feature dispatch point. * @param[in] Socket Zero based socket number to check. * @param[in] StdHeader Config handle for library and services. * * @retval AGESA_SUCCESS Always succeeds. * */ AGESA_STATUS STATIC F15TnInitializeCpb ( IN CPB_FAMILY_SERVICES *CpbServices, IN PLATFORM_CONFIGURATION *PlatformConfig, IN UINT64 EntryPoint, IN UINT32 Socket, IN AMD_CONFIG_PARAMS *StdHeader ) { CPB_CTRL_REGISTER CpbControl; PCI_ADDR PciAddress; F15_PSTATE_MSR PstateMsrData; UINT32 Pbx; if ((EntryPoint & (CPU_FEAT_AFTER_POST_MTRR_SYNC | CPU_FEAT_AFTER_RESUME_MTRR_SYNC)) != 0) { PciAddress.AddressValue = CPB_CTRL_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &CpbControl, StdHeader); if ((CpbControl.BoostSrc == 0) && (CpbControl.NumBoostStates != 0)) { // If any boosted P-state is still enabled, set BoostSrc = 1. for (Pbx = 0; Pbx < CpbControl.NumBoostStates; Pbx++) { LibAmdMsrRead (PS_REG_BASE + Pbx, (UINT64 *)&PstateMsrData, StdHeader); if (PstateMsrData.PsEnable == 1) { CpbControl.BoostSrc = 1; LibAmdPciWrite (AccessWidth32, PciAddress, &CpbControl, StdHeader); break; } } } } return AGESA_SUCCESS; }
/** * Writes to all nodes on the executing core's socket. * * @param[in] PciAddress The Function and Register to update * @param[in] Mask The bitwise AND mask to apply to the current register value * @param[in] Data The bitwise OR mask to apply to the current register value * @param[in] StdHeader Header for library and services. * */ VOID ModifyCurrSocketPciMulti ( IN PCI_ADDR *PciAddress, IN UINT32 Mask, IN UINT32 Data, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 Socket; UINT32 Module; UINT32 Core; UINT32 LocalPciRegister; AGESA_STATUS AgesaStatus; PCI_ADDR Reg; IdentifyCore (StdHeader, &Socket, &Module, &Core, &AgesaStatus); for (Module = 0; Module < (UINT8)GetPlatformNumberOfModules (); Module++) { if (GetPciAddress (StdHeader, Socket, Module, &Reg, &AgesaStatus)) { Reg.Address.Function = PciAddress->Address.Function; Reg.Address.Register = PciAddress->Address.Register; LibAmdPciRead (AccessWidth32, Reg, &LocalPciRegister, StdHeader); LocalPciRegister &= Mask; LocalPciRegister |= Data; LibAmdPciWrite (AccessWidth32, Reg, &LocalPciRegister, StdHeader); } } }
/** * Check to see if the input CPU supports L3 dependent features. * * @param[in] L3FeatureServices L3 Feature family services. * @param[in] Socket Processor socket to check. * @param[in] StdHeader Config Handle for library, services. * @param[in] PlatformConfig Contains the runtime modifiable feature input data. * * @retval TRUE L3 dependent features are supported. * @retval FALSE L3 dependent features are not supported. * */ BOOLEAN STATIC F10IsL3FeatureSupported ( IN L3_FEATURE_FAMILY_SERVICES *L3FeatureServices, IN UINT32 Socket, IN AMD_CONFIG_PARAMS *StdHeader, IN PLATFORM_CONFIGURATION *PlatformConfig ) { UINT32 Module; UINT32 LocalPciRegister; BOOLEAN IsSupported; PCI_ADDR PciAddress; AGESA_STATUS IgnoredStatus; IsSupported = FALSE; if (PlatformConfig->PlatformProfile.UseHtAssist) { for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) { if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredStatus)) { PciAddress.Address.Function = FUNC_3; PciAddress.Address.Register = NB_CAPS_REG; LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); if (((NB_CAPS_REGISTER *) &LocalPciRegister)->L3Capable == 1) { IsSupported = TRUE; } break; } } } return IsSupported; }
static void select_socket(UINT8 socket_id) { AMD_CONFIG_PARAMS StdHeader; UINT32 PciData32; UINT8 PciData8; PCI_ADDR PciAddress; /* Set SMBus MMIO. */ PciAddress.AddressValue = MAKE_SBDFO (0, 0, 20, 0, 0x90); PciData32 = (SMBUS0_BASE_ADDRESS & 0xFFFFFFF0) | BIT0; LibAmdPciWrite(AccessWidth32, PciAddress, &PciData32, &StdHeader); /* Enable SMBus MMIO. */ PciAddress.AddressValue = MAKE_SBDFO (0, 0, 20, 0, 0xD2); LibAmdPciRead(AccessWidth8, PciAddress, &PciData8, &StdHeader); ; PciData8 |= BIT0; LibAmdPciWrite(AccessWidth8, PciAddress, &PciData8, &StdHeader); switch (socket_id) { case 0: /* Switch onto the First CPU Socket SMBus */ writeSmbusByte(SMBUS0_BASE_ADDRESS, LTC4305_SMBUS_ADDR, 0x80, 0x03); break; case 1: /* Switch onto the Second CPU Socket SMBus */ writeSmbusByte(SMBUS0_BASE_ADDRESS, LTC4305_SMBUS_ADDR, 0x40, 0x03); break; default: /* Switch off two CPU Sockets SMBus */ writeSmbusByte(SMBUS0_BASE_ADDRESS, LTC4305_SMBUS_ADDR, 0x00, 0x03); break; } }
/** * Family specific call to get CPU pstate max state. * * @param[in] PstateCpuServices Pstate CPU services. * @param[out] MaxPStateNumber The max hw pstate value on the current socket. * @param[out] NumberOfBoostStates The number of boosted P-states on the current socket. * @param[in] StdHeader Handle of Header for calling lib functions and services. * * @retval AGESA_SUCCESS Always succeeds. */ AGESA_STATUS F12GetPstateMaxState ( IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices, OUT UINT32 *MaxPStateNumber, OUT UINT8 *NumberOfBoostStates, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 NumBoostStates; UINT64 MsrValue; UINT32 LocalPciRegister; PCI_ADDR PciAddress; // For F12 CPU, skip boosted p-state. The boosted p-state number = D18F4x15C[NumBoostStates]. PciAddress.AddressValue = CPB_CTRL_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader); // D18F4x15C NumBoostStates = ((CPB_CTRL_REGISTER *) &LocalPciRegister)->NumBoostStates; *NumberOfBoostStates = (UINT8) NumBoostStates; // // Read PstateMaxVal [6:4] from MSR C001_0061 // So, we will know the max pstate state in this socket. // LibAmdMsrRead (MSR_PSTATE_CURRENT_LIMIT, &MsrValue, StdHeader); *MaxPStateNumber = (UINT32) (((PSTATE_CURLIM_MSR *) &MsrValue)->PstateMaxVal) + NumBoostStates; return (AGESA_SUCCESS); }