1 #include <linux/init.h> 2 #include <linux/pci.h> 3 #include <linux/topology.h> 4 #include <linux/cpu.h> 5 #include <linux/range.h> 6 7 #include <asm/pci_x86.h> 8 9 #include <asm/pci-direct.h> 10 11 #include "bus_numa.h" 12 13 /* 14 * This discovers the pcibus <-> node mapping on AMD K8. 15 * also get peer root bus resource for io,mmio 16 */ 17 18 struct pci_hostbridge_probe { 19 u32 bus; 20 u32 slot; 21 u32 vendor; 22 u32 device; 23 }; 24 25 static struct pci_hostbridge_probe pci_probes[] __initdata = { 26 { 0, 0x18, PCI_VENDOR_ID_AMD, 0x1100 }, 27 { 0, 0x18, PCI_VENDOR_ID_AMD, 0x1200 }, 28 { 0xff, 0, PCI_VENDOR_ID_AMD, 0x1200 }, 29 { 0, 0x18, PCI_VENDOR_ID_AMD, 0x1300 }, 30 }; 31 32 static u64 __initdata fam10h_mmconf_start; 33 static u64 __initdata fam10h_mmconf_end; 34 static void __init get_pci_mmcfg_amd_fam10h_range(void) 35 { 36 u32 address; 37 u64 base, msr; 38 unsigned segn_busn_bits; 39 40 /* assume all cpus from fam10h have mmconf */ 41 if (boot_cpu_data.x86 < 0x10) 42 return; 43 44 address = MSR_FAM10H_MMIO_CONF_BASE; 45 rdmsrl(address, msr); 46 47 /* mmconfig is not enable */ 48 if (!(msr & FAM10H_MMIO_CONF_ENABLE)) 49 return; 50 51 base = msr & (FAM10H_MMIO_CONF_BASE_MASK<<FAM10H_MMIO_CONF_BASE_SHIFT); 52 53 segn_busn_bits = (msr >> FAM10H_MMIO_CONF_BUSRANGE_SHIFT) & 54 FAM10H_MMIO_CONF_BUSRANGE_MASK; 55 56 fam10h_mmconf_start = base; 57 fam10h_mmconf_end = base + (1ULL<<(segn_busn_bits + 20)) - 1; 58 } 59 60 #define RANGE_NUM 16 61 62 /** 63 * early_fill_mp_bus_to_node() 64 * called before pcibios_scan_root and pci_scan_bus 65 * fills the mp_bus_to_cpumask array based according to the LDT Bus Number 66 * Registers found in the K8 northbridge 67 */ 68 static int __init early_fill_mp_bus_info(void) 69 { 70 int i; 71 int j; 72 unsigned bus; 73 unsigned slot; 74 int node; 75 int link; 76 int def_node; 77 int def_link; 78 struct pci_root_info *info; 79 u32 reg; 80 struct resource *res; 81 u64 start; 82 u64 end; 83 struct range range[RANGE_NUM]; 84 u64 val; 85 u32 address; 86 bool found; 87 88 if (!early_pci_allowed()) 89 return -1; 90 91 found = false; 92 for (i = 0; i < ARRAY_SIZE(pci_probes); i++) { 93 u32 id; 94 u16 device; 95 u16 vendor; 96 97 bus = pci_probes[i].bus; 98 slot = pci_probes[i].slot; 99 id = read_pci_config(bus, slot, 0, PCI_VENDOR_ID); 100 101 vendor = id & 0xffff; 102 device = (id>>16) & 0xffff; 103 if (pci_probes[i].vendor == vendor && 104 pci_probes[i].device == device) { 105 found = true; 106 break; 107 } 108 } 109 110 if (!found) 111 return 0; 112 113 pci_root_num = 0; 114 for (i = 0; i < 4; i++) { 115 int min_bus; 116 int max_bus; 117 reg = read_pci_config(bus, slot, 1, 0xe0 + (i << 2)); 118 119 /* Check if that register is enabled for bus range */ 120 if ((reg & 7) != 3) 121 continue; 122 123 min_bus = (reg >> 16) & 0xff; 124 max_bus = (reg >> 24) & 0xff; 125 node = (reg >> 4) & 0x07; 126 #ifdef CONFIG_NUMA 127 for (j = min_bus; j <= max_bus; j++) 128 set_mp_bus_to_node(j, node); 129 #endif 130 link = (reg >> 8) & 0x03; 131 132 info = &pci_root_info[pci_root_num]; 133 info->bus_min = min_bus; 134 info->bus_max = max_bus; 135 info->node = node; 136 info->link = link; 137 sprintf(info->name, "PCI Bus #%02x", min_bus); 138 pci_root_num++; 139 } 140 141 /* get the default node and link for left over res */ 142 reg = read_pci_config(bus, slot, 0, 0x60); 143 def_node = (reg >> 8) & 0x07; 144 reg = read_pci_config(bus, slot, 0, 0x64); 145 def_link = (reg >> 8) & 0x03; 146 147 memset(range, 0, sizeof(range)); 148 add_range(range, RANGE_NUM, 0, 0, 0xffff + 1); 149 /* io port resource */ 150 for (i = 0; i < 4; i++) { 151 reg = read_pci_config(bus, slot, 1, 0xc0 + (i << 3)); 152 if (!(reg & 3)) 153 continue; 154 155 start = reg & 0xfff000; 156 reg = read_pci_config(bus, slot, 1, 0xc4 + (i << 3)); 157 node = reg & 0x07; 158 link = (reg >> 4) & 0x03; 159 end = (reg & 0xfff000) | 0xfff; 160 161 /* find the position */ 162 for (j = 0; j < pci_root_num; j++) { 163 info = &pci_root_info[j]; 164 if (info->node == node && info->link == link) 165 break; 166 } 167 if (j == pci_root_num) 168 continue; /* not found */ 169 170 info = &pci_root_info[j]; 171 printk(KERN_DEBUG "node %d link %d: io port [%llx, %llx]\n", 172 node, link, start, end); 173 174 /* kernel only handle 16 bit only */ 175 if (end > 0xffff) 176 end = 0xffff; 177 update_res(info, start, end, IORESOURCE_IO, 1); 178 subtract_range(range, RANGE_NUM, start, end + 1); 179 } 180 /* add left over io port range to def node/link, [0, 0xffff] */ 181 /* find the position */ 182 for (j = 0; j < pci_root_num; j++) { 183 info = &pci_root_info[j]; 184 if (info->node == def_node && info->link == def_link) 185 break; 186 } 187 if (j < pci_root_num) { 188 info = &pci_root_info[j]; 189 for (i = 0; i < RANGE_NUM; i++) { 190 if (!range[i].end) 191 continue; 192 193 update_res(info, range[i].start, range[i].end - 1, 194 IORESOURCE_IO, 1); 195 } 196 } 197 198 memset(range, 0, sizeof(range)); 199 /* 0xfd00000000-0xffffffffff for HT */ 200 end = cap_resource((0xfdULL<<32) - 1); 201 end++; 202 add_range(range, RANGE_NUM, 0, 0, end); 203 204 /* need to take out [0, TOM) for RAM*/ 205 address = MSR_K8_TOP_MEM1; 206 rdmsrl(address, val); 207 end = (val & 0xffffff800000ULL); 208 printk(KERN_INFO "TOM: %016llx aka %lldM\n", end, end>>20); 209 if (end < (1ULL<<32)) 210 subtract_range(range, RANGE_NUM, 0, end); 211 212 /* get mmconfig */ 213 get_pci_mmcfg_amd_fam10h_range(); 214 /* need to take out mmconf range */ 215 if (fam10h_mmconf_end) { 216 printk(KERN_DEBUG "Fam 10h mmconf [%llx, %llx]\n", fam10h_mmconf_start, fam10h_mmconf_end); 217 subtract_range(range, RANGE_NUM, fam10h_mmconf_start, 218 fam10h_mmconf_end + 1); 219 } 220 221 /* mmio resource */ 222 for (i = 0; i < 8; i++) { 223 reg = read_pci_config(bus, slot, 1, 0x80 + (i << 3)); 224 if (!(reg & 3)) 225 continue; 226 227 start = reg & 0xffffff00; /* 39:16 on 31:8*/ 228 start <<= 8; 229 reg = read_pci_config(bus, slot, 1, 0x84 + (i << 3)); 230 node = reg & 0x07; 231 link = (reg >> 4) & 0x03; 232 end = (reg & 0xffffff00); 233 end <<= 8; 234 end |= 0xffff; 235 236 /* find the position */ 237 for (j = 0; j < pci_root_num; j++) { 238 info = &pci_root_info[j]; 239 if (info->node == node && info->link == link) 240 break; 241 } 242 if (j == pci_root_num) 243 continue; /* not found */ 244 245 info = &pci_root_info[j]; 246 247 printk(KERN_DEBUG "node %d link %d: mmio [%llx, %llx]", 248 node, link, start, end); 249 /* 250 * some sick allocation would have range overlap with fam10h 251 * mmconf range, so need to update start and end. 252 */ 253 if (fam10h_mmconf_end) { 254 int changed = 0; 255 u64 endx = 0; 256 if (start >= fam10h_mmconf_start && 257 start <= fam10h_mmconf_end) { 258 start = fam10h_mmconf_end + 1; 259 changed = 1; 260 } 261 262 if (end >= fam10h_mmconf_start && 263 end <= fam10h_mmconf_end) { 264 end = fam10h_mmconf_start - 1; 265 changed = 1; 266 } 267 268 if (start < fam10h_mmconf_start && 269 end > fam10h_mmconf_end) { 270 /* we got a hole */ 271 endx = fam10h_mmconf_start - 1; 272 update_res(info, start, endx, IORESOURCE_MEM, 0); 273 subtract_range(range, RANGE_NUM, start, 274 endx + 1); 275 printk(KERN_CONT " ==> [%llx, %llx]", start, endx); 276 start = fam10h_mmconf_end + 1; 277 changed = 1; 278 } 279 if (changed) { 280 if (start <= end) { 281 printk(KERN_CONT " %s [%llx, %llx]", endx ? "and" : "==>", start, end); 282 } else { 283 printk(KERN_CONT "%s\n", endx?"":" ==> none"); 284 continue; 285 } 286 } 287 } 288 289 update_res(info, cap_resource(start), cap_resource(end), 290 IORESOURCE_MEM, 1); 291 subtract_range(range, RANGE_NUM, start, end + 1); 292 printk(KERN_CONT "\n"); 293 } 294 295 /* need to take out [4G, TOM2) for RAM*/ 296 /* SYS_CFG */ 297 address = MSR_K8_SYSCFG; 298 rdmsrl(address, val); 299 /* TOP_MEM2 is enabled? */ 300 if (val & (1<<21)) { 301 /* TOP_MEM2 */ 302 address = MSR_K8_TOP_MEM2; 303 rdmsrl(address, val); 304 end = (val & 0xffffff800000ULL); 305 printk(KERN_INFO "TOM2: %016llx aka %lldM\n", end, end>>20); 306 subtract_range(range, RANGE_NUM, 1ULL<<32, end); 307 } 308 309 /* 310 * add left over mmio range to def node/link ? 311 * that is tricky, just record range in from start_min to 4G 312 */ 313 for (j = 0; j < pci_root_num; j++) { 314 info = &pci_root_info[j]; 315 if (info->node == def_node && info->link == def_link) 316 break; 317 } 318 if (j < pci_root_num) { 319 info = &pci_root_info[j]; 320 321 for (i = 0; i < RANGE_NUM; i++) { 322 if (!range[i].end) 323 continue; 324 325 update_res(info, cap_resource(range[i].start), 326 cap_resource(range[i].end - 1), 327 IORESOURCE_MEM, 1); 328 } 329 } 330 331 for (i = 0; i < pci_root_num; i++) { 332 int res_num; 333 int busnum; 334 335 info = &pci_root_info[i]; 336 res_num = info->res_num; 337 busnum = info->bus_min; 338 printk(KERN_DEBUG "bus: [%02x, %02x] on node %x link %x\n", 339 info->bus_min, info->bus_max, info->node, info->link); 340 for (j = 0; j < res_num; j++) { 341 res = &info->res[j]; 342 printk(KERN_DEBUG "bus: %02x index %x %pR\n", 343 busnum, j, res); 344 } 345 } 346 347 return 0; 348 } 349 350 #define ENABLE_CF8_EXT_CFG (1ULL << 46) 351 352 static void enable_pci_io_ecs(void *unused) 353 { 354 u64 reg; 355 rdmsrl(MSR_AMD64_NB_CFG, reg); 356 if (!(reg & ENABLE_CF8_EXT_CFG)) { 357 reg |= ENABLE_CF8_EXT_CFG; 358 wrmsrl(MSR_AMD64_NB_CFG, reg); 359 } 360 } 361 362 static int __cpuinit amd_cpu_notify(struct notifier_block *self, 363 unsigned long action, void *hcpu) 364 { 365 int cpu = (long)hcpu; 366 switch (action) { 367 case CPU_ONLINE: 368 case CPU_ONLINE_FROZEN: 369 smp_call_function_single(cpu, enable_pci_io_ecs, NULL, 0); 370 break; 371 default: 372 break; 373 } 374 return NOTIFY_OK; 375 } 376 377 static struct notifier_block __cpuinitdata amd_cpu_notifier = { 378 .notifier_call = amd_cpu_notify, 379 }; 380 381 static int __init pci_io_ecs_init(void) 382 { 383 int cpu; 384 385 /* assume all cpus from fam10h have IO ECS */ 386 if (boot_cpu_data.x86 < 0x10) 387 return 0; 388 389 register_cpu_notifier(&amd_cpu_notifier); 390 for_each_online_cpu(cpu) 391 amd_cpu_notify(&amd_cpu_notifier, (unsigned long)CPU_ONLINE, 392 (void *)(long)cpu); 393 pci_probe |= PCI_HAS_IO_ECS; 394 395 return 0; 396 } 397 398 static int __init amd_postcore_init(void) 399 { 400 if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) 401 return 0; 402 403 early_fill_mp_bus_info(); 404 pci_io_ecs_init(); 405 406 return 0; 407 } 408 409 postcore_initcall(amd_postcore_init); 410