blob: 571b56a74fd2872236ca461b1bff460c884e9e79 [file] [log] [blame]
zbao7d94cf92012-07-02 14:19:14 +08001/* $NoKeywords:$ */
2/**
3 * @file
4 *
5 * External Interface implementation for coherent features.
6 *
7 * Contains routines for accessing the interface to the client BIOS,
8 * for support only required for coherent features.
9 *
10 * @xrefitem bom "File Content Label" "Release Content"
11 * @e project: AGESA
12 * @e sub-project: HyperTransport
13 * @e \$Revision: 63425 $ @e \$Date: 2011-12-22 11:24:10 -0600 (Thu, 22 Dec 2011) $
14 *
15 */
16/*
17 *****************************************************************************
18 *
Siyuan Wang641f00c2013-06-08 11:50:55 +080019 * Copyright (c) 2008 - 2012, Advanced Micro Devices, Inc.
20 * All rights reserved.
zbao7d94cf92012-07-02 14:19:14 +080021 *
Siyuan Wang641f00c2013-06-08 11:50:55 +080022 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions are met:
24 * * Redistributions of source code must retain the above copyright
25 * notice, this list of conditions and the following disclaimer.
26 * * Redistributions in binary form must reproduce the above copyright
27 * notice, this list of conditions and the following disclaimer in the
28 * documentation and/or other materials provided with the distribution.
29 * * Neither the name of Advanced Micro Devices, Inc. nor the names of
30 * its contributors may be used to endorse or promote products derived
31 * from this software without specific prior written permission.
zbao7d94cf92012-07-02 14:19:14 +080032 *
Siyuan Wang641f00c2013-06-08 11:50:55 +080033 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
34 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
35 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
36 * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
37 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
38 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
39 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
40 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
41 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
42 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
zbao7d94cf92012-07-02 14:19:14 +080043 * ***************************************************************************
44 *
45 */
46
47/*
48 *----------------------------------------------------------------------------
49 * MODULES USED
50 *
51 *----------------------------------------------------------------------------
52 */
53
54
55
56#include "AGESA.h"
57#include "amdlib.h"
58#include "Ids.h"
59#include "Topology.h"
60#include "htFeat.h"
61#include "htInterface.h"
62#include "htInterfaceGeneral.h"
63#include "htInterfaceCoherent.h"
64#include "htNb.h"
65#include "heapManager.h"
66#include "Filecode.h"
67CODE_GROUP (G1_PEICC)
68RDATA_GROUP (G1_PEICC)
69
70#define FILECODE PROC_HT_HTINTERFACECOHERENT_FILECODE
71/*----------------------------------------------------------------------------
72 * DEFINITIONS AND MACROS
73 *
74 *----------------------------------------------------------------------------
75 */
76
77/*----------------------------------------------------------------------------
78 * TYPEDEFS AND STRUCTURES
79 *
80 *----------------------------------------------------------------------------
81 */
82/*----------------------------------------------------------------------------
83 * PROTOTYPES OF LOCAL FUNCTIONS
84 *
85 *----------------------------------------------------------------------------
86 */
87/*----------------------------------------------------------------------------
88 * EXPORTED FUNCTIONS
89 *
90 *----------------------------------------------------------------------------
91 */
92
93/*----------------------------------------------------------------------------
94 * LOCAL FUNCTIONS
95 *
96 *----------------------------------------------------------------------------
97 */
98
99/*----------------------------------------------------------------------------------------*/
100/*----------------------------------------------------------------------------------------*/
101/**
102 * Get limits for CPU to CPU Links.
103 *
104 * @HtInterfaceMethod{::F_GET_CPU_2_CPU_PCB_LIMITS}
105 *
106 * For each coherent connection this routine is called once. Update the frequency
107 * and width if needed for this Link (usually based on board restriction). This is
108 * used with CPU device capabilities and northbridge limits to compute the default
109 * settings. The input width and frequency are valid, but do not necessarily reflect
110 * the minimum setting that will be chosen.
111 *
112 * @param[in] NodeA One Node on which this Link is located
113 * @param[in] LinkA The Link on this Node
114 * @param[in] NodeB The other Node on which this Link is located
115 * @param[in] LinkB The Link on that Node
116 * @param[in,out] ABLinkWidthLimit modify to change the Link Width In
117 * @param[in,out] BALinkWidthLimit modify to change the Link Width Out
118 * @param[in,out] PcbFreqCap modify to change the Link's frequency capability
119 * @param[in] State the input data
120 *
121 */
122VOID
123GetCpu2CpuPcbLimits (
124 IN UINT8 NodeA,
125 IN UINT8 LinkA,
126 IN UINT8 NodeB,
127 IN UINT8 LinkB,
128 IN OUT UINT8 *ABLinkWidthLimit,
129 IN OUT UINT8 *BALinkWidthLimit,
130 IN OUT UINT32 *PcbFreqCap,
131 IN STATE_DATA *State
132 )
133{
134 CPU_TO_CPU_PCB_LIMITS *p;
135 UINT8 SocketA;
136 UINT8 SocketB;
137 UINT8 PackageLinkA;
138 UINT8 PackageLinkB;
139
140 ASSERT ((NodeA < MAX_NODES) && (NodeB < MAX_NODES));
141 ASSERT ((LinkA < State->Nb->MaxLinks) && (LinkB < State->Nb->MaxLinks));
142
143 SocketA = State->HtInterface->GetSocketFromMap (NodeA, State);
144 PackageLinkA = State->Nb->GetPackageLink (NodeA, LinkA, State->Nb);
145 SocketB = State->HtInterface->GetSocketFromMap (NodeB, State);
146 PackageLinkB = State->Nb->GetPackageLink (NodeB, LinkB, State->Nb);
147
148 if (State->HtBlock->CpuToCpuPcbLimitsList != NULL) {
149 p = State->HtBlock->CpuToCpuPcbLimitsList;
150
151 while (p->SocketA != HT_LIST_TERMINAL) {
152 if (((p->SocketA == SocketA) || (p->SocketA == HT_LIST_MATCH_ANY)) &&
153 ((p->LinkA == PackageLinkA) || ((p->LinkA == HT_LIST_MATCH_ANY) && (!IsPackageLinkInternal (PackageLinkA))) ||
154 ((p->LinkA == HT_LIST_MATCH_INTERNAL_LINK) && (IsPackageLinkInternal (PackageLinkA)))) &&
155 ((p->SocketB == SocketB) || (p->SocketB == HT_LIST_MATCH_ANY)) &&
156 ((p->LinkB == PackageLinkB) || ((p->LinkB == HT_LIST_MATCH_ANY) && (!IsPackageLinkInternal (PackageLinkB))) ||
157 ((p->LinkB == HT_LIST_MATCH_INTERNAL_LINK) && (IsPackageLinkInternal (PackageLinkB))))) {
158 // Found a match, update width and frequency
159 *ABLinkWidthLimit = p->ABLinkWidthLimit;
160 *BALinkWidthLimit = p->BALinkWidthLimit;
161 *PcbFreqCap = p->PcbFreqCap;
162 break;
163 } else {
164 p++;
165 }
166 }
167 }
168}
169
170/*----------------------------------------------------------------------------------------*/
171/**
172 * Skip reganging of subLinks.
173 *
174 * @HtInterfaceMethod{::F_GET_SKIP_REGANG}
175 *
176 * This routine is called whenever two subLinks are both connected to the same CPUs.
177 * Normally, unganged sublinks between the same two CPUs are reganged. Return true
178 * from this routine to leave the Links unganged.
179 *
180 * @param[in] NodeA One Node on which this Link is located
181 * @param[in] LinkA The Link on this Node
182 * @param[in] NodeB The other Node on which this Link is located
183 * @param[in] LinkB The Link on that Node
184 * @param[in] State the input data
185 *
186 * @retval MATCHED leave Link unganged
187 * @retval POWERED_OFF leave link unganged and power off the paired sublink
188 * @retval UNMATCHED regang Link automatically
189 */
190FINAL_LINK_STATE
191GetSkipRegang (
192 IN UINT8 NodeA,
193 IN UINT8 LinkA,
194 IN UINT8 NodeB,
195 IN UINT8 LinkB,
196 IN STATE_DATA *State
197 )
198{
199 SKIP_REGANG *p;
200 FINAL_LINK_STATE Result;
201 UINT8 SocketA;
202 UINT8 SocketB;
203 UINT8 PackageLinkA;
204 UINT8 PackageLinkB;
205
206 ASSERT ((NodeA < MAX_NODES) && (NodeB < MAX_NODES));
207 ASSERT ((LinkA < State->Nb->MaxLinks) && (LinkB < State->Nb->MaxLinks));
208
209 Result = UNMATCHED;
210 SocketA = State->HtInterface->GetSocketFromMap (NodeA, State);
211 PackageLinkA = State->Nb->GetPackageLink (NodeA, LinkA, State->Nb);
212 SocketB = State->HtInterface->GetSocketFromMap (NodeB, State);
213 PackageLinkB = State->Nb->GetPackageLink (NodeB, LinkB, State->Nb);
214
215 if (State->HtBlock->SkipRegangList != NULL) {
216 p = State->HtBlock->SkipRegangList;
217
218 while (p->SocketA != HT_LIST_TERMINAL) {
219 if (((p->SocketA == SocketA) || (p->SocketA == HT_LIST_MATCH_ANY)) &&
220 ((p->LinkA == PackageLinkA) || ((p->LinkA == HT_LIST_MATCH_ANY) && (!IsPackageLinkInternal (PackageLinkA))) ||
221 ((p->LinkA == HT_LIST_MATCH_INTERNAL_LINK) && (IsPackageLinkInternal (PackageLinkA)))) &&
222 ((p->SocketB == SocketB) || (p->SocketB == HT_LIST_MATCH_ANY)) &&
223 ((p->LinkB == PackageLinkB) || ((p->LinkB == HT_LIST_MATCH_ANY) && (!IsPackageLinkInternal (PackageLinkB))) ||
224 ((p->LinkB == HT_LIST_MATCH_INTERNAL_LINK) && (IsPackageLinkInternal (PackageLinkB))))) {
225 // Found a match return final link state
226 Result = p->LinkState;
227 break;
228 } else {
229 p++;
230 }
231 }
232 }
233 return Result;
234}
235
236/*----------------------------------------------------------------------------------------*/
237/**
238 * Get a new, empty Hop Count Table, to make one for the installed topology.
239 *
240 * @HtInterfaceMethod{::F_NEW_HOP_COUNT_TABLE}
241 *
242 * For SLIT, publish a matrix with the hop count, by allocating a buffer on heap with a
243 * known signature.
244 *
245 * @param[in,out] State Keep our buffer handle.
246 *
247 */
248VOID
249NewHopCountTable (
250 IN OUT STATE_DATA *State
251 )
252{
253 ALLOCATE_HEAP_PARAMS AllocHeapParams;
254
255 AllocHeapParams.RequestedBufferSize = sizeof (HOP_COUNT_TABLE);
256 AllocHeapParams.BufferHandle = HOP_COUNT_TABLE_HANDLE;
257 AllocHeapParams.Persist = HEAP_SYSTEM_MEM;
258 if (HeapAllocateBuffer ( &AllocHeapParams, State->ConfigHandle) == AGESA_SUCCESS) {
259 State->HopCountTable = (HOP_COUNT_TABLE *)AllocHeapParams.BufferPtr;
260 } else {
261 State->HopCountTable = NULL;
262 }
263}