1/* 2 * This file is part of the coreboot project. 3 * 4 * Copyright (C) 2005 - 2008 Advanced Micro Devices, Inc. 5 * Copyright (C) 2007 coresystems GmbH 6 * 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. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21 22// 2005.9 yhlu serengeti support 23// 2005.9 yhlu modify that to more dynamic for AMD Opteron Based MB 24// 2007.9 stepan improve code documentation 25 26#include <mainboard.h> 27#include <console.h> 28#include <mtrr.h> 29#include <macros.h> 30#include <spd.h> 31#include <cpu.h> 32#include <msr.h> 33#include <amd/k8/k8.h> 34#include <amd/k8/sysconf.h> 35#include <device/pci.h> 36#include <device/hypertransport_def.h> 37#include <mc146818rtc.h> 38#include <lib.h> 39 40 41#if 0 42unsigned node_link_to_bus(unsigned node, unsigned link) 43{ 44 struct device * dev; 45 unsigned reg; 46 47 dev = dev_find_slot(0, PCI_DEVFN(0x18, 1)); 48 if (!dev) { 49 return 0; 50 } 51 for(reg = 0xE0; reg < 0xF0; reg += 0x04) { 52 u32 config_map; 53 unsigned dst_node; 54 unsigned dst_link; 55 unsigned bus_base; 56 config_map = pci_read_config32(dev, reg); 57 if ((config_map & 3) != 3) { 58 continue; 59 } 60 dst_node = (config_map >> 4) & 7; 61 dst_link = (config_map >> 8) & 3; 62 bus_base = (config_map >> 16) & 0xff; 63#if 0 64 printk(BIOS_DEBUG, "node.link=bus: %d.%d=%d 0x%2x->0x%08x\n", 65 dst_node, dst_link, bus_base, 66 reg, config_map); 67#endif 68 if ((dst_node == node) && (dst_link == link)) 69 { 70 return bus_base; 71 } 72 } 73 return 0; 74} 75#endif 76 77 78/** 79 * Why we need the pci1234[] array 80 * 81 * It will keep the sequence of HT devices in the HT link registers even when a 82 * given HT I/O card is not installed. 83 * 84 * The final result for pci1234[] will be 85 * 86 * pci1234[0] will record the south bridge link and bus range 87 * pci1234[i] will record HT chain i. 88 * 89 * For example, on the Tyan S2885 linxbios_ram will put the AMD8151 chain (HT 90 * link 0) into the register 0xE0, and the AMD8131/8111 HT chain into the 91 * register 0xE4. 92 * 93 * So we need to make sure that the south bridge link will always be on 94 * pci1234[0]. 95 * 96 * Imagine a scenario with multiple HT I/O cards, where you don't install HT I/O 1, 97 * but you only install HT I/O 2 and HT I/O 3. The HT I/Os will end up in registers 98 * 0xE4 and 0xE8. 99 * 100 * But we want to leave pci1234[1] to HT I/O 1 (even though it is disabled), 101 * and let HT I/O 2 and HT I/O 3 still use pci1234[2] and pci1234[3]. 102 * 103 * So we keep the sequence. You need to preset the pci1234[1], pci1234[2], 104 * pci1234[3] for this purpose. 105 * 106 * For this example you need to set 107 * 108 * unsigned pci1234[] = { 109 * 0x0000ff0, 110 * 0x0000f10, // HT IO 1 card always on node 1 111 * 0x0000f20, // HT IO 2 card always on node 2 112 * 0x0000f30 // HT IO 3 card always on node 3 113 * }; 114 * 115 * For 2P + htio(n1) + htio(n0_1) + htio(n1_1), 2P + htio(n1) + 2P + htio(n2) + htio(n3): 116 * You need an array pci1234[6]: 117 * 118 * unsigned pci1234[] = { 119 * 0x0000ff0, 120 * 0x0000010, // HT IO 1 card always on node 1 121 * 0x0000f00, // HT IO 2 card always on node 0 122 * 0x0000110, // HT IO 3 card always on node 1 123 * 0x0000f20, // HT IO 4 card always on node 2 124 * 0x0000f30 // HT IO 5 card always on node 3 125 * }; 126 * 127 * 128 * For 4p+htio(n1)+htio(n2)+htio(n3),4p+htio(n1)+4p+htio(n6)+htio(n7): 129 * You need an array pci1234[6]: 130 * 131 * unsigned pci1234[] = { 132 * 0x0000ff0, 133 * 0x0000f10, // HT IO 1 card always on node 1 134 * 0x0000f20, // HT IO 2 card always on node 2 135 * 0x0000f30, // HT IO 3 card always on node 3 136 * 0x0000f60, // HT IO 4 card always on node 6 137 * 0x0000f70 // HT IO 5 card always on node 7 138 * }; 139 * 140 * 141 * For 2p + htio(n1) + htio(n0_1) + htio(n1_1), 2P + htio(n1) + 2P + 142 * htio(n2) + htio(n3), 2P + htio(n1) + 4P + htio(n4) + htio(n5), 143 * you need an array pci1234[8]: 144 * 145 * unsigned pci1234[] = { 146 * 0x0000ff0, 147 * 0x0000010, // HT IO 1 card always on node 1 148 * 0x0000f00, // HT IO 2 card always on node 0 149 * 0x0000110, // HT IO 3 card always on node 1 150 * 0x0000f20, // HT IO 4 card always on node 2 151 * 0x0000f30 // HT IO 5 card always on node 3 152 * 0x0000f40, // HT IO 6 card always on node 4 153 * 0x0000f50 // HT IO 7 card always on node 5 154 * }; 155 * 156 * 157 * For 4P + htio(n1) + htio(n2) + htio(n3), 4p + htio(n1) + 2p + htio(n4) + 158 * htio(n5), 4p + htio(n1) + 4p + htio(n6) + htio(n7), 159 * you need an array pci1234[8]: 160 * 161 * unsigned pci1234[] = { 162 * 0x0000ff0, 163 * 0x0000f10, // HT IO 1 card always on node 1 164 * 0x0000f20, // HT IO 2 card always on node 2 165 * 0x0000f30, // HT IO 3 card always on node 3 166 * 0x0000f40, // HT IO 4 card always on node 4 167 * 0x0000f50 // HT IO 5 card always on node 5 168 * 0x0000f60, // HT IO 6 card always on node 6 169 * 0x0000f70 // HT IO 7 card always on node 7 170 * }; 171 * 172 * 173 * So the maximum posible value of HC_POSSIBLE_NUM is 8. (FIXME Why?) 174 * 175 * 1n: 3 176 * 2n: 2x2 - 1 177 * 4n: 1x4 - 2 178 * 6n: 2 179 * 8n: 2 180 * Total: 12 181 * 182 * Just put all the possible HT Node/link to the list tp pci1234[] in 183 * src/mainboard/<vendor>/<mainboard>get_bus_conf.c 184 * 185 * Also don't forget to increase the ACPI_SSDTX_NUM etc (FIXME what else) if 186 * you have too many SSDTs 187 * 188 * What about co-processor in socket 1 on a 2 way system? Or socket 2 and 189 * socket 3 on a 4 way system? Treat that as an HC, too! 190 * 191 */ 192 193void get_sblk_pci1234(void) 194{ 195 196 struct device * dev; 197 int i,j; 198 u32 dword; 199 200 /* read PCI_DEV(0,0x18,0) 0x64 bit [8:9] to find out SbLink m */ 201 dev = dev_find_slot(0, PCI_DEVFN(0x18,0)); 202 dword = pci_read_config32(dev, 0x64); 203 sysconf.sblk = (dword>>8) & 0x3; 204 205 dword &=0x0300; 206 dword |= 1; 207 sysconf.pci1234[0] = dword; 208 sysconf.hcid[0] = 0; 209 210 /* About hardcoded numbering for HT_IO support 211 * 212 * Set the node_id and link_id that could have a HT chain in the one 213 * array, (FIXME: which one?) then check if is enabled. Then update 214 * final value 215 */ 216 217 /* Here we need to set hcdn 218 * 219 * 1. hypertransport.c needs to record hcdn_reg together with 0xe0, 220 * 0xe4, 0xe8, 0xec when are set (FIXME: when WHAT is set?) 221 * 222 * 2. So at the same time we need update hcdn with hcdn_reg here. FIXME: Why? 223 */ 224 225 dev = dev_find_slot(0, PCI_DEVFN(0x18, 1)); 226 227 for(j=0;j<4;j++) { 228 u32 dwordx; 229 dwordx = pci_read_config32(dev, 0xe0 + j*4); 230 dwordx &=0xffff0ff1; /* keep bus num, node_id, link_num, enable bits */ 231 if((dwordx & 0xff1) == dword) { /* SBLINK */ 232 sysconf.pci1234[0] = dwordx; 233 sysconf.hcdn[0] = sysconf.hcdn_reg[j]; 234 continue; 235 } 236 237 if((dwordx & 1) == 1) { 238 /* We need to find out the number of HC 239 * for exact match 240 */ 241 for(i=1;i<sysconf.hc_possible_num;i++) { 242 if((dwordx & 0xff0) == (sysconf.pci1234[i] & 0xff0)) { 243 sysconf.pci1234[i] = dwordx; 244 sysconf.hcdn[i] = sysconf.hcdn_reg[j]; 245 break; 246 } 247 } 248 249 /* For 0xff0 match or same node */ 250 for(i=1;i<sysconf.hc_possible_num;i++) { 251 if((dwordx & 0xff0) == (dwordx & sysconf.pci1234[i] & 0xff0)) { 252 sysconf.pci1234[i] = dwordx; 253 sysconf.hcdn[i] = sysconf.hcdn_reg[j]; 254 break; 255 } 256 } 257 } 258 } 259 260 for(i=1;i<sysconf.hc_possible_num;i++) { 261 if((sysconf.pci1234[i] & 1) != 1) { 262 sysconf.pci1234[i] = 0; 263 sysconf.hcdn[i] = 0x20202020; 264 } 265 sysconf.hcid[i] = 0; 266 } 267 268} 269 270

