/**
 * @file
 *
 * HyperTransport features and sequence implementation.
 *
 * Implements the external AmdHtInitialize entry point.
 * Contains routines for directing the sequence of available features.
 * Mostly, but not exclusively, AGESA_TESTPOINT invocations should be
 * contained in this file, and not in the feature code.
 *
 * From a build option perspective, it may be that a few lines could be removed
 * from compilation in this file for certain options.  It is considered that
 * the code savings from this are too small to be of concern and this file
 * should not have any explicit build option implementation.
 *
 * @xrefitem bom "File Content Label" "Release Content"
 * @e project:      AGESA
 * @e sub-project:  HyperTransport
 * @e \$Revision: 44323 $   @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 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 "AdvancedApi.h"
#include "amdlib.h"
#include "Ids.h"
#include "Topology.h"
#include "htFeat.h"
#include "htInterface.h"
#include "htNb.h"
#include "heapManager.h"
#include "cpuServices.h"
#include "OptionsHt.h"
#include "Filecode.h"
#define FILECODE PROC_HT_HTMAIN_FILECODE
#define APIC_Base_BSP    8
#define APIC_Base        0x1b

extern OPTION_HT_CONFIGURATION OptionHtConfiguration;

/*----------------------------------------------------------------------------------------*/
/**
 * Update maps with the core range for each module.
 *
 * Cores are numbered relative to a Processor, but sometimes there is a need to know the
 * starting and ending core ids on a particular node.  This same info is also useful for
 * supporting the Core count on a node other than the one currently executing.
 *
 * For each Processor, get the core count of each node using the family specific PCI core count
 * interface. The order of cores in a processor, and whether it is special for the BSP is family
 * specific.  But whether the processor orders core ids by module or node, iterate in the right
 * order and use the counts to determine each start and end range.
 *
 * @param[in]   State    number of Nodes discovered.
*/
VOID
STATIC
UpdateCoreRanges (
  IN       STATE_DATA    *State
    )
{
  UINT8 Node;
  UINT8 ProcessorCores;
  UINT8 ModuleCoreCount[MAX_DIES];
  UINT8 Socket;
  UINT8 Module;

  ASSERT (State->SocketDieToNodeMap != NULL);
  ASSERT (State->NodeToSocketDieMap != NULL);

  for (Socket = 0; Socket < MAX_SOCKETS; Socket++) {
    // Is a Processor present in Socket?
    if ((*State->SocketDieToNodeMap)[Socket][0].Node != HT_LIST_TERMINAL) {
      // Get all the Module core counts for this processor
      // Note that the core counts are 1 based counts.
      for (Module = 0; Module < MAX_DIES; Module++) {
        if ((*State->SocketDieToNodeMap)[Socket][Module].Node != HT_LIST_TERMINAL) {
          ModuleCoreCount[Module] = State->Nb->GetNumCoresOnNode ((*State->SocketDieToNodeMap)[Socket][Module].Node, State->Nb);
        } else {
          ModuleCoreCount[Module] = 0;
        }
      }
      // Determine the core ordering rule for this processor.
      if ((((*State->NodeToSocketDieMap)[0].Socket == Socket) && State->Nb->IsOrderBSPCoresByNode) ||
          (!State->Nb->IsOrderCoresByModule)) {
        // Order core ranges on this processor by Node Id.
        ProcessorCores = 0;
        for (Node = 0; Node < State->Nb->GetNodeCount (State->Nb); Node++) {
          // Is this node a module in this processor?
          if ((*State->NodeToSocketDieMap)[Node].Socket == Socket) {
            Module = (*State->NodeToSocketDieMap)[Node].Die;
            if (ModuleCoreCount[Module] != 0) {
              (*State->SocketDieToNodeMap)[Socket][Module].LowCore = ProcessorCores;
              (*State->SocketDieToNodeMap)[Socket][Module].HighCore = ProcessorCores + (ModuleCoreCount[Module] - 1);
              ProcessorCores = ProcessorCores + ModuleCoreCount[Module];
            }
          }
        }
      } else {
        // Order core ranges in this processor by Module Id.
        ProcessorCores = 0;
        for (Module = 0; Module < MAX_DIES; Module++) {
          if (ModuleCoreCount[Module] != 0) {
            (*State->SocketDieToNodeMap)[Socket][Module].LowCore = ProcessorCores;
            (*State->SocketDieToNodeMap)[Socket][Module].HighCore = ProcessorCores + (ModuleCoreCount[Module] - 1);
            ProcessorCores = ProcessorCores + ModuleCoreCount[Module];
          }
        }
      }
    }
  }
}

/*----------------------------------------------------------------------------------------*/
/**
 * Complete the coherent init with any system level initialization.
 *
 * Find the total number of cores and update the number of Nodes and cores in all cpus.
 * Limit cpu config access to installed cpus.
 *
 * @param[in]   State    number of Nodes discovered.
*/
VOID
STATIC
FinalizeCoherentInit (
  IN       STATE_DATA    *State
    )
{
  UINT8 Node;
  UINT8 TotalCores;

  TotalCores = 0;

  for (Node = 0; Node < (State->NodesDiscovered + 1); Node++) {
    TotalCores = TotalCores + State->Nb->GetNumCoresOnNode (Node, State->Nb);
  }

  for (Node = 0; Node < (State->NodesDiscovered + 1); Node++) {
    State->Nb->SetTotalNodesAndCores (Node, State->NodesDiscovered + 1, TotalCores, State->Nb);
  }

  // Set all nodes to limit config space based on node count, after all nodes have a valid count.
  // (just being cautious, probably we could combine the loops.)
  for (Node = 0; Node < (State->NodesDiscovered + 1); Node++) {
    State->Nb->LimitNodes (Node, State->Nb);
  }
}

/*----------------------------------------------------------------------------------------*/
/**
 * Initialize the coherent fabric.
 *
 * Perform discovery and initialization of the coherent fabric, for builds including
 * support for multiple coherent nodes.
 *
 * @param[in]   State   global state
 */
VOID
STATIC
CoherentInit (
  IN OUT   STATE_DATA    *State
  )
{
  UINT8 i;
  UINT8 j;
  UINT8 ModuleType;
  UINT8 Module;
  UINT8 HardwareSocket;
  COHERENT_FABRIC Fabric;

  // Because Node 0, the BSP, is not discovered, initialize info about it specially here.
  // Allocate Socket Die Map.
  // While the BSP is always capable of being the only processor in the system, call the
  // IsExceededCapable method to make sure the BSP's capability is included in the aggregate system
  // capability. We don't care to check the return value.
  //
  State->Fabric = &Fabric;
  State->NodesDiscovered = 0;
  State->TotalLinks = 0;
  State->SysMpCap = MAX_NODES;
  State->Nb->IsExceededCapable (0, State, State->Nb);
  HardwareSocket = State->Nb->GetSocket (0, 0, State->Nb);
  ModuleType = 0;
  Module = 0;
  State->Nb->GetModuleInfo (0, &ModuleType, &Module, State->Nb);
  // No predecessor info for BSP, so pass 0xFF for those parameters.
  State->HtInterface->SetNodeToSocketMap (0xFF, 0xFF, 0xFF, 0, HardwareSocket, Module, State);

  // Initialize system state data structures
  for (i = 0; i < MAX_NODES; i++) {
    State->Fabric->SysDegree[i] = 0;
    for (j = 0; j < MAX_NODES; j++) {
      State->Fabric->SysMatrix[i][j] = 0;
    }
  }

  //
  // Call the coherent init features
  //

  // Discovery
  State->HtFeatures->CoherentDiscovery (State);
  State->HtInterface->PostMapToAp (State);
  // Topology matching and Routing
  AGESA_TESTPOINT (TpProcHtTopology, State->ConfigHandle);
  State->HtFeatures->LookupComputeAndLoadRoutingTables (State);
  State->HtFeatures->MakeHopCountTable (State);

  // UpdateCoreRanges requires the other maps to be initialized, and the node count set.
  FinalizeCoherentInit (State);
  UpdateCoreRanges (State);
  State->Fabric = NULL;
}

/***************************************************************************
 ***                       Non-coherent init code                        ***
 ***                             Algorithms                              ***
 ***************************************************************************/
/*----------------------------------------------------------------------------------------*/
/**
 * Initialize the non-coherent fabric.
 *
 * Begin with the Compat Link on the BSP, then find and initialize all other
 * non-coherent chains.
 *
 * @param[in]   State    our global state
 */
VOID
STATIC
NcInit (
  IN       STATE_DATA    *State
  )
{
  UINT8 Node;
  UINT8 Link;
  UINT8 CompatLink;
  FINAL_LINK_STATE FinalLinkState;

  // Initialize the southbridge chain.
  State->AutoBusCurrent = State->HtBlock->AutoBusStart;
  State->UsedCfgMapEntries = 0;
  CompatLink = State->Nb->ReadSouthbridgeLink (State->Nb);
  State->HtFeatures->ProcessLink (0, CompatLink, TRUE, State);

  // Find and initialize all other non-coherent chains.
  for (Node = 0; Node <= State->NodesDiscovered; Node++) {
    for (Link = 0; Link < State->Nb->MaxLinks; Link++) {
      // Skip the Link, if any of these tests indicate
      FinalLinkState = State->HtInterface->GetIgnoreLink (Node, Link, State->Nb->DefaultIgnoreLinkList, State);
      if (FinalLinkState == UNMATCHED) {
        if ( !((Node == 0) && (Link == CompatLink))) {
          if ( !(State->Nb->ReadTrueLinkFailStatus (Node, Link, State, State->Nb))) {
            if (State->Nb->VerifyLinkIsNonCoherent (Node, Link, State->Nb)) {
              State->HtFeatures->ProcessLink (Node, Link, FALSE, State);
            }
          }
        }
      }
    }
  }
}

/***************************************************************************
 ***                            Link Optimization                        ***
 ***************************************************************************/

/*----------------------------------------------------------------------------------------*/
/**
 * Optimize Link Features.
 *
 * Based on Link capabilities, apply optimization rules to come up with the best
 * settings, including several external limit decision from the interface. This includes
 * handling of subLinks.  Finally, after the port list data is updated, set the hardware
 * state for all Links.
 *
 * @param[in] State our global state
 */
VOID
STATIC
LinkOptimization (
  IN       STATE_DATA *State
  )
{
  AGESA_TESTPOINT (TpProcHtOptGather, State->ConfigHandle);
  State->HtFeatures->GatherLinkData (State);

  AGESA_TESTPOINT (TpProcHtOptRegang, State->ConfigHandle);
  State->HtFeatures->RegangLinks (State);

  AGESA_TESTPOINT (TpProcHtOptLinks, State->ConfigHandle);
  State->HtFeatures->SelectOptimalWidthAndFrequency (State);

  // A likely cause of mixed Retry settings on coherent links is sublink ratio balancing
  // so check this after doing the sublinks.
  AGESA_TESTPOINT (TpProcHtOptSubLinks, State->ConfigHandle);
  State->HtFeatures->SubLinkRatioFixup (State);
  if (State->HtFeatures->IsCoherentRetryFixup (State)) {
    // Fix sublinks again within HT1 only frequencies, as ratios may be invalid again.
    State->HtFeatures->SubLinkRatioFixup (State);
  }

  AGESA_TESTPOINT (TpProcHtOptFinish, State->ConfigHandle);
  State->HtFeatures->SetLinkData (State);
}

/*----------------------------------------------------------------------------------------*/
/**
 * Handle system and performance tunings.
 *
 * Including traffic distribution, fifo and
 * buffer tuning that can't be placed in the register table,
 * and special config tunings.
 *
 * @param[in] State    Total Nodes, port list data
 */
VOID
STATIC
Tuning (
  IN       STATE_DATA *State
  )
{
  UINT8 Node;

  // See if traffic distribution can be done and do it if so.
  //
  AGESA_TESTPOINT (TpProcHtTrafficDist, State->ConfigHandle);
  State->HtFeatures->TrafficDistribution (State);

  // For each Node, invoke northbridge specific buffer tunings that can not be done in reg table.
  //
  AGESA_TESTPOINT (TpProcHtTuning, State->ConfigHandle);
  for (Node = 0; Node < (State->NodesDiscovered + 1); Node++) {
    State->Nb->BufferOptimizations (Node, State, State->Nb);
  }
}

/*----------------------------------------------------------------------------------------*/
/**
 * Initialize the Node and Socket maps for an AP Core.
 *
 * In each core's local heap, create a Node to Socket map and a Socket/Module to Node map.
 * The mapping is filled in by reading the AP Mailboxes from PCI config on each node.
 *
 * @param[in]    State    global state, input data
 *
 */
VOID
STATIC
InitApMaps (
  IN       STATE_DATA *State
  )
{
  UINT8 Node;
  AP_MAIL_INFO NodeApMailBox;

  // There is no option to not have socket - node maps, if they aren't allocated that is a fatal bug.
  ASSERT (State->SocketDieToNodeMap != NULL);
  ASSERT (State->NodeToSocketDieMap != NULL);

  for (Node = 0; Node < State->Nb->GetNodeCount (State->Nb); Node++) {
    NodeApMailBox = State->Nb->RetrieveMailbox (Node, State->Nb);
    (*State->SocketDieToNodeMap)[NodeApMailBox.Fields.Socket][NodeApMailBox.Fields.Module].Node = Node;
    (*State->NodeToSocketDieMap)[Node].Socket = (UINT8)NodeApMailBox.Fields.Socket;
    (*State->NodeToSocketDieMap)[Node].Die = (UINT8)NodeApMailBox.Fields.Module;
  }
  // This requires the other maps to be initialized.
  UpdateCoreRanges (State);
}

/*----------------------------------------------------------------------------------------*/
/**
 * Is the currently running core the BSC?
 *
 * Determine whether the init steps for BSC or AP core should be run.
 *
 * @param[in]    State    global state, input data
 *
 * @retval       TRUE    This is the boot core.
 * @retval       FALSE   This is not the boot core.
 */
BOOLEAN
STATIC
IsBootCore (
  IN       STATE_DATA    *State
  )
{
  UINT64 Value;

  LibAmdMsrRead (APIC_Base, &Value, State->ConfigHandle);

  return ((BOOLEAN) (((UINT32) (Value & 0xFFFFFFFF) & ((UINT32)1 << APIC_Base_BSP)) != 0));
}

/***************************************************************************
 ***                            HT Initialize                             ***
 ***************************************************************************/

/*----------------------------------------------------------------------------------------*/
/**
 * 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;
}
