/**
* @file
*
* HT Features.
*
* This file provides definitions used in common by HT internal modules. The
* data is private and not for external client access.
* Definitions include the HT global internal state data structures, and
* access to the available HT features from the main HT entry point.
*
* This file includes the feature constructor and feature support which is not
* removed with various build options.
*
* @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.
*
* ***************************************************************************
*
*/
#ifndef _HT_FEAT_H_
#define _HT_FEAT_H_
/**
* @page htimplfeat HT Features Implementation Guide
*
* HT Features provides access to the HT Feature set, in a manner that isolates
* calling code from knowledge about the Feature set implementation or which
* features are supported in the current build. In the case of feature sets, this
* is mostly used for build options to reduce code size by removing unneeded features.
*
* @par Adding a Method to HT Features
*
* To add a new method to the HT Features, follow these steps.
*
* - Create a typedef for the Method with the correct parameters and return type.
*
*
* - Name the method typedef (F_METHOD_NAME)(), where METHOD_NAME is the same name as the method table item,
* but with "_"'s and UPPERCASE, rather than mixed case.
* @n typedef VOID (F_METHOD_NAME)(); @n
*
*
- Make a reference type for references to a method implementation:
* @n /// Reference to a Method
* @n typedef F_METHOD_NAME *PF_METHOD_NAME @n
*
*
* - Provide a standard doxygen function preamble for the Method typedef. Begin the
* detailed description by providing a reference to the method instances page by including
* the lines below:
* @code
* *
* * @HtFeatInstances.
* *
* @endcode
* @note It is important to provide documentation for the method type, because the method may not
* have an implementation in any families supported by the current package. @n
*
*
- Add to the ::HT_FEATURES struct an item for the Method:
* @n PF_METHOD_NAME MethodName; ///< Method: description. @n
*
*
* @par Implementing an HT Features Instance of the method.
*
* To implement an instance of a method for a specific feature follow these steps.
*
* - In appropriate files, implement the method with the return type and parameters
* matching the method typedef.
*
* - Name the function MethodName().
*
* - Create a doxygen function preamble for the method instance. Begin the detailed description with
* an Implements command to reference the method type and add this instance to the Method Instances page.
* @code
* *
* * @HtFeatMethod{::F_METHOD_NAME}.
* *
* @endcode
*
* - To access other Ht feature routines or data as part of the method implementation, the function
* must use HtFeatures->OtherMethod(). Do not directly access other HT feature
* routines, because in the table there may be overrides or this routine may be shared by multiple configurations.
*
* - Add the instance to the ::HT_FEATURES instances.
*
* - If a configuration does not need an instance of the method use one of the CommonReturns from
* CommonReturns.h with the same return type.
*
* @par Invoking HT Features Methods.
*
* The first step is carried out only once by the top level HT entry point.
* @n @code
* HT_FEATURES HtFeatures;
* // Get the current HT Feature Set
* NewHtFeatures (&HtFeatures);
* State->HtFeatures = &HtFeatures;
* @endcode
*
* The following example shows how to invoke a HT Features method.
* @n @code
* State->HtFeatures->MethodName ();
* @endcode
*
*/
/*----------------------------------------------------------------------------
* Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS)
*
*----------------------------------------------------------------------------
*/
/*-----------------------------------------------------------------------------
* DEFINITIONS AND MACROS
*
*-----------------------------------------------------------------------------
*/
#define MAX_PLATFORM_LINKS 64
#define MAX_LINK_PAIRS 4
/* These following are internal definitions */
#define ROUTE_TO_SELF 0x0F
#define INVALID_LINK 0xCC /* Used in port list data structure to mark unused data entries.
Can also be used for no Link found in a port list search */
/* definitions for working with the port list structure */
#define PORTLIST_TYPE_CPU 0
#define PORTLIST_TYPE_IO 1
/*
* Hypertransport Capability definitions and macros
*
*/
#define HT_INTERFACE_CAP_SUBTYPE_MASK ((UINT32)0xE00000FF)
#define HT_CAP_SUBTYPE_MASK ((UINT32)0xF80000FF)
/* HT Host Capability */
#define HT_HOST_CAPABILITY 1
#define HT_HOST_CAP_SIZE 0x20
/* Host CapabilityRegisters */
#define HTHOST_LINK_CAPABILITY_REG 0x00
#define HTHOST_LINK_CONTROL_REG 0x04
#define HTHOST_FREQ_REV_REG 0x08
#define HTHOST_REV_REV3 0x60
#define HTHOST_FEATURE_CAP_REG 0x0C
#define HTHOST_BUFFER_COUNT_REG 0x10
#define HTHOST_ISOC_REG 0x14
#define HTHOST_LINK_TYPE_REG 0x18
#define HTHOST_FREQ_EXTENSION 0x1C
#define HTHOST_TYPE_COHERENT 3
#define HTHOST_TYPE_NONCOHERENT 7
#define HTHOST_TYPE_MASK 0x1F
/* HT Slave Capability (HT1 compat) */
#define HT_SLAVE_CAPABILITY 0
#define HTSLAVE_LINK01_OFFSET 4
#define HTSLAVE_LINK_CONTROL_0_REG 4
#define HTSLAVE_FREQ_REV_0_REG 0xC
#define HTSLAVE_FEATURECAP_REG 0x10
#define HT_CONTROL_CLEAR_CRC (~(3 << 8))
#define HT_FREQUENCY_CLEAR_LINK_ERRORS (~(0x7 << 12))
#define MAX_BUID 31
/* HT3 gen Capability */
#define HT_GEN3_CAPABILITY (0xD << 1)
#define HTGEN3_LINK01_OFFSET 0x10
#define HTGEN3_LINK_TRAINING_0_REG 0x10
/* HT3 Retry Capability */
#define HT_RETRY_CAPABILITY (0xC << 1)
#define HTRETRY_CONTROL_REG 4
/* Unit ID Clumping Capability */
#define HT_UNITID_CAPABILITY (0x9 << 1)
#define HTUNIT_SUPPORT_REG 4
#define HTUNIT_ENABLE_REG 8
#define HT_CLUMPING_PASSIVE 1
/*----------------------------------------------------------------------------
* TYPEDEFS, STRUCTURES, ENUMS
*
*----------------------------------------------------------------------------
*/
// Forward declarations.
/// Used for forward reference.
typedef struct _NORTHBRIDGE NORTHBRIDGE;
typedef struct _HT_FEATURES HT_FEATURES;
typedef struct _HT_INTERFACE HT_INTERFACE;
/**
* Coherent Init Data.
*
* Metrics representing the coherent fabric which was discovered: Degree of nodes, adjacency,
* node numbering permutations, and the topology which it matched.
*/
typedef struct {
/** The number of coherent Links connected on each Node (the 'Degree' of the Node) */
UINT8 SysDegree[MAX_NODES];
/** The systems adjacency (sysMatrix[i][j] is true if Node_i has a Link to Node_j) */
BOOLEAN SysMatrix[MAX_NODES][MAX_NODES];
UINT8 DbDegree[MAX_NODES]; /**< Like sysDegree, but for the current database topology */
BOOLEAN DbMatrix[MAX_NODES][MAX_NODES]; /**< Like sysMatrix, but for the current database topology */
UINT8 Perm[MAX_NODES]; /**< The Node mapping from the system to the database */
UINT8 ReversePerm[MAX_NODES]; /**< The Node mapping from the database to the system */
UINT8 *MatchedTopology; /**< The topology that matched the current system or NULL */
} COHERENT_FABRIC;
/**
* Represent the system as Links of matched port pairs.
* A pair consists of a source Node, a Link to the destination Node, the
* destination Node, and its Link back to source Node. The even indices are
* the source Nodes and Links, and the odd indices are for the destination
* Nodes and Links.
* @note The Port pair 2*N and 2*N+1 are connected together to form a Link
* (e.g. 0,1 and 8,9 are ports on either end of an HT Link) The lower number
* port (2*N) is the source port. The device that owns the source port is
* always the device closer to the BSP. (i.e. nearer the CPU in a
* non-coherent chain, or the CPU with the lower NodeID).
*/
typedef struct {
/* This section is where the Link is in the system and how to find it */
UINT8 Type; /**< 0 = CPU, 1 = Device, all others reserved */
UINT8 Link; /**< 0-1 for devices, 0-7 for CPUs */
UINT8 NodeID; /**< The Node, or a pointer to the devices parent Node */
UINT8 HostLink; /**< For Devices, the root CPU's Link to the chain */
UINT8 HostDepth; /**< Link Depth in chain, only used by devices */
PCI_ADDR Pointer; /**< A pointer to the device's slave HT capability, so we don't have to keep searching */
/* This section is for the final settings, which are written to hardware */
BOOLEAN SelRegang; /**< Indicates to software regang Link, only used for CPU->CPU Links */
UINT8 SelWidthIn; /**< Width in setting */
UINT8 SelWidthOut; /**< Width out setting */
UINT8 SelFrequency; /**< Frequency setting */
/* This section is for keeping track of capabilities and possible configurations */
BOOLEAN RegangCap; /**< Is the port capable of reganging? CPUs only */
UINT32 PrvFrequencyCap; /**< Possible frequency settings */
UINT8 PrvWidthInCap; /**< Possible Width setting */
UINT8 PrvWidthOutCap; /**< Possible Width setting */
UINT32 CompositeFrequencyCap; /**< Possible Link frequency setting */
UINT32 ClumpingSupport; /**< Unit ID Clumping value (bit 0 = passive support) */
} PORT_DESCRIPTOR;
/// Reference to a set of PORT_DESCRIPTORs.
typedef PORT_DESCRIPTOR (*PORT_LIST)[MAX_PLATFORM_LINKS*2];
/**
* Our global state data structure
*/
typedef struct {
AMD_HT_INTERFACE *HtBlock; /**< The input data structure. */
UINT8 NodesDiscovered; /**< One less than the number of Nodes found in the system */
UINT8 TotalLinks; /**< How many HT Links have we discovered so far. */
UINT8 SysMpCap; /**< The maximum number of Nodes that all processors are capable of */
AGESA_STATUS MaxEventClass; /**< The event class of the highest severity event generated */
PORT_LIST PortList; /**< Represent the system as a set of Links, each two Ports. */
COHERENT_FABRIC *Fabric; /**< Describe metrics about the coherent fabric.
* Limited scope to CoherentInit(). */
/* Data interface to other Agesa Modules */
SOCKET_DIE_TO_NODE_MAP SocketDieToNodeMap; /**< For each Socket, Die the Node ids */
NODE_TO_SOCKET_DIE_MAP NodeToSocketDieMap; /**< For each Node id, Socket and Die */
HOP_COUNT_TABLE *HopCountTable; /**< Table of hops between nodes */
/* Data for non-coherent initialization */
UINT8 AutoBusCurrent; /**< The next bus number available */
UINT8 UsedCfgMapEntries; /**< The next Config address Map set available, Limit 4 (F1X[EC:E0]) */
BOOLEAN IsUsingRecoveryHt; /**< Manual BUID Swap List processing should assume that HT Recovery was used */
BOOLEAN IsSetHtCrcFlood; /**< Enable setting of HT CRC Flood */
BOOLEAN IsUsingUnitIdClumping; /**< Enable automatic Unit Id Clumping configuration. */
HT_INTERFACE *HtInterface; /**< Interface for feature code to external parameters */
HT_FEATURES *HtFeatures; /**< The current feature implementations */
NORTHBRIDGE *Nb; /**< The current northbridge */
PLATFORM_CONFIGURATION *PlatformConfiguration; /**< The platform specific configuration customizations */
VOID *ConfigHandle; /**< Config Pointer, opaque handle for passing to lib */
} STATE_DATA;
//
// Feature Method types
//
/**
* Discover all coherent devices in the system.
*
* @HtFeatInstances.
*
* @param[in,out] State our global state
*
*/
typedef VOID F_COHERENT_DISCOVERY (
IN OUT STATE_DATA *State
);
/// Reference to a method.
typedef F_COHERENT_DISCOVERY *PF_COHERENT_DISCOVERY;
/**
* Using the description of the fabric topology we discovered, try to find a match
* among the supported topologies.
*
* @HtFeatInstances.
*
* @param[in,out] State the discovered fabric, degree matrix, permutation
*
*/
typedef VOID F_LOOKUP_COMPUTE_AND_LOAD_ROUTING_TABLES (
IN OUT STATE_DATA *State
);
/// Reference to a method.
typedef F_LOOKUP_COMPUTE_AND_LOAD_ROUTING_TABLES *PF_LOOKUP_COMPUTE_AND_LOAD_ROUTING_TABLES;
/**
* Make a Hop Count Table for the installed topology.
*
* @HtFeatInstances.
*
* @param[in,out] State access topology, permutation, update hop table
*
*/
typedef VOID F_MAKE_HOP_COUNT_TABLE (
IN OUT STATE_DATA *State
);
/// Reference to a method.
typedef F_MAKE_HOP_COUNT_TABLE *PF_MAKE_HOP_COUNT_TABLE;
/**
* Process a non-coherent Link.
*
* @HtFeatInstances.
*
* @param[in] Node Node on which to process nc init
* @param[in] Link The non-coherent Link on that Node
* @param[in] IsCompatChain Is this the chain with the southbridge? TRUE if yes.
* @param[in,out] State our global state
*/
typedef VOID F_PROCESS_LINK (
IN UINT8 Node,
IN UINT8 Link,
IN BOOLEAN IsCompatChain,
IN OUT STATE_DATA *State
);
/// Reference to a method.
typedef F_PROCESS_LINK *PF_PROCESS_LINK;
/**
* Get Link features into system data structure.
*
* @HtFeatInstances.
*
* @param[in] State our global state, port list
*/
typedef VOID F_GATHER_LINK_DATA (
IN STATE_DATA *State
);
/// Reference to a method.
typedef F_GATHER_LINK_DATA *PF_GATHER_LINK_DATA;
/**
* Optimize Links.
*
* @HtFeatInstances.
*
* @param[in,out] State Process and update portlist
*/
typedef VOID F_SELECT_OPTIMAL_WIDTH_AND_FREQUENCY (
IN OUT STATE_DATA *State
);
/// Reference to a method.
typedef F_SELECT_OPTIMAL_WIDTH_AND_FREQUENCY *PF_SELECT_OPTIMAL_WIDTH_AND_FREQUENCY;
/**
* Change the hardware state for all Links according to the now optimized data in the
* port list data structure.
*
* @HtFeatInstances.
*
* @param[in] State our global state, port list
*/
typedef VOID F_SET_LINK_DATA (
IN STATE_DATA *State
);
/// Reference to a method.
typedef F_SET_LINK_DATA *PF_SET_LINK_DATA;
/**
* Retry must be enabled on all coherent links if it is enabled on any coherent links.
*
* @HtFeatInstances.
*
* @param[in,out] State global state, port frequency settings.
*
* @retval TRUE Fixup occurred, all coherent links HT1
* @retval FALSE No changes
*/
typedef BOOLEAN F_IS_COHERENT_RETRY_FIXUP (
IN STATE_DATA *State
);
/// Reference to a method.
typedef F_IS_COHERENT_RETRY_FIXUP *PF_IS_COHERENT_RETRY_FIXUP;
/**
* Test the subLinks of a Link to see if they qualify to be reganged.
*
* @HtFeatInstances.
*
* @param[in,out] State Our global state
*/
typedef VOID F_REGANG_LINKS (
IN OUT STATE_DATA *State
);
/// Reference to a method.
typedef F_REGANG_LINKS *PF_REGANG_LINKS;
/**
* Iterate through all Links, checking the frequency of each subLink pair.
*
* @HtFeatInstances.
*
* @param[in,out] State Link state and port list
*
*/
typedef VOID F_SUBLINK_RATIO_FIXUP (
IN OUT STATE_DATA *State
);
/// Reference to a method.
typedef F_SUBLINK_RATIO_FIXUP *PF_SUBLINK_RATIO_FIXUP;
/**
* Identify Links which can have traffic distribution.
*
* @HtFeatInstances.
*
* @param[in] State port list data
*/
typedef VOID F_TRAFFIC_DISTRIBUTION (
IN STATE_DATA *State
);
/// Reference to a method.
typedef F_TRAFFIC_DISTRIBUTION *PF_TRAFFIC_DISTRIBUTION;
/**
* Access HT Link Control Register.
*
* @HtFeatInstances.
*
* @param[in] Reg the PCI config address the control register
* @param[in] HiBit the high bit number
* @param[in] LoBit the low bit number
* @param[in] Value the value to write to that bit range. Bit 0 => loBit.
* @param[in] State Our state, config handle for lib
*/
typedef VOID F_SET_HT_CONTROL_REGISTER_BITS (
IN PCI_ADDR Reg,
IN UINT8 HiBit,
IN UINT8 LoBit,
IN UINT32 *Value,
IN STATE_DATA *State
);
/// Reference to a method.
typedef F_SET_HT_CONTROL_REGISTER_BITS *PF_SET_HT_CONTROL_REGISTER_BITS;
/**
* Translate a desired width setting to the bits to set in the register field.
*
* @HtFeatInstances.
*
* @param[in] Value the width Value
*
* @return The bits for the register
*/
typedef UINT8 F_CONVERT_WIDTH_TO_BITS (
IN UINT8 Value
);
/// Reference to a method.
typedef F_CONVERT_WIDTH_TO_BITS *PF_CONVERT_WIDTH_TO_BITS;
/**
* HT Feature Methods.
*
* Provides abstract methods which are bound to specific feature implementations.
*/
struct _HT_FEATURES {
PF_COHERENT_DISCOVERY CoherentDiscovery; /**< Method: Coherent Discovery. */
PF_LOOKUP_COMPUTE_AND_LOAD_ROUTING_TABLES LookupComputeAndLoadRoutingTables;
/**< Method: Route the discovered system */
PF_MAKE_HOP_COUNT_TABLE MakeHopCountTable; /**< Method: Compute slit hop counts */
PF_PROCESS_LINK ProcessLink; /**< Method: Process a non-coherent Link. */
PF_GATHER_LINK_DATA GatherLinkData; /**< Method: Gather Link Capabilities and data. */
PF_SELECT_OPTIMAL_WIDTH_AND_FREQUENCY SelectOptimalWidthAndFrequency;
/**< Method: Optimize link features. */
PF_REGANG_LINKS RegangLinks; /**< Method: Regang Sublinks. */
PF_SUBLINK_RATIO_FIXUP SubLinkRatioFixup; /**< Method: Fix Sublink Frequency ratios */
PF_IS_COHERENT_RETRY_FIXUP IsCoherentRetryFixup;
/**< Method: Fix Retry mixed on coherent links. */
PF_SET_LINK_DATA SetLinkData; /**< Method: Set optimized values. */
PF_TRAFFIC_DISTRIBUTION TrafficDistribution; /**< Method: Detect and Initialize Traffic Distribution */
PF_SET_HT_CONTROL_REGISTER_BITS SetHtControlRegisterBits; /**< Method: Access HT Link Control Reg. */
PF_CONVERT_WIDTH_TO_BITS ConvertWidthToBits; /**< Method: Convert a bit width to the value used for register setting. */
};
/*----------------------------------------------------------------------------
* Prototypes
*
*----------------------------------------------------------------------------
*/
/**
* Provide the current Feature set implementation.
*
* Add an implementation reference for the constructor, just to make sure the page is created.
* @HtFeatMethod{::HT_FEATURES}.
*
*/
VOID
NewHtFeatures (
OUT HT_FEATURES *HtFeatures,
IN AMD_CONFIG_PARAMS *StdHeader
);
#endif /* _HT_FEAT_H_ */