Beispiel #1
0
/**
 * 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;
}
Beispiel #4
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;
  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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
/**
 *  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;
}
Beispiel #7
0
/**
 *    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;
      }
    }
  }
}
Beispiel #9
0
/**
 * 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);
}
Beispiel #11
0
/**
 * 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);
}
Beispiel #12
0
/**
 *    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;
      }
    }
  }
}
Beispiel #16
0
/**
 *  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);
  }
Beispiel #17
0
/**
 * 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);
}
Beispiel #19
0
/**
 * 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);
}
Beispiel #20
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);
}
Beispiel #21
0
/**
 *---------------------------------------------------------------------------------------
 *
 *  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);
}
Beispiel #22
0
/**
 * 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));
}
Beispiel #24
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;
}
Beispiel #25
0
/**
 * 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;
}
Beispiel #26
0
/**
 * 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);
}
Beispiel #27
0
/**
 * 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);
      }
    }
  }
}
Beispiel #28
0
/**
 * 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;
}
Beispiel #30
0
/**
 *
 * 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);
}