/** * This routine checks whether any non-coherent links in the system * runs in HT1 mode; used to determine whether certain features * should be disabled when this routine returns TRUE. * * @param[in] StdHeader Standard AMD configuration parameters. * * @retval TRUE One of the non-coherent links in the * system runs in HT1 mode * @retval FALSE None of the non-coherent links in the * system is running in HT1 mode */ BOOLEAN IsNonCoherentHt1 ( IN AMD_CONFIG_PARAMS *StdHeader ) { UINTN Link; UINT32 Socket; UINT32 Module; PCI_ADDR PciAddress; AGESA_STATUS AgesaStatus; HT_HOST_FEATS HtHostFeats; CPU_SPECIFIC_SERVICES *CpuServices; for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { if (IsProcessorPresent (Socket, StdHeader)) { GetCpuServicesOfSocket (Socket, &CpuServices, StdHeader); for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) { if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &AgesaStatus)) { HtHostFeats.HtHostValue = 0; Link = 0; while (CpuServices->GetNextHtLinkFeatures (CpuServices, &Link, &PciAddress, &HtHostFeats, StdHeader)) { // Return TRUE and exit routine once we find a non-coherent link in HT1 if ((HtHostFeats.HtHostFeatures.NonCoherent == 1) && (HtHostFeats.HtHostFeatures.Ht1 == 1)) { return TRUE; } } } } } } return FALSE; }
/** * Multisocket call to determine if the BIOS is responsible for updating the * northbridge operating frequency and voltage. * * This function loops through all possible socket locations, checking whether * any populated sockets require NB COF VID programming. * * @param[in] StdHeader Config handle for library and services * * @retval TRUE BIOS needs to set up NB frequency and voltage * @retval FALSE BIOS does not need to set up NB frequency and voltage * */ BOOLEAN GetSystemNbCofVidUpdateMulti ( IN AMD_CONFIG_PARAMS *StdHeader ) { UINT8 Module; UINT32 Socket; UINT32 NumberOfSockets; BOOLEAN IgnoredBool; BOOLEAN AtLeast1RequiresUpdate; PCI_ADDR PciAddress; AGESA_STATUS Ignored; CPU_SPECIFIC_SERVICES *FamilySpecificServices; NumberOfSockets = GetPlatformNumberOfSockets (); AtLeast1RequiresUpdate = FALSE; for (Socket = 0; Socket < NumberOfSockets; Socket++) { if (IsProcessorPresent (Socket, StdHeader)) { GetCpuServicesOfSocket (Socket, (CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) { if (GetPciAddress (StdHeader, (UINT8) Socket, Module, &PciAddress, &Ignored)) { break; } } if (FamilySpecificServices->IsNbCofInitNeeded (FamilySpecificServices, &PciAddress, &IgnoredBool, StdHeader)) { AtLeast1RequiresUpdate = TRUE; break; } } } return AtLeast1RequiresUpdate; }
/** * Single socket call to determine the frequency that the northbridges must run. * * This function simply returns the executing core's NB frequency, and that all * NB frequencies are equivalent. * * @param[in] NbPstate NB P-state number to check (0 = fastest) * @param[in] PlatformConfig Platform profile/build option config structure. * @param[out] SystemNbCofNumerator NB frequency numerator for the system in MHz * @param[out] SystemNbCofDenominator NB frequency denominator for the system * @param[out] SystemNbCofsMatch Whether or not all NB frequencies are equivalent * @param[out] NbPstateIsEnabledOnAllCPUs Whether or not NbPstate is valid on all CPUs * @param[in] StdHeader Config handle for library and services * * @retval TRUE At least one processor has NbPstate enabled. * @retval FALSE NbPstate is disabled on all CPUs * */ BOOLEAN GetSystemNbCofSingle ( IN UINT32 NbPstate, IN PLATFORM_CONFIGURATION *PlatformConfig, OUT UINT32 *SystemNbCofNumerator, OUT UINT32 *SystemNbCofDenominator, OUT BOOLEAN *SystemNbCofsMatch, OUT BOOLEAN *NbPstateIsEnabledOnAllCPUs, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 Ignored; PCI_ADDR PciAddress; CPU_SPECIFIC_SERVICES *FamilySpecificServices; PciAddress.AddressValue = MAKE_SBDFO (0, 0, 24, 0, 0); *SystemNbCofsMatch = TRUE; GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader); *NbPstateIsEnabledOnAllCPUs = FamilySpecificServices->GetNbPstateInfo (FamilySpecificServices, PlatformConfig, &PciAddress, NbPstate, SystemNbCofNumerator, SystemNbCofDenominator, &Ignored, StdHeader); return *NbPstateIsEnabledOnAllCPUs; }
/** * Determines the base address of the executing core's heap. * * This function uses the executing core's socket/core numbers to determine * where it's heap should be located. * * @param[in] StdHeader Config handle for library and services. * * @return A pointer to the executing core's heap. * */ UINT64 STATIC HeapGetCurrentBase ( IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 SystemCoreNumber; UINT64 ReturnPtr; AGESA_STATUS IgnoredStatus; CPU_SPECIFIC_SERVICES *FamilyServices; if (IsBsp (StdHeader, &IgnoredStatus)) { ReturnPtr = AMD_HEAP_START_ADDRESS; } else { GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilyServices, StdHeader); ASSERT (FamilyServices != NULL); SystemCoreNumber = FamilyServices->GetApCoreNumber (FamilyServices, StdHeader); ASSERT (SystemCoreNumber != 0); ASSERT (SystemCoreNumber < 64); ReturnPtr = ((SystemCoreNumber * AMD_HEAP_SIZE_PER_CORE) + AMD_HEAP_START_ADDRESS); } ASSERT (ReturnPtr <= ((AMD_HEAP_REGION_END_ADDRESS + 1) - AMD_HEAP_SIZE_PER_CORE)); return ReturnPtr; }
BOOLEAN STATIC MemConstructRemoteNBBlockHY ( IN OUT MEM_NB_BLOCK *NBPtr, IN DIE_STRUCT *MCTPtr, IN MEM_FEAT_BLOCK_NB *FeatPtr ) { CPU_SPECIFIC_SERVICES *FamilySpecificServices; NBPtr->MCTPtr = MCTPtr; NBPtr->PciAddr.AddressValue = MCTPtr->PciAddr.AddressValue; MemNInitNBDataHy (NBPtr); FeatPtr->InitCPG (NBPtr); NBPtr->FeatPtr = FeatPtr; FeatPtr->InitHwRxEn (NBPtr); MemNSwitchDCTNb (NBPtr, 0); //---------------------------------------------------------------------------- // Get TSC rate of the this AP //---------------------------------------------------------------------------- GetCpuServicesOfCurrentCore ((const CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, &NBPtr->MemPtr->StdHeader); FamilySpecificServices->GetTscRate (FamilySpecificServices, &NBPtr->MemPtr->TscRate, &NBPtr->MemPtr->StdHeader); return TRUE; }
/** * Get the number of P-State to support * * @param[in,out] StdHeader The Pointer of AMD_CONFIG_PARAMS. * * @retval num The number of P-State to support. * **/ UINT8 IdsGetNumPstatesFamCommon ( IN OUT AMD_CONFIG_PARAMS *StdHeader ) { UINT8 pstatesnum; UINT8 i; UINT32 IddVal; UINT32 IddDiv; BOOLEAN PStateEnabled; UINT32 TempVar_c; CPU_SPECIFIC_SERVICES *FamilySpecificServices; pstatesnum = 0; GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader); FamilySpecificServices->GetPstateMaxState (FamilySpecificServices, &TempVar_c, StdHeader); for (i = 0; i <= TempVar_c; i++) { // Check if PState is enabled FamilySpecificServices->GetPstateRegisterInfo (FamilySpecificServices, (UINT32) i, &PStateEnabled, &IddVal, &IddDiv, StdHeader); if (PStateEnabled) { pstatesnum++; } } return pstatesnum; }
/** * This function will get the CPU register warm reset bits. * * Note: This function will be called by UEFI BIOS's * The UEFI wrapper code should register this function, to be called back later point * in time, before the wrapper code does warm reset. * * @param[in] StdHeader Config handle for library and services * @param[out] Request Indicate warm reset status * *--------------------------------------------------------------------------------------- **/ VOID GetWarmResetFlag ( IN AMD_CONFIG_PARAMS *StdHeader, OUT WARM_RESET_REQUEST *Request ) { CPU_SPECIFIC_SERVICES *FamilySpecificServices; FamilySpecificServices = NULL; GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader); FamilySpecificServices->GetWarmResetFlag (FamilySpecificServices, StdHeader, Request); switch (StdHeader->Func) { case AMD_INIT_RESET: Request->PostStage = (UINT8) WR_STATE_RESET; break; case AMD_INIT_EARLY: Request->PostStage = (UINT8) WR_STATE_EARLY; break; case AMD_INIT_POST: // Fall through to default case default: Request->PostStage = (UINT8) WR_STATE_POST; break; } }
/** * Multisocket BSC call to determine the maximum number of steps that any single * processor needs to execute. * * This function loops through all possible socket locations, gathering the number * of power management steps each populated socket requires, and returns the * highest number. * * @param[out] NumSystemSteps Maximum number of system steps required * @param[in] StdHeader Config handle for library and services * */ VOID GetNumberOfSystemPmStepsPtrMulti ( OUT UINT8 *NumSystemSteps, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT8 NumberOfSteps; UINT32 NumberOfSockets; UINT32 Socket; SYS_PM_TBL_STEP *Ignored; CPU_SPECIFIC_SERVICES *FamilySpecificServices; NumberOfSockets = GetPlatformNumberOfSockets (); *NumSystemSteps = 0; for (Socket = 0; Socket < NumberOfSockets; Socket++) { if (IsProcessorPresent (Socket, StdHeader)) { GetCpuServicesOfSocket (Socket, (CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); FamilySpecificServices->GetSysPmTableStruct (FamilySpecificServices, (CONST VOID **) &Ignored, &NumberOfSteps, StdHeader); if (NumberOfSteps > *NumSystemSteps) { *NumSystemSteps = NumberOfSteps; } } } }
/** * 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; }
/** * Single socket BSC call to determine the maximum number of steps that any single * processor needs to execute. * * This function simply returns the number of steps that the BSC needs. * * @param[out] NumSystemSteps Maximum number of system steps required * @param[in] StdHeader Config handle for library and services * */ VOID GetNumberOfSystemPmStepsPtrSingle ( OUT UINT8 *NumSystemSteps, IN AMD_CONFIG_PARAMS *StdHeader ) { SYS_PM_TBL_STEP *Ignored; CPU_SPECIFIC_SERVICES *FamilySpecificServices; GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader); FamilySpecificServices->GetSysPmTableStruct (FamilySpecificServices, (CONST VOID **) &Ignored, NumSystemSteps, StdHeader); }
/** * Transitions the executing core to the desired P-state. * * This function implements the AMD_CPU_EARLY_PARAMS.MemInitPState parameter, and is * run by all system cores. * * @param[in] StdHeader Config handle for library and services * @param[in] CpuEarlyParamsPtr Required input parameters for early CPU initialization * */ VOID STATIC GoToMemInitPstateCore ( IN AMD_CONFIG_PARAMS *StdHeader, IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr ) { CPU_SPECIFIC_SERVICES *FamilySpecificServices; GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); FamilySpecificServices->TransitionPstate (FamilySpecificServices, CpuEarlyParamsPtr->MemInitPState, (BOOLEAN) FALSE, StdHeader); }
/** * This function will set the CPU register warm reset bits. * * Note: This function will be called by UEFI BIOS's * The UEFI wrapper code should register this function, to be called back later point * in time, before the wrapper code does warm reset. * * @param[in] StdHeader Config handle for library and services * @param[in] Request Indicate warm reset status * *--------------------------------------------------------------------------------------- **/ VOID SetWarmResetFlag ( IN AMD_CONFIG_PARAMS *StdHeader, IN WARM_RESET_REQUEST *Request ) { CPU_SPECIFIC_SERVICES *FamilySpecificServices; FamilySpecificServices = NULL; GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader); FamilySpecificServices->SetWarmResetFlag (FamilySpecificServices, StdHeader, Request); }
/** * Single socket call to determine if the BIOS is responsible for updating the * northbridge operating frequency and voltage. * * This function simply returns whether or not the executing core needs NB COF * VID programming. * * @param[in] StdHeader Config handle for library and services * * @retval TRUE BIOS needs to set up NB frequency and voltage * @retval FALSE BIOS does not need to set up NB frequency and voltage * */ BOOLEAN GetSystemNbCofVidUpdateSingle ( IN AMD_CONFIG_PARAMS *StdHeader ) { BOOLEAN Ignored; PCI_ADDR PciAddress; CPU_SPECIFIC_SERVICES *FamilySpecificServices; PciAddress.AddressValue = MAKE_SBDFO (0, 0, 24, 0, 0); GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader); return (FamilySpecificServices->IsNbCofInitNeeded (FamilySpecificServices, &PciAddress, &Ignored, StdHeader)); }
/** * * WriteFeatures * * Write out least common features set of all CPUs * * @param[in,out] cpuFeatureListPtr - Pointer to CPU Feature List. * @param[in,out] StdHeader - Pointer to AMD_CONFIG_PARAMS struct. * */ VOID STATIC WriteFeatures ( IN OUT VOID *cpuFeatureListPtr, IN OUT AMD_CONFIG_PARAMS *StdHeader ) { CPU_SPECIFIC_SERVICES *FamilySpecificServices; FamilySpecificServices = NULL; GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); FamilySpecificServices->WriteFeatures (FamilySpecificServices, cpuFeatureListPtr, StdHeader); }
/** * Multisocket call to loop through all possible socket locations and Nb Pstates, * comparing the NB frequencies to determine the slowest system and P0 frequency * * @param[in] PlatformConfig Platform profile/build option config structure. * @param[out] MinSysNbFreq NB frequency numerator for the system in MHz * @param[out] MinP0NbFreq NB frequency numerator for P0 in MHz * @param[in] StdHeader Config handle for library and services */ VOID GetMinNbCofMulti ( IN PLATFORM_CONFIGURATION *PlatformConfig, OUT UINT32 *MinSysNbFreq, OUT UINT32 *MinP0NbFreq, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 Socket; UINT32 Module; UINT32 CurrMinFreq; UINT32 CurrMaxFreq; PCI_ADDR PciAddress; AGESA_STATUS Ignored; CPU_SPECIFIC_SERVICES *FamilySpecificServices; AGESA_STATUS AgesaStatus; *MinSysNbFreq = 0xFFFFFFFF; *MinP0NbFreq = 0xFFFFFFFF; for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { if (IsProcessorPresent (Socket, StdHeader)) { GetCpuServicesOfSocket (Socket, (CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) { if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &Ignored )) { break; } } AgesaStatus = FamilySpecificServices->GetMinMaxNbFrequency (FamilySpecificServices, PlatformConfig, &PciAddress, &CurrMinFreq, &CurrMaxFreq, StdHeader); ASSERT (AgesaStatus == AGESA_SUCCESS); ASSERT ((CurrMinFreq != 0) && (CurrMaxFreq != 0)); // Determine the slowest NB Pmin frequency if (CurrMinFreq < *MinSysNbFreq) { *MinSysNbFreq = CurrMinFreq; } // Determine the slowest NB P0 frequency if (CurrMaxFreq < *MinP0NbFreq) { *MinP0NbFreq = CurrMaxFreq; } } } }
/** * IDS Backend Function for Target Pstate * * * @param[in,out] DataPtr The Pointer of AMD_CPU_EARLY_PARAMS. * @param[in,out] StdHeader The Pointer of AMD_CONFIG_PARAMS. * @param[in] IdsNvPtr The Pointer of NV Table. * * @retval IDS_SUCCESS Backend function is called successfully. * @retval IDS_UNSUPPORTED No Backend function is found. * **/ IDS_STATUS IdsSubTargetPstate ( IN OUT VOID *DataPtr, IN OUT AMD_CONFIG_PARAMS *StdHeader, IN IDS_NV_ITEM *IdsNvPtr ) { IDS_STATUS tarpst; CPU_SPECIFIC_SERVICES *FamilySpecificServices; IDS_NV_READ_SKIP (tarpst, AGESA_IDS_NV_TARGET_PSTATE, IdsNvPtr) { GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader); FamilySpecificServices->TransitionPstate (FamilySpecificServices, (UINT8) tarpst, (BOOLEAN) FALSE, StdHeader); }
/** * Performs the next step in the executing core 0's family specific power * management table. * * This function determines if the input step is valid, and invokes the power * management step if appropriate. This must be run by processor core 0s only. * * @param[in] Step Zero based step number * @param[in] StdHeader Config handle for library and services * @param[in] CpuEarlyParamsPtr Required input parameters for early CPU initialization * */ VOID STATIC PerformThisPmStep ( IN VOID *Step, IN AMD_CONFIG_PARAMS *StdHeader, IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr ) { UINT8 MyNumberOfSteps; UINT32 ExeResetFlags; SYS_PM_TBL_STEP *FamilyTablePtr; CPU_SPECIFIC_SERVICES *FamilySpecificServices; BOOLEAN ThisIsWarmReset; BOOLEAN NoResetLimit; BOOLEAN NotConflictResetLimit; BOOLEAN WarmResetOnly; BOOLEAN ColdResetOnly; GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); FamilySpecificServices->GetSysPmTableStruct (FamilySpecificServices, (CONST VOID **) &FamilyTablePtr, &MyNumberOfSteps, StdHeader); if (*(UINT8 *)Step < MyNumberOfSteps) { if (FamilyTablePtr[*(UINT8 *)Step].FuncPtr != NULL) { ExeResetFlags = FamilyTablePtr[*(UINT8 *)Step].ExeFlags & (PM_EXEFLAGS_COLD_ONLY | PM_EXEFLAGS_WARM_ONLY); ThisIsWarmReset = IsWarmReset (StdHeader); NoResetLimit = (ExeResetFlags == 0) ? TRUE : FALSE; NotConflictResetLimit = (BOOLEAN) (ExeResetFlags != (PM_EXEFLAGS_COLD_ONLY | PM_EXEFLAGS_WARM_ONLY)); WarmResetOnly = (BOOLEAN) ((ExeResetFlags & PM_EXEFLAGS_WARM_ONLY) == PM_EXEFLAGS_WARM_ONLY); ColdResetOnly = (BOOLEAN) ((ExeResetFlags & PM_EXEFLAGS_COLD_ONLY) == PM_EXEFLAGS_COLD_ONLY); IDS_HDT_CONSOLE (CPU_TRACE, " \tIsWarmReset = %d.\n", ThisIsWarmReset); IDS_HDT_CONSOLE (CPU_TRACE, " \tNoResetLimit = %d\n", NoResetLimit); IDS_HDT_CONSOLE (CPU_TRACE, " \tNotConflictResetLimit = %d\n", NotConflictResetLimit); IDS_HDT_CONSOLE (CPU_TRACE, " \tWarmResetOnly = %d\n", WarmResetOnly); IDS_HDT_CONSOLE (CPU_TRACE, " \tColdResetOnly = %d\n", ColdResetOnly); ASSERT (NotConflictResetLimit); if (NoResetLimit || (NotConflictResetLimit && ((WarmResetOnly && ThisIsWarmReset) || (ColdResetOnly && !ThisIsWarmReset)))) { FamilyTablePtr[*(UINT8 *)Step].FuncPtr (FamilySpecificServices, CpuEarlyParamsPtr, StdHeader); } else { IDS_HDT_CONSOLE (CPU_TRACE, " \t\tThis PM init step was skipped!\n"); } } } }
/** * Single socket call to loop through all Nb Pstates, comparing the NB frequencies * to determine the slowest in the system. This routine also returns the NB P0 frequency. * * @param[in] PlatformConfig Platform profile/build option config structure. * @param[out] MinSysNbFreq NB frequency numerator for the system in MHz * @param[out] MinP0NbFreq NB frequency numerator for P0 in MHz * @param[in] StdHeader Config handle for library and services */ VOID GetMinNbCofSingle ( IN PLATFORM_CONFIGURATION *PlatformConfig, OUT UINT32 *MinSysNbFreq, OUT UINT32 *MinP0NbFreq, IN AMD_CONFIG_PARAMS *StdHeader ) { PCI_ADDR PciAddress; CPU_SPECIFIC_SERVICES *FamilySpecificServices; PciAddress.AddressValue = MAKE_SBDFO (0, 0, 24, 0, 0); GetCpuServicesOfCurrentCore ((const CPU_SPECIFIC_SERVICES **) &FamilySpecificServices, StdHeader); FamilySpecificServices->GetMinMaxNbFrequency (FamilySpecificServices, PlatformConfig, &PciAddress, MinSysNbFreq, MinP0NbFreq, StdHeader); }
/** * 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 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); }
/** *--------------------------------------------------------------------------------------- * * PutCoreInPState0 * * Description: * This function will take the CPU core into P0 * * Parameters: * @param[in] *PStateBuffer * @param[in] *StdHeader * * @retval VOID * *--------------------------------------------------------------------------------------- **/ VOID STATIC PutCoreInPState0 ( IN VOID *PStateBuffer, IN AMD_CONFIG_PARAMS *StdHeader ) { CPU_SPECIFIC_SERVICES *FamilySpecificServices; PSTATE_LEVELING *PStateBufferPtr; PStateBufferPtr = (PSTATE_LEVELING *) PStateBuffer; if ((PStateBufferPtr[0].SetPState0 == PSTATE_FLAG_1 ) || (PStateBufferPtr[0].SetPState0 == PSTATE_FLAG_2)) { return; } GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader); FamilySpecificServices->TransitionPstate (FamilySpecificServices, (UINT8) 0, (BOOLEAN) FALSE, StdHeader); }
/** * 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; 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; //Init break point IdsPerfSaveReg (&PerfReg, StdHeader); LibAmdMsrRead (0xC001100A, (UINT64 *)&SMsr, StdHeader); SMsr |= 1; LibAmdMsrWrite (0xC001100A, (UINT64 *)&SMsr, StdHeader); LibAmdWriteCpuReg (DR0_REG, 0x8899); LibAmdWriteCpuReg (DR7_REG, 0x00020402); LibAmdReadCpuReg (CR4_REG, &CR4reg); LibAmdWriteCpuReg (CR4_REG, CR4reg | ((UINT32)1 << 3)); IdsPerfHdtOut (1, (UINT32) LocateHeapStructPtr.BufferPtr, StdHeader); IdsPerfRestoreReg (&PerfReg, StdHeader); return status; }
/** * Single socket call to loop through all Nb Pstates, comparing the NB frequencies * to determine the slowest in the system. This routine also returns the NB P0 frequency. * * @param[in] PlatformConfig Platform profile/build option config structure. * @param[out] MinSysNbFreq NB frequency numerator for the system in MHz * @param[out] MinP0NbFreq NB frequency numerator for P0 in MHz * @param[in] StdHeader Config handle for library and services */ VOID GetMinNbCofSingle ( IN PLATFORM_CONFIGURATION *PlatformConfig, OUT UINT32 *MinSysNbFreq, OUT UINT32 *MinP0NbFreq, IN AMD_CONFIG_PARAMS *StdHeader ) { PCI_ADDR PciAddress; CPU_SPECIFIC_SERVICES *FamilySpecificServices; AGESA_STATUS AgesaStatus; PciAddress.AddressValue = MAKE_SBDFO (0, 0, 24, 0, 0); GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader); AgesaStatus = FamilySpecificServices->GetMinMaxNbFrequency (FamilySpecificServices, PlatformConfig, &PciAddress, MinSysNbFreq, MinP0NbFreq, StdHeader); ASSERT (AgesaStatus == AGESA_SUCCESS); ASSERT ((MinSysNbFreq != 0) && (MinP0NbFreq != 0)); }
/** * Determines the base address of the executing core's heap. * * This function uses the executing core's socket/core numbers to determine * where it's heap should be located. * * @param[in] StdHeader Config handle for library and services. * * @return A pointer to the executing core's heap. * */ UINT64 STATIC HeapGetCurrentBase ( IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 SystemCoreNumber; UINT64 ReturnPtr; UINTN FcnData; AGESA_STATUS IgnoredStatus; AGESA_REBASE_PARAMS HeapRebaseParams; CPU_SPECIFIC_SERVICES *FamilyServices; HeapRebaseParams.HeapAddress = AMD_HEAP_START_ADDRESS; HeapRebaseParams.StdHeader = *StdHeader; FcnData = 0; AgesaHeapRebase (FcnData, &HeapRebaseParams); if (IsBsp (StdHeader, &IgnoredStatus)) { ReturnPtr = HeapRebaseParams.HeapAddress; } else { GetCpuServicesOfCurrentCore (&FamilyServices, StdHeader); ASSERT (FamilyServices != NULL); SystemCoreNumber = FamilyServices->GetApCoreNumber (FamilyServices, StdHeader); ASSERT (SystemCoreNumber != 0); ASSERT (SystemCoreNumber < 64); ReturnPtr = ((SystemCoreNumber * AMD_HEAP_SIZE_PER_CORE) + HeapRebaseParams.HeapAddress); } // Normally, HeapRebaseParams.HeapAddress = AMD_HEAP_START_ADDRESS // But due to SecureS3, HeapAddress would be changed during run-time // So below checking for ReturnPtr needs to be run only if HeapRebaseParams.HeapAddress = AMD_HEAP_START_ADDRESS if (HeapRebaseParams.HeapAddress == AMD_HEAP_START_ADDRESS) { ASSERT (ReturnPtr <= ((AMD_HEAP_REGION_END_ADDRESS + 1) - AMD_HEAP_SIZE_PER_CORE)); } return ReturnPtr; }
/** * Is this boot a warm reset? * * This function reads the CPU register warm reset bit that is preserved after a warm reset. * Which in fact gets set before issuing warm reset. We just use the BSP's register always. * * @param[in] StdHeader Config handle for library and services * * @retval TRUE Warm Reset * @retval FALSE Not Warm Reset * */ BOOLEAN IsWarmReset ( IN AMD_CONFIG_PARAMS *StdHeader ) { UINT8 PostStage; WARM_RESET_REQUEST Request; BOOLEAN WarmReset; CPU_SPECIFIC_SERVICES *FamilySpecificServices; FamilySpecificServices = NULL; switch (StdHeader->Func) { case AMD_INIT_RESET: PostStage = WR_STATE_RESET; break; case AMD_INIT_EARLY: PostStage = WR_STATE_EARLY; break; case AMD_INIT_POST: default: PostStage = WR_STATE_POST; break; } GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader); FamilySpecificServices->GetWarmResetFlag (FamilySpecificServices, StdHeader, &Request); if (Request.StateBits >= PostStage) { WarmReset = TRUE; } else { WarmReset = FALSE; } return WarmReset; }
/** * Warm reset support routine for F10PmNbCofVidInit. * * This function implements steps 8 & 9 on each core. * * @param[in] FunctionData Contains NewNbVid determined by core 0 in step * 2, and NbVidUpdateAll. * @param[in] StdHeader Config handle for library and services. * */ VOID STATIC PmNbCofVidInitWarmCore ( IN VOID *FunctionData, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 MsrAddress; UINT64 MsrRegister; CPU_SPECIFIC_SERVICES *FamilySpecificServices; GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader); for (MsrAddress = PS_REG_BASE; MsrAddress <= PS_MAX_REG; MsrAddress++) { LibAmdMsrRead (MsrAddress, &MsrRegister, StdHeader); if (((PSTATE_MSR *) &MsrRegister)->PsEnable == 1) { if ((((PSTATE_MSR *) &MsrRegister)->NbDid == 0) || ((NB_COF_VID_INIT_WARM *) FunctionData)->NbVidUpdateAll) { ((PSTATE_MSR *) &MsrRegister)->NbVid = ((NB_COF_VID_INIT_WARM *) FunctionData)->NewNbVid; LibAmdMsrWrite (MsrAddress, &MsrRegister, StdHeader); } } } LibAmdMsrRead (MSR_COFVID_STS, &MsrRegister, StdHeader); FamilySpecificServices->TransitionPstate (FamilySpecificServices, (UINT8) (((COFVID_STS_MSR *) &MsrRegister)->StartupPstate), (BOOLEAN) FALSE, StdHeader); }
/** * Performs the next step in the executing core 0's family specific power * management table. * * This function determines if the input step is valid, and invokes the power * management step if appropriate. This must be run by processor core 0s only. * * @param[in] Step Zero based step number * @param[in] StdHeader Config handle for library and services * @param[in] CpuEarlyParamsPtr Required input parameters for early CPU initialization * */ VOID STATIC PerformThisPmStep ( IN VOID *Step, IN AMD_CONFIG_PARAMS *StdHeader, IN AMD_CPU_EARLY_PARAMS *CpuEarlyParamsPtr ) { UINT8 MyNumberOfSteps; SYS_PM_TBL_STEP *FamilyTablePtr; CPU_SPECIFIC_SERVICES *FamilySpecificServices; GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader); FamilySpecificServices->GetSysPmTableStruct (FamilySpecificServices, &FamilyTablePtr, &MyNumberOfSteps, StdHeader); if (*(UINT8 *)Step < MyNumberOfSteps) { if (FamilyTablePtr[*(UINT8 *)Step].FuncPtr != NULL) { if (!(BOOLEAN) (FamilyTablePtr[*(UINT8 *)Step].ExeFlags & PM_EXEFLAGS_WARM_ONLY) || IsWarmReset (StdHeader)) { FamilyTablePtr[*(UINT8 *)Step].FuncPtr (FamilySpecificServices, CpuEarlyParamsPtr, StdHeader); } } } }
/** * Entry point for enabling Power Status Indicator * * This function must be run after all P-State routines have been executed * * @param[in] PsiServices The current CPU's family services. * @param[in] EntryPoint Timepoint designator. * @param[in] PlatformConfig Contains the runtime modifiable feature input data. * @param[in] StdHeader Config handle for library and services. * * @retval AGESA_SUCCESS Always succeeds. * */ AGESA_STATUS STATIC F15CzInitializePsi ( IN PSI_FAMILY_SERVICES *PsiServices, IN UINT64 EntryPoint, IN PLATFORM_CONFIGURATION *PlatformConfig, IN AMD_CONFIG_PARAMS *StdHeader ) { PCI_ADDR PciAddress; CPU_SPECIFIC_SERVICES *FamilySpecificServices; UINT32 HwPstateMaxVal; F15_CZ_CLK_PWR_TIMING_CTRL2_REGISTER ClkPwrTimingCtrl2; UINT32 CoreVrmLowPowerThreshold; UINT32 Pstate; UINT32 PstateCurrent; UINT32 NextPstateCurrent; PSTATE_MSR PstateMsr; UINT32 CurrentVid; UINT32 PreviousVid; NB_PSTATE_REGISTER NbPstateReg; NB_PSTATE_CTRL_REGISTER NbPsCtrl; UINT32 NbVrmLowPowerThreshold; UINT32 NbPstate; UINT32 NbPstateMaxVal; UINT32 NbPstateCurrent; UINT32 NextNbPstateCurrent; UINT32 PreviousNbVid; UINT32 CurrentNbVid; SMUSVI_MISC_VID_STATUS_REGISTER SmuSviMiscVidStatus; SMUSVI_POWER_CONTROL_MISC_REGISTER SmuSviPowerCtrlMisc; if ((EntryPoint & (CPU_FEAT_AFTER_POST_MTRR_SYNC | CPU_FEAT_AFTER_RESUME_MTRR_SYNC)) != 0) { // Configure PsiVid GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **) &FamilySpecificServices, StdHeader); IDS_HDT_CONSOLE (CPU_TRACE, " F15CzPmVrmLowPowerModeEnable\n"); if (PlatformConfig->VrmProperties[CoreVrm].LowPowerThreshold != 0) { // Set up PSI0_L for VDD CoreVrmLowPowerThreshold = PlatformConfig->VrmProperties[CoreVrm].LowPowerThreshold; IDS_HDT_CONSOLE (CPU_TRACE, " Core VRM - LowPowerThreshold: %d \n", CoreVrmLowPowerThreshold); PreviousVid = 0xFF; PciAddress.AddressValue = CPTC2_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &ClkPwrTimingCtrl2, StdHeader); HwPstateMaxVal = ClkPwrTimingCtrl2.HwPstateMaxVal; IDS_HDT_CONSOLE (CPU_TRACE, " HwPstateMaxVal %d\n", HwPstateMaxVal); for (Pstate = 0; Pstate <= HwPstateMaxVal; Pstate++) { // Check only valid P-state if (FamilySpecificServices->GetProcIddMax (FamilySpecificServices, (UINT8) Pstate, &PstateCurrent, StdHeader) != TRUE) { continue; } LibAmdMsrRead ((UINT32) (Pstate + PS_REG_BASE), (UINT64 *) &PstateMsr, StdHeader); CurrentVid = (UINT32) PstateMsr.CpuVid; if (Pstate == HwPstateMaxVal) { NextPstateCurrent = 0; } else { // Check P-state from P1 to HwPstateMaxVal if (FamilySpecificServices->GetProcIddMax (FamilySpecificServices, (UINT8) (Pstate + 1), &NextPstateCurrent, StdHeader) != TRUE) { continue; } } if ((PstateCurrent <= CoreVrmLowPowerThreshold) && (NextPstateCurrent <= CoreVrmLowPowerThreshold) && (CurrentVid != PreviousVid)) { // Program PsiVid and PsiVidEn if PSI state is found and stop searching. GnbLibPciIndirectRead (MAKE_SBDFO (0, 0, 0, 0, 0xB8), SMUSVI_POWER_CONTROL_MISC, AccessWidth32, &SmuSviPowerCtrlMisc, StdHeader); SmuSviPowerCtrlMisc.PSIVID = CurrentVid; SmuSviPowerCtrlMisc.PSIVIDEN = 1; GnbLibPciIndirectWrite (MAKE_SBDFO (0, 0, 0, 0, 0xB8), SMUSVI_POWER_CONTROL_MISC, AccessWidth32, &SmuSviPowerCtrlMisc, StdHeader); IDS_HDT_CONSOLE (CPU_TRACE, " PsiVid is enabled at P-state %d. PsiVid: %d\n", Pstate, CurrentVid); break; } else { PreviousVid = CurrentVid; } } } if (PlatformConfig->VrmProperties[NbVrm].LowPowerThreshold != 0) { // Set up NBPSI0_L for VDDNB NbVrmLowPowerThreshold = PlatformConfig->VrmProperties[NbVrm].LowPowerThreshold; IDS_HDT_CONSOLE (CPU_TRACE, " NB VRM - LowPowerThreshold: %d\n", NbVrmLowPowerThreshold); PreviousNbVid = 0xFF; PciAddress.AddressValue = NB_PSTATE_CTRL_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &NbPsCtrl, StdHeader); NbPstateMaxVal = NbPsCtrl.NbPstateMaxVal; ASSERT (NbPstateMaxVal < NM_NB_PS_REG); IDS_HDT_CONSOLE (CPU_TRACE, " NbPstateMaxVal %d\n", NbPstateMaxVal); for (NbPstate = 0; NbPstate <= NbPstateMaxVal; NbPstate++) { // Check only valid NB P-state if (FamilySpecificServices->GetNbIddMax (FamilySpecificServices, (UINT8) NbPstate, &NbPstateCurrent, StdHeader) != TRUE) { continue; } PciAddress.Address.Register = (NB_PSTATE_0 + (sizeof (NB_PSTATE_REGISTER) * NbPstate)); LibAmdPciRead (AccessWidth32, PciAddress, &NbPstateReg, StdHeader); CurrentNbVid = (UINT32) GetF15CzNbVid (&NbPstateReg); if (NbPstate == NbPstateMaxVal) { NextNbPstateCurrent = 0; } else { // Check only valid NB P-state if (FamilySpecificServices->GetNbIddMax (FamilySpecificServices, (UINT8) (NbPstate + 1), &NextNbPstateCurrent, StdHeader) != TRUE) { continue; } } if ((NbPstateCurrent <= NbVrmLowPowerThreshold) && (NextNbPstateCurrent <= NbVrmLowPowerThreshold) && (CurrentNbVid != PreviousNbVid)) { // Program NbPsi0Vid and NbPsi0VidEn if PSI state is found and stop searching. GnbLibPciIndirectRead (MAKE_SBDFO (0, 0, 0, 0, 0xB8), SMUSVI_MISC_VID_STATUS, AccessWidth32, &SmuSviMiscVidStatus, StdHeader); SmuSviMiscVidStatus.NB_PSI_VID = CurrentNbVid; SmuSviMiscVidStatus.NB_PSI_VID_EN = 1; GnbLibPciIndirectWrite (MAKE_SBDFO (0, 0, 0, 0, 0xB8), SMUSVI_MISC_VID_STATUS, AccessWidth32, &SmuSviMiscVidStatus, StdHeader); IDS_HDT_CONSOLE (CPU_TRACE, " NbPsi0Vid is enabled at NB P-state %d. NbPsi0Vid: %d\n", NbPstate, CurrentNbVid); break; } else { PreviousNbVid = CurrentNbVid; } } } } return AGESA_SUCCESS; }
/** * Multisocket call to determine the frequency that the northbridges must run. * * This function loops through all possible socket locations, comparing the * maximum NB frequencies to determine the slowest. This function also * determines if all coherent NB frequencies are equivalent. * * @param[in] NbPstate NB P-state number to check (0 = fastest) * @param[in] PlatformConfig Platform profile/build option config structure. * @param[out] SystemNbCofNumerator NB frequency numerator for the system in MHz * @param[out] SystemNbCofDenominator NB frequency denominator for the system * @param[out] SystemNbCofsMatch Whether or not all NB frequencies are equivalent * @param[out] NbPstateIsEnabledOnAllCPUs Whether or not NbPstate is valid on all CPUs * @param[in] StdHeader Config handle for library and services * * @retval TRUE At least one processor has NbPstate enabled. * @retval FALSE NbPstate is disabled on all CPUs * */ BOOLEAN GetSystemNbCofMulti ( IN UINT32 NbPstate, IN PLATFORM_CONFIGURATION *PlatformConfig, OUT UINT32 *SystemNbCofNumerator, OUT UINT32 *SystemNbCofDenominator, OUT BOOLEAN *SystemNbCofsMatch, OUT BOOLEAN *NbPstateIsEnabledOnAllCPUs, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 Socket; UINT8 Module; UINT32 CurrentNbCof; UINT32 CurrentDivisor; UINT32 CurrentFreq; UINT32 LowFrequency; UINT32 Ignored32; BOOLEAN FirstCofNotFound; BOOLEAN NbPstateDisabled; BOOLEAN IsNbPstateEnabledOnAny; PCI_ADDR PciAddress; AGESA_STATUS Ignored; CPU_SPECIFIC_SERVICES *FamilySpecificServices; // Find the slowest NB COF in the system & whether or not all are equivalent LowFrequency = 0xFFFFFFFF; *SystemNbCofsMatch = TRUE; *NbPstateIsEnabledOnAllCPUs = FALSE; IsNbPstateEnabledOnAny = FALSE; FirstCofNotFound = TRUE; NbPstateDisabled = FALSE; for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { if (IsProcessorPresent (Socket, StdHeader)) { GetCpuServicesOfSocket (Socket, (CONST CPU_SPECIFIC_SERVICES **)&FamilySpecificServices, StdHeader); for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) { if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &Ignored)) { break; } } if (FamilySpecificServices->GetNbPstateInfo (FamilySpecificServices, PlatformConfig, &PciAddress, NbPstate, &CurrentNbCof, &CurrentDivisor, &Ignored32, StdHeader)) { ASSERT (CurrentDivisor != 0); CurrentFreq = (CurrentNbCof / CurrentDivisor); if (FirstCofNotFound) { *SystemNbCofNumerator = CurrentNbCof; *SystemNbCofDenominator = CurrentDivisor; LowFrequency = CurrentFreq; IsNbPstateEnabledOnAny = TRUE; if (!NbPstateDisabled) { *NbPstateIsEnabledOnAllCPUs = TRUE; } FirstCofNotFound = FALSE; } else { if (CurrentFreq != LowFrequency) { *SystemNbCofsMatch = FALSE; if (CurrentFreq < LowFrequency) { LowFrequency = CurrentFreq; *SystemNbCofNumerator = CurrentNbCof; *SystemNbCofDenominator = CurrentDivisor; } } } } else { NbPstateDisabled = TRUE; *NbPstateIsEnabledOnAllCPUs = FALSE; } } } return IsNbPstateEnabledOnAny; }
/** * * It will create the ACPI tale of WHEA and return the pointer to the table. * * @param[in, out] StdHeader Standard Head Pointer * @param[in, out] WheaMcePtr Point to Whea Hest Mce table * @param[in, out] WheaCmcPtr Point to Whea Hest Cmc table * * @retval UINT32 AGESA_STATUS */ AGESA_STATUS GetAcpiWheaMain ( IN OUT AMD_CONFIG_PARAMS *StdHeader, IN OUT VOID **WheaMcePtr, IN OUT VOID **WheaCmcPtr ) { UINT8 BankNum; UINT8 Entries; UINT16 HestMceTableSize; UINT16 HestCmcTableSize; UINT64 MsrData; AMD_HEST_MCE_TABLE *HestMceTablePtr; AMD_HEST_CMC_TABLE *HestCmcTablePtr; AMD_HEST_BANK *HestBankPtr; AMD_WHEA_INIT_DATA *WheaInitDataPtr; ALLOCATE_HEAP_PARAMS AllocParams; CPU_SPECIFIC_SERVICES *FamilySpecificServices; FamilySpecificServices = NULL; IDS_HDT_CONSOLE (CPU_TRACE, " WHEA is created\n"); // step 1: calculate Hest table size LibAmdMsrRead (MSR_MCG_CAP, &MsrData, StdHeader); BankNum = (UINT8) (((MSR_MCG_CAP_STRUCT *) (&MsrData))->Count); if (BankNum == 0) { return AGESA_ERROR; } GetCpuServicesOfCurrentCore (&FamilySpecificServices, StdHeader); FamilySpecificServices->GetWheaInitData (FamilySpecificServices, &WheaInitDataPtr, &Entries, StdHeader); ASSERT (WheaInitDataPtr->HestBankNum <= BankNum); HestMceTableSize = sizeof (AMD_HEST_MCE_TABLE) + WheaInitDataPtr->HestBankNum * sizeof (AMD_HEST_BANK); HestCmcTableSize = sizeof (AMD_HEST_CMC_TABLE) + WheaInitDataPtr->HestBankNum * sizeof (AMD_HEST_BANK); HestMceTablePtr = (AMD_HEST_MCE_TABLE *) *WheaMcePtr; HestCmcTablePtr = (AMD_HEST_CMC_TABLE *) *WheaCmcPtr; // step 2: allocate a buffer by callback function if ((HestMceTablePtr == NULL) || (HestCmcTablePtr == NULL)) { AllocParams.RequestedBufferSize = (UINT32) (HestMceTableSize + HestCmcTableSize); AllocParams.BufferHandle = AMD_WHEA_BUFFER_HANDLE; AllocParams.Persist = HEAP_SYSTEM_MEM; AGESA_TESTPOINT (TpProcCpuBeforeAllocateWheaBuffer, StdHeader); if (HeapAllocateBuffer (&AllocParams, StdHeader) != AGESA_SUCCESS) { return AGESA_ERROR; } AGESA_TESTPOINT (TpProcCpuAfterAllocateWheaBuffer, StdHeader); HestMceTablePtr = (AMD_HEST_MCE_TABLE *) AllocParams.BufferPtr; HestCmcTablePtr = (AMD_HEST_CMC_TABLE *) ((UINT8 *) (HestMceTablePtr + 1) + (WheaInitDataPtr->HestBankNum * sizeof (AMD_HEST_BANK))); } // step 3: fill in Hest MCE table HestMceTablePtr->TblLength = HestMceTableSize; HestMceTablePtr->GlobCapInitDataLSD = WheaInitDataPtr->GlobCapInitDataLSD; HestMceTablePtr->GlobCapInitDataMSD = WheaInitDataPtr->GlobCapInitDataMSD; HestMceTablePtr->GlobCtrlInitDataLSD = WheaInitDataPtr->GlobCtrlInitDataLSD; HestMceTablePtr->GlobCtrlInitDataMSD = WheaInitDataPtr->GlobCtrlInitDataMSD; HestMceTablePtr->NumHWBanks = WheaInitDataPtr->HestBankNum; HestBankPtr = (AMD_HEST_BANK *) (HestMceTablePtr + 1); CreateHestBank (HestBankPtr, WheaInitDataPtr->HestBankNum, WheaInitDataPtr); // step 4: fill in Hest CMC table HestCmcTablePtr->NumHWBanks = WheaInitDataPtr->HestBankNum; HestCmcTablePtr->TblLength = HestCmcTableSize; HestBankPtr = (AMD_HEST_BANK *) (HestCmcTablePtr + 1); CreateHestBank (HestBankPtr, WheaInitDataPtr->HestBankNum, WheaInitDataPtr); // step 5: fill in the incoming structure *WheaMcePtr = HestMceTablePtr; *WheaCmcPtr = HestCmcTablePtr; return (AGESA_SUCCESS); }