/** * 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); }
/** * 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); } }
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); }
VOID MemRecNFinalizeMctDR ( 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); }
/** * 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); }
/** * 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++; } } }
/** * 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); } } } }
/** * 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); } }
VOID STATIC MemRecUSetTargetWTIO ( IN UINT32 Address, IN OUT MEM_DATA_STRUCT *MemPtr ) { S_UINT64 SMsr; SMsr.lo = Address; SMsr.hi = 0; LibAmdMsrWrite (IORR0_BASE,(UINT64 *)&SMsr, &MemPtr->StdHeader); // ;IORR0 Base SMsr.hi = 0xFFFF; SMsr.lo = 0xFC000800; LibAmdMsrWrite (IORR0_MASK, (UINT64 *)&SMsr, &MemPtr->StdHeader); // ;64MB Mask }
/** * 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); } } } } }
/** * Family specific code for programming weights. * * @param[in] *SmuCpuInfoPtr Pointer to Smu data. * @param[in] StdHeader Config handle for library and services. * * @retval AGESA_SUCCESS Normalizer and weights programmed * @retval AGESA_ERROR Unable to locate Smu data, or error in Smu data * */ AGESA_STATUS STATIC F16MlProgramWeights ( IN SMU_RAM_CPU_INFO *SmuCpuInfoPtr, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 i; C001_1072_MSR PowerMonitorWeights; // If we get valid data, but number of counts is incorrect for Mullins, panic ! ASSERT (SmuCpuInfoPtr->CountApmWeights == WEIGHTS); if (SmuCpuInfoPtr->CountApmWeights != WEIGHTS) { PutEventLog (AGESA_ERROR, (CPU_EVENT_SCS_INITIALIZATION_ERROR + AGESA_SCS_WEIGHTS_MISMATCH), 0, 0, 0, 0, StdHeader); return AGESA_ERROR; } // Process table and program the Power Monitor Weights (MSRC001_1072) for (i = 0; i < SmuCpuInfoPtr->CountApmWeights; i++) { PowerMonitorWeights.ArrayIndex = i; PowerMonitorWeights.WriteCmd = 1; PowerMonitorWeights.WriteData = SmuCpuInfoPtr->MSRApmWeights[i].Weight; LibAmdMsrWrite (MSR_C001_1072, (UINT64 *) (&PowerMonitorWeights), StdHeader); } return AGESA_SUCCESS; }
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); }
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; }
/** * Enable Hardware C1e on a family 10h core. * * @param[in] IntPendMsr MSR value to write to C001_0055 as determined by core 0. * @param[in] StdHeader Config Handle for library, services. * */ VOID STATIC F10InitializeHwC1eOnCore ( IN VOID *IntPendMsr, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT64 MsrRegister; // Enable C1e LibAmdMsrWrite (MSR_INTPEND, (UINT64 *) IntPendMsr, StdHeader); // Set OS Visible Workaround Status BIT1 to indicate that C1e // is enabled. LibAmdMsrRead (MSR_OSVW_Status, &MsrRegister, StdHeader); MsrRegister |= BIT1; LibAmdMsrWrite (MSR_OSVW_Status, &MsrRegister, StdHeader); }
/** * Enable C-State on a family 14h core. * * @param[in] CstateBaseMsr MSR value to write to C001_0073 as determined by core 0. * @param[in] StdHeader Config Handle for library, services. * */ VOID STATIC F14InitializeIoCstateOnCore ( IN VOID *CstateBaseMsr, IN AMD_CONFIG_PARAMS *StdHeader ) { // Initialize MSRC001_0073[CstateAddr] on each core LibAmdMsrWrite (MSR_CSTATE_ADDRESS, (UINT64 *) CstateBaseMsr, 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); }
/** * 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); }
VOID STATIC MemRecUResetTargetWTIO ( IN OUT MEM_DATA_STRUCT *MemPtr ) { S_UINT64 Smsr; Smsr.hi = 0; Smsr.lo = 0; LibAmdMsrWrite (IORR0_MASK, (UINT64 *)&Smsr, &MemPtr->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); }
/** * Restores the context of a 'conditional' MSR device. * * This traverses the provided register list restoring 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 RestoreConditionalMsrDevice ( IN AMD_CONFIG_PARAMS *StdHeader, IN CONDITIONAL_MSR_DEVICE_DESCRIPTOR *Device, IN CALL_POINTS CallPoint, IN OUT UINT64 **OrMask ) { UINT8 SpecialCaseIndex; UINT8 BootMode; UINT16 i; UINT64 RegValueRead; UINT64 RegValueWrite; CMSR_REGISTER_BLOCK_HEADER *RegisterHdr; if (CallPoint == INIT_RESUME) { MemFS3GetCMsrDeviceRegisterList (Device, &RegisterHdr, StdHeader); } else { S3GetCMsrDeviceRegisterList (Device, &RegisterHdr, StdHeader); } BootMode = S3_RESUME_MODE; if (StdHeader->Func == AMD_INIT_POST) { BootMode = RESTORE_TRAINING_MODE | CAPSULE_REBOOT_MODE; } 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].BootMode == 0) || ((BootMode & RegisterHdr->RegisterList[i].BootMode) != 0)) { // Do not restore the register if not in the right boot mode // Pointer to the saved data buffer still needs to be adjusted as data will be saved regardless of boot mode RegValueWrite = **OrMask; if (RegisterHdr->RegisterList[i].Type.SpecialCaseFlag == 0) { LibAmdMsrRead (RegisterHdr->RegisterList[i].Address, &RegValueRead, StdHeader); RegValueWrite |= RegValueRead & (~RegisterHdr->RegisterList[i].AndMask); LibAmdMsrWrite (RegisterHdr->RegisterList[i].Address, &RegValueWrite, StdHeader); } else { SpecialCaseIndex = RegisterHdr->RegisterList[i].Type.SpecialCaseIndex; RegisterHdr->SpecialCases[SpecialCaseIndex].Save (RegisterHdr->RegisterList[i].Address, &RegValueRead, StdHeader); RegValueWrite |= RegValueRead & (~RegisterHdr->RegisterList[i].AndMask); RegisterHdr->SpecialCases[SpecialCaseIndex].Restore (RegisterHdr->RegisterList[i].Address, &RegValueWrite, StdHeader); } } (*OrMask)++; } } }
/** * Set MSR bits required for HT Assist on each core. * * @param[in] HtAssistServices HT Assist family services. * @param[in] StdHeader Config Handle for library, services. * */ VOID STATIC F10HookDisableCache ( IN HT_ASSIST_FAMILY_SERVICES *HtAssistServices, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT64 MsrRegister; LibAmdMsrRead (MSR_BU_CFG2, &MsrRegister, StdHeader); MsrRegister |= BIT42; LibAmdMsrWrite (MSR_BU_CFG2, &MsrRegister, StdHeader); }
/** * Family specific call to set core TscFreqSel. * * @param[in] PstateCpuServices Pstate CPU services. * @param[in] StdHeader Config Handle for library, services. * */ VOID STATIC F12SetTscFreqSel ( IN PSTATE_CPU_FAMILY_SERVICES *PstateCpuServices, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT64 MsrValue; LibAmdMsrRead (MSR_HWCR, &MsrValue, StdHeader); MsrValue = MsrValue | BIT24; LibAmdMsrWrite (MSR_HWCR, &MsrValue, StdHeader); }
/** * Copies the contents of one P-State MSR to another. * * @param[in] Dest Destination p-state number * @param[in] Src Source p-state number * @param[in] StdHeader Config handle for library and services * */ VOID STATIC F10PmPwrChkCopyPstate ( IN UINT8 Dest, IN UINT8 Src, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT64 LocalMsrRegister; LibAmdMsrRead ((UINT32) (PS_REG_BASE + Src), &LocalMsrRegister, StdHeader); LibAmdMsrWrite ((UINT32) (PS_REG_BASE + Dest), &LocalMsrRegister, StdHeader); }
VOID MemRecNFinalizeMctHy ( IN OUT MEM_NB_BLOCK *NBPtr ) { MEM_DATA_STRUCT *MemPtr; S_UINT64 SMsr; MemPtr = NBPtr->MemPtr; // Recommended settings for F2x11C MemRecNSetBitFieldNb (NBPtr, BFMctCfgHiReg, 0x2CE00F60); 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); }
/** * Set MSR bits required for L3 dependent features on each core. * * @param[in] L3FeatureServices L3 feature family services. * @param[in] HtAssistEnabled Indicates whether Ht Assist is enabled. * @param[in] StdHeader Config Handle for library, services. * */ VOID STATIC F10HookDisableCache ( IN L3_FEATURE_FAMILY_SERVICES *L3FeatureServices, IN BOOLEAN HtAssistEnabled, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT64 LocalMsrRegister; LibAmdMsrRead (MSR_BU_CFG2, &LocalMsrRegister, StdHeader); LocalMsrRegister |= BIT42; LibAmdMsrWrite (MSR_BU_CFG2, &LocalMsrRegister, StdHeader); }
STATIC VOID IdsPerfRestoreReg ( IN PERFREGBACKUP * perfreg, IN OUT AMD_CONFIG_PARAMS *StdHeader ) { LibAmdMsrWrite (0xC001100A, &perfreg->SMsr, StdHeader); LibAmdWriteCpuReg (DR0_REG, perfreg->Dr0Reg); LibAmdWriteCpuReg (DR7_REG, perfreg->Dr7Reg); LibAmdWriteCpuReg (CR4_REG, perfreg->Cr4Reg); }
/** * Reload microcode patch for a family 14h CPU after memory is initialized. * * @param[in] StdHeader Config Handle for library, services. * */ VOID STATIC F14ReloadMicrocodePatchAfterMemInit ( IN AMD_CONFIG_PARAMS *StdHeader ) { UINT64 MsrValue; // 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); // Reload microcode patches. LoadMicrocodePatch (StdHeader); LibAmdMsrRead (MSR_BU_CFG3, &MsrValue, StdHeader); MsrValue = MsrValue & ~((UINT64)BIT7); LibAmdMsrWrite (MSR_BU_CFG3, &MsrValue, StdHeader); }