Exemple #1
0
/**
 *  Check to see if the input CPU supports HT Assist.
 *
 * @param[in]    L3FeatureServices   L3 Feature family services.
 * @param[in]    PlatformConfig      Contains the runtime modifiable feature input data.
 * @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       L3_FEATURE_FAMILY_SERVICES *L3FeatureServices,
  IN       PLATFORM_CONFIGURATION *PlatformConfig,
  IN       AMD_CONFIG_PARAMS *StdHeader
  )
{
  BOOLEAN          IsSupported;
  UINT32           CpuCount;
  AP_MAILBOXES     ApMailboxes;

  IsSupported = FALSE;

  if (PlatformConfig->PlatformProfile.UseHtAssist) {
    CpuCount = GetNumberOfProcessors (StdHeader);
    ASSERT (CpuCount != 0);

    if (CpuCount == 1) {
      GetApMailbox (&ApMailboxes.ApMailInfo.Info, StdHeader);
      if (ApMailboxes.ApMailInfo.Fields.ModuleType != 0) {
        IsSupported = TRUE;
      }
    } else if (CpuCount > 1) {
      IsSupported = TRUE;
    }
  }
  return IsSupported;
}
Exemple #2
0
/**
 *  Should software C1e be enabled
 *
 * @param[in]    PlatformConfig     Contains the runtime modifiable feature input data.
 * @param[in]    StdHeader          Config Handle for library, services.
 *
 * @retval       TRUE               SW C1e is supported.
 * @retval       FALSE              SW C1e not supported.
 *
 */
BOOLEAN
STATIC
IsSwC1eFeatureEnabled (
  IN       PLATFORM_CONFIGURATION *PlatformConfig,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  BOOLEAN                IsEnabled;
  AP_MAILBOXES           ApMailboxes;
  SW_C1E_FAMILY_SERVICES *SwFamilyServices;

  ASSERT (PlatformConfig->C1eMode < MaxC1eMode);
  IsEnabled = FALSE;
  // Check whether software C1e is enabled only if hardware C1e is not supported or if the platform specifically
  // uses C1eModeSoftwareDeprecated.
  if ((PlatformConfig->C1eMode == C1eModeSoftwareDeprecated) ||
     ((PlatformConfig->C1eMode == C1eModeHardwareSoftwareDeprecated) && (!IsFeatureEnabled (HardwareC1e, PlatformConfig, StdHeader)))) {
    ASSERT ((PlatformConfig->C1ePlatformData1 < 0x10000) && (PlatformConfig->C1ePlatformData1 != 0));
    ASSERT (PlatformConfig->C1ePlatformData2 < 0x100);
    if ((PlatformConfig->C1ePlatformData1 != 0) && (PlatformConfig->C1ePlatformData1 < 0xFFFE) && (PlatformConfig->C1ePlatformData2 < 0xFF)) {
      if (!IsNonCoherentHt1 (StdHeader)) {
        if (GetNumberOfProcessors (StdHeader) == 1) {
          GetApMailbox (&ApMailboxes.ApMailInfo.Info, StdHeader);
          if (ApMailboxes.ApMailInfo.Fields.ModuleType == 0) {
            GetFeatureServicesOfCurrentCore (&SwC1eFamilyServiceTable, &SwFamilyServices, StdHeader);
            if (SwFamilyServices != NULL) {
              IsEnabled = SwFamilyServices->IsSwC1eSupported (SwFamilyServices, StdHeader);
            }
          }
        }
      }
    }
  }
  return IsEnabled;
}
Exemple #3
0
/**
 *  Should hardware C1e be enabled
 *
 * @param[in]    PlatformConfig     Contains the runtime modifiable feature input data.
 * @param[in]    StdHeader          Config Handle for library, services.
 *
 * @retval       TRUE               HW C1e is supported.
 * @retval       FALSE              HW C1e cannot be enabled.
 *
 */
BOOLEAN
STATIC
IsHwC1eFeatureEnabled (
  IN       PLATFORM_CONFIGURATION *PlatformConfig,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  BOOLEAN          IsEnabled;
  AP_MAILBOXES     ApMailboxes;
  HW_C1E_FAMILY_SERVICES *FamilyServices;

  ASSERT (PlatformConfig->C1eMode < MaxC1eMode);
  IsEnabled = FALSE;
  if (PlatformConfig->C1eMode == C1eModeHardware) {
    ASSERT (PlatformConfig->C1ePlatformData < 0x10000);
    ASSERT (PlatformConfig->C1ePlatformData != 0);
    if ((PlatformConfig->C1ePlatformData != 0) && (PlatformConfig->C1ePlatformData < 0xFFFE)) {
      if (GetNumberOfProcessors (StdHeader) == 1) {
        GetApMailbox (&ApMailboxes.ApMailInfo.Info, StdHeader);
        if (ApMailboxes.ApMailInfo.Fields.ModuleType == 0) {
          GetFeatureServicesOfCurrentCore (&HwC1eFamilyServiceTable, (CONST VOID **)&FamilyServices, StdHeader);
          if (FamilyServices != NULL) {
            IsEnabled = FamilyServices->IsHwC1eSupported (FamilyServices, StdHeader);
          }
        }
      }
    }
  }
  return IsEnabled;
}
/**
 * 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);
          }
        }
      }
    }
  }
}
/**
 * Performs core leveling for the system.
 *
 * This function implements the AMD_CPU_EARLY_PARAMS.CoreLevelingMode parameter.
 * The possible modes are:
 *    -0    CORE_LEVEL_LOWEST            Level to lowest common denominator
 *    -1    CORE_LEVEL_TWO               Level to 2 cores
 *    -2    CORE_LEVEL_POWER_OF_TWO      Level to 1,2,4 or 8
 *    -3    CORE_LEVEL_NONE              Do no leveling
 *    -4    CORE_LEVEL_COMPUTE_UNIT      Level cores to one core per compute unit
 *
 * @param[in]  EntryPoint        Timepoint designator.
 * @param[in]  PlatformConfig    Contains the leveling mode parameter
 * @param[in]  StdHeader         Config handle for library and services
 *
 * @return       The most severe status of any family specific service.
 *
 */
AGESA_STATUS
CoreLevelingAtEarly (
  IN       UINT64                 EntryPoint,
  IN       PLATFORM_CONFIGURATION *PlatformConfig,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  UINT32    CoreNumPerComputeUnit;
  UINT32    MinNumOfComputeUnit;
  UINT32    EnabledComputeUnit;
  UINT32    Socket;
  UINT32    Module;
  UINT32    NumberOfSockets;
  UINT32    NumberOfModules;
  UINT32    MinCoreCountOnNode;
  UINT32    MaxCoreCountOnNode;
  UINT32    LowCore;
  UINT32    HighCore;
  UINT32    LeveledCores;
  UINT32    RequestedCores;
  UINT32    TotalEnabledCoresOnNode;
  BOOLEAN   RegUpdated;
  AP_MAIL_INFO ApMailboxInfo;
  CORE_LEVELING_TYPE  CoreLevelMode;
  CPU_CORE_LEVELING_FAMILY_SERVICES  *FamilySpecificServices;
  WARM_RESET_REQUEST Request;

  MaxCoreCountOnNode = 0;
  MinCoreCountOnNode = 0xFFFFFFFF;
  LeveledCores = 0;
  CoreNumPerComputeUnit = 1;
  MinNumOfComputeUnit = 0xFF;

  ASSERT (PlatformConfig->CoreLevelingMode < CoreLevelModeMax);

  // Get OEM IO core level mode
  CoreLevelMode = (CORE_LEVELING_TYPE) PlatformConfig->CoreLevelingMode;

  // Get socket count
  NumberOfSockets = GetPlatformNumberOfSockets ();
  GetApMailbox (&ApMailboxInfo.Info, StdHeader);
  NumberOfModules = ApMailboxInfo.Fields.ModuleType + 1;

  // Collect cpu core info
  for (Socket = 0; Socket < NumberOfSockets; Socket++) {
    if (IsProcessorPresent (Socket, StdHeader)) {
      for (Module = 0; Module < NumberOfModules; Module++) {
        if (GetGivenModuleCoreRange (Socket, Module, &LowCore, &HighCore, StdHeader)) {
          // Get the highest and lowest core count in all nodes
          TotalEnabledCoresOnNode = HighCore - LowCore + 1;
          if (TotalEnabledCoresOnNode < MinCoreCountOnNode) {
            MinCoreCountOnNode = TotalEnabledCoresOnNode;
          }
          if (TotalEnabledCoresOnNode > MaxCoreCountOnNode) {
            MaxCoreCountOnNode = TotalEnabledCoresOnNode;
          }
          EnabledComputeUnit = TotalEnabledCoresOnNode;
          switch (GetComputeUnitMapping (StdHeader)) {
          case AllCoresMapping:
            // All cores are in their own compute unit.
            break;
          case EvenCoresMapping:
            // Cores are paired in compute units.
            CoreNumPerComputeUnit = 2;
            EnabledComputeUnit = (TotalEnabledCoresOnNode / 2);
            break;
          default:
            ASSERT (FALSE);
          }
          // Get minimum of compute unit.  This will either be the minimum number of cores (AllCoresMapping),
          // or less (EvenCoresMapping).
          if (EnabledComputeUnit < MinNumOfComputeUnit) {
            MinNumOfComputeUnit = EnabledComputeUnit;
          }
        }
      }
    }
  }

  // Get LeveledCores
  switch (CoreLevelMode) {
  case CORE_LEVEL_LOWEST:
    if (MinCoreCountOnNode == MaxCoreCountOnNode) {
      return (AGESA_SUCCESS);
    }
    LeveledCores = (MinCoreCountOnNode / CoreNumPerComputeUnit) * CoreNumPerComputeUnit;
    break;
  case CORE_LEVEL_TWO:
    LeveledCores = 2 / NumberOfModules;
    if (LeveledCores != 0) {
      LeveledCores = (LeveledCores <= MinCoreCountOnNode) ? LeveledCores : MinCoreCountOnNode;
    } else {
      return (AGESA_WARNING);
    }
    if ((LeveledCores * NumberOfModules) != 2) {
      PutEventLog (
      AGESA_WARNING,
      CPU_WARNING_ADJUSTED_LEVELING_MODE,
      2, (LeveledCores * NumberOfModules), 0, 0, StdHeader
      );
    }
    break;
  case CORE_LEVEL_POWER_OF_TWO:
    // Level to power of 2 (1, 2, 4, 8...)
    LeveledCores = 1;
    while (MinCoreCountOnNode >= (LeveledCores * 2)) {
      LeveledCores = LeveledCores * 2;
    }
    break;
  case CORE_LEVEL_COMPUTE_UNIT:
    // Level cores to one core per compute unit, with additional reduction to level
    // all processors to match the processor with the minimum number of cores.
    if (CoreNumPerComputeUnit == 1) {
      // If there is one core per compute unit, this is the same as CORE_LEVEL_LOWEST.
      if (MinCoreCountOnNode == MaxCoreCountOnNode) {
        return (AGESA_SUCCESS);
      }
      LeveledCores = MinCoreCountOnNode;
    } else {
      // If there are more than one core per compute unit, level to the number of compute units.
      LeveledCores = MinNumOfComputeUnit;
    }
    break;
  case CORE_LEVEL_ONE:
    LeveledCores = 1;
    if (NumberOfModules > 1) {
      PutEventLog (
      AGESA_WARNING,
      CPU_WARNING_ADJUSTED_LEVELING_MODE,
      1, NumberOfModules, 0, 0, StdHeader
      );
    }
    break;
  case CORE_LEVEL_THREE:
  case CORE_LEVEL_FOUR:
  case CORE_LEVEL_FIVE:
  case CORE_LEVEL_SIX:
  case CORE_LEVEL_SEVEN:
  case CORE_LEVEL_EIGHT:
  case CORE_LEVEL_NINE:
  case CORE_LEVEL_TEN:
  case CORE_LEVEL_ELEVEN:
  case CORE_LEVEL_TWELVE:
  case CORE_LEVEL_THIRTEEN:
  case CORE_LEVEL_FOURTEEN:
  case CORE_LEVEL_FIFTEEN:
    // MCM processors can not have an odd number of cores. For an odd CORE_LEVEL_N, MCM processors will be
    // leveled as though CORE_LEVEL_N+1 was chosen.
    // Processors with compute units disable all cores in an entire compute unit at a time, or on an MCM processor,
    // two compute units at a time. For example, on an SCM processor with two cores per compute unit, the effective
    // explicit levels are CORE_LEVEL_ONE, CORE_LEVEL_TWO, CORE_LEVEL_FOUR, CORE_LEVEL_SIX, and
    // CORE_LEVEL_EIGHT. The same example for an MCM processor with two cores per compute unit has effective
    // explicit levels of CORE_LEVEL_TWO, CORE_LEVEL_FOUR, CORE_LEVEL_EIGHT, and CORE_LEVEL_TWELVE.
    RequestedCores = CoreLevelMode - CORE_LEVEL_THREE + 3;
    LeveledCores = (RequestedCores + NumberOfModules - 1) / NumberOfModules;
    LeveledCores = (LeveledCores / CoreNumPerComputeUnit) * CoreNumPerComputeUnit;
    LeveledCores = (LeveledCores <= MinCoreCountOnNode) ? LeveledCores : MinCoreCountOnNode;
    if (LeveledCores != 1) {
      LeveledCores = (LeveledCores / CoreNumPerComputeUnit) * CoreNumPerComputeUnit;
    }
    if ((LeveledCores * NumberOfModules * CoreNumPerComputeUnit) != RequestedCores) {
      PutEventLog (
      AGESA_WARNING,
      CPU_WARNING_ADJUSTED_LEVELING_MODE,
      RequestedCores, (LeveledCores * NumberOfModules * CoreNumPerComputeUnit), 0, 0, StdHeader
      );
    }
    break;
  default:
    ASSERT (FALSE);
  }

  // Set down core register
  for (Socket = 0; Socket < NumberOfSockets; Socket++) {
    if (IsProcessorPresent (Socket, StdHeader)) {
      GetFeatureServicesOfSocket (&CoreLevelingFamilyServiceTable, Socket, &FamilySpecificServices, StdHeader);
      if (FamilySpecificServices != NULL) {
        for (Module = 0; Module < NumberOfModules; Module++) {
          RegUpdated = FamilySpecificServices->SetDownCoreRegister (FamilySpecificServices, &Socket, &Module, &LeveledCores, CoreLevelMode, StdHeader);
          // If the down core register is updated, trigger a warm reset.
          if (RegUpdated) {
            GetWarmResetFlag (StdHeader, &Request);
            Request.RequestBit = TRUE;
            Request.StateBits = Request.PostStage - 1;
            SetWarmResetFlag (StdHeader, &Request);
          }
        }
      }
    }
  }

  return (AGESA_SUCCESS);
}
Exemple #6
0
/**
 * The top level external interface for Hypertransport Initialization.
 *
 * Create our initial internal state, initialize the coherent fabric,
 * initialize the non-coherent chains, and perform any required fabric tuning or
 * optimization.
 *
 * @param[in]   StdHeader              Opaque handle to standard config header
 * @param[in]   PlatformConfiguration  The platform configuration options.
 * @param[in]   AmdHtInterface         HT Interface structure.
 *
 * @retval      AGESA_SUCCESS     Only information events logged.
 * @retval      AGESA_ALERT       Sync Flood or CRC error logged.
 * @retval      AGESA_WARNING     Example: expected capability not found
 * @retval      AGESA_ERROR       logged events indicating some devices may not be available
 * @retval      AGESA_FATAL       Mixed Family or MP capability mismatch
 *
 */
AGESA_STATUS
AmdHtInitialize (
  IN       AMD_CONFIG_PARAMS      *StdHeader,
  IN       PLATFORM_CONFIGURATION *PlatformConfiguration,
  IN       AMD_HT_INTERFACE       *AmdHtInterface
  )
{
  STATE_DATA State;
  NORTHBRIDGE Nb;
  HT_FEATURES HtFeatures;
  HT_INTERFACE HtInterface;
  AGESA_STATUS DeallocateStatus;
  AP_MAIL_INFO ApMailboxInfo;
  UINT8 ApNode;

  ALLOCATE_HEAP_PARAMS AllocHeapParams;

  State.HtBlock = AmdHtInterface;
  State.ConfigHandle = StdHeader;
  State.PlatformConfiguration = PlatformConfiguration;

  // Get the current HT internal interface (to HtBlock data)
  NewHtInterface (&HtInterface, State.ConfigHandle);
  State.HtInterface = &HtInterface;

  // Get the current HT Feature Set
  NewHtFeatures (&HtFeatures, State.ConfigHandle);
  State.HtFeatures = &HtFeatures;

  // Initialize from static options
  State.IsUsingRecoveryHt = OptionHtConfiguration.IsUsingRecoveryHt;
  State.IsSetHtCrcFlood = OptionHtConfiguration.IsSetHtCrcFlood;
  State.IsUsingUnitIdClumping = OptionHtConfiguration.IsUsingUnitIdClumping;

  // Initialize for status and event output
  State.MaxEventClass = AGESA_SUCCESS;

  // Allocate permanent heap structs that are interfaces to other AGESA services.
  State.HtInterface->NewNodeAndSocketTables (&State);

  if (IsBootCore (&State)) {
    AGESA_TESTPOINT (TpProcHtEntry, State.ConfigHandle);
    // Allocate Bsp only interface heap structs.
    State.HtInterface->NewHopCountTable (&State);
    // Allocate heap for our temporary working space.
    AllocHeapParams.RequestedBufferSize = (sizeof (PORT_DESCRIPTOR) * (MAX_PLATFORM_LINKS * 2));
    AllocHeapParams.BufferHandle = HT_STATE_DATA_HANDLE;
    AllocHeapParams.Persist = HEAP_LOCAL_CACHE;
    if (HeapAllocateBuffer (&AllocHeapParams, State.ConfigHandle) == AGESA_SUCCESS) {
      State.PortList = (PORT_LIST)AllocHeapParams.BufferPtr;
      // Create the BSP's northbridge.
      NewNorthBridge (0, &State, &Nb);
      State.Nb = &Nb;

      CoherentInit (&State);
      NcInit (&State);
      LinkOptimization (&State);
      Tuning (&State);

      DeallocateStatus = HeapDeallocateBuffer (HT_STATE_DATA_HANDLE, State.ConfigHandle);
      ASSERT (DeallocateStatus == AGESA_SUCCESS);
      AGESA_TESTPOINT (TpProcHtDone, State.ConfigHandle);
    } else {
      ASSERT (FALSE);
      State.MaxEventClass = AGESA_ERROR;
      // Cannot Log entry due to heap allocate failed.
    }
  } else {
    // Do the AP HT Init, which produces Node and Socket Maps for the AP's use.
    AGESA_TESTPOINT (TpProcHtApMapEntry, State.ConfigHandle);
    GetApMailbox (&ApMailboxInfo.Info, State.ConfigHandle);
    ASSERT (ApMailboxInfo.Fields.Node < MAX_NODES);
    ApNode = (UINT8)ApMailboxInfo.Fields.Node;
    NewNorthBridge (ApNode, &State, &Nb);
    State.Nb = &Nb;
    InitApMaps (&State);
    AGESA_TESTPOINT (TpProcHtApMapDone, State.ConfigHandle);
  }
  return State.MaxEventClass;
}
Exemple #7
0
/**
 *  Enable L3 dependent features.
 *
 * L3 features initialization requires the following series of steps.
 *  1. Disable L3 and DRAM scrubbers on all nodes
 *  2. Wait 40us for outstanding scrub results to complete
 *  3. Disable all cache activity in the system
 *  4. Issue WBINVD on all active cores
 *  5. Initialize Probe Filter, if supported
 *  6. Initialize ATM Mode, if supported
 *  7. Enable all cache activity in the system
 *  8. Restore L3 and DRAM scrubber register values
 *
 * @param[in]    EntryPoint         Timepoint designator.
 * @param[in]    PlatformConfig     Contains the runtime modifiable feature input data.
 * @param[in]    StdHeader          Config Handle for library, services.
 *
 * @retval       AGESA_SUCCESS      Always succeeds.
 *
 */
AGESA_STATUS
STATIC
InitializeL3Feature (
  IN       UINT64                 EntryPoint,
  IN       PLATFORM_CONFIGURATION *PlatformConfig,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  UINT32                      CpuCount;
  UINT32                      Socket;
  BOOLEAN                     HtAssistEnabled;
  BOOLEAN                     AtmModeEnabled;
  AGESA_STATUS                AgesaStatus;
  AP_MAILBOXES                ApMailboxes;
  AP_EXE_PARAMS               ApParams;
  UINT32                      Scrubbers[MAX_SOCKETS_SUPPORTED][L3_SCRUBBER_CONTEXT_ARRAY_SIZE];
  L3_FEATURE_FAMILY_SERVICES  *FamilyServices[MAX_SOCKETS_SUPPORTED];

  AgesaStatus     = AGESA_SUCCESS;
  HtAssistEnabled = TRUE;
  AtmModeEnabled  = TRUE;

  IDS_HDT_CONSOLE (CPU_TRACE, "    Enabling L3 dependent features\n");

  // There are many family service call outs.  Initialize the family service array while
  // cache is still enabled.
  for (Socket = 0; Socket < MAX_SOCKETS_SUPPORTED; Socket++) {
    if (IsProcessorPresent (Socket, StdHeader)) {
      GetFeatureServicesOfSocket (&L3FeatureFamilyServiceTable, Socket, (const VOID **) &FamilyServices[Socket], StdHeader);
    } else {
      FamilyServices[Socket] = NULL;
    }
  }

  if (EntryPoint == CPU_FEAT_AFTER_POST_MTRR_SYNC) {
    // Check for optimal settings
    GetApMailbox (&ApMailboxes.ApMailInfo.Info, StdHeader);
    CpuCount = GetNumberOfProcessors (StdHeader);
    if (((CpuCount == 1) && (ApMailboxes.ApMailInfo.Fields.ModuleType == 1)) ||
        ((CpuCount == 2) && (ApMailboxes.ApMailInfo.Fields.ModuleType == 0))) {
      for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) {
        // Only check for non-optimal HT Assist setting is if's supported.
        if ((FamilyServices[Socket] != NULL) &&
            (FamilyServices[Socket]->IsHtAssistSupported (FamilyServices[Socket], PlatformConfig, StdHeader))) {
          if (FamilyServices[Socket]->IsNonOptimalConfig (FamilyServices[Socket], Socket, StdHeader)) {
            // Non-optimal settings.  Log an event.
            AgesaStatus = AGESA_WARNING;
            PutEventLog (AgesaStatus, CPU_WARNING_NONOPTIMAL_HT_ASSIST_CFG, 0, 0, 0, 0, StdHeader);
            break;
          }
        }
      }
    }
  } else {
    // Disable the scrubbers.
    for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) {
      if (FamilyServices[Socket] != NULL) {
        FamilyServices[Socket]->GetL3ScrubCtrl (FamilyServices[Socket], Socket, &Scrubbers[Socket][0], StdHeader);

        // If any node in the system does not support Probe Filter, disable it on the system
        if (!FamilyServices[Socket]->IsHtAssistSupported (FamilyServices[Socket], PlatformConfig, StdHeader)) {
          HtAssistEnabled = FALSE;
        }
        // If any node in the system does not support ATM mode, disable it on the system
        if (!FamilyServices[Socket]->IsAtmModeSupported (FamilyServices[Socket], PlatformConfig, StdHeader)) {
          AtmModeEnabled = FALSE;
        }
      }
    }

    // Wait for 40us
    WaitMicroseconds ((UINT32) 40, StdHeader);

    // Run DisableAllCaches on AP cores.
    ApParams.StdHeader = *StdHeader;
    ApParams.FunctionNumber = AP_LATE_TASK_DISABLE_CACHE;
    ApParams.RelatedDataBlock = (VOID *) &HtAssistEnabled;
    ApParams.RelatedBlockLength = sizeof (BOOLEAN);
    RunLateApTaskOnAllAPs (&ApParams, StdHeader);

    // Run DisableAllCaches on core 0.
    DisableAllCaches (&ApParams);

    // Family hook before initialization.
    for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) {
      if (FamilyServices[Socket] != NULL) {
        FamilyServices[Socket]->HookBeforeInit (FamilyServices[Socket], Socket, StdHeader);
      }
    }

    // Activate Probe Filter & ATM mode.
    for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) {
      if (FamilyServices[Socket] != NULL) {
        if (HtAssistEnabled) {
          FamilyServices[Socket]->HtAssistInit (FamilyServices[Socket], Socket, StdHeader);
        }
        if (AtmModeEnabled) {
          FamilyServices[Socket]->AtmModeInit (FamilyServices[Socket], Socket, StdHeader);
        }
      }
    }

    // Family hook after initialization.
    for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) {
      if (FamilyServices[Socket] != NULL) {
        FamilyServices[Socket]->HookAfterInit (FamilyServices[Socket], Socket, StdHeader);
      }
    }

    // Run EnableAllCaches on core 0.
    EnableAllCaches (&ApParams);

    // Run EnableAllCaches on every core.
    ApParams.FunctionNumber = AP_LATE_TASK_ENABLE_CACHE;
    RunLateApTaskOnAllAPs (&ApParams, StdHeader);

    // Restore the scrubbers.
    for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) {
      if (FamilyServices[Socket] != NULL) {
        FamilyServices[Socket]->SetL3ScrubCtrl (FamilyServices[Socket], Socket, &Scrubbers[Socket][0], StdHeader);
      }
    }
  }

  return AgesaStatus;
}