5 * Coherent Feature Northbridge routines.
7 * Provide access to hardware for routing, coherent discovery.
9 * @xrefitem bom "File Content Label" "Release Content"
11 * @e sub-project: HyperTransport
12 * @e \$Revision: 56279 $ @e \$Date: 2011-07-11 13:11:28 -0600 (Mon, 11 Jul 2011) $
16 *****************************************************************************
18 * Copyright (C) 2012 Advanced Micro Devices, Inc.
19 * All rights reserved.
21 * Redistribution and use in source and binary forms, with or without
22 * modification, are permitted provided that the following conditions are met:
23 * * Redistributions of source code must retain the above copyright
24 * notice, this list of conditions and the following disclaimer.
25 * * Redistributions in binary form must reproduce the above copyright
26 * notice, this list of conditions and the following disclaimer in the
27 * documentation and/or other materials provided with the distribution.
28 * * Neither the name of Advanced Micro Devices, Inc. nor the names of
29 * its contributors may be used to endorse or promote products derived
30 * from this software without specific prior written permission.
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
33 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
35 * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
36 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
38 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
39 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43 * ***************************************************************************
48 *----------------------------------------------------------------------------
51 *----------------------------------------------------------------------------
62 #include "htNbCommonHardware.h"
63 #include "htNbCoherent.h"
68 #define FILECODE PROC_HT_NBCOMMON_HTNBCOHERENT_FILECODE
69 /*----------------------------------------------------------------------------
70 * DEFINITIONS AND MACROS
72 *----------------------------------------------------------------------------
75 /*----------------------------------------------------------------------------
76 * TYPEDEFS AND STRUCTURES
78 *----------------------------------------------------------------------------
80 /*----------------------------------------------------------------------------
81 * PROTOTYPES OF LOCAL FUNCTIONS
83 *----------------------------------------------------------------------------
86 /***************************************************************************
87 *** FAMILY/NORTHBRIDGE SPECIFIC FUNCTIONS ***
88 ***************************************************************************/
90 /*----------------------------------------------------------------------------------------*/
92 * Establish a Temporary route from one Node to another.
94 * @HtNbMethod{::F_WRITE_ROUTING_TABLE}
96 * This routine will modify the routing tables on the
97 * SourceNode to cause it to route both request and response traffic to the
98 * targetNode through the specified Link.
100 * @note: This routine is to be used for early discovery and initialization. The
101 * final routing tables must be loaded some other way because this
102 * routine does not address the issue of probes, or independent request
105 * @param[in] Node the Node that will have it's routing tables modified.
106 * @param[in] Target For routing to Node target
107 * @param[in] Link Link from Node to target
108 * @param[in] Nb this northbridge
121 ASSERT ((Node < MAX_NODES) && (Target < MAX_NODES) && (Link < Nb->MaxLinks));
122 Temp = (Nb->SelfRouteResponseMask | Nb->SelfRouteRequestMask) << (Link + 1);
123 Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node),
124 MakePciBusFromNode (Node),
125 MakePciDeviceFromNode (Node),
127 REG_ROUTE0_0X40 + (Target * 4));
128 LibAmdPciWrite (AccessWidth32, Reg, &Temp, Nb->ConfigHandle);
131 /*----------------------------------------------------------------------------------------*/
133 * Modifies the NodeID register on the target Node
135 * @HtNbMethod{::F_WRITE_NODEID}
137 * @param[in] Node the Node that will have its NodeID altered.
138 * @param[in] NodeID the new value for NodeID
139 * @param[in] Nb this northbridge
151 ASSERT ((Node < MAX_NODES) && (NodeID < MAX_NODES));
152 Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node),
153 MakePciBusFromNode (Node),
154 MakePciDeviceFromNode (Node),
157 LibAmdPciWriteBits (Reg, 2, 0, &Temp, Nb->ConfigHandle);
160 /*----------------------------------------------------------------------------------------*/
162 * Read the Default Link
164 * @HtNbMethod{::F_READ_DEFAULT_LINK}
166 * Read the DefLnk (the source Link of the current packet) from Node. Since this code
167 * is running on the BSP, this should be the Link pointing back towards the BSP.
169 * @param[in] Node the Node that will have its NodeID altered.
170 * @param[in] Nb this northbridge
172 * @return The HyperTransport Link where the request to
173 * read the default Link came from.
186 Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node),
187 MakePciBusFromNode (Node),
188 MakePciDeviceFromNode (Node),
190 REG_LINK_INIT_CONTROL_0X6C);
192 ASSERT ((Node < MAX_NODES));
193 LibAmdPciReadBits (Reg, 3, 2, &DefaultLink, Nb->ConfigHandle);
194 LibAmdPciReadBits (Reg, 8, 8, &Temp, Nb->ConfigHandle);
195 DefaultLink |= (Temp << 2);
196 return (UINT8)DefaultLink;
199 /*----------------------------------------------------------------------------------------*/
201 * Turns routing tables on for a given Node
203 * @HtNbMethod{::F_ENABLE_ROUTING_TABLES}
205 * @param[in] Node the Node that will have it's routing tables enabled
206 * @param[in] Nb this northbridge
209 EnableRoutingTables (
217 ASSERT ((Node < MAX_NODES));
218 Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node),
219 MakePciBusFromNode (Node),
220 MakePciDeviceFromNode (Node),
222 REG_LINK_INIT_CONTROL_0X6C);
223 LibAmdPciWriteBits (Reg, 0, 0, &Temp, Nb->ConfigHandle);
226 /*----------------------------------------------------------------------------------------*/
228 * Turns routing tables off for a given Node
230 * @HtNbMethod{::F_DISABLE_ROUTING_TABLES}
232 * @param[in] Node the Node that will have it's routing tables disabled
233 * @param[in] Nb this northbridge
236 DisableRoutingTables (
244 ASSERT ((Node < MAX_NODES));
245 Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node),
246 MakePciBusFromNode (Node),
247 MakePciDeviceFromNode (Node),
249 REG_LINK_INIT_CONTROL_0X6C);
250 LibAmdPciWriteBits (Reg, 0, 0, &Temp, Nb->ConfigHandle);
253 /*----------------------------------------------------------------------------------------*/
255 * Verify that the Link is coherent, connected, and ready
257 * @HtNbMethod{::F_VERIFY_LINK_IS_COHERENT}
259 * @param[in] Node the Node that will be examined
260 * @param[in] Link the Link on that Node to examine
261 * @param[in] Nb this northbridge
263 * @retval TRUE The Link has the following status
264 * - LinkCon=1, Link is connected
265 * - InitComplete=1, Link initialization is complete
266 * - NC=0, Link is coherent
267 * - UniP-cLDT=0, Link is not Uniprocessor cLDT
268 * - LinkConPend=0 Link connection is not pending
269 * @retval FALSE The Link has some other status
272 VerifyLinkIsCoherent (
281 ASSERT ((Node < MAX_NODES) && (Link < Nb->MaxLinks));
283 LinkBase = Nb->MakeLinkBase (Node, Link, Nb);
285 // FN0_98/A4/C4 = LDT Type Register
286 LinkBase.Address.Register += HTHOST_LINK_TYPE_REG;
287 LibAmdPciRead (AccessWidth32, LinkBase, &LinkType, Nb->ConfigHandle);
289 // Verify LinkCon = 1, InitComplete = 1, NC = 0, UniP-cLDT = 0, LinkConPend = 0
290 return (BOOLEAN) ((LinkType & HTHOST_TYPE_MASK) == HTHOST_TYPE_COHERENT);
293 /*----------------------------------------------------------------------------------------*/
295 * Read the token stored in the scratchpad register field.
297 * @HtNbMethod{::F_READ_TOKEN}
299 * Use the CPU core count as a scratch pad.
301 * @note The location used to store the token is arbitrary. The only requirement is
302 * that the location warm resets to zero, and that using it will have no ill-effects
303 * during HyperTransport initialization.
305 * @param[in] Node the Node that will be examined
306 * @param[in] Nb this northbridge
308 * @return the Token read from the Node
319 ASSERT ((Node < MAX_NODES));
320 // Use CpuCnt as a scratch register
321 Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node),
322 MakePciBusFromNode (Node),
323 MakePciDeviceFromNode (Node),
326 LibAmdPciReadBits (Reg, 19, 16, &Temp, Nb->ConfigHandle);
332 /*----------------------------------------------------------------------------------------*/
334 * Write the token stored in the scratchpad register
336 * @HtNbMethod{::F_WRITE_TOKEN}
338 * Use the CPU core count as a scratch pad.
340 * @note The location used to store the token is arbitrary. The only requirement is
341 * that the location warm resets to zero, and that using it will have no ill-effects
342 * during HyperTransport initialization.
344 * @param[in] Node the Node that marked with token
345 * @param[in] Value the token Value
346 * @param[in] Nb this northbridge
358 ASSERT ((Node < MAX_NODES));
359 // Use CpuCnt as a scratch register
360 Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node),
361 MakePciBusFromNode (Node),
362 MakePciDeviceFromNode (Node),
365 LibAmdPciWriteBits (Reg, 19, 16, &Temp, Nb->ConfigHandle);
368 /*----------------------------------------------------------------------------------------*/
370 * Full Routing Table Register initialization
372 * @HtNbMethod{::F_WRITE_FULL_ROUTING_TABLE}
374 * Write the routing table entry for Node to target, using the request Link, response
375 * Link, and broadcast Links provided.
377 * @param[in] Node the Node that will be examined
378 * @param[in] Target the Target Node for these routes
379 * @param[in] ReqLink the Link for requests to Target
380 * @param[in] RspLink the Link for responses to Target
381 * @param[in] BroadcastLinks the broadcast Links
382 * @param[in] Nb this northbridge
385 WriteFullRoutingTable (
390 IN UINT32 BroadcastLinks,
398 ASSERT ((Node < MAX_NODES) && (Target < MAX_NODES));
399 if (ReqLink == ROUTE_TO_SELF) {
400 Value |= Nb->SelfRouteRequestMask;
402 Value |= Nb->SelfRouteRequestMask << (ReqLink + 1);
405 if (RspLink == ROUTE_TO_SELF) {
406 Value |= Nb->SelfRouteResponseMask;
408 Value |= Nb->SelfRouteResponseMask << (RspLink + 1);
411 // Allow us to accept a Broadcast ourselves, then set broadcasts for routes
412 Value |= (UINT32)1 << Nb->BroadcastSelfBit;
413 Value |= (UINT32)BroadcastLinks << (Nb->BroadcastSelfBit + 1);
415 Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node),
416 MakePciBusFromNode (Node),
417 MakePciDeviceFromNode (Node),
419 REG_ROUTE0_0X40 + (Target * 4));
420 LibAmdPciWrite (AccessWidth32, Reg, &Value, Nb->ConfigHandle);
423 /*----------------------------------------------------------------------------------------*/
425 * Determine whether a Node is compatible with the discovered configuration so far.
427 * @HtNbMethod{::F_IS_ILLEGAL_TYPE_MIX}.
429 * Currently, that means the family, extended family of the new Node are the
432 * @param[in] Node the Node
433 * @param[in] Nb this northbridge
435 * @retval TRUE the new node is not compatible
436 * @retval FALSE the new node is compatible
444 return ((BOOLEAN) ((Nb->MakeKey (Node, Nb) & Nb->CompatibleKey) == 0));
447 /*----------------------------------------------------------------------------------------*/
449 * Fix (hopefully) exceptional conditions.
451 * @HtNbMethod{::F_HANDLE_SPECIAL_NODE_CASE}.
453 * Currently, this routine is implemented for all coherent HT families to check
454 * vendor ID of coherent Node. If the vendor ID is 0x1022 then return FALSE,
457 * @param[in] Node The Node which need to be checked.
458 * @param[in] Link The link to check for special conditions.
459 * @param[in] State our global state.
460 * @param[in] Nb this northbridge.
462 * @retval TRUE This node received special handling.
463 * @retval FALSE This node was not handled specially, handle it normally.
467 HandleSpecialNodeCase (
470 IN STATE_DATA *State,
480 Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node),
481 MakePciBusFromNode (Node),
482 MakePciDeviceFromNode (Node),
486 LibAmdPciReadBits (Reg, 15, 0, &VendorID, Nb->ConfigHandle);
487 if (VendorID == 0x1022) {