VOID MemRecNFinalizeMctDA ( IN OUT MEM_NB_BLOCK *NBPtr ) { MEM_DATA_STRUCT *MemPtr; S_UINT64 SMsr; MemPtr = NBPtr->MemPtr; // Recommended settings for F2x11C MemRecNSetBitFieldNb (NBPtr, BFMctWrLimit, 16); MemRecNSetBitFieldNb (NBPtr, BFPrefCpuDis, 0); MemRecNSetBitFieldNb (NBPtr, BFPrefIoDis, 0); MemRecNSetBitFieldNb (NBPtr, BFFlushWrOnStpGnt, 1); LibAmdMsrRead (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader); if (!NBPtr->ClToNbFlag) { SMsr.lo &= ~((UINT32) 1 << 15); // ClLinesToNbDis } LibAmdMsrWrite (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader); LibAmdMsrRead (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader); SMsr.hi &= ~((UINT32) 1 << (48 - 32)); // WbEnhWsbDis LibAmdMsrWrite (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader); }
BOOLEAN MemNFinalizeMctDr ( IN OUT MEM_NB_BLOCK *NBPtr ) { MEM_DATA_STRUCT *MemPtr; S_UINT64 SMsr; MemPtr = NBPtr->MemPtr; MemNSetBitFieldNb (NBPtr, BFAdapPrefMissRatio, 1); MemNSetBitFieldNb (NBPtr, BFAdapPrefPosStep, 0); MemNSetBitFieldNb (NBPtr, BFAdapPrefNegStep, 0); MemNSetBitFieldNb (NBPtr, BFCohPrefPrbLmt, 1); // Recommended settings for F2x11C MemNSetBitFieldNb (NBPtr, BFMctWrLimit, 16); MemNSetBitFieldNb (NBPtr, BFPrefCpuDis, 0); MemNSetBitFieldNb (NBPtr, BFPrefIoDis, 0); MemNSetBitFieldNb (NBPtr, BFFlushWrOnStpGnt, 1); if (NBPtr->Node == BSP_DIE) { if (!NBPtr->ClToNbFlag) { LibAmdMsrRead (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader); SMsr.lo &= ~((UINT32)1 << 15); // ClLinesToNbDis LibAmdMsrWrite (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader); } LibAmdMsrRead (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader); SMsr.hi &= ~((UINT32)1 << (48 - 32)); // WbEnhWsbDis LibAmdMsrWrite (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader); } return (BOOLEAN) (NBPtr->MCTPtr->ErrCode < AGESA_FATAL); }
BOOLEAN MemNInitializeMctC32 ( IN OUT MEM_NB_BLOCK *NBPtr ) { MEM_DATA_STRUCT *MemPtr; S_UINT64 SMsr; MemPtr = NBPtr->MemPtr; if (NBPtr->Node == BSP_DIE) { LibAmdMsrRead (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader); if (SMsr.lo & ((UINT32)1 << 15)) { NBPtr->ClToNbFlag = 1; } SMsr.lo |= (UINT32)1 << 15; // ClLinesToNbDis LibAmdMsrWrite (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader); LibAmdMsrRead (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader); SMsr.hi |= (UINT32)1 << (48 - 32); // WbEnhWsbDis LibAmdMsrWrite (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader); LibAmdMsrWrite (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader); } return (BOOLEAN) (NBPtr->MCTPtr->ErrCode < AGESA_FATAL); }
/** * Update microcode patch in current processor for Family14h ON. * * This function acts as a wrapper for calling the LoadMicrocodePatch * routine at AmdInitEarly. * * @param[in] FamilyServices The current Family Specific Services. * @param[in] EarlyParams Service parameters. * @param[in] StdHeader Config handle for library and services. * */ VOID F14OnLoadMicrocodePatchAtEarly ( IN CPU_SPECIFIC_SERVICES *FamilyServices, IN AMD_CPU_EARLY_PARAMS *EarlyParams, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT64 MsrValue; AGESA_TESTPOINT (TpProcCpuLoadUcode, StdHeader); // To load a microcode patch while using the cache as general storage, // the following steps are followed: // 1. Program MSRC001_102B[L2AllocDcFlushVictim]=1. // 2. Load the microcode patch. // 3. Program MSRC001_102B[L2AllocDcFlushVictim]=0. LibAmdMsrRead (MSR_BU_CFG3, &MsrValue, StdHeader); MsrValue = MsrValue | BIT7; LibAmdMsrWrite (MSR_BU_CFG3, &MsrValue, StdHeader); LoadMicrocodePatch (StdHeader); LibAmdMsrRead (MSR_BU_CFG3, &MsrValue, StdHeader); MsrValue = MsrValue & ~((UINT64)BIT7); LibAmdMsrWrite (MSR_BU_CFG3, &MsrValue, StdHeader); }
/** * 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] StdHeader Config handle for library and services. * */ VOID STATIC F10PmVrmLowPowerModeEnable ( IN CPU_SPECIFIC_SERVICES *FamilySpecificServices, IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 Pstate; UINT32 PstateCurrent; UINT32 NextPstateCurrent; UINT32 AndMask; UINT32 OrMask; UINT32 PreviousVID; UINT32 PstateVID; UINT64 PstateMsr; UINT64 PstateLimitMsr; BOOLEAN EnablePsi; PCI_ADDR PciAddress; if (CpuEarlyParams->PlatformConfig.VrmProperties.LowPowerThreshold != 0) { EnablePsi = FALSE; PreviousVID = 0x7F; // Initialize to invalid zero volt VID code PstateVID = 0x7F; LibAmdMsrRead (MSR_PSTATE_CURRENT_LIMIT, &PstateLimitMsr, StdHeader); for (Pstate = 0; Pstate <= (UINT32) ((PSTATE_CURLIM_MSR *) &PstateLimitMsr)->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) ((PSTATE_CURLIM_MSR *) &PstateLimitMsr)->PstateMaxVal) { NextPstateCurrent = 0; } else if (FamilySpecificServices->GetProcIddMax (FamilySpecificServices, (UINT8) (Pstate + 1), &NextPstateCurrent, StdHeader)) { NextPstateCurrent = CpuEarlyParams->PlatformConfig.VrmProperties.InrushCurrentLimit + NextPstateCurrent; } if ((PstateCurrent <= CpuEarlyParams->PlatformConfig.VrmProperties.LowPowerThreshold) && (NextPstateCurrent <= CpuEarlyParams->PlatformConfig.VrmProperties.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); } }
VOID MemRecUWait10ns ( IN UINT32 Count, IN OUT MEM_DATA_STRUCT *MemPtr ) { S_UINT64 SMsr; LibAmdMsrRead (TSC, (UINT64 *)&SMsr, &MemPtr->StdHeader); Count += SMsr.lo; while (SMsr.lo < Count) { LibAmdMsrRead (TSC, (UINT64 *)&SMsr, &MemPtr->StdHeader); } }
/** * Returns the encoded altvid voltage stabilization slam time for the executing * family 10h core. * * This function calculates how much time it will take for the voltage to * stabilize when transitioning from altvid to Pmin, and returns the necessary * encoded value for the amount of time discovered. * * @param[in] PviModeFlag Whether or not the platform uses VRMs that * employ the parallel VID interface. * @param[in] PciAddress Full PCI address of the executing core's config space. * @param[in] CpuEarlyParams Service parameters * @param[in] StdHeader Config handle for library and services. * * @retval Encoded register value. * */ UINT32 STATIC F10CalculateAltvidVSSlamTimeOnCore ( IN BOOLEAN PviModeFlag, IN PCI_ADDR *PciAddress, IN AMD_CPU_EARLY_PARAMS *CpuEarlyParams, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT8 NbVid; UINT8 AltVidCode; UINT8 PminVidCode; UINT32 MsrAddr; UINT32 PciRegister; UINT64 MsrRegister; PCI_ADDR LocalPciAddress; // Calculate Slam Time // VSSlamTime = 0.4us/mV (or 0.2us/mV) * Vpmin - Altvid // In our case, we will scale the values by 100 to avoid // decimals. // Get Pmin's index LibAmdMsrRead (MSR_PSTATE_CURRENT_LIMIT, &MsrRegister, StdHeader); MsrAddr = (UINT32) ((((PSTATE_CURLIM_MSR *) &MsrRegister)->PstateMaxVal) + PS_REG_BASE); // Get Pmin's VID LibAmdMsrRead (MsrAddr, &MsrRegister, StdHeader); PminVidCode = (UINT8) (((PSTATE_MSR *) &MsrRegister)->CpuVid); // If SVI, we only care about CPU VID. // If PVI, determine the higher voltage b/t NB and CPU if (PviModeFlag) { NbVid = (UINT8) (((PSTATE_MSR *) &MsrRegister)->NbVid); if (PminVidCode > NbVid) { PminVidCode = NbVid; } } // Get Alt VID LocalPciAddress.AddressValue = PciAddress->AddressValue; LocalPciAddress.Address.Function = FUNC_3; LocalPciAddress.Address.Register = CPTC2_REG; LibAmdPciRead (AccessWidth32, LocalPciAddress, &PciRegister, StdHeader); AltVidCode = (UINT8) (((CLK_PWR_TIMING_CTRL2_REGISTER *) &PciRegister)->AltVid); return (F10GetSlamTimeEncoding (PminVidCode, AltVidCode, CpuEarlyParams, AltvidSlamTime, StdHeader)); }
/** * 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; }
/** * 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); }
/** * 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; }
/** * 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; }
VOID EFIAPI AmdWheaCheckInstallTables ( IN EFI_EVENT Event, IN VOID *Context ) { EFI_STATUS Status; UINT64 MmioMsr; AMD_CONFIG_PARAMS StdHeader; LibAmdMsrRead (0xC0010058, &MmioMsr, &StdHeader); mEinjData->PcieBaseAddress = (UINT32) (MmioMsr & 0xfff00000); Status = AmdFchWheaInitEntryEinj (); if (!EFI_ERROR (Status)) { Status = AmdFchWheaInitEntryBert (); } if (!EFI_ERROR (Status)) { Status = AmdFchWheaInitEntryErst (); } if (!EFI_ERROR (Status)) { Status = AmdFchWheaInitEntryHest (); } }
/** * Initialize Machine Check Architecture registers * * This function initializes the MCA MSRs. On cold reset, these registers * have an invalid data that must be cleared on all cores. * * @param[in] StdHeader Config handle for library and services * *--------------------------------------------------------------------------------------- */ VOID McaInitialization ( IN AMD_CONFIG_PARAMS *StdHeader ) { UINT16 TempVar16_a; UINT32 MsrAddress; UINT64 MsrData; CPUID_DATA CpuIdDataStruct; if (!(IsWarmReset (StdHeader))) { // Run CPUID to verify that the processor supports MCE and MCA // i.e. edx[7], and edx[14] // CPUID_MODEL = 1 LibAmdCpuidRead (1, &CpuIdDataStruct, StdHeader); if ((CpuIdDataStruct.EDX_Reg & 0x4080) != 0) { // Check to see if the MCG_CTL_P bit is set // MCG = Global Machine Check Exception Reporting Control Register LibAmdMsrRead (MSR_MCG_CAP, &MsrData, StdHeader); if ((MsrData & MCG_CTL_P) != 0) { TempVar16_a = (UINT16) ((MsrData & 0x000000FF) << 2); TempVar16_a += MSR_MC0_CTL; // Initialize the data MsrData = 0; for (MsrAddress = MSR_MC0_CTL; MsrAddress < TempVar16_a; MsrAddress++) { LibAmdMsrWrite (MsrAddress, &MsrData, StdHeader); } } } } }
/** * Saves the context of a 'conditional' MSR device. * * This traverses the provided register list saving MSRs when appropriate. * * @param[in] StdHeader AMD standard header config param. * @param[in] Device 'conditional' MSR device to restore. * @param[in] CallPoint Indicates whether this is AMD_INIT_RESUME or * AMD_S3LATE_RESTORE. * @param[in,out] OrMask Current buffer pointer of raw register values. * */ VOID SaveConditionalMsrDevice ( IN AMD_CONFIG_PARAMS *StdHeader, IN CONDITIONAL_MSR_DEVICE_DESCRIPTOR *Device, IN CALL_POINTS CallPoint, IN OUT UINT64 **OrMask ) { UINT8 SpecialCaseIndex; UINT16 i; CMSR_REGISTER_BLOCK_HEADER *RegisterHdr; if (CallPoint == INIT_RESUME) { MemFS3GetCMsrDeviceRegisterList (Device, &RegisterHdr, StdHeader); } else { S3GetCMsrDeviceRegisterList (Device, &RegisterHdr, StdHeader); } for (i = 0; i < RegisterHdr->NumRegisters; i++) { if (((Device->Mask1 & RegisterHdr->RegisterList[i].Mask1) != 0) && ((Device->Mask2 & RegisterHdr->RegisterList[i].Mask2) != 0)) { if (RegisterHdr->RegisterList[i].Type.SpecialCaseFlag == 0) { LibAmdMsrRead (RegisterHdr->RegisterList[i].Address, (UINT64 *) *OrMask, StdHeader); } else { SpecialCaseIndex = RegisterHdr->RegisterList[i].Type.SpecialCaseIndex; RegisterHdr->SpecialCases[SpecialCaseIndex].Save (RegisterHdr->RegisterList[i].Address, (UINT64 *) *OrMask, StdHeader); } **OrMask &= RegisterHdr->RegisterList[i].AndMask; (*OrMask)++; } } }
/** * Family specific code for writing normalizer. * * @param[in] FiveBitExponent The current CPU's family services. * @param[in] FiveBitMantissa Timepoint designator. * @param[in] StdHeader Config handle for library and services. * */ VOID STATIC F16MlWriteNormalizer ( IN UINT8 FiveBitExponent, IN UINT8 FiveBitMantissa, IN AMD_CONFIG_PARAMS *StdHeader ) { D0F0xBC_x3F98C_STRUCT D0F0xBC_x3F98C; C001_1073_MSR LocalMsrRegister; LibAmdMsrRead (MSR_C001_1073, (UINT64 *) (&LocalMsrRegister), StdHeader); //Write normalizer as 5-bit exponent and 5 bit mantissa to MSRC001_1073[Exp/Man] and D0F0xBC_x3F98C[Exp/Man] LocalMsrRegister.Exponent = FiveBitExponent; LocalMsrRegister.Mantissa = FiveBitMantissa; LibAmdMsrWrite (MSR_C001_1073, (UINT64 *) (&LocalMsrRegister), StdHeader); GnbRegisterReadML (GnbGetHandle (StdHeader), D0F0xBC_x3F98C_TYPE, D0F0xBC_x3F98C_ADDRESS, &D0F0xBC_x3F98C, 0, StdHeader); D0F0xBC_x3F98C.Field.Exponent = FiveBitExponent; D0F0xBC_x3F98C.Field.Mantissa = FiveBitMantissa; GnbRegisterWriteML (GnbGetHandle (StdHeader), D0F0xBC_x3F98C_TYPE, D0F0xBC_x3F98C_ADDRESS, &D0F0xBC_x3F98C, 0, StdHeader); // Toggle the Ready bit to ensure proper operation. LocalMsrRegister.Ready = 0; LibAmdMsrWrite (MSR_C001_1073, (UINT64 *) (&LocalMsrRegister), StdHeader); LocalMsrRegister.Ready = 1; LibAmdMsrWrite (MSR_C001_1073, (UINT64 *) (&LocalMsrRegister), StdHeader); IDS_SKIP_HOOK (IDS_MSR_ACCESS_OVERRIDE, NULL, StdHeader) { LocalMsrRegister.Lock = 1; LibAmdMsrWrite (MSR_C001_1073, (UINT64 *) (&LocalMsrRegister), StdHeader); }
/** * Update microcode patch in current processor for Family15h OR. * * This function acts as a wrapper for calling the LoadMicrocodePatch * routine at AmdInitEarly. * * This particualr version implements a workaround to a potential problem caused * when upgrading the microcode on Orochi B1 processors. * * @param[in] FamilyServices The current Family Specific Services. * @param[in] EarlyParams Service parameters. * @param[in] StdHeader Config handle for library and services. * */ VOID F15OrLoadMicrocodePatchAtEarly ( IN CPU_SPECIFIC_SERVICES *FamilyServices, IN AMD_CPU_EARLY_PARAMS *EarlyParams, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT64 MsrValue; UINT64 BuCfg2MsrValue; UINT64 CuCfgMsrValue; BOOLEAN IsPatchLoaded; AGESA_TESTPOINT (TpProcCpuLoadUcode, StdHeader); if (IsCorePairPrimary (FirstCoreIsComputeUnitPrimary, StdHeader)) { F15OrEarlySampleLoadMcuPatch.F15OrESAvoidNbCyclesStart (StdHeader, &BuCfg2MsrValue); // Erratum #655 // Set MSR C001_1023[1] = 1b, prior to writing to MSR C001_1020 LibAmdMsrRead (MSR_CU_CFG, &CuCfgMsrValue, StdHeader); MsrValue = CuCfgMsrValue | BIT1; LibAmdMsrWrite (MSR_CU_CFG, &MsrValue, StdHeader); IsPatchLoaded = F15OrEarlySampleLoadMcuPatch.F15OrUpdateMcuPatchHook (StdHeader); // Erratum #655 // Restore MSR C001_1023[1] = previous setting LibAmdMsrWrite (MSR_CU_CFG, &CuCfgMsrValue, StdHeader); F15OrEarlySampleLoadMcuPatch.F15OrESAvoidNbCyclesEnd (StdHeader, &BuCfg2MsrValue); F15OrEarlySampleLoadMcuPatch.F15OrESAfterPatchLoaded (StdHeader, IsPatchLoaded); } }
/** * Support routine for F10CpuAmdPmPwrPlaneInit. * * This function implements step 1 on each core. * * @param[in] StdHeader Config handle for library and services. * */ VOID STATIC F10PmPwrPlaneInitPviCore ( IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 MsrAddr; UINT32 NbVid; UINT32 CpuVid; UINT64 MsrRegister; for (MsrAddr = PS_REG_BASE; MsrAddr <= PS_MAX_REG; MsrAddr++) { LibAmdMsrRead (MsrAddr, &MsrRegister, StdHeader); if (((PSTATE_MSR *) &MsrRegister)->PsEnable == (UINT64) 1) { NbVid = (UINT32) (((PSTATE_MSR *) &MsrRegister)->NbVid); CpuVid = (UINT32) (((PSTATE_MSR *) &MsrRegister)->CpuVid); if (NbVid != CpuVid) { if (NbVid > CpuVid) { NbVid = CpuVid; } ((PSTATE_MSR *) &MsrRegister)->NbVid = NbVid; ((PSTATE_MSR *) &MsrRegister)->CpuVid = NbVid; LibAmdMsrWrite (MsrAddr, &MsrRegister, StdHeader); } } } }
BOOLEAN MemNFinalizeMctDA ( IN OUT MEM_NB_BLOCK *NBPtr ) { UINT8 Dct; MEM_DATA_STRUCT *MemPtr; S_UINT64 SMsr; MemPtr = NBPtr->MemPtr; MemNSetBitFieldNb (NBPtr, BFAdapPrefMissRatio, 1); MemNSetBitFieldNb (NBPtr, BFAdapPrefPosStep, 0); MemNSetBitFieldNb (NBPtr, BFAdapPrefNegStep, 0); MemNSetBitFieldNb (NBPtr, BFCohPrefPrbLmt, 1); // Recommended settings for F2x11C MemNSetBitFieldNb (NBPtr, BFMctWrLimit, 16); MemNSetBitFieldNb (NBPtr, BFPrefCpuDis, 0); MemNSetBitFieldNb (NBPtr, BFPrefIoDis, 0); MemNSetBitFieldNb (NBPtr, BFFlushWrOnStpGnt, 1); // For power saving for (Dct = 0; Dct < NBPtr->DctCount; Dct++) { NBPtr->SwitchDCT (NBPtr, Dct); if (NBPtr->DCTPtr->Timings.DctMemSize != 0) { if (NBPtr->ChannelPtr->Dimmx4Present == 0) { MemNSetBitFieldNb (NBPtr, BFPhy0x0D0F0F13, (MemNGetBitFieldNb (NBPtr, BFPhy0x0D0F0F13) | 0x80)); } if (!NBPtr->MCTPtr->Status[SbEccDimms]) { MemNSetBitFieldNb (NBPtr, BFPhy0x0D0F0830, (MemNGetBitFieldNb (NBPtr, BFPhy0x0D0F0830) | 0x10)); } MemNSetBitFieldNb (NBPtr, BFPhy0x0D07812F, (MemNGetBitFieldNb (NBPtr, BFPhy0x0D07812F) | 0x01)); } } if (NBPtr->Node == BSP_DIE) { if (!NBPtr->ClToNbFlag) { LibAmdMsrRead (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader); SMsr.lo &= ~((UINT32)1 << 15); // ClLinesToNbDis LibAmdMsrWrite (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader); } LibAmdMsrRead (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader); SMsr.hi &= ~((UINT32)1 << (48 - 32)); // WbEnhWsbDis LibAmdMsrWrite (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader); } return (BOOLEAN) (NBPtr->MCTPtr->ErrCode < AGESA_FATAL); }
/** * * Get Ids Performance analysis table pointer in the AGESA Heap. * * @param[in,out] StdHeader The Pointer of AGESA Header * @param[in] TestPoint Progress indicator value, see @ref AGESA_TP * * @retval AGESA_SUCCESS Success to get the pointer of Performance analysis Table. * @retval AGESA_ERROR Fail to get the pointer of Performance analysis Table. * @retval AGESA_UNSUPPORTED Get an exclude testpoint * **/ AGESA_STATUS IdsPerfTimestamp ( IN OUT AMD_CONFIG_PARAMS *StdHeader, IN AGESA_TP TestPoint ) { AGESA_STATUS status; UINT8 Index; UINT8 i; TP_Perf_STRUCT *PerfTableEntry; ALLOCATE_HEAP_PARAMS AllocHeapParams; LOCATE_HEAP_PTR LocateHeapStructPtr; UINT64 CurrentTsc; // Exclude some testpoint which may cause deadloop for (i = 0; i < (sizeof (IdsPerfExcludeTp) / sizeof (AGESA_TP)); i++) { if (TestPoint == IdsPerfExcludeTp[i]) { return AGESA_UNSUPPORTED; } } //if heap is not ready yet, don't invoke locate buffer, or else will cause event log & locate heap dead loop if (StdHeader->HeapStatus != HEAP_DO_NOT_EXIST_YET ) { LibAmdMsrRead (TSC, &CurrentTsc, StdHeader); LocateHeapStructPtr.BufferHandle = IDS_CHECK_POINT_PERF_HANDLE; LocateHeapStructPtr.BufferPtr = NULL; status = HeapLocateBuffer (&LocateHeapStructPtr, StdHeader); if (status == AGESA_SUCCESS) { PerfTableEntry = (TP_Perf_STRUCT *) (LocateHeapStructPtr.BufferPtr); } else { AllocHeapParams.RequestedBufferSize = sizeof (TP_Perf_STRUCT); AllocHeapParams.BufferHandle = IDS_CHECK_POINT_PERF_HANDLE; AllocHeapParams.Persist = HEAP_SYSTEM_MEM; status = HeapAllocateBuffer (&AllocHeapParams, StdHeader); if (status != AGESA_SUCCESS) { return status; } PerfTableEntry = (TP_Perf_STRUCT *) (AllocHeapParams.BufferPtr); LibAmdMemFill (PerfTableEntry, 0, sizeof (TP_Perf_STRUCT), StdHeader); } Index = PerfTableEntry ->Index; //TPPerfUnit doesn't need to check, it may used for multiple time, used to check the time // consumption of each perf measure routine. if ((TestPoint != TpPerfUnit)) { for (i = 0; i < Index; i++) { if ((UINT8) TestPoint == PerfTableEntry ->TP[i].TestPoint) { return AGESA_SUCCESS; } } } PerfTableEntry ->TP[Index].TestPoint = (UINT8) TestPoint; PerfTableEntry ->TP[Index].StartTsc = CurrentTsc; PerfTableEntry ->Index = ++Index; } return AGESA_SUCCESS; }
VOID MemFS3Wait10ns ( IN UINT32 Count, IN OUT MEM_DATA_STRUCT *MemPtr ) { UINT64 TargetTsc; UINT64 CurrentTsc; ASSERT (Count <= 1000000); LibAmdMsrRead (TSC, &CurrentTsc, &MemPtr->StdHeader); TargetTsc = CurrentTsc + ((Count * MemPtr->TscRate + 99) / 100); do { LibAmdMsrRead (TSC, &CurrentTsc, &MemPtr->StdHeader); } while (CurrentTsc < TargetTsc); }
BOOLEAN MemNFinalizeMctC32 ( IN OUT MEM_NB_BLOCK *NBPtr ) { MEM_DATA_STRUCT *MemPtr; S_UINT64 SMsr; UINT16 Speed; UINT32 ExtMctCfgLoRegVal; MemPtr = NBPtr->MemPtr; Speed = NBPtr->DCTPtr->Timings.Speed; MemNSetBitFieldNb (NBPtr, BFMctCfgHiReg, (!NBPtr->Ganged) ? 0x2CE00F60 : 0x2CE00F40); ExtMctCfgLoRegVal = MemNGetBitFieldNb (NBPtr, BFExtMctCfgLoReg); ExtMctCfgLoRegVal |= (NBPtr->Ganged) ? 0x0FC00001 : 0x0FC01001; ExtMctCfgLoRegVal &= 0x0FFFFFFF; if (Speed == DDR667_FREQUENCY) { ExtMctCfgLoRegVal |= 0x40000000; } else if (Speed == DDR800_FREQUENCY) { ExtMctCfgLoRegVal |= 0x50000000; } else if (Speed == DDR1066_FREQUENCY) { ExtMctCfgLoRegVal |= 0x60000000; } else if (Speed == DDR1333_FREQUENCY) { ExtMctCfgLoRegVal |= 0x80000000; } else { ExtMctCfgLoRegVal |= 0x90000000; } MemNSetBitFieldNb (NBPtr, BFExtMctCfgLoReg, ExtMctCfgLoRegVal); if (NBPtr->Node == BSP_DIE) { if (!NBPtr->ClToNbFlag) { LibAmdMsrRead (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader); SMsr.lo &= ~((UINT32)1 << 15); // ClLinesToNbDis LibAmdMsrWrite (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader); } LibAmdMsrRead (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader); SMsr.hi &= ~((UINT32)1 << (48 - 32)); // WbEnhWsbDis LibAmdMsrWrite (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader); } return (BOOLEAN) (NBPtr->MCTPtr->ErrCode < AGESA_FATAL); }
/** * Output Test Point function . * * @param[in,out] StdHeader The Pointer of Standard Header. * * @retval AGESA_SUCCESS Success to get the pointer of IDS_CHECK_POINT_PERF_HANDLE. * @retval AGESA_ERROR Fail to get the pointer of IDS_CHECK_POINT_PERF_HANDLE. * **/ AGESA_STATUS IdsPerfAnalyseTimestamp ( IN OUT AMD_CONFIG_PARAMS *StdHeader ) { AGESA_STATUS status; LOCATE_HEAP_PTR LocateHeapStructPtr; UINT32 TscRateInMhz; CPU_SPECIFIC_SERVICES *FamilySpecificServices; IDS_CALLOUT_STRUCT IdsCalloutData; AGESA_STATUS Status; PERFREGBACKUP PerfReg; UINT32 CR4reg; UINT64 SMsr; LocateHeapStructPtr.BufferHandle = IDS_CHECK_POINT_PERF_HANDLE; LocateHeapStructPtr.BufferPtr = NULL; status = HeapLocateBuffer (&LocateHeapStructPtr, StdHeader); if (status != AGESA_SUCCESS) { return status; } GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader); FamilySpecificServices->GetTscRate (FamilySpecificServices, &TscRateInMhz, StdHeader); ((TP_Perf_STRUCT *) (LocateHeapStructPtr.BufferPtr)) ->TscInMhz = TscRateInMhz; ((TP_Perf_STRUCT *) (LocateHeapStructPtr.BufferPtr)) ->Version = IDS_PERF_VERSION; IdsCalloutData.IdsNvPtr = NULL; IdsCalloutData.StdHeader = *StdHeader; IdsCalloutData.Reserved = 0; Status = AgesaGetIdsData (IDS_CALLOUT_GET_PERF_BUFFER, &IdsCalloutData); //Check if Platform BIOS provide a buffer to copy if ((Status == AGESA_SUCCESS) && (IdsCalloutData.Reserved != 0)) { LibAmdMemCopy ((VOID *)IdsCalloutData.Reserved, LocateHeapStructPtr.BufferPtr, sizeof (TP_Perf_STRUCT), StdHeader); } else { //No platform performance buffer provide, use the default HDTOUT output if (AmdIdsHdtOutSupport () == FALSE) { //Init break point IdsPerfSaveReg (&PerfReg, StdHeader); LibAmdMsrRead (0xC001100A, (UINT64 *)&SMsr, StdHeader); SMsr |= 1; LibAmdMsrWrite (0xC001100A, (UINT64 *)&SMsr, StdHeader); LibAmdWriteCpuReg (DR2_REG, 0x99cc); LibAmdWriteCpuReg (DR7_REG, 0x02000420); LibAmdReadCpuReg (CR4_REG, &CR4reg); LibAmdWriteCpuReg (CR4_REG, CR4reg | ((UINT32)1 << 3)); IdsPerfHdtOut (1, (UINT32) (UINT64) LocateHeapStructPtr.BufferPtr, StdHeader); IdsPerfRestoreReg (&PerfReg, StdHeader); } } return status; }
/** * 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); } }
void PSPProgBar3Msr(void *Buffer) { u32 Bar3Addr; u64 Tmp64; /* Get Bar3 Addr */ Bar3Addr = PspLibPciReadPspConfig(0x20); Tmp64 = Bar3Addr; printk(BIOS_DEBUG, "Bar3=%llx\n", Tmp64); LibAmdMsrWrite(0xC00110A2, &Tmp64, NULL); LibAmdMsrRead(0xC00110A2, &Tmp64, NULL); }
/** * 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; }
/** * Cold reset support routine for F10PmNbCofVidInit. * * This function implements steps 3, 4, & 5 on each core. * * @param[in] NewNbVid NewNbVid determined by core 0 in step 2. * @param[in] StdHeader Config handle for library and services. * */ VOID STATIC PmNbCofVidInitP0P1Core ( IN VOID *NewNbVid, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 MsrAddress; UINT64 MsrRegister; CPU_SPECIFIC_SERVICES *FamilySpecificServices = NULL; GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader); LibAmdMsrRead (MSR_COFVID_STS, &MsrRegister, StdHeader); MsrAddress = (UINT32) ((((COFVID_STS_MSR *) &MsrRegister)->StartupPstate) + PS_REG_BASE); LibAmdMsrRead (MsrAddress, &MsrRegister, StdHeader); LibAmdMsrWrite ((UINT32) (PS_REG_BASE + 1), &MsrRegister, StdHeader); ((PSTATE_MSR *) &MsrRegister)->NbVid = *(UINT8 *) NewNbVid; LibAmdMsrWrite (PS_REG_BASE, &MsrRegister, StdHeader); FamilySpecificServices->TransitionPstate (FamilySpecificServices, (UINT8) 1, (BOOLEAN) FALSE, StdHeader); }
/** * Support routine for F16MlPmCoreAfterReset to perform MSR initialization on all * cores of a family 16h socket. * * This function implements steps 1 - 3 on each core. * * @param[in] StdHeader Config handle for library and services. * */ VOID STATIC F16MlPmCoreAfterResetPhase1OnCore ( IN AMD_CONFIG_PARAMS *StdHeader ) { BOOLEAN SkipStep3; UINT64 CofvidSts; UINT64 LocalMsrRegister; UINT64 PstateCtrl; IDS_HDT_CONSOLE (CPU_TRACE, " F16MlPmCoreAfterResetPhase1OnCore\n"); // 1. If MSRC001_0071[CurPstate] = MSRC001_0071[CurPstateLimit], then skip step 3 for that core LibAmdMsrRead (MSR_COFVID_STS, &CofvidSts, StdHeader); if (((COFVID_STS_MSR *) &CofvidSts)->CurPstate == ((COFVID_STS_MSR *) &CofvidSts)->CurPstateLimit) { SkipStep3 = TRUE; } else { SkipStep3 = FALSE; } // 2. Write 0 to MSRC001_0062[PstateCmd] on all cores in the processor. PstateCtrl = 0; LibAmdMsrWrite (MSR_PSTATE_CTL, &PstateCtrl, StdHeader); // 3. Wait for MSRC001_0071[CurCpuFid, CurCpuDid] = [CpuFid, CpuDid] from // MSRC001_00[6B:64] indexed by MSRC001_0071[CurPstateLimit]. if (!SkipStep3) { do { LibAmdMsrRead (MSR_COFVID_STS, &CofvidSts, StdHeader); LibAmdMsrRead ((UINT32) (MSR_PSTATE_0 + (UINT32) (((COFVID_STS_MSR *) &CofvidSts)->CurPstateLimit)), &LocalMsrRegister, StdHeader); } while ((((COFVID_STS_MSR *) &CofvidSts)->CurCpuFid != ((PSTATE_MSR *) &LocalMsrRegister)->CpuFid) || (((COFVID_STS_MSR *) &CofvidSts)->CurCpuDid != ((PSTATE_MSR *) &LocalMsrRegister)->CpuDid)); } // 4. Write MSRC001_0061[PstateMaxVal] to MSRC001_0062[PstateCmd] on all // cores in the processor. LibAmdMsrRead (MSR_PSTATE_CURRENT_LIMIT, &LocalMsrRegister, StdHeader); ((PSTATE_CTRL_MSR *) &PstateCtrl)->PstateCmd = ((PSTATE_CURLIM_MSR *) &LocalMsrRegister)->PstateMaxVal; LibAmdMsrWrite (MSR_PSTATE_CTL, &PstateCtrl, StdHeader); }
VOID MemRecNInitializeMctDR ( IN OUT MEM_NB_BLOCK *NBPtr ) { MEM_DATA_STRUCT *MemPtr; S_UINT64 SMsr; MemPtr = NBPtr->MemPtr; LibAmdMsrRead (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader); if (SMsr.lo & ((UINT32) 1 << 15)) { NBPtr->ClToNbFlag = TRUE; } SMsr.lo |= (UINT32) 1 << 15; // ClLinesToNbDis LibAmdMsrWrite (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader); LibAmdMsrRead (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader); SMsr.hi |= (UINT32) 1 << (48 - 32); // WbEnhWsbDis LibAmdMsrWrite (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader); }
/** * Is the currently running core the BSC? * * Determine whether the init steps for BSC or AP core should be run. * * @param[in] State global state, input data * * @retval TRUE This is the boot core. * @retval FALSE This is not the boot core. */ BOOLEAN STATIC IsBootCore ( IN STATE_DATA *State ) { UINT64 Value; LibAmdMsrRead (APIC_Base, &Value, State->ConfigHandle); return ((BOOLEAN) (((UINT32) (Value & 0xFFFFFFFF) & ((UINT32)1 << APIC_Base_BSP)) != 0)); }
VOID MemFS3Wait10ns ( IN UINT32 Count, IN OUT MEM_DATA_STRUCT *MemPtr ) { UINT32 TscRate; UINT64 TargetTsc; UINT64 CurrentTsc; CPU_SPECIFIC_SERVICES *FamilySpecificServices; ASSERT (Count <= 1000000); GetCpuServicesOfCurrentCore ((const CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, &MemPtr->StdHeader); FamilySpecificServices->GetTscRate (FamilySpecificServices, &TscRate, &MemPtr->StdHeader); LibAmdMsrRead (TSC, &CurrentTsc, &MemPtr->StdHeader); TargetTsc = CurrentTsc + ((Count * TscRate + 99) / 100); do { LibAmdMsrRead (TSC, &CurrentTsc, &MemPtr->StdHeader); } while (CurrentTsc < TargetTsc); }