blob: 6552be9532cb4ea42682dd02b61b7844004498c3 [file] [log] [blame]
Marc Jones8ae8c882007-12-19 01:32:08 +00001/*
Stefan Reinauer7e61e452008-01-18 10:35:56 +00002 * This file is part of the coreboot project.
Marc Jones8ae8c882007-12-19 01:32:08 +00003 *
Timothy Pearson88d213a2015-01-23 20:28:13 -06004 * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
Marc Jonesda4ce6b2008-04-22 22:11:31 +00005 * Copyright (C) 2007-2008 Advanced Micro Devices, Inc.
Marc Jones8ae8c882007-12-19 01:32:08 +00006 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
Marc Jones8ae8c882007-12-19 01:32:08 +000015 */
16
Elyes HAOUASd2b9ec12018-10-27 09:41:02 +020017#include <arch/cpu.h>
Patrick Georgi3d5bb232010-05-09 21:15:13 +000018#include <cpu/x86/msr.h>
19#include <console/console.h>
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +020020#include <device/pci_ops.h>
Timothy Pearson1c4508e2015-09-05 17:50:29 -050021#include "ht_wrapper.h"
22
Marc Jones8ae8c882007-12-19 01:32:08 +000023/*----------------------------------------------------------------------------
24 * TYPEDEFS, DEFINITIONS AND MACROS
25 *
26 *----------------------------------------------------------------------------
27 */
28
29/* Single CPU system? */
Timothy Pearson88d213a2015-01-23 20:28:13 -060030#if (CONFIG_MAX_PHYSICAL_CPUS == 1)
31 /* FIXME
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020032 * This #define is used by other #included .c files
Timothy Pearson88d213a2015-01-23 20:28:13 -060033 * When set, multiprocessor support is completely disabled
Elyes HAOUAS6e8b3c12016-09-02 19:22:00 +020034 */
Marc Jones8ae8c882007-12-19 01:32:08 +000035 #define HT_BUILD_NC_ONLY 1
36#endif
37
38/* Debugging Options */
39#define AMD_DEBUG 1
40//#define AMD_DEBUG_ERROR_STOP 1
41
42/*----------------------------------------------------------------------------
43 * MODULES USED
44 *
45 *----------------------------------------------------------------------------
46 */
47
48#undef FILECODE
49#define FILECODE 0xFF01
50#include "comlib.h"
51#include "h3gtopo.h"
52#include "h3finit.h"
53
Marc Jones8ae8c882007-12-19 01:32:08 +000054/*----------------------------------------------------------------------------
55 * LOCAL FUNCTIONS
56 *
57 *----------------------------------------------------------------------------
58 */
59
Timothy Pearson0122afb2015-07-30 14:07:15 -050060static const char * event_class_string_decodes[] = {
61 [HT_EVENT_CLASS_CRITICAL] = "CRITICAL",
62 [HT_EVENT_CLASS_ERROR] = "ERROR",
63 [HT_EVENT_CLASS_HW_FAULT] = "HARDWARE FAULT",
64 [HT_EVENT_CLASS_WARNING] = "WARNING",
65 [HT_EVENT_CLASS_INFO] = "INFO"
66};
67
Timothy Pearson69056d92015-11-16 11:48:38 -060068typedef struct {
69 uint32_t code;
Elyes HAOUASfd051dc2018-07-08 12:39:34 +020070 const char *string;
Timothy Pearson69056d92015-11-16 11:48:38 -060071} event_string_decode_t;
72
73static const event_string_decode_t event_string_decodes[] = {
74 { HT_EVENT_COH_EVENTS, "HT_EVENT_COH_EVENTS" },
75 { HT_EVENT_COH_NO_TOPOLOGY, "HT_EVENT_COH_NO_TOPOLOGY" },
76 { HT_EVENT_COH_LINK_EXCEED, "HT_EVENT_COH_LINK_EXCEED" },
77 { HT_EVENT_COH_FAMILY_FEUD, "HT_EVENT_COH_FAMILY_FEUD" },
78 { HT_EVENT_COH_NODE_DISCOVERED, "HT_EVENT_COH_NODE_DISCOVERED" },
79 { HT_EVENT_COH_MPCAP_MISMATCH, "HT_EVENT_COH_MPCAP_MISMATCH" },
80 { HT_EVENT_NCOH_EVENTS, "HT_EVENT_NCOH_EVENTS" },
81 { HT_EVENT_NCOH_BUID_EXCEED, "HT_EVENT_NCOH_BUID_EXCEED" },
82 { HT_EVENT_NCOH_LINK_EXCEED, "HT_EVENT_NCOH_LINK_EXCEED" },
83 { HT_EVENT_NCOH_BUS_MAX_EXCEED, "HT_EVENT_NCOH_BUS_MAX_EXCEED" },
84 { HT_EVENT_NCOH_CFG_MAP_EXCEED, "HT_EVENT_NCOH_CFG_MAP_EXCEED" },
85 { HT_EVENT_NCOH_DEVICE_FAILED, "HT_EVENT_NCOH_DEVICE_FAILED" },
86 { HT_EVENT_NCOH_AUTO_DEPTH, "HT_EVENT_NCOH_AUTO_DEPTH" },
87 { HT_EVENT_OPT_EVENTS, "HT_EVENT_OPT_EVENTS" },
88 { HT_EVENT_OPT_REQUIRED_CAP_RETRY, "HT_EVENT_OPT_REQUIRED_CAP_RETRY" },
89 { HT_EVENT_OPT_REQUIRED_CAP_GEN3, "HT_EVENT_OPT_REQUIRED_CAP_GEN3" },
90 { HT_EVENT_HW_EVENTS, "HT_EVENT_HW_EVENTS" },
91 { HT_EVENT_HW_SYNCHFLOOD, "HT_EVENT_HW_SYNCHFLOOD" },
92 { HT_EVENT_HW_HTCRC, "HT_EVENT_HW_HTCRC" }
Timothy Pearson0122afb2015-07-30 14:07:15 -050093};
Marc Jones8ae8c882007-12-19 01:32:08 +000094
Elyes HAOUASfd051dc2018-07-08 12:39:34 +020095static const char *event_string_decode(uint32_t event)
96{
Timothy Pearson69056d92015-11-16 11:48:38 -060097 uint32_t i;
98 for (i = 0; i < ARRAY_SIZE(event_string_decodes); i++)
99 if (event_string_decodes[i].code == event)
100 break;
101 if (i == ARRAY_SIZE(event_string_decodes))
102 return "ERROR: Unmatched event code! "
103 "Did you forget to update event_string_decodes[]?";
104 return event_string_decodes[i].string;
105}
106
Marc Jones8ae8c882007-12-19 01:32:08 +0000107/**
108 * void AMD_CB_EventNotify (u8 evtClass, u16 event, const u8 *pEventData0)
Marc Jones8ae8c882007-12-19 01:32:08 +0000109 */
Myles Watson075fbe82010-04-15 05:19:29 +0000110static void AMD_CB_EventNotify (u8 evtClass, u16 event, const u8 *pEventData0)
Marc Jones8ae8c882007-12-19 01:32:08 +0000111{
Timothy Pearson0122afb2015-07-30 14:07:15 -0500112 uint8_t i;
113 uint8_t log_level;
114 uint8_t dump_event_detail;
Marc Joneseafcedd2008-07-17 19:54:06 +0000115
Paul Menzel33292622017-03-03 14:41:33 +0100116 printk(BIOS_DEBUG, "%s: ", __func__);
Marc Joneseafcedd2008-07-17 19:54:06 +0000117
Timothy Pearson0122afb2015-07-30 14:07:15 -0500118 /* Decode event */
119 dump_event_detail = 1;
120 switch (evtClass) {
121 case HT_EVENT_CLASS_CRITICAL:
122 case HT_EVENT_CLASS_ERROR:
123 case HT_EVENT_CLASS_HW_FAULT:
124 case HT_EVENT_CLASS_WARNING:
125 case HT_EVENT_CLASS_INFO:
126 log_level = BIOS_DEBUG;
Paul Menzelf6776fa2017-01-20 14:49:35 +0100127 printk(log_level, "%s", event_class_string_decodes[evtClass]);
Timothy Pearson0122afb2015-07-30 14:07:15 -0500128 break;
129 default:
130 log_level = BIOS_DEBUG;
131 printk(log_level, "UNKNOWN");
132 break;
Marc Joneseafcedd2008-07-17 19:54:06 +0000133 }
Timothy Pearson0122afb2015-07-30 14:07:15 -0500134 printk(log_level, ": ");
Marc Jones8ae8c882007-12-19 01:32:08 +0000135
Elyes HAOUAS0ce41f12018-11-13 10:03:31 +0100136 switch (event) {
Timothy Pearson0122afb2015-07-30 14:07:15 -0500137 case HT_EVENT_COH_EVENTS:
138 case HT_EVENT_COH_NO_TOPOLOGY:
139 case HT_EVENT_COH_LINK_EXCEED:
140 case HT_EVENT_COH_FAMILY_FEUD:
Paul Menzelf6776fa2017-01-20 14:49:35 +0100141 printk(log_level, "%s", event_string_decode(event));
Timothy Pearson0122afb2015-07-30 14:07:15 -0500142 break;
143 case HT_EVENT_COH_NODE_DISCOVERED:
144 {
145 printk(log_level, "HT_EVENT_COH_NODE_DISCOVERED");
146 sHtEventCohNodeDiscovered *evt = (sHtEventCohNodeDiscovered*)pEventData0;
147 printk(log_level, ": node %d link %d new node: %d",
148 evt->node, evt->link, evt->newNode);
149 dump_event_detail = 0;
150 break;
151 }
152 case HT_EVENT_COH_MPCAP_MISMATCH:
153 case HT_EVENT_NCOH_EVENTS:
154 case HT_EVENT_NCOH_BUID_EXCEED:
155 case HT_EVENT_NCOH_LINK_EXCEED:
156 case HT_EVENT_NCOH_BUS_MAX_EXCEED:
157 case HT_EVENT_NCOH_CFG_MAP_EXCEED:
Paul Menzelf6776fa2017-01-20 14:49:35 +0100158 printk(log_level, "%s", event_string_decode(event));
Timothy Pearson0122afb2015-07-30 14:07:15 -0500159 break;
160 case HT_EVENT_NCOH_DEVICE_FAILED:
161 {
Paul Menzelf6776fa2017-01-20 14:49:35 +0100162 printk(log_level, "%s", event_string_decode(event));
Timothy Pearson0122afb2015-07-30 14:07:15 -0500163 sHtEventNcohDeviceFailed *evt = (sHtEventNcohDeviceFailed*)pEventData0;
164 printk(log_level, ": node %d link %d depth: %d attemptedBUID: %d",
165 evt->node, evt->link, evt->depth, evt->attemptedBUID);
166 dump_event_detail = 0;
167 break;
168 }
169 case HT_EVENT_NCOH_AUTO_DEPTH:
170 {
Paul Menzelf6776fa2017-01-20 14:49:35 +0100171 printk(log_level, "%s", event_string_decode(event));
Timothy Pearson0122afb2015-07-30 14:07:15 -0500172 sHtEventNcohAutoDepth *evt = (sHtEventNcohAutoDepth*)pEventData0;
173 printk(log_level, ": node %d link %d depth: %d",
174 evt->node, evt->link, evt->depth);
175 dump_event_detail = 0;
176 break;
177 }
178 case HT_EVENT_OPT_EVENTS:
179 case HT_EVENT_OPT_REQUIRED_CAP_RETRY:
180 case HT_EVENT_OPT_REQUIRED_CAP_GEN3:
181 case HT_EVENT_HW_EVENTS:
182 case HT_EVENT_HW_SYNCHFLOOD:
183 case HT_EVENT_HW_HTCRC:
Paul Menzelf6776fa2017-01-20 14:49:35 +0100184 printk(log_level, "%s", event_string_decode(event));
Timothy Pearson0122afb2015-07-30 14:07:15 -0500185 break;
186 default:
187 printk(log_level, "HT_EVENT_UNKNOWN");
188 break;
189 }
190 printk(log_level, "\n");
191
192 if (dump_event_detail) {
193 printk(BIOS_DEBUG, " event class: %02x\n event: %04x\n data: ", evtClass, event);
194
195 for (i = 0; i < *pEventData0; i++) {
196 printk(BIOS_DEBUG, " %02x ", *(pEventData0 + i));
197 }
198 printk(BIOS_DEBUG, "\n");
199 }
Marc Jones8ae8c882007-12-19 01:32:08 +0000200}
201
202/**
203 * void getAmdTopolist(u8 ***p)
204 *
205 * point to the stock topo list array
206 *
207 */
208void getAmdTopolist(u8 ***p)
209{
210 *p = (u8 **)amd_topo_list;
211}
212
Timothy Pearson1c4508e2015-09-05 17:50:29 -0500213/**
214 * BOOL AMD_CB_IgnoreLink(u8 Node, u8 Link)
215 * Description:
216 * This routine is used to ignore connected yet faulty HT links,
217 * such as those present in a G34 processor package.
218 *
219 * Parameters:
220 * @param[in] node = The node on which this chain is located
221 * @param[in] link = The link on the host for this chain
222 */
223static BOOL AMD_CB_IgnoreLink (u8 node, u8 link)
224{
225 return 0;
226}
Marc Jones8ae8c882007-12-19 01:32:08 +0000227
228/**
229 * void amd_ht_init(struct sys_info *sysinfo)
230 *
Stefan Reinauerf8ee1802008-01-18 15:08:58 +0000231 * AMD HT init coreboot wrapper
Marc Jones8ae8c882007-12-19 01:32:08 +0000232 *
233 */
Damien Zammit75a3d1f2016-11-28 00:29:10 +1100234void amd_ht_init(struct sys_info *sysinfo)
Marc Jones8ae8c882007-12-19 01:32:08 +0000235{
Marc Joneseafcedd2008-07-17 19:54:06 +0000236
Damien Zammit33aaa922016-02-10 14:01:36 +1100237 if (!sysinfo) {
Paul Menzel33292622017-03-03 14:41:33 +0100238 printk(BIOS_DEBUG, "Skipping %s\n", __func__);
Damien Zammit33aaa922016-02-10 14:01:36 +1100239 return;
240 }
241
Marc Jones8ae8c882007-12-19 01:32:08 +0000242 AMD_HTBLOCK ht_wrapper = {
243 NULL, // u8 **topolist;
244 0, // u8 AutoBusStart;
245 32, // u8 AutoBusMax;
246 6, // u8 AutoBusIncrement;
Timothy Pearson1c4508e2015-09-05 17:50:29 -0500247 AMD_CB_IgnoreLink, // BOOL (*AMD_CB_IgnoreLink)();
Marc Jones8ae8c882007-12-19 01:32:08 +0000248 NULL, // BOOL (*AMD_CB_OverrideBusNumbers)();
Marc Joneseafcedd2008-07-17 19:54:06 +0000249 AMD_CB_ManualBUIDSwapList, // BOOL (*AMD_CB_ManualBUIDSwapList)();
Marc Jones8ae8c882007-12-19 01:32:08 +0000250 NULL, // void (*AMD_CB_DeviceCapOverride)();
251 NULL, // void (*AMD_CB_Cpu2CpuPCBLimits)();
252 NULL, // void (*AMD_CB_IOPCBLimits)();
253 NULL, // BOOL (*AMD_CB_SkipRegang)();
254 NULL, // BOOL (*AMD_CB_CustomizeTrafficDistribution)();
255 NULL, // BOOL (*AMD_CB_CustomizeBuffers)();
256 NULL, // void (*AMD_CB_OverrideDevicePort)();
257 NULL, // void (*AMD_CB_OverrideCpuPort)();
Timothy Pearson586d6e22015-02-16 14:57:06 -0600258 AMD_CB_EventNotify, // void (*AMD_CB_EventNotify) ();
259 &sysinfo->ht_link_cfg // struct ht_link_config*
Marc Jones8ae8c882007-12-19 01:32:08 +0000260 };
261
Paul Menzel33292622017-03-03 14:41:33 +0100262 printk(BIOS_DEBUG, "Enter %s\n", __func__);
Marc Jones8ae8c882007-12-19 01:32:08 +0000263 amdHtInitialize(&ht_wrapper);
Paul Menzel33292622017-03-03 14:41:33 +0100264 printk(BIOS_DEBUG, "Exit %s\n", __func__);
Timothy Pearson1c4508e2015-09-05 17:50:29 -0500265}
Marc Jones8ae8c882007-12-19 01:32:08 +0000266
Timothy Pearson1c4508e2015-09-05 17:50:29 -0500267/**
268 * void amd_ht_fixup(struct sys_info *sysinfo)
269 *
270 * AMD HT fixup
271 *
272 */
273void amd_ht_fixup(struct sys_info *sysinfo) {
Paul Menzel33292622017-03-03 14:41:33 +0100274 printk(BIOS_DEBUG, "%s\n", __func__);
Timothy Pearson1c4508e2015-09-05 17:50:29 -0500275 if (IS_ENABLED(CONFIG_CPU_AMD_MODEL_10XXX)) {
276 uint8_t rev_gte_d = 0;
Timothy Pearson730a0432015-10-16 13:51:51 -0500277 uint8_t fam15h = 0;
Timothy Pearson1c4508e2015-09-05 17:50:29 -0500278 uint8_t dual_node = 0;
279 uint32_t f3xe8;
280 uint32_t family;
281 uint32_t model;
Marc Jones8ae8c882007-12-19 01:32:08 +0000282
Timothy Pearson1c4508e2015-09-05 17:50:29 -0500283 family = model = cpuid_eax(0x80000001);
Timothy Pearson730a0432015-10-16 13:51:51 -0500284 model = ((model & 0xf0000) >> 12) | ((model & 0xf0) >> 4);
285 family = ((family & 0xf00000) >> 16) | ((family & 0xf00) >> 8);
Timothy Pearson1c4508e2015-09-05 17:50:29 -0500286
Timothy Pearson730a0432015-10-16 13:51:51 -0500287 if (family >= 0x6f)
288 /* Family 15h or later */
289 fam15h = 1;
290
291 if ((model >= 0x8) || fam15h)
292 /* Family 10h Revision D or later */
Timothy Pearson1c4508e2015-09-05 17:50:29 -0500293 rev_gte_d = 1;
294
295 if (rev_gte_d) {
296 f3xe8 = pci_read_config32(NODE_PCI(0, 3), 0xe8);
297
298 /* Check for dual node capability */
299 if (f3xe8 & 0x20000000)
300 dual_node = 1;
301
302 if (dual_node) {
303 /* Each G34 processor contains a defective HT link.
Timothy Pearson730a0432015-10-16 13:51:51 -0500304 * See the Family 10h BKDG Rev 3.62 section 2.7.1.5 for details
305 * For Family 15h see the BKDG Rev. 3.14 section 2.12.1.5 for details.
Timothy Pearson1c4508e2015-09-05 17:50:29 -0500306 */
307 uint8_t node;
308 uint8_t node_count = get_nodes();
309 uint32_t dword;
310 for (node = 0; node < node_count; node++) {
311 f3xe8 = pci_read_config32(NODE_PCI(node, 3), 0xe8);
312 uint8_t internal_node_number = ((f3xe8 & 0xc0000000) >> 30);
Paul Menzel33292622017-03-03 14:41:33 +0100313 printk(BIOS_DEBUG,
314 "%s: node %d (internal node "
315 "ID %d): disabling defective "
316 "HT link", __func__, node,
317 internal_node_number);
Timothy Pearson1c4508e2015-09-05 17:50:29 -0500318 if (internal_node_number == 0) {
Timothy Pearson730a0432015-10-16 13:51:51 -0500319 uint8_t package_link_3_connected = pci_read_config32(NODE_PCI(node, 0), (fam15h)?0x98:0xd8) & 0x1;
Timothy Pearson0122afb2015-07-30 14:07:15 -0500320 printk(BIOS_DEBUG, " (L3 connected: %d)\n", package_link_3_connected);
Timothy Pearson1c4508e2015-09-05 17:50:29 -0500321 if (package_link_3_connected) {
322 /* Set WidthIn and WidthOut to 0 */
Timothy Pearson730a0432015-10-16 13:51:51 -0500323 dword = pci_read_config32(NODE_PCI(node, 0), (fam15h)?0x84:0xc4);
Timothy Pearson1c4508e2015-09-05 17:50:29 -0500324 dword &= ~0x77000000;
Timothy Pearson730a0432015-10-16 13:51:51 -0500325 pci_write_config32(NODE_PCI(node, 0), (fam15h)?0x84:0xc4, dword);
Timothy Pearson1c4508e2015-09-05 17:50:29 -0500326 /* Set Ganged to 1 */
Timothy Pearson730a0432015-10-16 13:51:51 -0500327 dword = pci_read_config32(NODE_PCI(node, 0), (fam15h)?0x170:0x178);
Timothy Pearson1c4508e2015-09-05 17:50:29 -0500328 dword |= 0x00000001;
Timothy Pearson730a0432015-10-16 13:51:51 -0500329 pci_write_config32(NODE_PCI(node, 0), (fam15h)?0x170:0x178, dword);
Timothy Pearson1c4508e2015-09-05 17:50:29 -0500330 } else {
331 /* Set ConnDly to 1 */
332 dword = pci_read_config32(NODE_PCI(node, 0), 0x16c);
333 dword |= 0x00000100;
334 pci_write_config32(NODE_PCI(node, 0), 0x16c, dword);
335 /* Set TransOff and EndOfChain to 1 */
Timothy Pearson730a0432015-10-16 13:51:51 -0500336 dword = pci_read_config32(NODE_PCI(node, 4), (fam15h)?0x84:0xc4);
Timothy Pearson1c4508e2015-09-05 17:50:29 -0500337 dword |= 0x000000c0;
Timothy Pearson730a0432015-10-16 13:51:51 -0500338 pci_write_config32(NODE_PCI(node, 4), (fam15h)?0x84:0xc4, dword);
Timothy Pearson1c4508e2015-09-05 17:50:29 -0500339 }
340 } else if (internal_node_number == 1) {
Timothy Pearson730a0432015-10-16 13:51:51 -0500341 uint8_t package_link_3_connected = pci_read_config32(NODE_PCI(node, 0), (fam15h)?0xf8:0xb8) & 0x1;
Timothy Pearson0122afb2015-07-30 14:07:15 -0500342 printk(BIOS_DEBUG, " (L3 connected: %d)\n", package_link_3_connected);
Timothy Pearson1c4508e2015-09-05 17:50:29 -0500343 if (package_link_3_connected) {
344 /* Set WidthIn and WidthOut to 0 */
Timothy Pearson730a0432015-10-16 13:51:51 -0500345 dword = pci_read_config32(NODE_PCI(node, 0), (fam15h)?0xe4:0xa4);
Timothy Pearson1c4508e2015-09-05 17:50:29 -0500346 dword &= ~0x77000000;
Timothy Pearson730a0432015-10-16 13:51:51 -0500347 pci_write_config32(NODE_PCI(node, 0), (fam15h)?0xe4:0xa4, dword);
Timothy Pearson1c4508e2015-09-05 17:50:29 -0500348 /* Set Ganged to 1 */
Timothy Pearson0122afb2015-07-30 14:07:15 -0500349 /* WARNING
350 * The Family 15h BKDG states that 0x18c should be set,
351 * however this is in error. 0x17c is the correct control
352 * register (sublink 0) for these processors...
353 */
354 dword = pci_read_config32(NODE_PCI(node, 0), (fam15h)?0x17c:0x174);
Timothy Pearson1c4508e2015-09-05 17:50:29 -0500355 dword |= 0x00000001;
Timothy Pearson0122afb2015-07-30 14:07:15 -0500356 pci_write_config32(NODE_PCI(node, 0), (fam15h)?0x17c:0x174, dword);
Timothy Pearson1c4508e2015-09-05 17:50:29 -0500357 } else {
358 /* Set ConnDly to 1 */
359 dword = pci_read_config32(NODE_PCI(node, 0), 0x16c);
360 dword |= 0x00000100;
361 pci_write_config32(NODE_PCI(node, 0), 0x16c, dword);
362 /* Set TransOff and EndOfChain to 1 */
Timothy Pearson730a0432015-10-16 13:51:51 -0500363 dword = pci_read_config32(NODE_PCI(node, 4), (fam15h)?0xe4:0xa4);
Timothy Pearson1c4508e2015-09-05 17:50:29 -0500364 dword |= 0x000000c0;
Timothy Pearson730a0432015-10-16 13:51:51 -0500365 pci_write_config32(NODE_PCI(node, 4), (fam15h)?0xe4:0xa4, dword);
Timothy Pearson1c4508e2015-09-05 17:50:29 -0500366 }
367 }
368 }
369 }
370 }
371 }
Marc Jones8ae8c882007-12-19 01:32:08 +0000372}
Damien Zammit75a3d1f2016-11-28 00:29:10 +1100373
374u32 get_nodes(void)
375{
376 pci_devfn_t dev;
377 u32 nodes;
378
379 dev = PCI_DEV(CONFIG_CBB, CONFIG_CDB, 0);
380 nodes = ((pci_read_config32(dev, 0x60)>>4) & 7);
381#if CONFIG_MAX_PHYSICAL_CPUS > 8
382 nodes += (((pci_read_config32(dev, 0x160)>>4) & 7)<<3);
383#endif
384 nodes++;
385
386 return nodes;
387}