Esempio n. 1
0
/**
 * A Family Specific Workaround method, to sync internal node 1 SbiAddr setting.
 *
 * @param[in] Data      The table data value (unused in this routine)
 * @param[in] StdHeader Config handle for library and services
 *
 *---------------------------------------------------------------------------------------
 **/
VOID
STATIC
F10RevDSyncInternalNode1SbiAddr (
  IN       UINT32            Data,
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  UINT32       Socket;
  UINT32       Module;
  UINT32       DataOr;
  UINT32       DataAnd;
  UINT32       ModuleType;
  PCI_ADDR     PciAddress;
  AGESA_STATUS AgesaStatus;
  UINT32       SyncToModule;
  AP_MAIL_INFO ApMailboxInfo;
  UINT32       LocalPciRegister;

  ApMailboxInfo.Info = 0;

  GetApMailbox (&ApMailboxInfo.Info, StdHeader);
  ASSERT (ApMailboxInfo.Fields.Socket < MAX_SOCKETS);
  ASSERT (ApMailboxInfo.Fields.Module < MAX_DIES);
  Socket = ApMailboxInfo.Fields.Socket;
  Module = ApMailboxInfo.Fields.Module;
  ModuleType = ApMailboxInfo.Fields.ModuleType;

  // sync is just needed on multinode cpu
  if (ModuleType != 0) {
    // check if it is internal node 0 of every socket
    if (Module == 0) {
      if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &AgesaStatus)) {
        PciAddress.Address.Function = FUNC_3;
        PciAddress.Address.Register = 0x1E4;
        // read internal node 0 F3x1E4[6:4]
        LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
        DataOr = LocalPciRegister & ((UINT32) (7 << 4));
        DataAnd = ~(UINT32) (7 << 4);
        for (SyncToModule = 1; SyncToModule < GetPlatformNumberOfModules (); SyncToModule++) {
          if (GetPciAddress (StdHeader, Socket, SyncToModule, &PciAddress, &AgesaStatus)) {
            PciAddress.Address.Function = FUNC_3;
            PciAddress.Address.Register = 0x1E4;
            // sync the other internal node F3x1E4[6:4]
            LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
            LocalPciRegister &= DataAnd;
            LocalPciRegister |= DataOr;
            LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
          }
        }
      }
    }
  }
}
/**
 *  Writes to all nodes on the executing core's socket.
 *
 *  @param[in]     PciAddress    The Function and Register to update
 *  @param[in]     Mask          The bitwise AND mask to apply to the current register value
 *  @param[in]     Data          The bitwise OR mask to apply to the current register value
 *  @param[in]     StdHeader     Header for library and services.
 *
 */
VOID
ModifyCurrSocketPciMulti (
  IN       PCI_ADDR               *PciAddress,
  IN       UINT32                 Mask,
  IN       UINT32                 Data,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  UINT32 Socket;
  UINT32 Module;
  UINT32 Core;
  UINT32 LocalPciRegister;
  AGESA_STATUS AgesaStatus;
  PCI_ADDR Reg;

  IdentifyCore (StdHeader, &Socket, &Module, &Core, &AgesaStatus);

  for (Module = 0; Module < (UINT8)GetPlatformNumberOfModules (); Module++) {
    if (GetPciAddress (StdHeader, Socket, Module, &Reg, &AgesaStatus)) {
      Reg.Address.Function = PciAddress->Address.Function;
      Reg.Address.Register = PciAddress->Address.Register;
      LibAmdPciRead (AccessWidth32, Reg, &LocalPciRegister, StdHeader);
      LocalPciRegister &= Mask;
      LocalPciRegister |= Data;
      LibAmdPciWrite (AccessWidth32, Reg, &LocalPciRegister, StdHeader);
    }
  }
}
Esempio n. 3
0
/**
 *  Check to see if the input CPU supports L3 dependent features.
 *
 * @param[in]    L3FeatureServices   L3 Feature family services.
 * @param[in]    Socket              Processor socket to check.
 * @param[in]    StdHeader           Config Handle for library, services.
 * @param[in]    PlatformConfig      Contains the runtime modifiable feature input data.
 *
 * @retval       TRUE                L3 dependent features are supported.
 * @retval       FALSE               L3 dependent features are not supported.
 *
 */
BOOLEAN
STATIC
F10IsL3FeatureSupported (
  IN       L3_FEATURE_FAMILY_SERVICES *L3FeatureServices,
  IN       UINT32 Socket,
  IN       AMD_CONFIG_PARAMS *StdHeader,
  IN       PLATFORM_CONFIGURATION *PlatformConfig
  )
{
  UINT32       Module;
  UINT32       LocalPciRegister;
  BOOLEAN      IsSupported;
  PCI_ADDR     PciAddress;
  AGESA_STATUS IgnoredStatus;

  IsSupported = FALSE;

  if (PlatformConfig->PlatformProfile.UseHtAssist) {
  for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) {
    if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredStatus)) {
      PciAddress.Address.Function = FUNC_3;
      PciAddress.Address.Register = NB_CAPS_REG;
      LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
      if (((NB_CAPS_REGISTER *) &LocalPciRegister)->L3Capable == 1) {
        IsSupported = TRUE;
      }
      break;
    }
  }
  }
  return IsSupported;
}
Esempio n. 4
0
/**
 *    Main entry point for initializing the Thermal Control
 *    safety net feature.
 *
 *    This must be run by all Family 10h core 0s in the system.
 *
 * @param[in]  FamilySpecificServices  The current Family Specific Services.
 * @param[in]  CpuEarlyParamsPtr       Service parameters.
 * @param[in]  StdHeader               Config handle for library and services.
 */
VOID
F10PmThermalInit (
  IN       CPU_SPECIFIC_SERVICES *FamilySpecificServices,
  IN       AMD_CPU_EARLY_PARAMS  *CpuEarlyParamsPtr,
  IN       AMD_CONFIG_PARAMS     *StdHeader
  )
{
  UINT32    Core;
  UINT32    Module;
  UINT32    LocalPciRegister;
  UINT32    Socket;
  PCI_ADDR  PciAddress;
  AGESA_STATUS  IgnoredSts;

  IdentifyCore (StdHeader, &Socket, &Module, &Core, &IgnoredSts);
  ASSERT (Core == 0);

  if (GetPciAddress (StdHeader, Socket, 0, &PciAddress, &IgnoredSts)) {
    PciAddress.Address.Function = FUNC_3;
    PciAddress.Address.Register = NB_CAPS_REG;
    LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
    if (((NB_CAPS_REGISTER *) &LocalPciRegister)->HtcCapable == 1) {
      // Enable HTC
      PciAddress.Address.Register = HTC_REG;
      LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
      ((HTC_REGISTER *) &LocalPciRegister)->HtcSlewSel = 0;
      ((HTC_REGISTER *) &LocalPciRegister)->HtcEn = 1;
      LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
    }
  }
}
/**
 * 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;
}
Esempio n. 6
0
/**
 * Clear EnableCf8ExtCfg on all socket
 *
 * Clear F3x8C bit 14 EnableCf8ExtCfg
 *
 * @param[in]  StdHeader         Config handle for library and services
 *
 *
 */
VOID
DisableCf8ExtCfg (
  IN       AMD_CONFIG_PARAMS   *StdHeader
  )
{
  AGESA_STATUS  AgesaStatus;
  PCI_ADDR PciAddress;
  UINT32 Socket;
  UINT32 Module;
  UINT32 PciData;
  UINT32 LegacyPciAccess;

  ASSERT (IsBsp (StdHeader, &AgesaStatus));

  for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) {
    for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) {
      if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &AgesaStatus)) {
        PciAddress.Address.Function = FUNC_3;
        PciAddress.Address.Register = NB_CFG_HIGH_REG;
        LegacyPciAccess = ((1 << 31) + (PciAddress.Address.Register & 0xFC) + (PciAddress.Address.Function << 8) + (PciAddress.Address.Device << 11) + (PciAddress.Address.Bus << 16) + ((PciAddress.Address.Register & 0xF00) << (24 - 8)));
        // read from PCI register
        LibAmdIoWrite (AccessWidth32, IOCF8, &LegacyPciAccess, StdHeader);
        LibAmdIoRead (AccessWidth32, IOCFC, &PciData, StdHeader);
        // Disable Cf8ExtCfg
        PciData &= 0xFFFFBFFF;
        // write to PCI register
        LibAmdIoWrite (AccessWidth32, IOCF8, &LegacyPciAccess, StdHeader);
        LibAmdIoWrite (AccessWidth32, IOCFC, &PciData, StdHeader);
      }
    }
  }
}
Esempio n. 7
0
/**
 * Ids Write PCI register to All node
 *
 *
 * @param[in] PciAddress    Pci address
 * @param[in]   Highbit       High bit position of the field in DWORD
 * @param[in]   Lowbit        Low bit position of the field in DWORD
 * @param[in] Value         Pointer to input value
 * @param[in] StdHeader     Standard configuration header
 *
 */
VOID
IdsLibPciWriteBitsToAllNode (
  IN       PCI_ADDR PciAddress,
  IN       UINT8 Highbit,
  IN       UINT8 Lowbit,
  IN       UINT32 *Value,
  IN OUT   AMD_CONFIG_PARAMS *StdHeader
  )
{
  UINT32 Socket;
  UINT32 Module;
  AGESA_STATUS IgnoreStatus;
  PCI_ADDR PciAddr;


  for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) {
    for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) {
      if (GetPciAddress (StdHeader, Socket, Module, &PciAddr, &IgnoreStatus)) {
        PciAddr.Address.Function = PciAddress.Address.Function;
        PciAddr.Address.Register = PciAddress.Address.Register;
        LibAmdPciWriteBits (PciAddr, Highbit, Lowbit, Value, StdHeader);
      }
    }
  }
}
Esempio n. 8
0
/**
 *  Check to see if the input CPU supports HT Assist.
 *
 * @param[in]    HtAssistServices    HT Assist family services.
 * @param[in]    Socket              Processor socket to check.
 * @param[in]    StdHeader           Config Handle for library, services.
 *
 * @retval       TRUE               HT Assist is supported.
 * @retval       FALSE              HT Assist cannot be enabled.
 *
 */
BOOLEAN
STATIC
F10IsHtAssistSupported (
  IN       HT_ASSIST_FAMILY_SERVICES *HtAssistServices,
  IN       UINT32 Socket,
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  UINT32       Module;
  UINT32       PciRegister;
  BOOLEAN      IsSupported;
  PCI_ADDR     PciAddress;
  AGESA_STATUS IgnoredStatus;

  IsSupported = FALSE;
  for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) {
    if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredStatus)) {
      PciAddress.Address.Function = FUNC_3;
      PciAddress.Address.Register = NB_CAPS_REG;
      LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader);
      if (((NB_CAPS_REGISTER *) &PciRegister)->L3Capable == 1) {
        IsSupported = TRUE;
      }
      break;
    }
  }
  return IsSupported;
}
Esempio n. 9
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;
}
Esempio n. 10
0
/**
 *
 *  InitializeCacheFlushOnHaltFeature
 *
 *    CPU feature leveling. Enable Cpu Cache Flush On Halt Function
 *
 *    @param[in]       EntryPoint       Timepoint designator.
 *    @param[in]       PlatformConfig   Contains the runtime modifiable feature input data.
 *    @param[in,out]   StdHeader        Pointer to AMD_CONFIG_PARAMS struct.
 *
 *    @return          The most severe status of any family specific service.
 */
STATIC AGESA_STATUS
InitializeCacheFlushOnHaltFeature (
  IN       UINT64                 EntryPoint,
  IN       PLATFORM_CONFIGURATION *PlatformConfig,
  IN OUT   AMD_CONFIG_PARAMS      *StdHeader
  )
{
  UINT32 Socket;
  UINT32 Module;
  UINT32 AndMask;
  UINT32 OrMask;
  UINT32 PciRegister;
  PCI_ADDR PciAddress;
  PCI_ADDR CfohPciAddress;
  AGESA_STATUS AgesaStatus;
  CPU_CFOH_FAMILY_SERVICES *FamilySpecificServices;

  ASSERT (IsBsp (StdHeader, &AgesaStatus));

  FamilySpecificServices = NULL;
  AndMask = 0xFFFFFFFF;
  OrMask = 0x00000000;
  PciRegister = 0;
  AgesaStatus = AGESA_SUCCESS;

  for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) {
    if (IsProcessorPresent (Socket, StdHeader)) {

      // Get services for the socket
      GetFeatureServicesOfSocket (&CacheFlushOnHaltFamilyServiceTable, Socket, (CONST VOID **)&FamilySpecificServices, StdHeader);
      if (FamilySpecificServices != NULL) {
        FamilySpecificServices->GetCacheFlushOnHaltRegister (FamilySpecificServices, &CfohPciAddress, &AndMask, &OrMask, StdHeader);

        // Get the Or Mask value from IDS
        IDS_OPTION_HOOK (IDS_CACHE_FLUSH_HLT, &OrMask, StdHeader);

        // Set Cache Flush On Halt register
        for (Module = 0; Module < (UINT8)GetPlatformNumberOfModules (); Module++) {
          if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &AgesaStatus)) {
            PciAddress.Address.Function = CfohPciAddress.Address.Function;
            PciAddress.Address.Register = CfohPciAddress.Address.Register;
            LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader);
            PciRegister &= AndMask;
            PciRegister |= OrMask;
            LibAmdPciWrite (AccessWidth32, PciAddress, &PciRegister, StdHeader);
          }
        }
      }
    }
  }
  return AgesaStatus;
}
/**
 * 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;
      }
    }
  }
}
Esempio n. 12
0
/**
 * Family 10h core 0 entry point for performing the necessary steps after
 * a warm reset has occurred.
 *
 * The steps are as follows:
 *    1. Modify F3xDC[PstateMaxVal] to reflect the lowest performance P-state
 *       supported, as indicated in MSRC001_00[68:64][PstateEn]
 *    2. If MSRC001_0071[CurNbDid] = 0, set MSRC001_001F[GfxNbPstateDis]
 *    3. If MSRC001_0071[CurPstate] != F3xDC[PstateMaxVal], go to step 20
 *    4. If F3xDC[PstateMaxVal] = 0 or F3xDC[PstateMaxVal] != 4, go to step 7
 *    5. If MSRC001_0061[CurPstateLimit] <= F3xDC[PstateMaxVal]-1, go to step 17
 *    6. Exit the sequence
 *    7. Copy the P-state register pointed to by F3xDC[PstateMaxVal] to the P-state
 *       register pointed to by F3xDC[PstateMaxVal]+1
 *    8. Write F3xDC[PstateMaxVal]+1 to F3xDC[PstateMaxVal]
 *    9. Write (the new) F3xDC[PstateMaxVal] to MSRC001_0062[PstateCmd]
 *   10. Wait for MSRC001_0071[CurCpuFid/CurCpuDid] = CpuFid/CpuDid from the P-state
 *       register pointed to by (the new) F3xDC[PstateMaxVal]
 *   11. Copy (the new) F3xDC[PstateMaxVal]-1 to MSRC001_0062[PstateCmd]
 *   12. Wait for MSRC001_0071[CurCpuFid/CurCpuDid] = CpuFid/CpuDid from the P-state
 *       register pointed to by (the new) F3xDC[PstateMaxVal]-1
 *   13. If MSRC001_0071[CurNbDid] = 1, set MSRC001_001F[GfxNbPstateDis]
 *   14. If required, transition the NB COF and VID to the NbDid and NbVid from the
 *       P-state register pointed to by MSRC001_0061[CurPstateLimit] using the NB COF
 *       and VID transition sequence after a warm reset
 *   15. Write MSRC001_00[68:64][PstateEn]=0 for the P-state pointed to by F3xDC[PstateMaxVal]
 *   16. Write (the new) F3xDC[PstateMaxVal]-1 to F3xDC[PstateMaxVal] and exit the sequence
 *   17. Copy F3xDC[PstateMaxVal]-1 to MSRC001_0062[PstateCmd]
 *   18. Wait for MSRC001_0071[CurCpuFid/CurCpuDid] = CpuFid/CpuDid from the P-state
 *       register pointed to by F3xDC[PstateMaxVal]-1
 *   19. If MSRC001_0071[CurNbDid] = 0, set MSRC001_001F[GfxNbPstateDis]
 *   20. Copy F3xDC[PstateMaxVal] to MSRC001_0062[PstateCmd]
 *   21. Wait for MSRC001_0071[CurCpuFid/CurCpuDid] = CpuFid/CpuDid from the P-state
 *       register pointed to by F3xDC[PstateMaxVal]
 *   22. If MSRC001_0071[CurNbDid] = 1, set MSRC001_001F[GfxNbPstateDis]
 *   23. Issue an LDTSTOP assertion in the IO hub and exit sequence
 *   24. If required, transition the NB COF and VID to the NbDid and NbVid from the
 *       P-state register pointed to by F3xDC[PstateMaxVal] using the NB COF and VID
 *       transition sequence after a warm reset
 *
 * @param[in]  FamilySpecificServices  The current Family Specific Services.
 * @param[in]  CpuEarlyParamsPtr       Service parameters
 * @param[in]  StdHeader               Config handle for library and services.
 *
 */
VOID
F10PmAfterReset (
  IN       CPU_SPECIFIC_SERVICES *FamilySpecificServices,
  IN       AMD_CPU_EARLY_PARAMS  *CpuEarlyParamsPtr,
  IN       AMD_CONFIG_PARAMS     *StdHeader
  )
{
  UINT32    Socket;
  UINT32    Module;
  UINT32    PsMaxVal;
  UINT32    CoreNum;
  UINT32    MsrAddr;
  UINT32    Core;
  UINT32    AndMask;
  UINT32    OrMask;
  UINT64    LocalMsrRegister;
  PCI_ADDR  PciAddress;
  AP_TASK   TaskPtr;
  AGESA_STATUS IgnoredSts;

  IdentifyCore (StdHeader, &Socket, &Module, &Core, &IgnoredSts);
  GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts);
  GetActiveCoresInCurrentSocket (&CoreNum, StdHeader);

  ASSERT (Core == 0);

  // Step 1 Modify F3xDC[PstateMaxVal] to reflect the lowest performance
  //        P-state supported, as indicated in MSRC001_00[68:64][PstateEn]
  for (MsrAddr = PS_MAX_REG; MsrAddr > PS_REG_BASE; --MsrAddr) {
    LibAmdMsrRead (MsrAddr, &LocalMsrRegister, StdHeader);
    if (((PSTATE_MSR *) &LocalMsrRegister)->PsEnable == 1) {
      break;
    }
  }
  PsMaxVal = MsrAddr - PS_REG_BASE;
  PciAddress.Address.Function = FUNC_3;
  PciAddress.Address.Register = CPTC2_REG;
  AndMask = 0xFFFFFFFF;
  OrMask = 0x00000000;
  ((CLK_PWR_TIMING_CTRL2_REGISTER *) &AndMask)->PstateMaxVal = 0;
  ((CLK_PWR_TIMING_CTRL2_REGISTER *) &OrMask)->PstateMaxVal = PsMaxVal;
  ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader);

  // Launch each local core to perform the remaining steps.
  TaskPtr.FuncAddress.PfApTask = F10PmAfterResetCore;
  TaskPtr.DataTransfer.DataSizeInDwords = 0;
  TaskPtr.ExeFlags = WAIT_FOR_CORE;
  ApUtilRunCodeOnAllLocalCoresAtEarly (&TaskPtr, StdHeader, CpuEarlyParamsPtr);
}
Esempio n. 13
0
/**
 *  Check to see if the input CPU is running in the optimal configuration.
 *
 * @param[in]    HtAssistServices    HT Assist family services.
 * @param[in]    Socket              Processor socket to check.
 * @param[in]    StdHeader           Config Handle for library, services.
 *
 * @retval       TRUE               HT Assist is running sub-optimally.
 * @retval       FALSE              HT Assist is running optimally.
 *
 */
STATIC BOOLEAN
F10IsNonOptimalConfig (
  IN       HT_ASSIST_FAMILY_SERVICES *HtAssistServices,
  IN       UINT32 Socket,
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  BOOLEAN      IsNonOptimal;
  BOOLEAN      IsMemoryPresent;
  UINT32       Module;
  UINT32       PciRegister;
  PCI_ADDR     PciAddress;
  AGESA_STATUS IgnoredStatus;

  IsNonOptimal = FALSE;
  for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) {
    if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredStatus)) {
      IsMemoryPresent = FALSE;
      PciAddress.Address.Function = FUNC_2;
      PciAddress.Address.Register = DRAM_CFG_HI_REG0;

      LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader);
      if (((DRAM_CFG_HI_REGISTER *) &PciRegister)->MemClkFreqVal == 1) {
        IsMemoryPresent = TRUE;
        if (((DRAM_CFG_HI_REGISTER *) &PciRegister)->MemClkFreq < 4) {
          IsNonOptimal = TRUE;
          break;
        }
      }

      PciAddress.Address.Register = DRAM_CFG_HI_REG1;

      LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader);
      if (((DRAM_CFG_HI_REGISTER *) &PciRegister)->MemClkFreqVal == 1) {
        IsMemoryPresent = TRUE;
        if (((DRAM_CFG_HI_REGISTER *) &PciRegister)->MemClkFreq < 4) {
          IsNonOptimal = TRUE;
          break;
        }
      }
      if (!IsMemoryPresent) {
        IsNonOptimal = TRUE;
        break;
      }
    }
  }
  return IsNonOptimal;
}
Esempio n. 14
0
UINT8
PciRead8 (
  UINT8   Segment,
  UINT8   Bus,
  UINT8   DevFunc,
  UINT8   Register
  )
/*++

Routine Description:
  Perform an one byte PCI config cycle read
    
Arguments:
  Segment   - PCI Segment ACPI _SEG
  Bus       - PCI Bus
  DevFunc   - PCI Device(7:3) and Func(2:0)
  Register  - PCI config space register

Returns:
  Data read from PCI config space

--*/
{
  EFI_STATUS  Status;
  UINT32      PciAddress;
  UINT32      PciAddress1;
  UINT8       Data;

  PciAddress = GetPciAddress (Segment, Bus, DevFunc, Register);
  //
  // Set bit 31 for PCI config access
  //
  PciAddress1 = PciAddress;
  PciAddress  = ((PciAddress & 0xFFFFFFFC) | (0x80000000));

  Status      = EfiIoWrite (EfiCpuIoWidthUint32, PCI_CONFIG_INDEX_PORT, 1, &PciAddress);

  if (EFI_ERROR (Status)) {
    return 0;
  }

  EfiIoRead (EfiCpuIoWidthUint8, (PCI_CONFIG_DATA_PORT + (PciAddress1 & 0x3)), 1, &Data);

  return Data;
}
Esempio n. 15
0
/**
 *  Hook before the probe filter initialization sequence.
 *
 * @param[in]    HtAssistServices    HT Assist family services.
 * @param[in]    Socket              Processor socket to check.
 * @param[in]    StdHeader           Config Handle for library, services.
 *
 */
VOID
STATIC
F10HookBeforeInit (
  IN       HT_ASSIST_FAMILY_SERVICES *HtAssistServices,
  IN       UINT32 Socket,
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  UINT32          Module;
  UINT32          PciRegister;
  UINT32          PfCtrlRegister;
  PCI_ADDR        PciAddress;
  CPU_LOGICAL_ID  LogicalId;
  AGESA_STATUS    IgnoredStatus;
  UINT32          PackageType;

  GetLogicalIdOfSocket (Socket, &LogicalId, StdHeader);
  PackageType = LibAmdGetPackageType (StdHeader);

  PciRegister = 0;
  ((PROBE_FILTER_CTRL_REGISTER *) &PciRegister)->PFWayNum = 2;
  ((PROBE_FILTER_CTRL_REGISTER *) &PciRegister)->PFSubCacheEn = 15;
  ((PROBE_FILTER_CTRL_REGISTER *) &PciRegister)->PFLoIndexHashEn = 1;
  for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) {
    if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredStatus)) {
      PciAddress.Address.Function = FUNC_3;
      PciAddress.Address.Register = PROBE_FILTER_CTRL_REG;
      LibAmdPciRead (AccessWidth32, PciAddress, &PfCtrlRegister, StdHeader);
      ((PROBE_FILTER_CTRL_REGISTER *) &PciRegister)->PFPreferredSORepl =
        ((PROBE_FILTER_CTRL_REGISTER *) &PfCtrlRegister)->PFPreferredSORepl;
      LibAmdPciWrite (AccessWidth32, PciAddress, &PciRegister, StdHeader);

      // Assumption: all socket use the same CPU package.
      if (((LogicalId.Revision & AMD_F10_D0) != 0) && (PackageType == PACKAGE_TYPE_C32)) {
        // Apply erratum #384
        // Set F2x11C[13:12] = 11b
        PciAddress.Address.Function = FUNC_2;
        PciAddress.Address.Register = 0x11C;
        LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader);
        PciRegister |= 0x3000;
        LibAmdPciWrite (AccessWidth32, PciAddress, &PciRegister, StdHeader);
      }
    }
  }
}
Esempio n. 16
0
VOID
PciWrite32 (
  UINT8   Segment,
  UINT8   Bus,
  UINT8   DevFunc,
  UINT8   Register,
  UINT32  Data
  )
/*++

Routine Description:
  Perform an four byte PCI config cycle write
    
Arguments:
  Segment   - PCI Segment ACPI _SEG
  Bus       - PCI Bus
  DevFunc   - PCI Device(7:3) and Func(2:0)
  Register  - PCI config space register
  Data      - Data to write

Returns:
  NONE

--*/
{
  EFI_STATUS  Status;
  UINT32      PciAddress;
  UINT32      PciAddress1;

  PciAddress = GetPciAddress (Segment, Bus, DevFunc, Register);
  //
  // Set bit 31 for PCI config access
  //
  PciAddress1 = PciAddress;
  PciAddress  = ((PciAddress & 0xFFFFFFFC) | (0x80000000));

  Status      = EfiIoWrite (EfiCpuIoWidthUint32, PCI_CONFIG_INDEX_PORT, 1, &PciAddress);

  if (EFI_ERROR (Status)) {
    return ;
  }

  EfiIoWrite (EfiCpuIoWidthUint32, (PCI_CONFIG_DATA_PORT + (PciAddress1 & 0x3)), 1, &Data);
}
Esempio n. 17
0
/**
 *  Save the current settings of the scrubbers, and disabled them.
 *
 * @param[in]    HtAssistServices    HT Assist family services.
 * @param[in]    Socket              Processor socket to check.
 * @param[in]    ScrubSettings       Location to store current L3 scrubber settings.
 * @param[in]    StdHeader           Config Handle for library, services.
 *
 */
VOID
STATIC
F10GetL3ScrubCtrl (
  IN       HT_ASSIST_FAMILY_SERVICES *HtAssistServices,
  IN       UINT32 Socket,
  IN       UINT32 ScrubSettings[L3_SCRUBBER_CONTEXT_ARRAY_SIZE],
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  UINT32       Module;
  UINT32       ScrubCtrl;
  UINT32       ScrubAddr;
  PCI_ADDR     PciAddress;
  AGESA_STATUS IgnoredStatus;

  for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) {
    if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredStatus)) {

      ASSERT (Module < L3_SCRUBBER_CONTEXT_ARRAY_SIZE);

      PciAddress.Address.Function = FUNC_3;
      PciAddress.Address.Register = DRAM_SCRUB_ADDR_LOW_REG;
      LibAmdPciRead (AccessWidth32, PciAddress, &ScrubAddr, StdHeader);

      PciAddress.Address.Register = SCRUB_RATE_CTRL_REG;
      LibAmdPciRead (AccessWidth32, PciAddress, &ScrubCtrl, StdHeader);

      ((F10_SCRUB_CONTEXT *) &ScrubSettings[Module])->DramScrub =
        ((SCRUB_RATE_CTRL_REGISTER *) &ScrubCtrl)->DramScrub;
      ((F10_SCRUB_CONTEXT *) &ScrubSettings[Module])->L3Scrub =
        ((SCRUB_RATE_CTRL_REGISTER *) &ScrubCtrl)->L3Scrub;
      ((F10_SCRUB_CONTEXT *) &ScrubSettings[Module])->Redirect =
        ((DRAM_SCRUB_ADDR_LOW_REGISTER *) &ScrubAddr)->ScrubReDirEn;

      ((SCRUB_RATE_CTRL_REGISTER *) &ScrubCtrl)->DramScrub = 0;
      ((SCRUB_RATE_CTRL_REGISTER *) &ScrubCtrl)->L3Scrub = 0;
      ((DRAM_SCRUB_ADDR_LOW_REGISTER *) &ScrubAddr)->ScrubReDirEn = 0;
      LibAmdPciWrite (AccessWidth32, PciAddress, &ScrubCtrl, StdHeader);
      PciAddress.Address.Register = DRAM_SCRUB_ADDR_LOW_REG;
      LibAmdPciWrite (AccessWidth32, PciAddress, &ScrubAddr, StdHeader);
    }
  }
}
Esempio n. 18
0
/**
 *  Enable the Probe filter feature.
 *
 * @param[in]    HtAssistServices    HT Assist family services.
 * @param[in]    Socket              Processor socket to check.
 * @param[in]    StdHeader           Config Handle for library, services.
 *
 */
VOID
STATIC
F10HtAssistInit (
  IN       HT_ASSIST_FAMILY_SERVICES  *HtAssistServices,
  IN       UINT32  Socket,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  UINT32                     Module;
  UINT32                     PciRegister;
  PCI_ADDR                   PciAddress;
  AGESA_STATUS               IgnoredStatus;

  for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) {
    if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredStatus)) {
      PciAddress.Address.Function = FUNC_3;
      PciAddress.Address.Register = L3_CACHE_PARAM_REG;
      LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader);
      ((L3_CACHE_PARAM_REGISTER *) &PciRegister)->L3TagInit = 1;
      LibAmdPciWrite (AccessWidth32, PciAddress, &PciRegister, StdHeader);
      do {
        LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader);
      } while (((L3_CACHE_PARAM_REGISTER *) &PciRegister)->L3TagInit != 0);

      PciAddress.Address.Register = PROBE_FILTER_CTRL_REG;
      LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader);
      ((PROBE_FILTER_CTRL_REGISTER *) &PciRegister)->PFMode = 0;
      LibAmdPciWrite (AccessWidth32, PciAddress, &PciRegister, StdHeader);

      F10RevDProbeFilterCritical (PciAddress, PciRegister);

      do {
        LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader);
      } while (((PROBE_FILTER_CTRL_REGISTER *) &PciRegister)->PFInitDone != 1);
      IDS_OPTION_HOOK (IDS_HT_ASSIST, &PciAddress, StdHeader);
    }
  }
}
Esempio n. 19
0
AGESA_STATUS
AmdMemRecovery (
  IN OUT   MEM_DATA_STRUCT *MemPtr
  )
{
  UINT8 Socket;
  UINT8 Module;
  UINT8 i;
  AGESA_STATUS AgesaStatus;
  PCI_ADDR Address;
  MEM_NB_BLOCK NBBlock;
  MEM_TECH_BLOCK TechBlock;
  LOCATE_HEAP_PTR  SocketWithMem;
  ALLOCATE_HEAP_PARAMS AllocHeapParams;


  //
  // Read SPD data
  //
  MemRecSPDDataProcess (MemPtr);

  //
  // Get the socket id from heap.
  //
  SocketWithMem.BufferHandle = AMD_REC_MEM_SOCKET_HANDLE;
  if (HeapLocateBuffer (&SocketWithMem, &MemPtr->StdHeader) == AGESA_SUCCESS) {
    Socket = *(UINT8 *) SocketWithMem.BufferPtr;
  } else {
    ASSERT(FALSE);  // Socket handle not found
    return AGESA_FATAL;
  }

  //
  // Allocate buffer for memory init structures
  //
  AllocHeapParams.RequestedBufferSize = MAX_DIES_PER_SOCKET * sizeof (DIE_STRUCT);
  AllocHeapParams.BufferHandle = GENERATE_MEM_HANDLE (ALLOC_DIE_STRUCT_HANDLE, 0, 0, 0);
  AllocHeapParams.Persist = HEAP_LOCAL_CACHE;
  if (HeapAllocateBuffer (&AllocHeapParams, &MemPtr->StdHeader) != AGESA_SUCCESS) {
    ASSERT(FALSE); // Heap allocation failed to allocate Die struct
    return AGESA_FATAL;
  }
  MemPtr->DiesPerSystem = (DIE_STRUCT *)AllocHeapParams.BufferPtr;

  //
  // Discover populated CPUs
  //
  for (Module = 0; Module < MAX_DIES_PER_SOCKET; Module++) {
    if (GetPciAddress ((VOID *)MemPtr, Socket, Module, &Address, &AgesaStatus)) {
      MemPtr->DiesPerSystem[Module].SocketId = Socket;
      MemPtr->DiesPerSystem[Module].DieId = Module;
      MemPtr->DiesPerSystem[Module].PciAddr.AddressValue = Address.AddressValue;
    }
  }

  i = 0;
  while (MemRecNBInstalled[i] != NULL) {
    if (MemRecNBInstalled[i] (&NBBlock, MemPtr, 0) == TRUE) {
      break;
    }
    i++;
  };
  if (MemRecNBInstalled[i] == NULL) {
    ASSERT(FALSE);    // No NB installed
    return AGESA_FATAL;
  }
  MemRecTechInstalled[0] (&TechBlock, &NBBlock);
  NBBlock.TechPtr = &TechBlock;

  return NBBlock.InitRecovery (&NBBlock);
}
Esempio n. 20
0
/**
 *
 *
 * MemSocketScan - Scan all nodes, recording the physical Socket number,
 * Die Number (relative to the socket), and PCI Device address of each
 * populated socket.
 *
 * This information is used by the northbridge block to map a dram
 * channel on a particular DCT, on a particular CPU Die, in a particular
 * socket to a the DRAM SPD Data for the DIMMS physically connected to
 * that channel.
 *
 * Also, the customer socket map is populated with pointers to the
 * appropriate channel structures, so that the customer can locate the
 * appropriate channel configuration data.
 *
 * This socket scan will always result in Die 0 as the BSP.
 *
 *     @param[in,out]   *mmPtr   - Pointer to the MEM_MAIN_DATA_BLOCK
 *
 */
AGESA_STATUS
MemSocketScan (
  IN OUT   MEM_MAIN_DATA_BLOCK *mmPtr
  )
{
  MEM_DATA_STRUCT *MemPtr;
  UINT8 DieIndex;
  UINT8 DieCount;
  UINT32 SocketId;
  UINT32 DieId;
  UINT8 Die;
  PCI_ADDR Address;
  AGESA_STATUS AgesaStatus;
  ALLOCATE_HEAP_PARAMS AllocHeapParams;

  ASSERT (mmPtr != NULL);
  ASSERT (mmPtr->MemPtr != NULL);
  MemPtr = mmPtr->MemPtr;

  //
  //  Count the number of dies in the system
  //
  DieCount = 0;
  for (Die = 0; Die < MAX_NODES_SUPPORTED; Die++) {
    if (GetSocketModuleOfNode ((UINT32)Die, &SocketId, &DieId, (VOID *)MemPtr)) {
      DieCount++;
    }
  }
  MemPtr->DieCount = DieCount;
  mmPtr->DieCount = DieCount;

  if (DieCount > 0) {
    //
    //  Allocate buffer for DIE_STRUCTs
    //
    AllocHeapParams.RequestedBufferSize = ((UINT16)DieCount * sizeof (DIE_STRUCT));
    AllocHeapParams.BufferHandle = GENERATE_MEM_HANDLE (ALLOC_DIE_STRUCT_HANDLE, 0, 0, 0);
    AllocHeapParams.Persist = HEAP_LOCAL_CACHE;
    if (HeapAllocateBuffer (&AllocHeapParams, &MemPtr->StdHeader) == AGESA_SUCCESS) {
      MemPtr->DiesPerSystem = (DIE_STRUCT *)AllocHeapParams.BufferPtr;
      //
      //  Find SocketId, DieId, and PCI address of each node
      //
      DieIndex = 0;
      for (Die = 0; Die < MAX_NODES_SUPPORTED; Die++) {
        if (GetSocketModuleOfNode ((UINT32)Die, &SocketId, &DieId, (VOID *)MemPtr)) {
          if (GetPciAddress ((VOID *)MemPtr, (UINT8)SocketId, (UINT8)DieId, &Address, &AgesaStatus)) {
            MemPtr->DiesPerSystem[DieIndex].SocketId = (UINT8)SocketId;
            MemPtr->DiesPerSystem[DieIndex].DieId = (UINT8)DieId;
            MemPtr->DiesPerSystem[DieIndex].PciAddr.AddressValue = Address.AddressValue;

            DieIndex++;
          }
        }
      }
      AgesaStatus = AGESA_SUCCESS;
    } else {
      ASSERT(FALSE); // Heap allocation failed for DIE_STRUCTs
      AgesaStatus = AGESA_FATAL;
    }
  } else {
    ASSERT(FALSE); // No die in the system
    AgesaStatus = AGESA_FATAL;
  }
  return AgesaStatus;
}
Esempio n. 21
0
/**
 * Family 10h core 0 entry point for performing power plane initialization.
 *
 * The steps are as follows:
 *    1. If single plane, program lower VID code of CpuVid & NbVid for all
 *       enabled P-States.
 *    2. Configure F3xA0[SlamMode] & F3xD8[VsRampTime & VsSlamTime] based on
 *       platform requirements.
 *    3. Configure F3xD4[PowerStepUp & PowerStepDown]
 *    4. Optionally configure F3xA0[PsiVidEn & PsiVid]
 *
 * @param[in]  FamilySpecificServices  The current Family Specific Services.
 * @param[in]  CpuEarlyParams          Service parameters
 * @param[in]  StdHeader               Config handle for library and services.
 *
 */
VOID
F10CpuAmdPmPwrPlaneInit (
  IN       CPU_SPECIFIC_SERVICES *FamilySpecificServices,
  IN       AMD_CPU_EARLY_PARAMS  *CpuEarlyParams,
  IN       AMD_CONFIG_PARAMS     *StdHeader
  )
{
  BOOLEAN   PviModeFlag;
  PCI_ADDR  PciAddress;
  UINT16    PowerStepTime;
  UINT32    PowerStepEncoded;
  UINT32    PciRegister;
  UINT32    VsSlamTime;
  UINT32    Socket;
  UINT32    Module;
  UINT32    Core;
  UINT32    NumOfCores;
  UINT32    LowCore;
  UINT32    AndMask;
  UINT32    OrMask;
  UINT64    MsrRegister;
  AP_TASK   TaskPtr;
  AGESA_STATUS  IgnoredSts;
  PLATFORM_FEATS Features;
  CPU_LOGICAL_ID LogicalId;

  // Initialize the union
  Features.PlatformValue = 0;
  GetPlatformFeatures (&Features, &CpuEarlyParams->PlatformConfig, StdHeader);

  IdentifyCore (StdHeader, &Socket, &Module, &Core, &IgnoredSts);
  GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts);

  ASSERT (Core == 0);

  GetLogicalIdOfCurrentCore (&LogicalId, StdHeader);

  // Set SlamVidMode
  PciAddress.Address.Function = FUNC_3;
  PciAddress.Address.Register = PW_CTL_MISC_REG;
  LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader);
  AndMask = 0xFFFFFFFF;
  OrMask = 0x00000000;
  if (((POWER_CTRL_MISC_REGISTER *) &PciRegister)->PviMode == 1) {
    PviModeFlag = TRUE;
    ((POWER_CTRL_MISC_REGISTER *) &AndMask)->SlamVidMode = 0;

    // Have all single plane cores adjust their NB and CPU VID fields
    TaskPtr.FuncAddress.PfApTask = F10PmPwrPlaneInitPviCore;
    TaskPtr.DataTransfer.DataSizeInDwords = 0;
    TaskPtr.ExeFlags = WAIT_FOR_CORE;
    ApUtilRunCodeOnAllLocalCoresAtEarly (&TaskPtr, StdHeader, CpuEarlyParams);

  } else {
    PviModeFlag = FALSE;
    ((POWER_CTRL_MISC_REGISTER *) &OrMask)->SlamVidMode = 1;
  }
  ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader);

  F10ProgramVSSlamTimeOnSocket (&PciAddress, CpuEarlyParams, StdHeader);

  // Configure PowerStepUp/PowerStepDown
  PciAddress.Address.Register = CPTC0_REG;
  if ((Features.PlatformFeatures.PlatformSingleLink == 1) ||
      (Features.PlatformFeatures.PlatformUma == 1) ||
      (Features.PlatformFeatures.PlatformUmaIfcm == 1) ||
      (Features.PlatformFeatures.PlatformIfcm == 1) ||
      (Features.PlatformFeatures.PlatformIommu == 1)) {
    PowerStepEncoded = 0x8;
  } else {
    GetGivenModuleCoreRange ((UINT32) Socket,
                             (UINT32) Module,
                             &LowCore,
                             &NumOfCores,
                             StdHeader);
    NumOfCores = ((NumOfCores - LowCore) + 1);
    PowerStepTime = (UINT16) (400 / NumOfCores);
    for (PowerStepEncoded = 0xF; PowerStepEncoded > 0; PowerStepEncoded--) {
      if (PowerStepTime <= PowerStepEncodings[PowerStepEncoded]) {
        break;
      }
    }
  }
  AndMask = 0xFFFFFFFF;
  ((CLK_PWR_TIMING_CTRL_REGISTER *) &AndMask)->PowerStepUp = 0;
  ((CLK_PWR_TIMING_CTRL_REGISTER *) &AndMask)->PowerStepDown = 0;
  OrMask = 0x00000000;
  ((CLK_PWR_TIMING_CTRL_REGISTER *) &OrMask)->PowerStepUp = PowerStepEncoded;
  ((CLK_PWR_TIMING_CTRL_REGISTER *) &OrMask)->PowerStepDown = PowerStepEncoded;
  ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader);

  if ((LogicalId.Revision & AMD_F10_C3) != 0) {
    // Set up Pop up P-state register
    PciAddress.Address.Register = CPTC2_REG;
    LibAmdPciRead (AccessWidth32, PciAddress, &PciRegister, StdHeader);
    AndMask = 0xFFFFFFFF;
    ((POPUP_PSTATE_REGISTER *) &AndMask)->PopupPstate = 0;
    ((POPUP_PSTATE_REGISTER *) &AndMask)->PopupCpuVid = 0;
    ((POPUP_PSTATE_REGISTER *) &AndMask)->PopupCpuFid = 0;
    ((POPUP_PSTATE_REGISTER *) &AndMask)->PopupCpuDid = 0;
    OrMask = 0x00000000;
    ((POPUP_PSTATE_REGISTER *) &OrMask)->PopupEn = 0;
    ((POPUP_PSTATE_REGISTER *) &OrMask)->PopupPstate = ((CLK_PWR_TIMING_CTRL2_REGISTER *) &PciRegister)->PstateMaxVal;
    LibAmdMsrRead ((((CLK_PWR_TIMING_CTRL2_REGISTER *) &PciRegister)->PstateMaxVal + PS_REG_BASE), &MsrRegister, StdHeader);
    ((POPUP_PSTATE_REGISTER *) &OrMask)->PopupCpuVid = (UINT32) ((PSTATE_MSR *) &MsrRegister)->CpuVid;
    ((POPUP_PSTATE_REGISTER *) &OrMask)->PopupCpuFid = (UINT32) ((PSTATE_MSR *) &MsrRegister)->CpuFid;
    ((POPUP_PSTATE_REGISTER *) &OrMask)->PopupCpuDid = (UINT32) ((PSTATE_MSR *) &MsrRegister)->CpuDid;
    PciAddress.Address.Register = POPUP_PSTATE_REG;
    ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader);

    // Set AltVidStart
    PciAddress.Address.Register = CPTC1_REG;
    AndMask = 0xFFFFFFFF;
    ((CLK_PWR_TIMING_CTRL1_REGISTER *) &AndMask)->AltVidStart = 0;
    OrMask = 0x00000000;
    ((CLK_PWR_TIMING_CTRL1_REGISTER *) &OrMask)->AltVidStart = (UINT32) ((PSTATE_MSR *) &MsrRegister)->CpuVid;
    ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader);

    // Set up Altvid slam time
    PciAddress.Address.Register = CPTC2_REG;
    VsSlamTime = F10CalculateAltvidVSSlamTimeOnCore (PviModeFlag, &PciAddress, CpuEarlyParams, StdHeader);
    AndMask = 0xFFFFFFFF;
    ((CLK_PWR_TIMING_CTRL2_REGISTER *) &AndMask)->AltvidVSSlamTime = 0;
    ((CLK_PWR_TIMING_CTRL2_REGISTER *) &AndMask)->SlamTimeMode = 0;
    OrMask = 0x00000000;
    ((CLK_PWR_TIMING_CTRL2_REGISTER *) &OrMask)->AltvidVSSlamTime = VsSlamTime;
    ((CLK_PWR_TIMING_CTRL2_REGISTER *) &OrMask)->SlamTimeMode = 2;
    ModifyCurrentSocketPci (&PciAddress, AndMask, OrMask, StdHeader);
  }

  if (IsWarmReset (StdHeader) && !PviModeFlag) {
    // Configure PsiVid
    F10PmVrmLowPowerModeEnable (FamilySpecificServices, CpuEarlyParams, StdHeader);
  }
}
Esempio n. 22
0
/**
 * Set down core register on Mullins
 *
 * This function set F3x190 Downcore Control Register[5:0]
 *
 * @param[in]   FamilySpecificServices   The current Family Specific Services.
 * @param[in]   Socket                   Socket ID.
 * @param[in]   Module                   Module ID in socket.
 * @param[in]   LeveledCores             Number of core.
 * @param[in]   CoreLevelMode            Core level mode.
 * @param[in]   StdHeader                Header for library and services.
 *
 * @retval      TRUE                     Down Core register is updated.
 * @retval      FALSE                    Down Core register is not updated.
 */
BOOLEAN
F16MlSetDownCoreRegister (
    IN       CPU_CORE_LEVELING_FAMILY_SERVICES *FamilySpecificServices,
    IN       UINT32 *Socket,
    IN       UINT32 *Module,
    IN       UINT32 *LeveledCores,
    IN       CORE_LEVELING_TYPE CoreLevelMode,
    IN       AMD_CONFIG_PARAMS *StdHeader
)
{
    UINT8     NumOfComputeUnit;
    UINT8     CoresPerComputeUnit;
    UINT32    LocalPciRegister;
    UINT32    CoreDisableBits;
    UINT32    TempVar32_a;
    PCI_ADDR  PciAddress;
    BOOLEAN   IsUpdated;
    AGESA_STATUS AgesaStatus;

    IsUpdated = FALSE;
    CoreDisableBits = 0;
    TempVar32_a = 1;
    CoresPerComputeUnit = 1;

    switch (CoreLevelMode) {
    // There's no 'break' except 'case CORE_LEVEL_COMPUTE_UNIT'.
    // It's for generating CoreDisableBits and CoresPerComputeUnit
    case CORE_LEVEL_COMPUTE_UNIT_THREE:
        TempVar32_a = TempVar32_a << 1;
        CoresPerComputeUnit++;
    case CORE_LEVEL_COMPUTE_UNIT_TWO:
        TempVar32_a = TempVar32_a << 1;
        CoresPerComputeUnit++;
    case CORE_LEVEL_COMPUTE_UNIT:
        TempVar32_a = (TempVar32_a << 1) - 1;
        TempVar32_a = FOUR_CORE_COMPUTE_UNIT_BITMAP & (~TempVar32_a);
        NumOfComputeUnit = (UINT8) ((*LeveledCores) / CoresPerComputeUnit);
        for (CoreDisableBits = 0; NumOfComputeUnit > 0; NumOfComputeUnit--) {
            CoreDisableBits <<= FOUR_CORE_COMPUTE_UNIT_BITWIDTH;
            CoreDisableBits |= TempVar32_a;
        }
        break;
    default:
        TempVar32_a = *LeveledCores;
        if (TempVar32_a == 1) {
            CoreDisableBits = DOWNCORE_MASK_SINGLE;
        } else {
            CoreDisableBits = ALL_CORES_DISABLE_BITMAP;
            TempVar32_a = ((1 << TempVar32_a) - 1);
            CoreDisableBits &= ~TempVar32_a;
        }
    }

    if (CoreDisableBits != 0) {
        if (GetPciAddress (StdHeader, (UINT8) *Socket, (UINT8) *Module, &PciAddress, &AgesaStatus)) {
            PciAddress.Address.Function = FUNC_5;
            PciAddress.Address.Register = NORTH_BRIDGE_CAPABILITIES_2_REG;
            LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
            LocalPciRegister = (LocalPciRegister & 0xFF) + 1;
            LocalPciRegister = (1 << LocalPciRegister) - 1;
            CoreDisableBits &= LocalPciRegister;

            PciAddress.Address.Function = FUNC_3;
            PciAddress.Address.Register = DOWNCORE_CTRL;
            LibAmdPciRead (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
            if ((LocalPciRegister | CoreDisableBits) != LocalPciRegister) {
                LocalPciRegister |= CoreDisableBits;
                LibAmdPciWrite (AccessWidth32, PciAddress, &LocalPciRegister, StdHeader);
                IsUpdated = TRUE;
            }
        }
    }

    return IsUpdated;
}
Esempio n. 23
0
/**--------------------------------------------------------------------------------------
 *
 *  PStateLevelingMain
 *
 *  Description:
 *     This is the common routine for creating the ACPI information tables.
 *
 *  Parameters:
 *    @param[in,out]    *PStateStrucPtr
 *    @param[in]        *StdHeader
 *
 *    @retval         AGESA_STATUS
 *
 *---------------------------------------------------------------------------------------
 **/
AGESA_STATUS
PStateLevelingMain (
  IN OUT   S_CPU_AMD_PSTATE   *PStateStrucPtr,
  IN       AMD_CONFIG_PARAMS  *StdHeader
  )
{
  UINT32                   i;
  UINT32                   k;
  UINT32                   m;
  UINT32                   TotalIterations;
  UINT32                   LogicalSocketCount;
  UINT32                   TempVar_a;
  UINT32                   TempVar_b;
  UINT32                   TempVar_c;
  UINT32                   TempVar_d;
  UINT32                   TempVar_e;
  UINT32                   TempVar_f;
  PCI_ADDR                 PciAddress;

  UINT32                   TempFreqArray[20];
  UINT32                   TempPowerArray[20];
  UINT32                   TempIddValueArray[20];
  UINT32                   TempIddDivArray[20];
  UINT32                   TempSocketPiArray[20];
  UINT32                   TempSwP0Array[MAX_SOCKETS_SUPPORTED];

  BOOLEAN                  TempFlag1;
  BOOLEAN                  TempFlag2;
  BOOLEAN                  TempFlag3;
  BOOLEAN                  TempFlag4;
  BOOLEAN                  AllCoresHaveHtcCapEquToZeroFlag;
  BOOLEAN                  AllCoreHaveMaxOnePStateFlag;
  BOOLEAN                  PstateMaxValEquToPstateHtcLimitFlag;
  BOOLEAN                  AtLeastOneCoreHasPstateHtcLimitEquToOneFlag;
  BOOLEAN                  PstateMaxValMinusHtcPstateLimitLessThan2Flag;
  PSTATE_LEVELING          *PStateBufferPtr;
  PSTATE_LEVELING          *PStateBufferPtrTmp;
  UINT32                   MaxPstateInNode;
  AGESA_STATUS             Status;

  TempFlag1 = FALSE;
  TempFlag2 = FALSE;
  TempFlag3 = FALSE;
  TempFlag4 = FALSE;
  AllCoresHaveHtcCapEquToZeroFlag = FALSE;
  AllCoreHaveMaxOnePStateFlag = FALSE;
  PstateMaxValEquToPstateHtcLimitFlag = FALSE;
  AtLeastOneCoreHasPstateHtcLimitEquToOneFlag = FALSE;
  PstateMaxValMinusHtcPstateLimitLessThan2Flag = FALSE;
  PStateBufferPtr = PStateStrucPtr->PStateLevelingStruc;
  Status = AGESA_SUCCESS;

  if (PStateBufferPtr[0].SetPState0 == PSTATE_FLAG_1) {
    PStateBufferPtr[0].AllCpusHaveIdenticalPStates = TRUE;
    PStateBufferPtr[0].InitStruct = 1;
    return AGESA_UNSUPPORTED;
  }

  LogicalSocketCount = PStateStrucPtr->TotalSocketInSystem;
  ASSERT (LogicalSocketCount <= MAX_SOCKETS_SUPPORTED);

  // This section of code will execute only for "core 0" i.e. BSP
  // Read P-States of all the cores.
  if (PStateBufferPtr[0].InitStruct == 0) {
    // Determine 'software' P0 indices for each socket
    for (i = 0; i < LogicalSocketCount; i++) {
      CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
      TempSwP0Array[i] = (UINT32) (PStateBufferPtrTmp->PStateCoreStruct[0].NumberOfBoostedStates);
    }

    // Check if core frequency and power are same across all sockets.
    TempFlag1 = FALSE;
    m = TempSwP0Array[0];
    for (i = 1; i < LogicalSocketCount; i++) {
      CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
      if ((PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue != PStateBufferPtr[0].PStateCoreStruct[0].PStateMaxValue)) {
        TempFlag1 = TRUE;
        break;
      }
      MaxPstateInNode = PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue;
      for (k = TempSwP0Array[i]; k <= MaxPstateInNode; k++, m++) {
        if ((PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[m].CoreFreq !=
             PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[k].CoreFreq) ||
            (PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[m].Power !=
             PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[k].Power)) {
          TempFlag1 = TRUE;
          break; // Come out of the inner FOR loop
        }
      }
      if (TempFlag1) {
        break; // Come out of the outer FOR loop
      }
    }

    if (!TempFlag1) {
      // No need to do pStateLeveling, or writing to pState MSR registers
      // if all CPUs have Identical PStates
      PStateBufferPtr[0].AllCpusHaveIdenticalPStates = TRUE;
      PStateBufferPtr[0].InitStruct = 1;
      PutAllCoreInPState0 (PStateBufferPtr, StdHeader);
      return AGESA_UNSUPPORTED;
    } else {
      PStateBufferPtr[0].AllCpusHaveIdenticalPStates = FALSE;
    }

    // 1_b) & 1_c)
    TempFlag1 = FALSE;
    TempFlag2 = FALSE;
    for (i = 0; i < LogicalSocketCount; i++) {
      CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
      if (PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue == TempSwP0Array[i]) {
        TempFlag1 = TRUE;
      } else {
        TempFlag2 = TRUE;
      }
      if (PStateBufferPtrTmp->PStateCoreStruct[0].HtcCapable == 0) {
        TempFlag3 = TRUE;
      } else {
        TempFlag4 = TRUE;
      }

      if ((PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue -
           PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit) < 2) {
        PstateMaxValMinusHtcPstateLimitLessThan2Flag = TRUE;
      }

      if (PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue ==
          PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit) {
        PstateMaxValEquToPstateHtcLimitFlag = TRUE;
      }

      if (PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit == 1) {
        AtLeastOneCoreHasPstateHtcLimitEquToOneFlag = TRUE;
      }
    }

    // Do general setup of flags, that we may use later
    // Implementation of (1_b)
    if (TempFlag1 && TempFlag2) {
      //
      //Processors with only one enabled P-state (F3xDC[PstateMaxVal]=000b) cannot be mixed in a system with
      //processors with more than one enabled P-state (F3xDC[PstateMaxVal]!=000b).
      //
      PStateBufferPtr[0].InitStruct = 1;
      PStateBufferPtr[0].CreateAcpiTables = 0;
      PutAllCoreInPState0 (PStateBufferPtr, StdHeader);
      return AGESA_UNSUPPORTED;
    } else if (TempFlag1 && !TempFlag2) {
      //
      //all processors have only 1 enabled P-state
      //
      AllCoreHaveMaxOnePStateFlag = TRUE;
      PStateBufferPtr[0].OnlyOneEnabledPState = TRUE;
    }

    // Processors with F3xE8[HTC_CAPABLE] = 1 can not be
    // mixed in system with processors with F3xE8[HTC_CAPABLE] = 0.
    if (TempFlag3 && TempFlag4) {
      PStateBufferPtr[0].InitStruct = 1;
      for (i = 0; i < LogicalSocketCount; i++) {
        CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
        PStateBufferPtrTmp[0].CreateAcpiTables = 0;
      }
      PutAllCoreInPState0 (PStateBufferPtr, StdHeader);
      return AGESA_UNSUPPORTED;
    }

    if (TempFlag3) {
      //
      //If code run to here means that all processors do not have HTC_CAPABLE.
      //
      AllCoresHaveHtcCapEquToZeroFlag = TRUE;
    }

    //--------------------------------------------------------------------------------
    // S T E P - 2
    //--------------------------------------------------------------------------------
    // Now run the PState Leveling Algorithm which will create mixed CPU P-State
    // Tables.
    // Follow the algorithm in the latest BKDG
    // -------------------------------------------------------------------------------
    // Match P0 CPU COF for all CPU cores to the lowest P0 CPU COF value in the
    // coherent fabric, and match P0 power for all CPU cores to the highest P0 power
    // value in the coherent fabric.
    // 2_a) If all processors have only 1 enabled P-State BIOS must write the
    //      appropriate CpuFid value resulting from the matched CPU COF to all
    //      copies of MSRC001_0070[CpuFid], and exit the sequence (No further
    //      steps are executed)
    //--------------------------------------------------------------------------------
    // Identify the lowest P0 Frequency and maximum P0 Power
    TempVar_d = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSwP0Array[0]].CoreFreq;
    TempVar_e = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSwP0Array[0]].Power;
    TempVar_a = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSwP0Array[0]].IddValue;
    TempVar_b = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSwP0Array[0]].IddDiv;

    for (i = 0; i < LogicalSocketCount; i++) {
      CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
      if (TempVar_d > PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSwP0Array[i]].CoreFreq) {
        TempVar_d = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSwP0Array[i]].CoreFreq;
      }

      if (TempVar_e < PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSwP0Array[i]].Power) {
        TempVar_e = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSwP0Array[i]].Power;
        TempVar_a = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSwP0Array[i]].IddValue;
        TempVar_b = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSwP0Array[i]].IddDiv;
      }
    }

    // Set P0 Frequency and Power for all CPUs
    for (i = 0; i < LogicalSocketCount; i++) {
      CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
      PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSwP0Array[i]].CoreFreq = TempVar_d;
      PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSwP0Array[i]].Power = TempVar_e;
      PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSwP0Array[i]].IddValue = TempVar_a;
      PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSwP0Array[i]].IddDiv = TempVar_b;
    }

    // 2_a)
    if (!AllCoreHaveMaxOnePStateFlag) {
      //--------------------------------------------------------------------------
      // STEP - 3
      //--------------------------------------------------------------------------
      // Match the CPU COF and power for P-states used by HTC. Skip to step 4
      // is any processor reports F3xE8[HTC_Capable] = 0;
      // 3_a) Set F3x64[HtcPstateLimit] = 001b and F3x68[StcPstateLimit] = 001b for
      //      processors with F3x64[HtcPstateLimit] = 000b.
      // 3_b) Identify the lowest CPU COF for all processors in the P-state
      //      pointed to by [The Hardware Thermal Control (HTC) Register]
      //      F3x64[HtcPstateLimit]
      // 3_c) Modify the CPU COF pointed to by [The Hardware Thermal Control
      //      (HTC) Register] F3x64[HtcPstateLimit] for all processors to the
      //      previously identified lowest CPU COF value.
      // 3_d) Identify the highest power for all processors in the P-state
      //      pointed to by [The Hardware Thermal Control (HTC) Register]
      //      F3x64[HtcPstateLimit].
      // 3_e) Modify the power pointed to by [The Hardware Thermal Control (HTC)
      //      Register] F3x64[HtcPstateLimit] to the previously identified
      //      highest power value.
      if (!AllCoresHaveHtcCapEquToZeroFlag) {
        // 3_a)
        for (i = 0; i < LogicalSocketCount; i++) {
          CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
          if (PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit == 0) {
            // To Be Done (Set Htc and Stc PstateLimit values)
            // for this CPU (using PCI address space)
            for (k = 0; k < (UINT8)GetPlatformNumberOfModules (); k++) {
              if (GetPciAddress (StdHeader, PStateBufferPtrTmp->SocketNumber, k, &PciAddress, &Status)) {
                // Set F3x64[HtcPstateLimit] = 001b
                PciAddress.Address.Function = FUNC_3;
                PciAddress.Address.Register = HARDWARE_THERMAL_CTRL_REG;
                LibAmdPciRead (AccessWidth32, PciAddress, &TempVar_d, StdHeader);
                // Bits 30:28
                TempVar_d = (TempVar_d & 0x8FFFFFFF) | 0x10000000;
                LibAmdPciWrite (AccessWidth32, PciAddress, &TempVar_d, StdHeader);

                // Set F3x68[StcPstateLimit] = 001b
                PciAddress.Address.Register = SOFTWARE_THERMAL_CTRL_REG;
                LibAmdPciRead (AccessWidth32, PciAddress, &TempVar_d, StdHeader);
                // Bits 28:30
                TempVar_d = (TempVar_d & 0x8FFFFFFF) | 0x10000000;
                LibAmdPciWrite (AccessWidth32, PciAddress, &TempVar_d, StdHeader);
              }
            }
            // Set LocalBuffer
            PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit = 1;
            if ((PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue - 1) < 2) {
              PstateMaxValMinusHtcPstateLimitLessThan2Flag = TRUE;
            }

            if (PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue == 1) {
              PstateMaxValEquToPstateHtcLimitFlag = TRUE;
            }
          }

          if (PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit == 1) {
            AtLeastOneCoreHasPstateHtcLimitEquToOneFlag = TRUE;
          }
        }

        // 3_b) and 3_d)
        TempVar_a = PStateBufferPtr[0].PStateCoreStruct[0].HtcPstateLimit;
        TempVar_d = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempVar_a].CoreFreq;
        TempVar_e = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempVar_a].Power;
        TempVar_f = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempVar_a].IddValue;
        TempVar_c = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempVar_a].IddDiv;
        for (i = 0; i < LogicalSocketCount; i++) {
          CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
          for (k = 0; k < 1; k++) {
            TempVar_b = PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit;
            if (TempVar_d > PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_b].CoreFreq) {
              TempVar_d = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_b].CoreFreq;
            }

            if (TempVar_e < PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_b].Power) {
              TempVar_e = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_b].Power;
              TempVar_f = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_b].IddValue;
              TempVar_c = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_b].IddDiv;
            }
          }
        }

        // 3_c) and 3_e)
        for (i = 0; i < LogicalSocketCount; i++) {
          CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
          TempVar_a = PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit;
          PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_a].CoreFreq = TempVar_d;
          PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_a].Power = TempVar_e;
          PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_a].IddValue = TempVar_f;
          PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_a].IddDiv = TempVar_c;
        }
      } // if(AllCoresHaveHtcCapEquToZeroFlag)


      //--------------------------------------------------------------------------
      // STEP - 4
      //--------------------------------------------------------------------------
      // Match the CPU COF and power for the lowest performance P-state:
      // 4_a) If F3xDC[PstateMaxVal] = F3x64[HtcPstateLimit] for any processor,
      //      set PstateEn = 0 for all the P-states greater than
      //      F3x64[HtcPstateLimit] for all processors.
      // 4_b) Identify the lowest CPU COF for all processors in the P-state
      //      pointed to by F3xDC[PstateMaxVal].
      // 4_c) Modify the CPU COF for all processors in the P-state pointed to by
      //      F3xDC[PstateMaxVal] to the previously identified lowest CPU COF
      //      value.
      // 4_d) Identify the highest power for all processors in the P-state
      //      pointed to by F3xDC[PstateMaxVal].
      // 4_e) Modify the power for all processors in the P-state pointed to by
      //      F3xDC[PstateMaxVal] to the previously identified highest power
      //      value.

      // 4_a)
      if (PstateMaxValEquToPstateHtcLimitFlag) {
        for (i = 0; i < LogicalSocketCount; i++) {
          CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
          TempVar_b = PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit + 1;
          for (k = TempVar_b; k <= PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue; k++) {
            PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[k].PStateEnable = 0;
          }
          //--------------------------------------------------------------------------
          // STEP - 5
          //--------------------------------------------------------------------------
          // 5_a) Modify F3xDC[PstateMaxVal] to indicate the lowest performance
          //      P-state with PstateEn set for each processor (Step 4 can disable
          //      P-states pointed to by F3xDC[PstateMaxVal])

          // Use this value of HtcPstateLimit to program the
          // F3xDC[pStateMaxValue]
          TempVar_e = PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit;
          TempVar_e <<= 8;
          // Bits 10:8

          for (m = 0; m < (UINT8)GetPlatformNumberOfModules (); m++) {
            if (GetPciAddress (StdHeader, PStateBufferPtrTmp->SocketNumber, m, &PciAddress, &Status)) {
              PciAddress.Address.Function = FUNC_3;
              PciAddress.Address.Register = CLOCK_POWER_TIMING_CTRL2_REG;
              LibAmdPciRead (AccessWidth32, PciAddress, &TempVar_d, StdHeader);
              TempVar_d = (TempVar_d & 0xFFFFF8FF) | TempVar_e;
              LibAmdPciWrite (AccessWidth32, PciAddress, &TempVar_d, StdHeader);
            }
          }//End of step 5
        }
      }// End of 4_a)

      // 4_b) and 4_d)
      TempVar_a = PStateBufferPtr[0].PStateCoreStruct[0].PStateMaxValue;
      TempVar_d = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempVar_a].CoreFreq;
      TempVar_e = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempVar_a].Power;
      TempVar_f = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempVar_a].IddValue;
      TempVar_c = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempVar_a].IddDiv;

      for (i = 0; i < LogicalSocketCount; i++) {
        CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
        TempVar_b = PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue;
        if (TempVar_d >
            PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_b].CoreFreq) {
          TempVar_d =
          PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_b].CoreFreq;
        }

        if (TempVar_e < PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_b].Power) {
          TempVar_e = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_b].Power;
          TempVar_f = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_b].IddValue;
          TempVar_c = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_b].IddDiv;
        }
      }

      // 4_c) and 4_e)
      for (i = 0; i < LogicalSocketCount; i++) {
        CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
        TempVar_a = PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue;
        PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_a].CoreFreq = TempVar_d;
        PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_a].Power = TempVar_e;
        PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_a].IddValue = TempVar_f;
        PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempVar_a].IddDiv = TempVar_c;
      }


      //--------------------------------------------------------------------------
      // STEP - 6
      //--------------------------------------------------------------------------
      // Match the CPU COF and power for upper intermediate performance
      // P-state(s):
      // Upper intermediate PStates = PStates between (Not including) P0 and
      // F3x64[HtcPstateLimit]
      // 6_a) If F3x64[HtcPstateLimit] = 001b for any processor, set PstateEn = 0
      //      for enabled upper intermediate P-states for all processors with
      //      F3x64[HtcPstateLimit] > 001b and skip the remaining actions for
      //      this numbered step.
      // 6_b) Define each of the available upper intermediate P-states; for each
      //      processor concurrently evaluate the following loop; when any
      //      processor falls out of the loop (runs out of available upper
      //      intermediate Pstates) all other processors have their remaining
      //      upper intermediate P-states invalidated (PstateEn = 0);
      //      for (i = F3x64[HtcPstateLimit] - 1; i > 0; i--)
      //         - Identify the lowest CPU COF for P(i).
      //         - Identify the highest power for P(i).
      //         - Modify P(i) CPU COF for all processors to the previously
      //           identified lowest CPU COF value.
      //         - Modify P(i) power for all processors to the previously
      //           identified highest power value.

      // 6_a)
      if (AtLeastOneCoreHasPstateHtcLimitEquToOneFlag) {
        for (i = 0; i < LogicalSocketCount; i++) {
          CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
          for (k = TempSwP0Array[i] + 1; k < (PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit); k++) {
            if (PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit > 1) {
              // Make a function call to clear the
              // structure values
              PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[k].PStateEnable = 0;
            }
          }
        }
      }
      // 6_b)
      else {
        // Identify Lowest Frequency and Highest Power
        TotalIterations = 0;
        TempFlag1 = TRUE;

        for (i = 0; i < LogicalSocketCount; i++) {
          CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
          TempSocketPiArray[i] = PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit - 1;
        }

        do {
          //For first socket, try to find a candidate
          if (TempSocketPiArray[0] != TempSwP0Array[0]) {
            while (PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSocketPiArray[0]].PStateEnable == 0) {
              TempSocketPiArray[0] = TempSocketPiArray[0] - 1;
              if (TempSocketPiArray[0] == TempSwP0Array[0]) {
                TempFlag1 = FALSE;
                break;
              }
            }
          } else {
            TempFlag1 = FALSE;
          }
          if (TempFlag1) {
            TempFreqArray[TotalIterations] = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSocketPiArray[0]].CoreFreq;
            TempPowerArray[TotalIterations] = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSocketPiArray[0]].Power;
            TempIddValueArray[TotalIterations] = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSocketPiArray[0]].IddValue;
            TempIddDivArray[TotalIterations] = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSocketPiArray[0]].IddDiv;

            //Try to find next candidate
            for (i = 1; i < LogicalSocketCount; i++) {
              CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
              if (TempSocketPiArray[i] != TempSwP0Array[i]) {
                while (PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].PStateEnable == 0) {
                  TempSocketPiArray[i]--;
                  if (TempSocketPiArray[i] == TempSwP0Array[i]) {
                    TempFlag1 = FALSE;
                    break;
                  }
                }//end while
              } else {
                TempFlag1 = FALSE;
              }

            } //end for LogicalSocketCount
          }

          if (TempFlag1) {
            for (i = 0; i < LogicalSocketCount; i++) {
              //
              //Compare
              //
              CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
              if (TempFreqArray[TotalIterations] > PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].CoreFreq) {
                TempFreqArray[TotalIterations] = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].CoreFreq;
              }

              if (TempPowerArray[TotalIterations] < PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].Power) {
                TempPowerArray[TotalIterations] = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].Power;
                TempIddValueArray[TotalIterations] = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].IddValue;
                TempIddDivArray[TotalIterations] = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].IddDiv;
              }
            }
            // Modify (Pi) CPU COF and Power for all the CPUs
            for (i = 0; i < LogicalSocketCount; i++) {
              CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
              PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].CoreFreq = TempFreqArray[TotalIterations];
              PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].Power    = TempPowerArray[TotalIterations];
              PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].IddValue = TempIddValueArray[TotalIterations];
              PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].IddDiv   = TempIddDivArray[TotalIterations];
              TempSocketPiArray[i] = TempSocketPiArray[i] - 1;
            }
          } else {
            for (i = 0; i < LogicalSocketCount; i++) {
              CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
              for (m = TempSocketPiArray[i]; m > TempSwP0Array[i]; m--) {
                PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[m].PStateEnable = 0;
              }
            }
          }

          TotalIterations++;
        } while (TempFlag1);

      } // else

      //--------------------------------------------------------------------------
      // STEP - 7
      //--------------------------------------------------------------------------
      // Match the CPU COF and power for lower intermediate performance P - state(s)
      // Lower Intermediate Pstates = Pstates between (not including)
      // F3x64[HtcPstateLimit] and F3xDC[PstateMaxVal]
      // 7_a) If F3xDC[PstateMaxVal] - F3x64[HtcPstateLimit] < 2 for any
      //      processor, set PstateEn = 0 for enabled lower intermediate P - states
      //      for all processors with (F3xDC[PstateMaxVal] -
      //      F3x64[HtcPstateLimit] > 1) and skip the remaining actions for this
      //      numbered step.
      // 7_b) Define each of the available lower intermediate P-states; for each
      //      processor concurrently evaluate the following loop; when any
      //      processor falls out of the loop (runs out of available lower
      //      intermediate Pstates) all other processors have their remaining
      //      lower intermediate P-states invalidated (PstateEn = 0);
      //      for (i = F3xDC[PstateMaxVal]-1; i > F3x64[HtcPstateLimit]; i--)
      //         - Identify the lowest CPU COF for P-states between
      //           (not including) F3x64[HtcPstateLimit] and P(i).
      //         - Identify the highest power for P-states between
      //           (not including) F3x64[HtcPstateLimit] and P(i).
      //         - Modify P(i) CPU COF for all processors to the previously
      //           identified lowest CPU COF value.
      //         - Modify P(i) power for all processors to the previously
      //           identified highest power value.


      // 7_a)
      if (PstateMaxValMinusHtcPstateLimitLessThan2Flag) {
        for (i = 0; i < LogicalSocketCount; i++) {
          CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);

          for (k = PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue - 1;
              k > PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit;
              k--) {
            if ((PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue -
                 PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit) > 1) {
              PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[k].PStateEnable = 0;
            }
          }
        }
      }

      // 7_b)
      else {
        // Identify Lowest Frequency and Highest Power

        TotalIterations = 0;
        TempFlag1 = TRUE;

        for (i = 0; i < LogicalSocketCount; i++) {
          CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
          TempSocketPiArray[i] = PStateBufferPtrTmp->PStateCoreStruct[0].PStateMaxValue - 1;
        }

        do {
          //For first socket, try to find a candidate
          if (TempSocketPiArray[0] != PStateBufferPtr[0].PStateCoreStruct[0].HtcPstateLimit) {
            while (PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSocketPiArray[0]].PStateEnable == 0) {
              TempSocketPiArray[0] = TempSocketPiArray[0] - 1;
              if (TempSocketPiArray[0] == PStateBufferPtr[0].PStateCoreStruct[0].HtcPstateLimit) {
                TempFlag1 = FALSE;
                break;
              }
            }
          } else {
            TempFlag1 = FALSE;
          }
          if (TempFlag1) {
            TempFreqArray[TotalIterations] = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSocketPiArray[0]].CoreFreq;
            TempPowerArray[TotalIterations] = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSocketPiArray[0]].Power;
            TempIddValueArray[TotalIterations] = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSocketPiArray[0]].IddValue;
            TempIddDivArray[TotalIterations] = PStateBufferPtr[0].PStateCoreStruct[0].PStateStruct[TempSocketPiArray[0]].IddDiv;

            //Try to find next candidate
            for (i = 1; i < LogicalSocketCount; i++) {
              CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
              if (TempSocketPiArray[i] != PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit) {
                while (PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].PStateEnable == 0) {
                  TempSocketPiArray[i]--;
                  if (TempSocketPiArray[i] == PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit) {
                    TempFlag1 = FALSE;
                    break;
                  }
                }//end while
              } else {
                TempFlag1 = FALSE;
              }
            } //end for LogicalSocketCount
          }

          if (TempFlag1) {
            for (i = 0; i < LogicalSocketCount; i++) {
              //
              //Compare
              //
              CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
              if (TempFreqArray[TotalIterations] > PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].CoreFreq) {
                TempFreqArray[TotalIterations] = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].CoreFreq;
              }
              if (TempPowerArray[TotalIterations] < PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].Power) {
                TempPowerArray[TotalIterations] = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].Power;
                TempIddValueArray[TotalIterations] = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].IddValue;
                TempIddDivArray[TotalIterations] = PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].IddDiv;
              }
            }
            // Modify (Pi) CPU COF and Power for all the CPUs
            for (i = 0; i < LogicalSocketCount; i++) {
              CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
              PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].CoreFreq = TempFreqArray[TotalIterations];
              PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].Power    = TempPowerArray[TotalIterations];
              PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].IddValue = TempIddValueArray[TotalIterations];
              PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[TempSocketPiArray[i]].IddDiv   = TempIddDivArray[TotalIterations];
              TempSocketPiArray[i] = TempSocketPiArray[i] - 1;
            }
          } else {
            for (i = 0; i < LogicalSocketCount; i++) {
              CpuGetPStateLevelStructure (&PStateBufferPtrTmp, PStateStrucPtr, i, StdHeader);
              for (m = TempSocketPiArray[i]; m > PStateBufferPtrTmp->PStateCoreStruct[0].HtcPstateLimit; m--) {
                PStateBufferPtrTmp->PStateCoreStruct[0].PStateStruct[m].PStateEnable = 0;
              }
            }
          }
          TotalIterations++;
        } while (TempFlag1);
      } // else
    } // if(!AllCoreHaveMaxOnePStateFlag)

    PStateBufferPtr[0].InitStruct = 1;
  } // CurrentCore


  // Update the pState MSRs
  // This can be done only by individual core
  StartPstateMsrModify (PStateStrucPtr, StdHeader);

  //----------------------------------------------------------------------------------
  // STEP - 8
  //----------------------------------------------------------------------------------
  // Place all cores into a valid COF and VID configuration corresponding to an
  // enabled P-state:
  // 8_a) Select an enabled P-state != to the P-state pointed to by
  //      MSRC001_0063[CurPstate] for each core.
  // 8_b) Transition all cores to the selected P-states by writing the Control value
  //      from the_PSS object corresponding to the selected P-state to
  //      MSRC001_0062[PstateCmd].
  // 8_c) Wait for all cores to report the Status value from the _PSS object
  //      corresponding to the selected P-state in MSRC001_0063[CurPstate].
  //
  PutAllCoreInPState0 (PStateBufferPtr, StdHeader);

  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;
}
Esempio n. 25
0
/**
 *  Save and Restore or Initialize the content of the mailbox registers.
 *
 * The registers used for AP mailbox should have the content related to their function
 * preserved.
 *
 * @param[in]    EntryPoint         Timepoint designator.
 * @param[in]    PlatformConfig     Contains the runtime modifiable feature input data.
 * @param[in]    StdHeader          Config Handle for library, services.
 *
 * @return       AGESA_SUCCESS      Always succeeds.
 *
 */
AGESA_STATUS
STATIC
PreserveMailboxes (
  IN       UINT64                 EntryPoint,
  IN       PLATFORM_CONFIGURATION *PlatformConfig,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  PRESERVE_MAILBOX_FAMILY_SERVICES *FamilySpecificServices;
  UINT32 Socket;
  UINT32 Module;
  PCI_ADDR BaseAddress;
  PCI_ADDR MailboxRegister;
  PCI_ADDR *NextRegister;
  AGESA_STATUS IgnoredStatus;
  AGESA_STATUS HeapStatus;
  UINT32 Value;
  ALLOCATE_HEAP_PARAMS AllocateParams;
  LOCATE_HEAP_PTR LocateParams;
  UINT32 RegisterEntryIndex;

  BaseAddress.AddressValue = ILLEGAL_SBDFO;

  if (EntryPoint == CPU_FEAT_AFTER_COHERENT_DISCOVERY) {
    // The save step.  Save either the register content or zero (for cold boot, if family specifies that).
    AllocateParams.BufferHandle = PRESERVE_MAIL_BOX_HANDLE;
    AllocateParams.RequestedBufferSize = (sizeof (UINT32) * (MAX_PRESERVE_REGISTER_ENTRIES * (MAX_SOCKETS * MAX_DIES)));
    AllocateParams.Persist = HEAP_SYSTEM_MEM;
    HeapStatus = HeapAllocateBuffer (&AllocateParams, StdHeader);
    ASSERT ((HeapStatus == AGESA_SUCCESS) && (AllocateParams.BufferPtr != NULL));
    LibAmdMemFill (AllocateParams.BufferPtr, 0xFF, AllocateParams.RequestedBufferSize, StdHeader);
    RegisterEntryIndex = 0;
    for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) {
      for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) {
        if (GetPciAddress (StdHeader, Socket, Module, &BaseAddress, &IgnoredStatus)) {
          GetFeatureServicesOfSocket (&PreserveMailboxFamilyServiceTable, Socket, (const VOID **)&FamilySpecificServices, StdHeader);
          ASSERT (FamilySpecificServices != NULL);
          NextRegister = FamilySpecificServices->RegisterList;
          while (NextRegister->AddressValue != ILLEGAL_SBDFO) {
            ASSERT (RegisterEntryIndex <
                    (MAX_PRESERVE_REGISTER_ENTRIES * GetPlatformNumberOfSockets () * GetPlatformNumberOfModules ()));
            if (FamilySpecificServices->IsZeroOnCold && (!IsWarmReset (StdHeader))) {
              Value = 0;
            } else {
              MailboxRegister = BaseAddress;
              MailboxRegister.Address.Function = NextRegister->Address.Function;
              MailboxRegister.Address.Register = NextRegister->Address.Register;
              LibAmdPciRead (AccessWidth32, MailboxRegister, &Value, StdHeader);
            }
            (* (MAILBOX_REGISTER_SAVE_ENTRY) AllocateParams.BufferPtr) [RegisterEntryIndex] = Value;
            RegisterEntryIndex++;
            NextRegister++;
          }
        }
      }
    }
  } else if ((EntryPoint == CPU_FEAT_INIT_LATE_END) || (EntryPoint == CPU_FEAT_AFTER_RESUME_MTRR_SYNC)) {
    // The restore step.  Just write out the saved content in the buffer.
    LocateParams.BufferHandle = PRESERVE_MAIL_BOX_HANDLE;
    HeapStatus = HeapLocateBuffer (&LocateParams, StdHeader);
    ASSERT ((HeapStatus == AGESA_SUCCESS) && (LocateParams.BufferPtr != NULL));
    RegisterEntryIndex = 0;
    for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) {
      for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) {
        if (GetPciAddress (StdHeader, Socket, Module, &BaseAddress, &IgnoredStatus)) {
          GetFeatureServicesOfSocket (&PreserveMailboxFamilyServiceTable, Socket, (const VOID **)&FamilySpecificServices, StdHeader);
          NextRegister = FamilySpecificServices->RegisterList;
          while (NextRegister->AddressValue != ILLEGAL_SBDFO) {
            ASSERT (RegisterEntryIndex <
                    (MAX_PRESERVE_REGISTER_ENTRIES * GetPlatformNumberOfSockets () * GetPlatformNumberOfModules ()));
            MailboxRegister = BaseAddress;
            MailboxRegister.Address.Function = NextRegister->Address.Function;
            MailboxRegister.Address.Register = NextRegister->Address.Register;
            Value = (* (MAILBOX_REGISTER_SAVE_ENTRY) LocateParams.BufferPtr) [RegisterEntryIndex];
            LibAmdPciWrite (AccessWidth32, MailboxRegister, &Value, StdHeader);
            RegisterEntryIndex++;
            NextRegister++;
          }
        }
      }
    }
    HeapStatus = HeapDeallocateBuffer (PRESERVE_MAIL_BOX_HANDLE, StdHeader);
  }
  return AGESA_SUCCESS;
}
Esempio n. 26
0
/**
 * Set down core register on Orochi
 *
 * This function set F3x190 Downcore Control Register[5:0]
 *
 * @param[in]   FamilySpecificServices   The current Family Specific Services.
 * @param[in]   Socket                   Socket ID.
 * @param[in]   Module                   Module ID in socket.
 * @param[in]   LeveledCores             Number of core.
 * @param[in]   CoreLevelMode            Core level mode.
 * @param[in]   StdHeader                Header for library and services.
 *
 * @retval      TRUE                     Down Core register is updated.
 * @retval      FALSE                    Down Core register is not updated.
 */
BOOLEAN
F15OrSetDownCoreRegister (
  IN       CPU_CORE_LEVELING_FAMILY_SERVICES *FamilySpecificServices,
  IN       UINT32 *Socket,
  IN       UINT32 *Module,
  IN       UINT32 *LeveledCores,
  IN       CORE_LEVELING_TYPE CoreLevelMode,
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  UINT8     Xbar2SriFreeListCBC;
  UINT8     L3FreeListCBC;
  UINT32    TempVar32_a;
  UINT32    CoreDisableBits;
  UINT32    NumberOfEnabledCores;
  UINT32    NumberOfEnabledCU;
  PCI_ADDR  PciAddress;
  BOOLEAN   IsUpdated;
  AGESA_STATUS                    AgesaStatus;
  NB_CAPS_REGISTER                NbCaps;
  FREE_LIST_BUFFER_COUNT_REGISTER FreeListBufferCount;
  L3_BUFFER_COUNT_REGISTER        L3BufferCnt;

  IsUpdated = FALSE;

  if (CoreLevelMode == CORE_LEVEL_COMPUTE_UNIT) {
    switch (*LeveledCores) {
    case 1:
      CoreDisableBits = DOWNCORE_MASK_SINGLE;
      break;
    case 2:
      CoreDisableBits = DOWNCORE_MASK_DUAL_COMPUTE_UNIT;
      break;
    case 3:
      CoreDisableBits = DOWNCORE_MASK_TRI_COMPUTE_UNIT;
      break;
    case 4:
      CoreDisableBits = DOWNCORE_MASK_FOUR_COMPUTE_UNIT;
      break;
    default:
      CoreDisableBits = 0;
      break;
    }

  } else {
    switch (*LeveledCores) {
    case 1:
      CoreDisableBits = DOWNCORE_MASK_SINGLE;
      break;
    case 2:
      CoreDisableBits = DOWNCORE_MASK_DUAL;
      break;
    case 4:
      CoreDisableBits = DOWNCORE_MASK_FOUR;
      break;
    case 6:
      CoreDisableBits = DOWNCORE_MASK_SIX;
      break;
    default:
      CoreDisableBits = 0;
      break;
    }
  }

  if (CoreDisableBits != 0) {
    if (GetPciAddress (StdHeader, (UINT8) *Socket, (UINT8) *Module, &PciAddress, &AgesaStatus)) {
      PciAddress.Address.Function = FUNC_5;
      PciAddress.Address.Register = NORTH_BRIDGE_CAPABILITIES_2_REG;
      LibAmdPciRead (AccessWidth32, PciAddress, &TempVar32_a, StdHeader);
      TempVar32_a = (TempVar32_a & 0xFF) + 1;
      TempVar32_a = (1 << TempVar32_a) - 1;
      CoreDisableBits &= TempVar32_a;
      NumberOfEnabledCores = ~(CoreDisableBits | ~(TempVar32_a));

      PciAddress.Address.Function = FUNC_3;
      PciAddress.Address.Register = DOWNCORE_CTRL;
      LibAmdPciRead (AccessWidth32, PciAddress, &TempVar32_a, StdHeader);
      if ((TempVar32_a | CoreDisableBits) != TempVar32_a) {
        TempVar32_a |= CoreDisableBits;
        LibAmdPciWrite (AccessWidth32, PciAddress, &TempVar32_a, StdHeader);
        IsUpdated = TRUE;

        for (NumberOfEnabledCU = 0; NumberOfEnabledCores != 0; NumberOfEnabledCores >>= 2) {
          NumberOfEnabledCU += ((NumberOfEnabledCores & 3) != 0) ? 1 : 0;
        }
        switch (NumberOfEnabledCU) {
        case 1:
          Xbar2SriFreeListCBC = 0x16;
          L3FreeListCBC = 0x1C;
          break;
        case 2:
          Xbar2SriFreeListCBC = 0x14;
          L3FreeListCBC = 0x18;
          break;
        case 3:
          Xbar2SriFreeListCBC = 0x12;
          L3FreeListCBC = 0x14;
          break;
        case 4:
          Xbar2SriFreeListCBC = 0x10;
          L3FreeListCBC = 0x10;
          break;
        default:
          Xbar2SriFreeListCBC = 0x16;
          L3FreeListCBC = 0xE;
          break;
        }
        //D18F3x1A0[8:4] L3FreeListCBC:
        //BIOS: IF (NumOfCompUnitsOnNode==1) THEN 1Ch ELSEIF (NumOfCompUnitsOnNode==2)
        //THEN 18h ELSEIF (NumOfCompUnitsOnNode==3) THEN 14h ELSEIF
        //(NumOfCompUnitsOnNode==4) THEN 10h ELSEIF (NumOfCompUnitsOnNode==5) THEN 11h
        //ELSE 0Eh ENDIF.
        PciAddress.Address.Function = FUNC_3;
        PciAddress.Address.Register = L3_BUFFER_COUNT_REG;
        LibAmdPciRead (AccessWidth32, PciAddress, &L3BufferCnt, StdHeader);
        L3BufferCnt.L3FreeListCBC = L3FreeListCBC;
        LibAmdPciWrite (AccessWidth32, PciAddress, &L3BufferCnt, StdHeader);

        //D18F3x7C[4:0]Xbar2SriFreeListCBC:
        //BIOS: IF (L3Enabled) THEN 16h ELSEIF (D18F5x80[Enabled[3]]==1) THEN 10h ELSEIF
        //(D18F5x80[Enabled[2]]==1) THEN 12h ELSEIF (D18F5x80[Enabled[1]]==1) THEN 14h ELSE 16h ENDIF.
        PciAddress.Address.Function = FUNC_3;
        PciAddress.Address.Register = NB_CAPS_REG;
        LibAmdPciRead (AccessWidth32, PciAddress, &NbCaps, StdHeader);
        if (NbCaps.L3Capable == 0) {
          PciAddress.Address.Function = FUNC_3;
          PciAddress.Address.Register = FREE_LIST_BUFFER_COUNT_REG;
          LibAmdPciRead (AccessWidth32, PciAddress, &FreeListBufferCount, StdHeader);
          FreeListBufferCount.Xbar2SriFreeListCBC = Xbar2SriFreeListCBC;
          LibAmdPciWrite (AccessWidth32, PciAddress, &FreeListBufferCount, StdHeader);
        }
      }
    }
Esempio n. 27
0
/**
 * Restores the context of a 'conditional' PCI device.
 *
 * This traverses the provided register list restoring PCI registers when appropriate.
 *
 * @param[in]     StdHeader      AMD standard header config param.
 * @param[in]     Device         'conditional' PCI 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
RestoreConditionalPciDevice (
  IN       AMD_CONFIG_PARAMS                 *StdHeader,
  IN       CONDITIONAL_PCI_DEVICE_DESCRIPTOR *Device,
  IN       CALL_POINTS                       CallPoint,
  IN OUT   VOID                              **OrMask
  )
{
  UINT8   RegSizeInBytes;
  UINT8   SpecialCaseIndex;
  UINT8   *IntermediatePtr;
  UINT8   BootMode;
  UINT16  i;
  UINT32  Socket;
  UINT32  Module;
  UINT32  RegValueRead;
  UINT32  RegValueWrite;
  UINT32  AndMask;
  ACCESS_WIDTH AccessWidth;
  AGESA_STATUS IgnoredSts;
  PCI_ADDR PciAddress;
  CPCI_REGISTER_BLOCK_HEADER *RegisterHdr;

  GetSocketModuleOfNode ((UINT32) Device->Node,
                               &Socket,
                               &Module,
                               StdHeader);
  GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts);

  if (CallPoint == INIT_RESUME) {
    MemFS3GetCPciDeviceRegisterList (Device, &RegisterHdr, StdHeader);
  } else {
    S3GetCPciDeviceRegisterList (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)) {
      PciAddress.Address.Function = RegisterHdr->RegisterList[i].Function;
      PciAddress.Address.Register = RegisterHdr->RegisterList[i].Offset;
      RegSizeInBytes = RegisterHdr->RegisterList[i].Type.RegisterSize;
      switch (RegSizeInBytes) {
      case 1:
        AndMask = 0xFFFFFFFF & ((UINT8) RegisterHdr->RegisterList[i].AndMask);
        RegValueWrite = **(UINT8 **)OrMask;
        AccessWidth = AccessS3SaveWidth8;
        break;
      case 2:
        AndMask = 0xFFFFFFFF & ((UINT16) RegisterHdr->RegisterList[i].AndMask);
        RegValueWrite = **(UINT16 **)OrMask;
        AccessWidth = AccessS3SaveWidth16;
        break;
      case 3:
        // In this case, we don't need to restore a register. We just need to call a special
        //  function to do certain things in the save and resume sequence.
        // This should not be used in a non-special case.
        AndMask = 0;
        RegValueWrite = 0;
        RegSizeInBytes = 0;
        AccessWidth = 0;
        break;
      default:
        AndMask = RegisterHdr->RegisterList[i].AndMask;
        RegSizeInBytes = 4;
        RegValueWrite = **(UINT32 **)OrMask;
        AccessWidth = AccessS3SaveWidth32;
        break;
      }
      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
        if (RegisterHdr->RegisterList[i].Type.SpecialCaseFlag == 0) {
          LibAmdPciRead (AccessWidth, PciAddress, &RegValueRead, StdHeader);
          RegValueWrite |= RegValueRead & (~AndMask);
          LibAmdPciWrite (AccessWidth, PciAddress, &RegValueWrite, StdHeader);
        } else {
          SpecialCaseIndex = RegisterHdr->RegisterList[i].Type.SpecialCaseIndex;
          if (AndMask != 0) {
            RegisterHdr->SpecialCases[SpecialCaseIndex].Save (AccessWidth,
                                               PciAddress,
                                               &RegValueRead,
                                               StdHeader);
            RegValueWrite |= RegValueRead & (~AndMask);
          }
          RegisterHdr->SpecialCases[SpecialCaseIndex].Restore (AccessWidth,
                                                 PciAddress,
                                                 &RegValueWrite,
                                                 StdHeader);
        }
        IDS_OPTION_HOOK (IDS_AFTER_RESTORING_PCI_REG, RegisterHdr, StdHeader);
      }
      IntermediatePtr = (UINT8 *) *OrMask;
      *OrMask = &IntermediatePtr[RegSizeInBytes];
      if ((RegSizeInBytes == 0) && (RegValueWrite == RESTART_FROM_BEGINNING_LIST)) {
        // Restart from the beginning of the register list
        i = 0xFFFF;
      }
    }
  }
}
Esempio n. 28
0
/**
 *  Should message-based C1e be enabled
 *
 * @param[in]    PlatformConfig     Contains the runtime modifiable feature input data.
 * @param[in]    StdHeader          Config Handle for library, services.
 *
 * @retval       TRUE               Message-based C1e is supported.
 * @retval       FALSE              Message-based C1e cannot be enabled.
 *
 */
BOOLEAN
STATIC
IsMsgBasedC1eFeatureEnabled (
  IN       PLATFORM_CONFIGURATION *PlatformConfig,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  UINTN                         Link;
  UINTN                         LinkCount;
  UINT32                        Socket;
  UINT32                        Module;
  BOOLEAN                       IsEnabled;
  PCI_ADDR                      PciAddress;
  AGESA_STATUS                  AgesaStatus;
  HT_HOST_FEATS                 HtHostFeats;
  CPU_SPECIFIC_SERVICES         *CpuServices;
  MSG_BASED_C1E_FAMILY_SERVICES *FamilyServices;

  ASSERT (PlatformConfig->C1eMode < MaxC1eMode);

  IsEnabled = FALSE;
  if (PlatformConfig->C1eMode == C1eModeMsgBased) {
    ASSERT (PlatformConfig->C1ePlatformData < 0x10000);
    ASSERT (PlatformConfig->C1ePlatformData != 0);
    if ((PlatformConfig->C1ePlatformData != 0) && (PlatformConfig->C1ePlatformData < 0xFFFE)) {
      IsEnabled = TRUE;
      for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) {
        if (IsProcessorPresent (Socket, StdHeader)) {
          GetFeatureServicesOfSocket (&MsgBasedC1eFamilyServiceTable, Socket, (CONST VOID **)&FamilyServices, StdHeader);
          if ((FamilyServices == NULL) || !FamilyServices->IsMsgBasedC1eSupported (FamilyServices, Socket, StdHeader)) {
            IsEnabled = FALSE;
            break;
          } else {
            // If the CPU revision supports message-based C1e, check whether the feature should
            // be disabled based on the speed of ncHT links (HT1).
            GetCpuServicesOfSocket (Socket, &CpuServices, StdHeader);
            for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) {
              if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &AgesaStatus)) {
                HtHostFeats.HtHostValue = 0;
                for (LinkCount = 0; LinkCount < 8; LinkCount++) {
                  if (FindHtHostCapability (LinkCount, &PciAddress, StdHeader)) {
                    CpuServices->GetHtLinkFeatures (CpuServices, &Link, &PciAddress, &HtHostFeats, StdHeader);
                    if ((HtHostFeats.HtHostFeatures.NonCoherent == 1) && (HtHostFeats.HtHostFeatures.Ht1 == 1)) {
                      IsEnabled = FALSE;
                      break;
                    }
                  }
                }
              }
              // Exit for (Module = 0; Module < GetPlatformNumberOfModules; Module++)
              if (!IsEnabled) {
                break;
              }
            }
          }
        }
        // Exit for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++)
        if (!IsEnabled) {
          break;
        }
      }
    }
  }
  return IsEnabled;
}
Esempio n. 29
0
/**
 * Saves the context of a 'conditional' PCI device.
 *
 * This traverses the provided register list saving PCI registers when appropriate.
 *
 * @param[in]     StdHeader      AMD standard header config param.
 * @param[in]     Device         'conditional' PCI 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
SaveConditionalPciDevice (
  IN       AMD_CONFIG_PARAMS                 *StdHeader,
  IN       CONDITIONAL_PCI_DEVICE_DESCRIPTOR *Device,
  IN       CALL_POINTS                       CallPoint,
  IN OUT   VOID                              **OrMask
  )
{
  UINT8   RegSizeInBytes;
  UINT8   SpecialCaseIndex;
  UINT8   *IntermediatePtr;
  UINT16  i;
  UINT32  Socket;
  UINT32  Module;
  UINT32  AndMask;
  ACCESS_WIDTH AccessWidth;
  AGESA_STATUS IgnoredSts;
  PCI_ADDR PciAddress;
  CPCI_REGISTER_BLOCK_HEADER *RegisterHdr;

  GetSocketModuleOfNode ((UINT32) Device->Node,
                               &Socket,
                               &Module,
                               StdHeader);
  GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts);

  if (CallPoint == INIT_RESUME) {
    MemFS3GetCPciDeviceRegisterList (Device, &RegisterHdr, StdHeader);
  } else {
    S3GetCPciDeviceRegisterList (Device, &RegisterHdr, StdHeader);
  }

  for (i = 0; i < RegisterHdr->NumRegisters; i++) {
    if (((Device->Mask1 & RegisterHdr->RegisterList[i].Mask1) != 0) &&
        ((Device->Mask2 & RegisterHdr->RegisterList[i].Mask2) != 0)) {
      PciAddress.Address.Function = RegisterHdr->RegisterList[i].Function;
      PciAddress.Address.Register = RegisterHdr->RegisterList[i].Offset;
      RegSizeInBytes = RegisterHdr->RegisterList[i].Type.RegisterSize;
      switch (RegSizeInBytes) {
      case 1:
        AndMask = 0xFFFFFFFF & ((UINT8) RegisterHdr->RegisterList[i].AndMask);
        AccessWidth = AccessS3SaveWidth8;
        break;
      case 2:
        AndMask = 0xFFFFFFFF & ((UINT16) RegisterHdr->RegisterList[i].AndMask);
        AccessWidth = AccessS3SaveWidth16;
        break;
      case 3:
        // In this case, we don't need to save a register. We just need to call a special
        // function to do certain things in the save and resume sequence.
        // This should not be used in a non-special case.
        AndMask = 0;
        RegSizeInBytes = 0;
        AccessWidth = 0;
        break;
      default:
        AndMask = RegisterHdr->RegisterList[i].AndMask;
        RegSizeInBytes = 4;
        AccessWidth = AccessS3SaveWidth32;
        break;
      }
      if (RegisterHdr->RegisterList[i].Type.SpecialCaseFlag == 0) {
        ASSERT ((AndMask != 0) && (RegSizeInBytes != 0) && (AccessWidth != 0));
        LibAmdPciRead (AccessWidth, PciAddress, *OrMask, StdHeader);
      } else {
        SpecialCaseIndex = RegisterHdr->RegisterList[i].Type.SpecialCaseIndex;
        RegisterHdr->SpecialCases[SpecialCaseIndex].Save (AccessWidth, PciAddress, *OrMask, StdHeader);
      }
      if (AndMask != 0) {
        // If AndMask is 0, then it is a not-care. Don't need to apply it to the OrMask
        **((UINT32 **) OrMask) &= AndMask;
      }
      if ((RegSizeInBytes == 0) && (**((UINT32 **) OrMask) == RESTART_FROM_BEGINNING_LIST)) {
        // Restart from the beginning of the register list
        i = 0xFFFF;
      }
      IntermediatePtr = (UINT8 *) *OrMask;
      *OrMask = &IntermediatePtr[RegSizeInBytes]; // += RegSizeInBytes;
    }
  }
}
Esempio n. 30
0
File: S3.c Progetto: Godkey/coreboot
/**
 * Restores the context of a PCI device.
 *
 * This traverses the provided register list restoring PCI registers.
 *
 * @param[in]     StdHeader      AMD standard header config param.
 * @param[in]     Device         'conditional' PCI 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
RestorePciDevice (
  IN       AMD_CONFIG_PARAMS     *StdHeader,
  IN       PCI_DEVICE_DESCRIPTOR *Device,
  IN       CALL_POINTS           CallPoint,
  IN OUT   VOID                  **OrMask
  )
{
  UINT8   RegSizeInBytes;
  UINT8   SpecialCaseIndex;
  UINT8   *IntermediatePtr;
  UINT16  i;
  UINT32  Socket;
  UINT32  Module;
  UINT32  AndMask;
  UINT32  RegValueRead;
  UINT32  RegValueWrite;
  ACCESS_WIDTH AccessWidth;
  AGESA_STATUS IgnoredSts;
  PCI_ADDR PciAddress;
  PCI_REGISTER_BLOCK_HEADER *RegisterHdr;

  GetSocketModuleOfNode ((UINT32) Device->Node,
                               &Socket,
                               &Module,
                               StdHeader);
  GetPciAddress (StdHeader, Socket, Module, &PciAddress, &IgnoredSts);

  if (CallPoint == INIT_RESUME) {
    MemFS3GetPciDeviceRegisterList (Device, &RegisterHdr, StdHeader);
  } else {
    S3GetPciDeviceRegisterList (Device, &RegisterHdr, StdHeader);
  }

  for (i = 0; i < RegisterHdr->NumRegisters; i++) {
    PciAddress.Address.Function = RegisterHdr->RegisterList[i].Function;
    PciAddress.Address.Register = RegisterHdr->RegisterList[i].Offset;
    RegSizeInBytes = RegisterHdr->RegisterList[i].Type.RegisterSize;
    switch (RegSizeInBytes) {
    case 1:
      AndMask = 0xFFFFFFFF & ((UINT8) RegisterHdr->RegisterList[i].AndMask);
      RegValueWrite = **(UINT8 **)OrMask;
      AccessWidth = AccessS3SaveWidth8;
      break;
    case 2:
      AndMask = 0xFFFFFFFF & ((UINT16) RegisterHdr->RegisterList[i].AndMask);
      RegValueWrite = **(UINT16 **)OrMask;
      AccessWidth = AccessS3SaveWidth16;
      break;
    case 3:
      // In this case, we don't need to restore a register. We just need to call a special
      // function to do certain things in the save and resume sequence.
      // This should not be used in a non-special case.
      AndMask = 0;
      RegValueWrite = 0;
      RegSizeInBytes = 0;
      AccessWidth = 0;
      break;
    default:
      AndMask = RegisterHdr->RegisterList[i].AndMask;
      RegSizeInBytes = 4;
      RegValueWrite = **(UINT32 **)OrMask;
      AccessWidth = AccessS3SaveWidth32;
      break;
    }
    if (RegisterHdr->RegisterList[i].Type.SpecialCaseFlag == 0) {
      ASSERT ((AndMask != 0) && (RegSizeInBytes != 0) && (AccessWidth != 0));
      LibAmdPciRead (AccessWidth, PciAddress, &RegValueRead, StdHeader);
      RegValueWrite |= RegValueRead & (~AndMask);
      LibAmdPciWrite (AccessWidth, PciAddress, &RegValueWrite, StdHeader);
    } else {
      SpecialCaseIndex = RegisterHdr->RegisterList[i].Type.SpecialCaseIndex;
      if (AndMask != 0) {
        RegisterHdr->SpecialCases[SpecialCaseIndex].Save (AccessWidth,
                                             PciAddress,
                                             &RegValueRead,
                                             StdHeader);
        RegValueWrite |= RegValueRead & (~AndMask);
      }
      RegisterHdr->SpecialCases[SpecialCaseIndex].Restore (AccessWidth,
                                             PciAddress,
                                             &RegValueWrite,
                                             StdHeader);
    }
    IntermediatePtr = (UINT8 *) *OrMask;
    *OrMask = &IntermediatePtr[RegSizeInBytes]; // += RegSizeInBytes;
  }
}