xref: /openbmc/linux/arch/x86/pci/amd_bus.c (revision 93dc544c)
1 #include <linux/init.h>
2 #include <linux/pci.h>
3 #include <linux/topology.h>
4 #include "pci.h"
5 
6 #ifdef CONFIG_X86_64
7 #include <asm/pci-direct.h>
8 #include <asm/mpspec.h>
9 #include <linux/cpumask.h>
10 #endif
11 
12 /*
13  * This discovers the pcibus <-> node mapping on AMD K8.
14  * also get peer root bus resource for io,mmio
15  */
16 
17 #ifdef CONFIG_NUMA
18 
19 #define BUS_NR 256
20 
21 #ifdef CONFIG_X86_64
22 
23 static int mp_bus_to_node[BUS_NR];
24 
25 void set_mp_bus_to_node(int busnum, int node)
26 {
27 	if (busnum >= 0 &&  busnum < BUS_NR)
28 		mp_bus_to_node[busnum] = node;
29 }
30 
31 int get_mp_bus_to_node(int busnum)
32 {
33 	int node = -1;
34 
35 	if (busnum < 0 || busnum > (BUS_NR - 1))
36 		return node;
37 
38 	node = mp_bus_to_node[busnum];
39 
40 	/*
41 	 * let numa_node_id to decide it later in dma_alloc_pages
42 	 * if there is no ram on that node
43 	 */
44 	if (node != -1 && !node_online(node))
45 		node = -1;
46 
47 	return node;
48 }
49 
50 #else /* CONFIG_X86_32 */
51 
52 static unsigned char mp_bus_to_node[BUS_NR];
53 
54 void set_mp_bus_to_node(int busnum, int node)
55 {
56 	if (busnum >= 0 &&  busnum < BUS_NR)
57 	mp_bus_to_node[busnum] = (unsigned char) node;
58 }
59 
60 int get_mp_bus_to_node(int busnum)
61 {
62 	int node;
63 
64 	if (busnum < 0 || busnum > (BUS_NR - 1))
65 		return 0;
66 	node = mp_bus_to_node[busnum];
67 	return node;
68 }
69 
70 #endif /* CONFIG_X86_32 */
71 
72 #endif /* CONFIG_NUMA */
73 
74 #ifdef CONFIG_X86_64
75 
76 /*
77  * sub bus (transparent) will use entres from 3 to store extra from root,
78  * so need to make sure have enought slot there, increase PCI_BUS_NUM_RESOURCES?
79  */
80 #define RES_NUM 16
81 struct pci_root_info {
82 	char name[12];
83 	unsigned int res_num;
84 	struct resource res[RES_NUM];
85 	int bus_min;
86 	int bus_max;
87 	int node;
88 	int link;
89 };
90 
91 /* 4 at this time, it may become to 32 */
92 #define PCI_ROOT_NR 4
93 static int pci_root_num;
94 static struct pci_root_info pci_root_info[PCI_ROOT_NR];
95 
96 void set_pci_bus_resources_arch_default(struct pci_bus *b)
97 {
98 	int i;
99 	int j;
100 	struct pci_root_info *info;
101 
102 	/* if only one root bus, don't need to anything */
103 	if (pci_root_num < 2)
104 		return;
105 
106 	for (i = 0; i < pci_root_num; i++) {
107 		if (pci_root_info[i].bus_min == b->number)
108 			break;
109 	}
110 
111 	if (i == pci_root_num)
112 		return;
113 
114 	info = &pci_root_info[i];
115 	for (j = 0; j < info->res_num; j++) {
116 		struct resource *res;
117 		struct resource *root;
118 
119 		res = &info->res[j];
120 		b->resource[j] = res;
121 		if (res->flags & IORESOURCE_IO)
122 			root = &ioport_resource;
123 		else
124 			root = &iomem_resource;
125 		insert_resource(root, res);
126 	}
127 }
128 
129 #define RANGE_NUM 16
130 
131 struct res_range {
132 	size_t start;
133 	size_t end;
134 };
135 
136 static void __init update_range(struct res_range *range, size_t start,
137 				size_t end)
138 {
139 	int i;
140 	int j;
141 
142 	for (j = 0; j < RANGE_NUM; j++) {
143 		if (!range[j].end)
144 			continue;
145 
146 		if (start <= range[j].start && end >= range[j].end) {
147 			range[j].start = 0;
148 			range[j].end = 0;
149 			continue;
150 		}
151 
152 		if (start <= range[j].start && end < range[j].end && range[j].start < end + 1) {
153 			range[j].start = end + 1;
154 			continue;
155 		}
156 
157 
158 		if (start > range[j].start && end >= range[j].end && range[j].end > start - 1) {
159 			range[j].end = start - 1;
160 			continue;
161 		}
162 
163 		if (start > range[j].start && end < range[j].end) {
164 			/* find the new spare */
165 			for (i = 0; i < RANGE_NUM; i++) {
166 				if (range[i].end == 0)
167 					break;
168 			}
169 			if (i < RANGE_NUM) {
170 				range[i].end = range[j].end;
171 				range[i].start = end + 1;
172 			} else {
173 				printk(KERN_ERR "run of slot in ranges\n");
174 			}
175 			range[j].end = start - 1;
176 			continue;
177 		}
178 	}
179 }
180 
181 static void __init update_res(struct pci_root_info *info, size_t start,
182 			      size_t end, unsigned long flags, int merge)
183 {
184 	int i;
185 	struct resource *res;
186 
187 	if (!merge)
188 		goto addit;
189 
190 	/* try to merge it with old one */
191 	for (i = 0; i < info->res_num; i++) {
192 		size_t final_start, final_end;
193 		size_t common_start, common_end;
194 
195 		res = &info->res[i];
196 		if (res->flags != flags)
197 			continue;
198 
199 		common_start = max((size_t)res->start, start);
200 		common_end = min((size_t)res->end, end);
201 		if (common_start > common_end + 1)
202 			continue;
203 
204 		final_start = min((size_t)res->start, start);
205 		final_end = max((size_t)res->end, end);
206 
207 		res->start = final_start;
208 		res->end = final_end;
209 		return;
210 	}
211 
212 addit:
213 
214 	/* need to add that */
215 	if (info->res_num >= RES_NUM)
216 		return;
217 
218 	res = &info->res[info->res_num];
219 	res->name = info->name;
220 	res->flags = flags;
221 	res->start = start;
222 	res->end = end;
223 	res->child = NULL;
224 	info->res_num++;
225 }
226 
227 struct pci_hostbridge_probe {
228 	u32 bus;
229 	u32 slot;
230 	u32 vendor;
231 	u32 device;
232 };
233 
234 static struct pci_hostbridge_probe pci_probes[] __initdata = {
235 	{ 0, 0x18, PCI_VENDOR_ID_AMD, 0x1100 },
236 	{ 0, 0x18, PCI_VENDOR_ID_AMD, 0x1200 },
237 	{ 0xff, 0, PCI_VENDOR_ID_AMD, 0x1200 },
238 	{ 0, 0x18, PCI_VENDOR_ID_AMD, 0x1300 },
239 };
240 
241 static u64 __initdata fam10h_mmconf_start;
242 static u64 __initdata fam10h_mmconf_end;
243 static void __init get_pci_mmcfg_amd_fam10h_range(void)
244 {
245 	u32 address;
246 	u64 base, msr;
247 	unsigned segn_busn_bits;
248 
249 	/* assume all cpus from fam10h have mmconf */
250         if (boot_cpu_data.x86 < 0x10)
251 		return;
252 
253 	address = MSR_FAM10H_MMIO_CONF_BASE;
254 	rdmsrl(address, msr);
255 
256 	/* mmconfig is not enable */
257 	if (!(msr & FAM10H_MMIO_CONF_ENABLE))
258 		return;
259 
260 	base = msr & (FAM10H_MMIO_CONF_BASE_MASK<<FAM10H_MMIO_CONF_BASE_SHIFT);
261 
262 	segn_busn_bits = (msr >> FAM10H_MMIO_CONF_BUSRANGE_SHIFT) &
263 			 FAM10H_MMIO_CONF_BUSRANGE_MASK;
264 
265 	fam10h_mmconf_start = base;
266 	fam10h_mmconf_end = base + (1ULL<<(segn_busn_bits + 20)) - 1;
267 }
268 
269 /**
270  * early_fill_mp_bus_to_node()
271  * called before pcibios_scan_root and pci_scan_bus
272  * fills the mp_bus_to_cpumask array based according to the LDT Bus Number
273  * Registers found in the K8 northbridge
274  */
275 static int __init early_fill_mp_bus_info(void)
276 {
277 	int i;
278 	int j;
279 	unsigned bus;
280 	unsigned slot;
281 	int found;
282 	int node;
283 	int link;
284 	int def_node;
285 	int def_link;
286 	struct pci_root_info *info;
287 	u32 reg;
288 	struct resource *res;
289 	size_t start;
290 	size_t end;
291 	struct res_range range[RANGE_NUM];
292 	u64 val;
293 	u32 address;
294 
295 #ifdef CONFIG_NUMA
296 	for (i = 0; i < BUS_NR; i++)
297 		mp_bus_to_node[i] = -1;
298 #endif
299 
300 	if (!early_pci_allowed())
301 		return -1;
302 
303 	found = 0;
304 	for (i = 0; i < ARRAY_SIZE(pci_probes); i++) {
305 		u32 id;
306 		u16 device;
307 		u16 vendor;
308 
309 		bus = pci_probes[i].bus;
310 		slot = pci_probes[i].slot;
311 		id = read_pci_config(bus, slot, 0, PCI_VENDOR_ID);
312 
313 		vendor = id & 0xffff;
314 		device = (id>>16) & 0xffff;
315 		if (pci_probes[i].vendor == vendor &&
316 		    pci_probes[i].device == device) {
317 			found = 1;
318 			break;
319 		}
320 	}
321 
322 	if (!found)
323 		return 0;
324 
325 	pci_root_num = 0;
326 	for (i = 0; i < 4; i++) {
327 		int min_bus;
328 		int max_bus;
329 		reg = read_pci_config(bus, slot, 1, 0xe0 + (i << 2));
330 
331 		/* Check if that register is enabled for bus range */
332 		if ((reg & 7) != 3)
333 			continue;
334 
335 		min_bus = (reg >> 16) & 0xff;
336 		max_bus = (reg >> 24) & 0xff;
337 		node = (reg >> 4) & 0x07;
338 #ifdef CONFIG_NUMA
339 		for (j = min_bus; j <= max_bus; j++)
340 			mp_bus_to_node[j] = (unsigned char) node;
341 #endif
342 		link = (reg >> 8) & 0x03;
343 
344 		info = &pci_root_info[pci_root_num];
345 		info->bus_min = min_bus;
346 		info->bus_max = max_bus;
347 		info->node = node;
348 		info->link = link;
349 		sprintf(info->name, "PCI Bus #%02x", min_bus);
350 		pci_root_num++;
351 	}
352 
353 	/* get the default node and link for left over res */
354 	reg = read_pci_config(bus, slot, 0, 0x60);
355 	def_node = (reg >> 8) & 0x07;
356 	reg = read_pci_config(bus, slot, 0, 0x64);
357 	def_link = (reg >> 8) & 0x03;
358 
359 	memset(range, 0, sizeof(range));
360 	range[0].end = 0xffff;
361 	/* io port resource */
362 	for (i = 0; i < 4; i++) {
363 		reg = read_pci_config(bus, slot, 1, 0xc0 + (i << 3));
364 		if (!(reg & 3))
365 			continue;
366 
367 		start = reg & 0xfff000;
368 		reg = read_pci_config(bus, slot, 1, 0xc4 + (i << 3));
369 		node = reg & 0x07;
370 		link = (reg >> 4) & 0x03;
371 		end = (reg & 0xfff000) | 0xfff;
372 
373 		/* find the position */
374 		for (j = 0; j < pci_root_num; j++) {
375 			info = &pci_root_info[j];
376 			if (info->node == node && info->link == link)
377 				break;
378 		}
379 		if (j == pci_root_num)
380 			continue; /* not found */
381 
382 		info = &pci_root_info[j];
383 		printk(KERN_DEBUG "node %d link %d: io port [%llx, %llx]\n",
384 		       node, link, (u64)start, (u64)end);
385 
386 		/* kernel only handle 16 bit only */
387 		if (end > 0xffff)
388 			end = 0xffff;
389 		update_res(info, start, end, IORESOURCE_IO, 1);
390 		update_range(range, start, end);
391 	}
392 	/* add left over io port range to def node/link, [0, 0xffff] */
393 	/* find the position */
394 	for (j = 0; j < pci_root_num; j++) {
395 		info = &pci_root_info[j];
396 		if (info->node == def_node && info->link == def_link)
397 			break;
398 	}
399 	if (j < pci_root_num) {
400 		info = &pci_root_info[j];
401 		for (i = 0; i < RANGE_NUM; i++) {
402 			if (!range[i].end)
403 				continue;
404 
405 			update_res(info, range[i].start, range[i].end,
406 				   IORESOURCE_IO, 1);
407 		}
408 	}
409 
410 	memset(range, 0, sizeof(range));
411 	/* 0xfd00000000-0xffffffffff for HT */
412 	range[0].end = (0xfdULL<<32) - 1;
413 
414 	/* need to take out [0, TOM) for RAM*/
415 	address = MSR_K8_TOP_MEM1;
416 	rdmsrl(address, val);
417 	end = (val & 0xffffff800000ULL);
418 	printk(KERN_INFO "TOM: %016lx aka %ldM\n", end, end>>20);
419 	if (end < (1ULL<<32))
420 		update_range(range, 0, end - 1);
421 
422 	/* get mmconfig */
423 	get_pci_mmcfg_amd_fam10h_range();
424 	/* need to take out mmconf range */
425 	if (fam10h_mmconf_end) {
426 		printk(KERN_DEBUG "Fam 10h mmconf [%llx, %llx]\n", fam10h_mmconf_start, fam10h_mmconf_end);
427 		update_range(range, fam10h_mmconf_start, fam10h_mmconf_end);
428 	}
429 
430 	/* mmio resource */
431 	for (i = 0; i < 8; i++) {
432 		reg = read_pci_config(bus, slot, 1, 0x80 + (i << 3));
433 		if (!(reg & 3))
434 			continue;
435 
436 		start = reg & 0xffffff00; /* 39:16 on 31:8*/
437 		start <<= 8;
438 		reg = read_pci_config(bus, slot, 1, 0x84 + (i << 3));
439 		node = reg & 0x07;
440 		link = (reg >> 4) & 0x03;
441 		end = (reg & 0xffffff00);
442 		end <<= 8;
443 		end |= 0xffff;
444 
445 		/* find the position */
446 		for (j = 0; j < pci_root_num; j++) {
447 			info = &pci_root_info[j];
448 			if (info->node == node && info->link == link)
449 				break;
450 		}
451 		if (j == pci_root_num)
452 			continue; /* not found */
453 
454 		info = &pci_root_info[j];
455 
456 		printk(KERN_DEBUG "node %d link %d: mmio [%llx, %llx]",
457 		       node, link, (u64)start, (u64)end);
458 		/*
459 		 * some sick allocation would have range overlap with fam10h
460 		 * mmconf range, so need to update start and end.
461 		 */
462 		if (fam10h_mmconf_end) {
463 			int changed = 0;
464 			u64 endx = 0;
465 			if (start >= fam10h_mmconf_start &&
466 			    start <= fam10h_mmconf_end) {
467 				start = fam10h_mmconf_end + 1;
468 				changed = 1;
469 			}
470 
471 			if (end >= fam10h_mmconf_start &&
472 			    end <= fam10h_mmconf_end) {
473 				end = fam10h_mmconf_start - 1;
474 				changed = 1;
475 			}
476 
477 			if (start < fam10h_mmconf_start &&
478 			    end > fam10h_mmconf_end) {
479 				/* we got a hole */
480 				endx = fam10h_mmconf_start - 1;
481 				update_res(info, start, endx, IORESOURCE_MEM, 0);
482 				update_range(range, start, endx);
483 				printk(KERN_CONT " ==> [%llx, %llx]", (u64)start, endx);
484 				start = fam10h_mmconf_end + 1;
485 				changed = 1;
486 			}
487 			if (changed) {
488 				if (start <= end) {
489 					printk(KERN_CONT " %s [%llx, %llx]", endx?"and":"==>", (u64)start, (u64)end);
490 				} else {
491 					printk(KERN_CONT "%s\n", endx?"":" ==> none");
492 					continue;
493 				}
494 			}
495 		}
496 
497 		update_res(info, start, end, IORESOURCE_MEM, 1);
498 		update_range(range, start, end);
499 		printk(KERN_CONT "\n");
500 	}
501 
502 	/* need to take out [4G, TOM2) for RAM*/
503 	/* SYS_CFG */
504 	address = MSR_K8_SYSCFG;
505 	rdmsrl(address, val);
506 	/* TOP_MEM2 is enabled? */
507 	if (val & (1<<21)) {
508 		/* TOP_MEM2 */
509 		address = MSR_K8_TOP_MEM2;
510 		rdmsrl(address, val);
511 		end = (val & 0xffffff800000ULL);
512 		printk(KERN_INFO "TOM2: %016lx aka %ldM\n", end, end>>20);
513 		update_range(range, 1ULL<<32, end - 1);
514 	}
515 
516 	/*
517 	 * add left over mmio range to def node/link ?
518 	 * that is tricky, just record range in from start_min to 4G
519 	 */
520 	for (j = 0; j < pci_root_num; j++) {
521 		info = &pci_root_info[j];
522 		if (info->node == def_node && info->link == def_link)
523 			break;
524 	}
525 	if (j < pci_root_num) {
526 		info = &pci_root_info[j];
527 
528 		for (i = 0; i < RANGE_NUM; i++) {
529 			if (!range[i].end)
530 				continue;
531 
532 			update_res(info, range[i].start, range[i].end,
533 				   IORESOURCE_MEM, 1);
534 		}
535 	}
536 
537 	for (i = 0; i < pci_root_num; i++) {
538 		int res_num;
539 		int busnum;
540 
541 		info = &pci_root_info[i];
542 		res_num = info->res_num;
543 		busnum = info->bus_min;
544 		printk(KERN_DEBUG "bus: [%02x,%02x] on node %x link %x\n",
545 		       info->bus_min, info->bus_max, info->node, info->link);
546 		for (j = 0; j < res_num; j++) {
547 			res = &info->res[j];
548 			printk(KERN_DEBUG "bus: %02x index %x %s: [%llx, %llx]\n",
549 			       busnum, j,
550 			       (res->flags & IORESOURCE_IO)?"io port":"mmio",
551 			       res->start, res->end);
552 		}
553 	}
554 
555 	return 0;
556 }
557 
558 postcore_initcall(early_fill_mp_bus_info);
559 
560 #endif
561 
562 /* common 32/64 bit code */
563 
564 #define ENABLE_CF8_EXT_CFG      (1ULL << 46)
565 
566 static void enable_pci_io_ecs_per_cpu(void *unused)
567 {
568 	u64 reg;
569 	rdmsrl(MSR_AMD64_NB_CFG, reg);
570 	if (!(reg & ENABLE_CF8_EXT_CFG)) {
571 		reg |= ENABLE_CF8_EXT_CFG;
572 		wrmsrl(MSR_AMD64_NB_CFG, reg);
573 	}
574 }
575 
576 static int __init enable_pci_io_ecs(void)
577 {
578 	/* assume all cpus from fam10h have IO ECS */
579         if (boot_cpu_data.x86 < 0x10)
580 		return 0;
581 	on_each_cpu(enable_pci_io_ecs_per_cpu, NULL, 1);
582 	pci_probe |= PCI_HAS_IO_ECS;
583 	return 0;
584 }
585 
586 postcore_initcall(enable_pci_io_ecs);
587