/* $NoKeywords:$ */
/**
 * @file
 *
 * AMD CPU Core Leveling Function.
 *
 * Contains code to Level the number of core in a multi-socket system
 *
 * @xrefitem bom "File Content Label" "Release Content"
 * @e project:      AGESA
 * @e sub-project:  CPU
 * @e \$Revision: 35136 $   @e \$Date: 2010-07-16 11:29:48 +0800 (Fri, 16 Jul 2010) $
 *
 */
/*
 *****************************************************************************
 *
 * Copyright (c) 2011, Advanced Micro Devices, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Advanced Micro Devices, Inc. nor the names of
 *       its contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * ***************************************************************************
 *
 */


/*
 *----------------------------------------------------------------------------
 *                                MODULES USED
 *
 *----------------------------------------------------------------------------
 */
#include "AGESA.h"
#include "AMD.h"
#include "amdlib.h"
#include "Topology.h"
#include "cpuRegisters.h"
#include "GeneralServices.h"
#include "cpuServices.h"
#include "cpuFamilyTranslation.h"
#include "cpuFeatures.h"
#include "cpuEarlyInit.h"
#include "heapManager.h"
#include "Filecode.h"
CODE_GROUP (G1_PEICC)
RDATA_GROUP (G1_PEICC)
#define FILECODE PROC_CPU_FEATURE_CPUCORELEVELING_FILECODE
/*----------------------------------------------------------------------------
 *                          DEFINITIONS AND MACROS
 *
 *----------------------------------------------------------------------------
 */


/*----------------------------------------------------------------------------
 *                           TYPEDEFS AND STRUCTURES
 *
 *----------------------------------------------------------------------------
 */

/*----------------------------------------------------------------------------------------
 *                          E X P O R T E D    F U N C T I O N S
 *----------------------------------------------------------------------------------------
 */
extern CPU_FAMILY_SUPPORT_TABLE CoreLevelingFamilyServiceTable;

/*----------------------------------------------------------------------------
 *                        PROTOTYPES OF LOCAL FUNCTIONS
 *
 *----------------------------------------------------------------------------
 */

/*----------------------------------------------------------------------------------------
 *                          P U B L I C     F U N C T I O N S
 *----------------------------------------------------------------------------------------
 */

/*---------------------------------------------------------------------------------------*/
/**
 *  Should core leveling be enabled
 *
 * @param[in]    PlatformConfig     Contains the runtime modifiable feature input data.
 * @param[in]    StdHeader          Config Handle for library, services.
 *
 * @retval       TRUE               core leveling is supported.
 * @retval       FALSE              core leveling cannot be enabled.
 *
 */
BOOLEAN
STATIC
IsCoreLevelingEnabled (
  IN       PLATFORM_CONFIGURATION *PlatformConfig,
  IN       AMD_CONFIG_PARAMS      *StdHeader
  )
{
  CORE_LEVELING_TYPE  CoreLevelMode;

  CoreLevelMode = (CORE_LEVELING_TYPE) PlatformConfig->CoreLevelingMode;
  if (CoreLevelMode != CORE_LEVEL_NONE) {
    return (TRUE);
  } else {
    return (FALSE);
  }
}

/*---------------------------------------------------------------------------------------*/
/**
 * 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, (const VOID **)&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);
}


CONST CPU_FEATURE_DESCRIPTOR ROMDATA CpuFeatureCoreLeveling =
{
  CoreLeveling,
  (CPU_FEAT_AFTER_PM_INIT),
  IsCoreLevelingEnabled,
  CoreLevelingAtEarly
};

/*----------------------------------------------------------------------------------------
 *                          L O C A L      F U N C T I O N S
 *----------------------------------------------------------------------------------------
 */

