aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-04-29 11:26:51 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-29 11:26:51 -0400
commit5f78e4d33945b291d12765cdd7e4304f437b9361 (patch)
tree113cea729de15a98bb941cc4afb8d13301534ca7 /arch
parent867a89e0b73af48838c7987e80899a1ff26dd6ff (diff)
parent5f0b2976cb2b62668a076f54419c24b8ab677167 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86-bigbox-pci
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86-bigbox-pci: x86: add pci=check_enable_amd_mmconf and dmi check x86: work around io allocation overlap of HT links acpi: get boot_cpu_id as early for k8_scan_nodes x86_64: don't need set default res if only have one root bus x86: double check the multi root bus with fam10h mmconf x86: multi pci root bus with different io resource range, on 64-bit x86: use bus conf in NB conf fun1 to get bus range on, on 64-bit x86: get mp_bus_to_node early x86 pci: remove checking type for mmconfig probe x86: remove unneeded check in mmconf reject driver core: try parent numa_node at first before using default x86: seperate mmconf for fam10h out from setup_64.c x86: if acpi=off, force setting the mmconf for fam10h x86_64: check MSR to get MMCONFIG for AMD Family 10h x86_64: check and enable MMCONFIG for AMD Family 10h x86_64: set cfg_size for AMD Family 10h in case MMCONFIG x86: mmconf enable mcfg early x86: clear pci_mmcfg_virt when mmcfg get rejected x86: validate against acpi motherboard resources Fixed up fairly trivial conflicts in arch/x86/pci/{init.c,pci.h} due to OLPC support manually.
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/Makefile2
-rw-r--r--arch/x86/kernel/acpi/boot.c70
-rw-r--r--arch/x86/kernel/mmconf-fam10h_64.c243
-rw-r--r--arch/x86/kernel/setup_64.c20
-rw-r--r--arch/x86/mm/k8topology_64.c38
-rw-r--r--arch/x86/pci/Makefile_321
-rw-r--r--arch/x86/pci/Makefile_642
-rw-r--r--arch/x86/pci/acpi.c27
-rw-r--r--arch/x86/pci/common.c22
-rw-r--r--arch/x86/pci/direct.c8
-rw-r--r--arch/x86/pci/fixup.c17
-rw-r--r--arch/x86/pci/init.c14
-rw-r--r--arch/x86/pci/irq.c4
-rw-r--r--arch/x86/pci/k8-bus_64.c575
-rw-r--r--arch/x86/pci/legacy.c4
-rw-r--r--arch/x86/pci/mmconfig-shared.c247
-rw-r--r--arch/x86/pci/mmconfig_32.c4
-rw-r--r--arch/x86/pci/mmconfig_64.c22
-rw-r--r--arch/x86/pci/mp_bus_to_node.c23
-rw-r--r--arch/x86/pci/pci.h3
20 files changed, 1219 insertions, 127 deletions
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 350eb1b2a208..30d54ed27e55 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -103,4 +103,6 @@ ifeq ($(CONFIG_X86_64),y)
103 obj-$(CONFIG_GART_IOMMU) += pci-gart_64.o aperture_64.o 103 obj-$(CONFIG_GART_IOMMU) += pci-gart_64.o aperture_64.o
104 obj-$(CONFIG_CALGARY_IOMMU) += pci-calgary_64.o tce_64.o 104 obj-$(CONFIG_CALGARY_IOMMU) += pci-calgary_64.o tce_64.o
105 obj-$(CONFIG_SWIOTLB) += pci-swiotlb_64.o 105 obj-$(CONFIG_SWIOTLB) += pci-swiotlb_64.o
106
107 obj-$(CONFIG_PCI_MMCONFIG) += mmconf-fam10h_64.o
106endif 108endif
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 977ed5cdeaa3..c49ebcc6c41e 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -771,6 +771,32 @@ static void __init acpi_register_lapic_address(unsigned long address)
771 boot_cpu_physical_apicid = GET_APIC_ID(read_apic_id()); 771 boot_cpu_physical_apicid = GET_APIC_ID(read_apic_id());
772} 772}
773 773
774static int __init early_acpi_parse_madt_lapic_addr_ovr(void)
775{
776 int count;
777
778 if (!cpu_has_apic)
779 return -ENODEV;
780
781 /*
782 * Note that the LAPIC address is obtained from the MADT (32-bit value)
783 * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value).
784 */
785
786 count =
787 acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE,
788 acpi_parse_lapic_addr_ovr, 0);
789 if (count < 0) {
790 printk(KERN_ERR PREFIX
791 "Error parsing LAPIC address override entry\n");
792 return count;
793 }
794
795 acpi_register_lapic_address(acpi_lapic_addr);
796
797 return count;
798}
799
774static int __init acpi_parse_madt_lapic_entries(void) 800static int __init acpi_parse_madt_lapic_entries(void)
775{ 801{
776 int count; 802 int count;
@@ -901,6 +927,33 @@ static inline int acpi_parse_madt_ioapic_entries(void)
901} 927}
902#endif /* !CONFIG_X86_IO_APIC */ 928#endif /* !CONFIG_X86_IO_APIC */
903 929
930static void __init early_acpi_process_madt(void)
931{
932#ifdef CONFIG_X86_LOCAL_APIC
933 int error;
934
935 if (!acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt)) {
936
937 /*
938 * Parse MADT LAPIC entries
939 */
940 error = early_acpi_parse_madt_lapic_addr_ovr();
941 if (!error) {
942 acpi_lapic = 1;
943 smp_found_config = 1;
944 }
945 if (error == -EINVAL) {
946 /*
947 * Dell Precision Workstation 410, 610 come here.
948 */
949 printk(KERN_ERR PREFIX
950 "Invalid BIOS MADT, disabling ACPI\n");
951 disable_acpi();
952 }
953 }
954#endif
955}
956
904static void __init acpi_process_madt(void) 957static void __init acpi_process_madt(void)
905{ 958{
906#ifdef CONFIG_X86_LOCAL_APIC 959#ifdef CONFIG_X86_LOCAL_APIC
@@ -1233,6 +1286,23 @@ int __init acpi_boot_table_init(void)
1233 return 0; 1286 return 0;
1234} 1287}
1235 1288
1289int __init early_acpi_boot_init(void)
1290{
1291 /*
1292 * If acpi_disabled, bail out
1293 * One exception: acpi=ht continues far enough to enumerate LAPICs
1294 */
1295 if (acpi_disabled && !acpi_ht)
1296 return 1;
1297
1298 /*
1299 * Process the Multiple APIC Description Table (MADT), if present
1300 */
1301 early_acpi_process_madt();
1302
1303 return 0;
1304}
1305
1236int __init acpi_boot_init(void) 1306int __init acpi_boot_init(void)
1237{ 1307{
1238 /* 1308 /*
diff --git a/arch/x86/kernel/mmconf-fam10h_64.c b/arch/x86/kernel/mmconf-fam10h_64.c
new file mode 100644
index 000000000000..edc5fbfe85c0
--- /dev/null
+++ b/arch/x86/kernel/mmconf-fam10h_64.c
@@ -0,0 +1,243 @@
1/*
2 * AMD Family 10h mmconfig enablement
3 */
4
5#include <linux/types.h>
6#include <linux/mm.h>
7#include <linux/string.h>
8#include <linux/pci.h>
9#include <linux/dmi.h>
10#include <asm/pci-direct.h>
11#include <linux/sort.h>
12#include <asm/io.h>
13#include <asm/msr.h>
14#include <asm/acpi.h>
15
16#include "../pci/pci.h"
17
18struct pci_hostbridge_probe {
19 u32 bus;
20 u32 slot;
21 u32 vendor;
22 u32 device;
23};
24
25static u64 __cpuinitdata fam10h_pci_mmconf_base;
26static int __cpuinitdata fam10h_pci_mmconf_base_status;
27
28static struct pci_hostbridge_probe pci_probes[] __cpuinitdata = {
29 { 0, 0x18, PCI_VENDOR_ID_AMD, 0x1200 },
30 { 0xff, 0, PCI_VENDOR_ID_AMD, 0x1200 },
31};
32
33struct range {
34 u64 start;
35 u64 end;
36};
37
38static int __cpuinit cmp_range(const void *x1, const void *x2)
39{
40 const struct range *r1 = x1;
41 const struct range *r2 = x2;
42 int start1, start2;
43
44 start1 = r1->start >> 32;
45 start2 = r2->start >> 32;
46
47 return start1 - start2;
48}
49
50/*[47:0] */
51/* need to avoid (0xfd<<32) and (0xfe<<32), ht used space */
52#define FAM10H_PCI_MMCONF_BASE (0xfcULL<<32)
53#define BASE_VALID(b) ((b != (0xfdULL << 32)) && (b != (0xfeULL << 32)))
54static void __cpuinit get_fam10h_pci_mmconf_base(void)
55{
56 int i;
57 unsigned bus;
58 unsigned slot;
59 int found;
60
61 u64 val;
62 u32 address;
63 u64 tom2;
64 u64 base = FAM10H_PCI_MMCONF_BASE;
65
66 int hi_mmio_num;
67 struct range range[8];
68
69 /* only try to get setting from BSP */
70 /* -1 or 1 */
71 if (fam10h_pci_mmconf_base_status)
72 return;
73
74 if (!early_pci_allowed())
75 goto fail;
76
77 found = 0;
78 for (i = 0; i < ARRAY_SIZE(pci_probes); i++) {
79 u32 id;
80 u16 device;
81 u16 vendor;
82
83 bus = pci_probes[i].bus;
84 slot = pci_probes[i].slot;
85 id = read_pci_config(bus, slot, 0, PCI_VENDOR_ID);
86
87 vendor = id & 0xffff;
88 device = (id>>16) & 0xffff;
89 if (pci_probes[i].vendor == vendor &&
90 pci_probes[i].device == device) {
91 found = 1;
92 break;
93 }
94 }
95
96 if (!found)
97 goto fail;
98
99 /* SYS_CFG */
100 address = MSR_K8_SYSCFG;
101 rdmsrl(address, val);
102
103 /* TOP_MEM2 is not enabled? */
104 if (!(val & (1<<21))) {
105 tom2 = 0;
106 } else {
107 /* TOP_MEM2 */
108 address = MSR_K8_TOP_MEM2;
109 rdmsrl(address, val);
110 tom2 = val & (0xffffULL<<32);
111 }
112
113 if (base <= tom2)
114 base = tom2 + (1ULL<<32);
115
116 /*
117 * need to check if the range is in the high mmio range that is
118 * above 4G
119 */
120 hi_mmio_num = 0;
121 for (i = 0; i < 8; i++) {
122 u32 reg;
123 u64 start;
124 u64 end;
125 reg = read_pci_config(bus, slot, 1, 0x80 + (i << 3));
126 if (!(reg & 3))
127 continue;
128
129 start = (((u64)reg) << 8) & (0xffULL << 32); /* 39:16 on 31:8*/
130 reg = read_pci_config(bus, slot, 1, 0x84 + (i << 3));
131 end = (((u64)reg) << 8) & (0xffULL << 32); /* 39:16 on 31:8*/
132
133 if (!end)
134 continue;
135
136 range[hi_mmio_num].start = start;
137 range[hi_mmio_num].end = end;
138 hi_mmio_num++;
139 }
140
141 if (!hi_mmio_num)
142 goto out;
143
144 /* sort the range */
145 sort(range, hi_mmio_num, sizeof(struct range), cmp_range, NULL);
146
147 if (range[hi_mmio_num - 1].end < base)
148 goto out;
149 if (range[0].start > base)
150 goto out;
151
152 /* need to find one window */
153 base = range[0].start - (1ULL << 32);
154 if ((base > tom2) && BASE_VALID(base))
155 goto out;
156 base = range[hi_mmio_num - 1].end + (1ULL << 32);
157 if ((base > tom2) && BASE_VALID(base))
158 goto out;
159 /* need to find window between ranges */
160 if (hi_mmio_num > 1)
161 for (i = 0; i < hi_mmio_num - 1; i++) {
162 if (range[i + 1].start > (range[i].end + (1ULL << 32))) {
163 base = range[i].end + (1ULL << 32);
164 if ((base > tom2) && BASE_VALID(base))
165 goto out;
166 }
167 }
168
169fail:
170 fam10h_pci_mmconf_base_status = -1;
171 return;
172out:
173 fam10h_pci_mmconf_base = base;
174 fam10h_pci_mmconf_base_status = 1;
175}
176
177void __cpuinit fam10h_check_enable_mmcfg(void)
178{
179 u64 val;
180 u32 address;
181
182 if (!(pci_probe & PCI_CHECK_ENABLE_AMD_MMCONF))
183 return;
184
185 address = MSR_FAM10H_MMIO_CONF_BASE;
186 rdmsrl(address, val);
187
188 /* try to make sure that AP's setting is identical to BSP setting */
189 if (val & FAM10H_MMIO_CONF_ENABLE) {
190 unsigned busnbits;
191 busnbits = (val >> FAM10H_MMIO_CONF_BUSRANGE_SHIFT) &
192 FAM10H_MMIO_CONF_BUSRANGE_MASK;
193
194 /* only trust the one handle 256 buses, if acpi=off */
195 if (!acpi_pci_disabled || busnbits >= 8) {
196 u64 base;
197 base = val & (0xffffULL << 32);
198 if (fam10h_pci_mmconf_base_status <= 0) {
199 fam10h_pci_mmconf_base = base;
200 fam10h_pci_mmconf_base_status = 1;
201 return;
202 } else if (fam10h_pci_mmconf_base == base)
203 return;
204 }
205 }
206
207 /*
208 * if it is not enabled, try to enable it and assume only one segment
209 * with 256 buses
210 */
211 get_fam10h_pci_mmconf_base();
212 if (fam10h_pci_mmconf_base_status <= 0)
213 return;
214
215 printk(KERN_INFO "Enable MMCONFIG on AMD Family 10h\n");
216 val &= ~((FAM10H_MMIO_CONF_BASE_MASK<<FAM10H_MMIO_CONF_BASE_SHIFT) |
217 (FAM10H_MMIO_CONF_BUSRANGE_MASK<<FAM10H_MMIO_CONF_BUSRANGE_SHIFT));
218 val |= fam10h_pci_mmconf_base | (8 << FAM10H_MMIO_CONF_BUSRANGE_SHIFT) |
219 FAM10H_MMIO_CONF_ENABLE;
220 wrmsrl(address, val);
221}
222
223static int __devinit set_check_enable_amd_mmconf(const struct dmi_system_id *d)
224{
225 pci_probe |= PCI_CHECK_ENABLE_AMD_MMCONF;
226 return 0;
227}
228
229static struct dmi_system_id __devinitdata mmconf_dmi_table[] = {
230 {
231 .callback = set_check_enable_amd_mmconf,
232 .ident = "Sun Microsystems Machine",
233 .matches = {
234 DMI_MATCH(DMI_SYS_VENDOR, "Sun Microsystems"),
235 },
236 },
237 {}
238};
239
240void __init check_enable_amd_mmconf_dmi(void)
241{
242 dmi_check_system(mmconf_dmi_table);
243}
diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c
index a94fb959a87a..22c14e21c97c 100644
--- a/arch/x86/kernel/setup_64.c
+++ b/arch/x86/kernel/setup_64.c
@@ -29,6 +29,7 @@
29#include <linux/crash_dump.h> 29#include <linux/crash_dump.h>
30#include <linux/root_dev.h> 30#include <linux/root_dev.h>
31#include <linux/pci.h> 31#include <linux/pci.h>
32#include <asm/pci-direct.h>
32#include <linux/efi.h> 33#include <linux/efi.h>
33#include <linux/acpi.h> 34#include <linux/acpi.h>
34#include <linux/kallsyms.h> 35#include <linux/kallsyms.h>
@@ -40,6 +41,7 @@
40#include <linux/dmi.h> 41#include <linux/dmi.h>
41#include <linux/dma-mapping.h> 42#include <linux/dma-mapping.h>
42#include <linux/ctype.h> 43#include <linux/ctype.h>
44#include <linux/sort.h>
43#include <linux/uaccess.h> 45#include <linux/uaccess.h>
44#include <linux/init_ohci1394_dma.h> 46#include <linux/init_ohci1394_dma.h>
45#include <linux/kvm_para.h> 47#include <linux/kvm_para.h>
@@ -288,6 +290,18 @@ static void __init parse_setup_data(void)
288 } 290 }
289} 291}
290 292
293#ifdef CONFIG_PCI_MMCONFIG
294extern void __cpuinit fam10h_check_enable_mmcfg(void);
295extern void __init check_enable_amd_mmconf_dmi(void);
296#else
297void __cpuinit fam10h_check_enable_mmcfg(void)
298{
299}
300void __init check_enable_amd_mmconf_dmi(void)
301{
302}
303#endif
304
291/* 305/*
292 * setup_arch - architecture-specific boot-time initializations 306 * setup_arch - architecture-specific boot-time initializations
293 * 307 *
@@ -515,6 +529,9 @@ void __init setup_arch(char **cmdline_p)
515 conswitchp = &dummy_con; 529 conswitchp = &dummy_con;
516#endif 530#endif
517#endif 531#endif
532
533 /* do this before identify_cpu for boot cpu */
534 check_enable_amd_mmconf_dmi();
518} 535}
519 536
520static int __cpuinit get_model_name(struct cpuinfo_x86 *c) 537static int __cpuinit get_model_name(struct cpuinfo_x86 *c)
@@ -767,6 +784,9 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
767 /* MFENCE stops RDTSC speculation */ 784 /* MFENCE stops RDTSC speculation */
768 set_cpu_cap(c, X86_FEATURE_MFENCE_RDTSC); 785 set_cpu_cap(c, X86_FEATURE_MFENCE_RDTSC);
769 786
787 if (c->x86 == 0x10)
788 fam10h_check_enable_mmcfg();
789
770 if (amd_apic_timer_broken()) 790 if (amd_apic_timer_broken())
771 disable_apic_timer = 1; 791 disable_apic_timer = 1;
772 792
diff --git a/arch/x86/mm/k8topology_64.c b/arch/x86/mm/k8topology_64.c
index 86808e666f9c..1f476e477844 100644
--- a/arch/x86/mm/k8topology_64.c
+++ b/arch/x86/mm/k8topology_64.c
@@ -13,12 +13,15 @@
13#include <linux/nodemask.h> 13#include <linux/nodemask.h>
14#include <asm/io.h> 14#include <asm/io.h>
15#include <linux/pci_ids.h> 15#include <linux/pci_ids.h>
16#include <linux/acpi.h>
16#include <asm/types.h> 17#include <asm/types.h>
17#include <asm/mmzone.h> 18#include <asm/mmzone.h>
18#include <asm/proto.h> 19#include <asm/proto.h>
19#include <asm/e820.h> 20#include <asm/e820.h>
20#include <asm/pci-direct.h> 21#include <asm/pci-direct.h>
21#include <asm/numa.h> 22#include <asm/numa.h>
23#include <asm/mpspec.h>
24#include <asm/apic.h>
22 25
23static __init int find_northbridge(void) 26static __init int find_northbridge(void)
24{ 27{
@@ -44,6 +47,30 @@ static __init int find_northbridge(void)
44 return -1; 47 return -1;
45} 48}
46 49
50static __init void early_get_boot_cpu_id(void)
51{
52 /*
53 * need to get boot_cpu_id so can use that to create apicid_to_node
54 * in k8_scan_nodes()
55 */
56 /*
57 * Find possible boot-time SMP configuration:
58 */
59 early_find_smp_config();
60#ifdef CONFIG_ACPI
61 /*
62 * Read APIC information from ACPI tables.
63 */
64 early_acpi_boot_init();
65#endif
66 /*
67 * get boot-time SMP configuration:
68 */
69 if (smp_found_config)
70 early_get_smp_config();
71 early_init_lapic_mapping();
72}
73
47int __init k8_scan_nodes(unsigned long start, unsigned long end) 74int __init k8_scan_nodes(unsigned long start, unsigned long end)
48{ 75{
49 unsigned long prevbase; 76 unsigned long prevbase;
@@ -56,6 +83,7 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end)
56 unsigned cores; 83 unsigned cores;
57 unsigned bits; 84 unsigned bits;
58 int j; 85 int j;
86 unsigned apicid_base;
59 87
60 if (!early_pci_allowed()) 88 if (!early_pci_allowed())
61 return -1; 89 return -1;
@@ -174,11 +202,19 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end)
174 /* use the coreid bits from early_identify_cpu */ 202 /* use the coreid bits from early_identify_cpu */
175 bits = boot_cpu_data.x86_coreid_bits; 203 bits = boot_cpu_data.x86_coreid_bits;
176 cores = (1<<bits); 204 cores = (1<<bits);
205 apicid_base = 0;
206 /* need to get boot_cpu_id early for system with apicid lifting */
207 early_get_boot_cpu_id();
208 if (boot_cpu_physical_apicid > 0) {
209 printk(KERN_INFO "BSP APIC ID: %02x\n",
210 boot_cpu_physical_apicid);
211 apicid_base = boot_cpu_physical_apicid;
212 }
177 213
178 for (i = 0; i < 8; i++) { 214 for (i = 0; i < 8; i++) {
179 if (nodes[i].start != nodes[i].end) { 215 if (nodes[i].start != nodes[i].end) {
180 nodeid = nodeids[i]; 216 nodeid = nodeids[i];
181 for (j = 0; j < cores; j++) 217 for (j = apicid_base; j < cores + apicid_base; j++)
182 apicid_to_node[(nodeid << bits) + j] = i; 218 apicid_to_node[(nodeid << bits) + j] = i;
183 setup_node_bootmem(i, nodes[i].start, nodes[i].end); 219 setup_node_bootmem(i, nodes[i].start, nodes[i].end);
184 } 220 }
diff --git a/arch/x86/pci/Makefile_32 b/arch/x86/pci/Makefile_32
index b859047a6376..2a1516efb542 100644
--- a/arch/x86/pci/Makefile_32
+++ b/arch/x86/pci/Makefile_32
@@ -11,5 +11,6 @@ pci-y += legacy.o irq.o
11 11
12pci-$(CONFIG_X86_VISWS) := visws.o fixup.o 12pci-$(CONFIG_X86_VISWS) := visws.o fixup.o
13pci-$(CONFIG_X86_NUMAQ) := numa.o irq.o 13pci-$(CONFIG_X86_NUMAQ) := numa.o irq.o
14pci-$(CONFIG_NUMA) += mp_bus_to_node.o
14 15
15obj-y += $(pci-y) common.o early.o 16obj-y += $(pci-y) common.o early.o
diff --git a/arch/x86/pci/Makefile_64 b/arch/x86/pci/Makefile_64
index 7d8c467bf143..8fbd19832cf6 100644
--- a/arch/x86/pci/Makefile_64
+++ b/arch/x86/pci/Makefile_64
@@ -13,5 +13,5 @@ obj-y += legacy.o irq.o common.o early.o
13# mmconfig has a 64bit special 13# mmconfig has a 64bit special
14obj-$(CONFIG_PCI_MMCONFIG) += mmconfig_64.o direct.o mmconfig-shared.o 14obj-$(CONFIG_PCI_MMCONFIG) += mmconfig_64.o direct.o mmconfig-shared.o
15 15
16obj-$(CONFIG_NUMA) += k8-bus_64.o 16obj-y += k8-bus_64.o
17 17
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index 2664cb3fc96c..1a9c0c6a1a18 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -191,7 +191,10 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do
191{ 191{
192 struct pci_bus *bus; 192 struct pci_bus *bus;
193 struct pci_sysdata *sd; 193 struct pci_sysdata *sd;
194 int node;
195#ifdef CONFIG_ACPI_NUMA
194 int pxm; 196 int pxm;
197#endif
195 198
196 dmi_check_system(acpi_pciprobe_dmi_table); 199 dmi_check_system(acpi_pciprobe_dmi_table);
197 200
@@ -201,6 +204,17 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do
201 return NULL; 204 return NULL;
202 } 205 }
203 206
207 node = -1;
208#ifdef CONFIG_ACPI_NUMA
209 pxm = acpi_get_pxm(device->handle);
210 if (pxm >= 0)
211 node = pxm_to_node(pxm);
212 if (node != -1)
213 set_mp_bus_to_node(busnum, node);
214 else
215 node = get_mp_bus_to_node(busnum);
216#endif
217
204 /* Allocate per-root-bus (not per bus) arch-specific data. 218 /* Allocate per-root-bus (not per bus) arch-specific data.
205 * TODO: leak; this memory is never freed. 219 * TODO: leak; this memory is never freed.
206 * It's arguable whether it's worth the trouble to care. 220 * It's arguable whether it's worth the trouble to care.
@@ -212,13 +226,7 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do
212 } 226 }
213 227
214 sd->domain = domain; 228 sd->domain = domain;
215 sd->node = -1; 229 sd->node = node;
216
217 pxm = acpi_get_pxm(device->handle);
218#ifdef CONFIG_ACPI_NUMA
219 if (pxm >= 0)
220 sd->node = pxm_to_node(pxm);
221#endif
222 /* 230 /*
223 * Maybe the desired pci bus has been already scanned. In such case 231 * Maybe the desired pci bus has been already scanned. In such case
224 * it is unnecessary to scan the pci bus with the given domain,busnum. 232 * it is unnecessary to scan the pci bus with the given domain,busnum.
@@ -238,9 +246,9 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do
238 kfree(sd); 246 kfree(sd);
239 247
240#ifdef CONFIG_ACPI_NUMA 248#ifdef CONFIG_ACPI_NUMA
241 if (bus != NULL) { 249 if (bus) {
242 if (pxm >= 0) { 250 if (pxm >= 0) {
243 printk("bus %d -> pxm %d -> node %d\n", 251 printk(KERN_DEBUG "bus %02x -> pxm %d -> node %d\n",
244 busnum, pxm, pxm_to_node(pxm)); 252 busnum, pxm, pxm_to_node(pxm));
245 } 253 }
246 } 254 }
@@ -248,7 +256,6 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do
248 256
249 if (bus && (pci_probe & PCI_USE__CRS)) 257 if (bus && (pci_probe & PCI_USE__CRS))
250 get_current_resources(device, busnum, domain, bus); 258 get_current_resources(device, busnum, domain, bus);
251
252 return bus; 259 return bus;
253} 260}
254 261
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 75fcc29ecf52..2a4d751818b7 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -342,9 +342,14 @@ struct pci_bus * __devinit pcibios_scan_root(int busnum)
342 return NULL; 342 return NULL;
343 } 343 }
344 344
345 sd->node = get_mp_bus_to_node(busnum);
346
345 printk(KERN_DEBUG "PCI: Probing PCI hardware (bus %02x)\n", busnum); 347 printk(KERN_DEBUG "PCI: Probing PCI hardware (bus %02x)\n", busnum);
348 bus = pci_scan_bus_parented(NULL, busnum, &pci_root_ops, sd);
349 if (!bus)
350 kfree(sd);
346 351
347 return pci_scan_bus_parented(NULL, busnum, &pci_root_ops, sd); 352 return bus;
348} 353}
349 354
350extern u8 pci_cache_line_size; 355extern u8 pci_cache_line_size;
@@ -420,6 +425,10 @@ char * __devinit pcibios_setup(char *str)
420 pci_probe &= ~PCI_PROBE_MMCONF; 425 pci_probe &= ~PCI_PROBE_MMCONF;
421 return NULL; 426 return NULL;
422 } 427 }
428 else if (!strcmp(str, "check_enable_amd_mmconf")) {
429 pci_probe |= PCI_CHECK_ENABLE_AMD_MMCONF;
430 return NULL;
431 }
423#endif 432#endif
424 else if (!strcmp(str, "noacpi")) { 433 else if (!strcmp(str, "noacpi")) {
425 acpi_noirq_set(); 434 acpi_noirq_set();
@@ -480,7 +489,7 @@ void pcibios_disable_device (struct pci_dev *dev)
480 pcibios_disable_irq(dev); 489 pcibios_disable_irq(dev);
481} 490}
482 491
483struct pci_bus *__devinit pci_scan_bus_with_sysdata(int busno) 492struct pci_bus *pci_scan_bus_on_node(int busno, struct pci_ops *ops, int node)
484{ 493{
485 struct pci_bus *bus = NULL; 494 struct pci_bus *bus = NULL;
486 struct pci_sysdata *sd; 495 struct pci_sysdata *sd;
@@ -495,10 +504,15 @@ struct pci_bus *__devinit pci_scan_bus_with_sysdata(int busno)
495 printk(KERN_ERR "PCI: OOM, skipping PCI bus %02x\n", busno); 504 printk(KERN_ERR "PCI: OOM, skipping PCI bus %02x\n", busno);
496 return NULL; 505 return NULL;
497 } 506 }
498 sd->node = -1; 507 sd->node = node;
499 bus = pci_scan_bus(busno, &pci_root_ops, sd); 508 bus = pci_scan_bus(busno, ops, sd);
500 if (!bus) 509 if (!bus)
501 kfree(sd); 510 kfree(sd);
502 511
503 return bus; 512 return bus;
504} 513}
514
515struct pci_bus *pci_scan_bus_with_sysdata(int busno)
516{
517 return pci_scan_bus_on_node(busno, &pci_root_ops, -1);
518}
diff --git a/arch/x86/pci/direct.c b/arch/x86/pci/direct.c
index 42f3e4cad179..21d1e0e0d535 100644
--- a/arch/x86/pci/direct.c
+++ b/arch/x86/pci/direct.c
@@ -258,7 +258,8 @@ void __init pci_direct_init(int type)
258{ 258{
259 if (type == 0) 259 if (type == 0)
260 return; 260 return;
261 printk(KERN_INFO "PCI: Using configuration type %d\n", type); 261 printk(KERN_INFO "PCI: Using configuration type %d for base access\n",
262 type);
262 if (type == 1) 263 if (type == 1)
263 raw_pci_ops = &pci_direct_conf1; 264 raw_pci_ops = &pci_direct_conf1;
264 else 265 else
@@ -275,8 +276,10 @@ int __init pci_direct_probe(void)
275 if (!region) 276 if (!region)
276 goto type2; 277 goto type2;
277 278
278 if (pci_check_type1()) 279 if (pci_check_type1()) {
280 raw_pci_ops = &pci_direct_conf1;
279 return 1; 281 return 1;
282 }
280 release_resource(region); 283 release_resource(region);
281 284
282 type2: 285 type2:
@@ -290,7 +293,6 @@ int __init pci_direct_probe(void)
290 goto fail2; 293 goto fail2;
291 294
292 if (pci_check_type2()) { 295 if (pci_check_type2()) {
293 printk(KERN_INFO "PCI: Using configuration type 2\n");
294 raw_pci_ops = &pci_direct_conf2; 296 raw_pci_ops = &pci_direct_conf2;
295 return 2; 297 return 2;
296 } 298 }
diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c
index a5ef5f551373..b60b2abd480c 100644
--- a/arch/x86/pci/fixup.c
+++ b/arch/x86/pci/fixup.c
@@ -493,3 +493,20 @@ static void __devinit pci_siemens_interrupt_controller(struct pci_dev *dev)
493} 493}
494DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SIEMENS, 0x0015, 494DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SIEMENS, 0x0015,
495 pci_siemens_interrupt_controller); 495 pci_siemens_interrupt_controller);
496
497/*
498 * Regular PCI devices have 256 bytes, but AMD Family 10h Opteron ext config
499 * have 4096 bytes. Even if the device is capable, that doesn't mean we can
500 * access it. Maybe we don't have a way to generate extended config space
501 * accesses. So check it
502 */
503static void fam10h_pci_cfg_space_size(struct pci_dev *dev)
504{
505 dev->cfg_size = pci_cfg_space_size_ext(dev, 0);
506}
507
508DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1200, fam10h_pci_cfg_space_size);
509DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1201, fam10h_pci_cfg_space_size);
510DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1202, fam10h_pci_cfg_space_size);
511DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1203, fam10h_pci_cfg_space_size);
512DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1204, fam10h_pci_cfg_space_size);
diff --git a/arch/x86/pci/init.c b/arch/x86/pci/init.c
index 0f5f7dd2a620..dd30c6076b5d 100644
--- a/arch/x86/pci/init.c
+++ b/arch/x86/pci/init.c
@@ -6,19 +6,17 @@
6 in the right sequence from here. */ 6 in the right sequence from here. */
7static __init int pci_access_init(void) 7static __init int pci_access_init(void)
8{ 8{
9 int type __maybe_unused = 0;
10
11#ifdef CONFIG_PCI_DIRECT 9#ifdef CONFIG_PCI_DIRECT
10 int type = 0;
11
12 type = pci_direct_probe(); 12 type = pci_direct_probe();
13#endif 13#endif
14#ifdef CONFIG_PCI_MMCONFIG 14
15 pci_mmcfg_init(type); 15 pci_mmcfg_early_init();
16#endif 16
17#ifdef CONFIG_PCI_OLPC 17#ifdef CONFIG_PCI_OLPC
18 pci_olpc_init(); 18 pci_olpc_init();
19#endif 19#endif
20 if (raw_pci_ops)
21 return 0;
22#ifdef CONFIG_PCI_BIOS 20#ifdef CONFIG_PCI_BIOS
23 pci_pcbios_init(); 21 pci_pcbios_init();
24#endif 22#endif
@@ -31,7 +29,7 @@ static __init int pci_access_init(void)
31#ifdef CONFIG_PCI_DIRECT 29#ifdef CONFIG_PCI_DIRECT
32 pci_direct_init(type); 30 pci_direct_init(type);
33#endif 31#endif
34 if (!raw_pci_ops) 32 if (!raw_pci_ops && !raw_pci_ext_ops)
35 printk(KERN_ERR 33 printk(KERN_ERR
36 "PCI: Fatal: No config space access function found\n"); 34 "PCI: Fatal: No config space access function found\n");
37 35
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c
index 579745ca6b66..0908fca901bf 100644
--- a/arch/x86/pci/irq.c
+++ b/arch/x86/pci/irq.c
@@ -136,9 +136,11 @@ static void __init pirq_peer_trick(void)
136 busmap[e->bus] = 1; 136 busmap[e->bus] = 1;
137 } 137 }
138 for(i = 1; i < 256; i++) { 138 for(i = 1; i < 256; i++) {
139 int node;
139 if (!busmap[i] || pci_find_bus(0, i)) 140 if (!busmap[i] || pci_find_bus(0, i))
140 continue; 141 continue;
141 if (pci_scan_bus_with_sysdata(i)) 142 node = get_mp_bus_to_node(i);
143 if (pci_scan_bus_on_node(i, &pci_root_ops, node))
142 printk(KERN_INFO "PCI: Discovered primary peer " 144 printk(KERN_INFO "PCI: Discovered primary peer "
143 "bus %02x [IRQ]\n", i); 145 "bus %02x [IRQ]\n", i);
144 } 146 }
diff --git a/arch/x86/pci/k8-bus_64.c b/arch/x86/pci/k8-bus_64.c
index 9cc813e29706..ab6d4b18a88f 100644
--- a/arch/x86/pci/k8-bus_64.c
+++ b/arch/x86/pci/k8-bus_64.c
@@ -1,83 +1,536 @@
1#include <linux/init.h> 1#include <linux/init.h>
2#include <linux/pci.h> 2#include <linux/pci.h>
3#include <asm/pci-direct.h>
3#include <asm/mpspec.h> 4#include <asm/mpspec.h>
4#include <linux/cpumask.h> 5#include <linux/cpumask.h>
6#include <linux/topology.h>
5 7
6/* 8/*
7 * This discovers the pcibus <-> node mapping on AMD K8. 9 * This discovers the pcibus <-> node mapping on AMD K8.
8 * 10 * also get peer root bus resource for io,mmio
9 * RED-PEN need to call this again on PCI hotplug
10 * RED-PEN empty cpus get reported wrong
11 */ 11 */
12 12
13#define NODE_ID_REGISTER 0x60 13
14#define NODE_ID(dword) (dword & 0x07) 14/*
15#define LDT_BUS_NUMBER_REGISTER_0 0x94 15 * sub bus (transparent) will use entres from 3 to store extra from root,
16#define LDT_BUS_NUMBER_REGISTER_1 0xB4 16 * so need to make sure have enought slot there, increase PCI_BUS_NUM_RESOURCES?
17#define LDT_BUS_NUMBER_REGISTER_2 0xD4 17 */
18#define NR_LDT_BUS_NUMBER_REGISTERS 3 18#define RES_NUM 16
19#define SECONDARY_LDT_BUS_NUMBER(dword) ((dword >> 8) & 0xFF) 19struct pci_root_info {
20#define SUBORDINATE_LDT_BUS_NUMBER(dword) ((dword >> 16) & 0xFF) 20 char name[12];
21#define PCI_DEVICE_ID_K8HTCONFIG 0x1100 21 unsigned int res_num;
22 struct resource res[RES_NUM];
23 int bus_min;
24 int bus_max;
25 int node;
26 int link;
27};
28
29/* 4 at this time, it may become to 32 */
30#define PCI_ROOT_NR 4
31static int pci_root_num;
32static struct pci_root_info pci_root_info[PCI_ROOT_NR];
33
34#ifdef CONFIG_NUMA
35
36#define BUS_NR 256
37
38static int mp_bus_to_node[BUS_NR];
39
40void set_mp_bus_to_node(int busnum, int node)
41{
42 if (busnum >= 0 && busnum < BUS_NR)
43 mp_bus_to_node[busnum] = node;
44}
45
46int get_mp_bus_to_node(int busnum)
47{
48 int node = -1;
49
50 if (busnum < 0 || busnum > (BUS_NR - 1))
51 return node;
52
53 node = mp_bus_to_node[busnum];
54
55 /*
56 * let numa_node_id to decide it later in dma_alloc_pages
57 * if there is no ram on that node
58 */
59 if (node != -1 && !node_online(node))
60 node = -1;
61
62 return node;
63}
64#endif
65
66void set_pci_bus_resources_arch_default(struct pci_bus *b)
67{
68 int i;
69 int j;
70 struct pci_root_info *info;
71
72 /* if only one root bus, don't need to anything */
73 if (pci_root_num < 2)
74 return;
75
76 for (i = 0; i < pci_root_num; i++) {
77 if (pci_root_info[i].bus_min == b->number)
78 break;
79 }
80
81 if (i == pci_root_num)
82 return;
83
84 info = &pci_root_info[i];
85 for (j = 0; j < info->res_num; j++) {
86 struct resource *res;
87 struct resource *root;
88
89 res = &info->res[j];
90 b->resource[j] = res;
91 if (res->flags & IORESOURCE_IO)
92 root = &ioport_resource;
93 else
94 root = &iomem_resource;
95 insert_resource(root, res);
96 }
97}
98
99#define RANGE_NUM 16
100
101struct res_range {
102 size_t start;
103 size_t end;
104};
105
106static void __init update_range(struct res_range *range, size_t start,
107 size_t end)
108{
109 int i;
110 int j;
111
112 for (j = 0; j < RANGE_NUM; j++) {
113 if (!range[j].end)
114 continue;
115
116 if (start <= range[j].start && end >= range[j].end) {
117 range[j].start = 0;
118 range[j].end = 0;
119 continue;
120 }
121
122 if (start <= range[j].start && end < range[j].end && range[j].start < end + 1) {
123 range[j].start = end + 1;
124 continue;
125 }
126
127
128 if (start > range[j].start && end >= range[j].end && range[j].end > start - 1) {
129 range[j].end = start - 1;
130 continue;
131 }
132
133 if (start > range[j].start && end < range[j].end) {
134 /* find the new spare */
135 for (i = 0; i < RANGE_NUM; i++) {
136 if (range[i].end == 0)
137 break;
138 }
139 if (i < RANGE_NUM) {
140 range[i].end = range[j].end;
141 range[i].start = end + 1;
142 } else {
143 printk(KERN_ERR "run of slot in ranges\n");
144 }
145 range[j].end = start - 1;
146 continue;
147 }
148 }
149}
150
151static void __init update_res(struct pci_root_info *info, size_t start,
152 size_t end, unsigned long flags, int merge)
153{
154 int i;
155 struct resource *res;
156
157 if (!merge)
158 goto addit;
159
160 /* try to merge it with old one */
161 for (i = 0; i < info->res_num; i++) {
162 size_t final_start, final_end;
163 size_t common_start, common_end;
164
165 res = &info->res[i];
166 if (res->flags != flags)
167 continue;
168
169 common_start = max((size_t)res->start, start);
170 common_end = min((size_t)res->end, end);
171 if (common_start > common_end + 1)
172 continue;
173
174 final_start = min((size_t)res->start, start);
175 final_end = max((size_t)res->end, end);
176
177 res->start = final_start;
178 res->end = final_end;
179 return;
180 }
181
182addit:
183
184 /* need to add that */
185 if (info->res_num >= RES_NUM)
186 return;
187
188 res = &info->res[info->res_num];
189 res->name = info->name;
190 res->flags = flags;
191 res->start = start;
192 res->end = end;
193 res->child = NULL;
194 info->res_num++;
195}
196
197struct pci_hostbridge_probe {
198 u32 bus;
199 u32 slot;
200 u32 vendor;
201 u32 device;
202};
203
204static struct pci_hostbridge_probe pci_probes[] __initdata = {
205 { 0, 0x18, PCI_VENDOR_ID_AMD, 0x1100 },
206 { 0, 0x18, PCI_VENDOR_ID_AMD, 0x1200 },
207 { 0xff, 0, PCI_VENDOR_ID_AMD, 0x1200 },
208 { 0, 0x18, PCI_VENDOR_ID_AMD, 0x1300 },
209};
210
211static u64 __initdata fam10h_mmconf_start;
212static u64 __initdata fam10h_mmconf_end;
213static void __init get_pci_mmcfg_amd_fam10h_range(void)
214{
215 u32 address;
216 u64 base, msr;
217 unsigned segn_busn_bits;
218
219 /* assume all cpus from fam10h have mmconf */
220 if (boot_cpu_data.x86 < 0x10)
221 return;
222
223 address = MSR_FAM10H_MMIO_CONF_BASE;
224 rdmsrl(address, msr);
225
226 /* mmconfig is not enable */
227 if (!(msr & FAM10H_MMIO_CONF_ENABLE))
228 return;
229
230 base = msr & (FAM10H_MMIO_CONF_BASE_MASK<<FAM10H_MMIO_CONF_BASE_SHIFT);
231
232 segn_busn_bits = (msr >> FAM10H_MMIO_CONF_BUSRANGE_SHIFT) &
233 FAM10H_MMIO_CONF_BUSRANGE_MASK;
234
235 fam10h_mmconf_start = base;
236 fam10h_mmconf_end = base + (1ULL<<(segn_busn_bits + 20)) - 1;
237}
22 238
23/** 239/**
24 * fill_mp_bus_to_cpumask() 240 * early_fill_mp_bus_to_node()
241 * called before pcibios_scan_root and pci_scan_bus
25 * fills the mp_bus_to_cpumask array based according to the LDT Bus Number 242 * fills the mp_bus_to_cpumask array based according to the LDT Bus Number
26 * Registers found in the K8 northbridge 243 * Registers found in the K8 northbridge
27 */ 244 */
28__init static int 245static int __init early_fill_mp_bus_info(void)
29fill_mp_bus_to_cpumask(void)
30{ 246{
31 struct pci_dev *nb_dev = NULL; 247 int i;
32 int i, j; 248 int j;
33 u32 ldtbus, nid; 249 unsigned bus;
34 static int lbnr[3] = { 250 unsigned slot;
35 LDT_BUS_NUMBER_REGISTER_0, 251 int found;
36 LDT_BUS_NUMBER_REGISTER_1, 252 int node;
37 LDT_BUS_NUMBER_REGISTER_2 253 int link;
38 }; 254 int def_node;
39 255 int def_link;
40 while ((nb_dev = pci_get_device(PCI_VENDOR_ID_AMD, 256 struct pci_root_info *info;
41 PCI_DEVICE_ID_K8HTCONFIG, nb_dev))) { 257 u32 reg;
42 pci_read_config_dword(nb_dev, NODE_ID_REGISTER, &nid); 258 struct resource *res;
43 259 size_t start;
44 for (i = 0; i < NR_LDT_BUS_NUMBER_REGISTERS; i++) { 260 size_t end;
45 pci_read_config_dword(nb_dev, lbnr[i], &ldtbus); 261 struct res_range range[RANGE_NUM];
46 /* 262 u64 val;
47 * if there are no busses hanging off of the current 263 u32 address;
48 * ldt link then both the secondary and subordinate 264
49 * bus number fields are set to 0. 265#ifdef CONFIG_NUMA
50 * 266 for (i = 0; i < BUS_NR; i++)
51 * RED-PEN 267 mp_bus_to_node[i] = -1;
52 * This is slightly broken because it assumes 268#endif
53 * HT node IDs == Linux node ids, which is not always 269
54 * true. However it is probably mostly true. 270 if (!early_pci_allowed())
55 */ 271 return -1;
56 if (!(SECONDARY_LDT_BUS_NUMBER(ldtbus) == 0 272
57 && SUBORDINATE_LDT_BUS_NUMBER(ldtbus) == 0)) { 273 found = 0;
58 for (j = SECONDARY_LDT_BUS_NUMBER(ldtbus); 274 for (i = 0; i < ARRAY_SIZE(pci_probes); i++) {
59 j <= SUBORDINATE_LDT_BUS_NUMBER(ldtbus); 275 u32 id;
60 j++) { 276 u16 device;
61 struct pci_bus *bus; 277 u16 vendor;
62 struct pci_sysdata *sd; 278
63 279 bus = pci_probes[i].bus;
64 long node = NODE_ID(nid); 280 slot = pci_probes[i].slot;
65 /* Algorithm a bit dumb, but 281 id = read_pci_config(bus, slot, 0, PCI_VENDOR_ID);
66 it shouldn't matter here */ 282
67 bus = pci_find_bus(0, j); 283 vendor = id & 0xffff;
68 if (!bus) 284 device = (id>>16) & 0xffff;
69 continue; 285 if (pci_probes[i].vendor == vendor &&
70 if (!node_online(node)) 286 pci_probes[i].device == device) {
71 node = 0; 287 found = 1;
72 288 break;
73 sd = bus->sysdata; 289 }
74 sd->node = node; 290 }
75 } 291
292 if (!found)
293 return 0;
294
295 pci_root_num = 0;
296 for (i = 0; i < 4; i++) {
297 int min_bus;
298 int max_bus;
299 reg = read_pci_config(bus, slot, 1, 0xe0 + (i << 2));
300
301 /* Check if that register is enabled for bus range */
302 if ((reg & 7) != 3)
303 continue;
304
305 min_bus = (reg >> 16) & 0xff;
306 max_bus = (reg >> 24) & 0xff;
307 node = (reg >> 4) & 0x07;
308#ifdef CONFIG_NUMA
309 for (j = min_bus; j <= max_bus; j++)
310 mp_bus_to_node[j] = (unsigned char) node;
311#endif
312 link = (reg >> 8) & 0x03;
313
314 info = &pci_root_info[pci_root_num];
315 info->bus_min = min_bus;
316 info->bus_max = max_bus;
317 info->node = node;
318 info->link = link;
319 sprintf(info->name, "PCI Bus #%02x", min_bus);
320 pci_root_num++;
321 }
322
323 /* get the default node and link for left over res */
324 reg = read_pci_config(bus, slot, 0, 0x60);
325 def_node = (reg >> 8) & 0x07;
326 reg = read_pci_config(bus, slot, 0, 0x64);
327 def_link = (reg >> 8) & 0x03;
328
329 memset(range, 0, sizeof(range));
330 range[0].end = 0xffff;
331 /* io port resource */
332 for (i = 0; i < 4; i++) {
333 reg = read_pci_config(bus, slot, 1, 0xc0 + (i << 3));
334 if (!(reg & 3))
335 continue;
336
337 start = reg & 0xfff000;
338 reg = read_pci_config(bus, slot, 1, 0xc4 + (i << 3));
339 node = reg & 0x07;
340 link = (reg >> 4) & 0x03;
341 end = (reg & 0xfff000) | 0xfff;
342
343 /* find the position */
344 for (j = 0; j < pci_root_num; j++) {
345 info = &pci_root_info[j];
346 if (info->node == node && info->link == link)
347 break;
348 }
349 if (j == pci_root_num)
350 continue; /* not found */
351
352 info = &pci_root_info[j];
353 printk(KERN_DEBUG "node %d link %d: io port [%llx, %llx]\n",
354 node, link, (u64)start, (u64)end);
355
356 /* kernel only handle 16 bit only */
357 if (end > 0xffff)
358 end = 0xffff;
359 update_res(info, start, end, IORESOURCE_IO, 1);
360 update_range(range, start, end);
361 }
362 /* add left over io port range to def node/link, [0, 0xffff] */
363 /* find the position */
364 for (j = 0; j < pci_root_num; j++) {
365 info = &pci_root_info[j];
366 if (info->node == def_node && info->link == def_link)
367 break;
368 }
369 if (j < pci_root_num) {
370 info = &pci_root_info[j];
371 for (i = 0; i < RANGE_NUM; i++) {
372 if (!range[i].end)
373 continue;
374
375 update_res(info, range[i].start, range[i].end,
376 IORESOURCE_IO, 1);
377 }
378 }
379
380 memset(range, 0, sizeof(range));
381 /* 0xfd00000000-0xffffffffff for HT */
382 range[0].end = (0xfdULL<<32) - 1;
383
384 /* need to take out [0, TOM) for RAM*/
385 address = MSR_K8_TOP_MEM1;
386 rdmsrl(address, val);
387 end = (val & 0xffffff8000000ULL);
388 printk(KERN_INFO "TOM: %016lx aka %ldM\n", end, end>>20);
389 if (end < (1ULL<<32))
390 update_range(range, 0, end - 1);
391
392 /* get mmconfig */
393 get_pci_mmcfg_amd_fam10h_range();
394 /* need to take out mmconf range */
395 if (fam10h_mmconf_end) {
396 printk(KERN_DEBUG "Fam 10h mmconf [%llx, %llx]\n", fam10h_mmconf_start, fam10h_mmconf_end);
397 update_range(range, fam10h_mmconf_start, fam10h_mmconf_end);
398 }
399
400 /* mmio resource */
401 for (i = 0; i < 8; i++) {
402 reg = read_pci_config(bus, slot, 1, 0x80 + (i << 3));
403 if (!(reg & 3))
404 continue;
405
406 start = reg & 0xffffff00; /* 39:16 on 31:8*/
407 start <<= 8;
408 reg = read_pci_config(bus, slot, 1, 0x84 + (i << 3));
409 node = reg & 0x07;
410 link = (reg >> 4) & 0x03;
411 end = (reg & 0xffffff00);
412 end <<= 8;
413 end |= 0xffff;
414
415 /* find the position */
416 for (j = 0; j < pci_root_num; j++) {
417 info = &pci_root_info[j];
418 if (info->node == node && info->link == link)
419 break;
420 }
421 if (j == pci_root_num)
422 continue; /* not found */
423
424 info = &pci_root_info[j];
425
426 printk(KERN_DEBUG "node %d link %d: mmio [%llx, %llx]",
427 node, link, (u64)start, (u64)end);
428 /*
429 * some sick allocation would have range overlap with fam10h
430 * mmconf range, so need to update start and end.
431 */
432 if (fam10h_mmconf_end) {
433 int changed = 0;
434 u64 endx = 0;
435 if (start >= fam10h_mmconf_start &&
436 start <= fam10h_mmconf_end) {
437 start = fam10h_mmconf_end + 1;
438 changed = 1;
439 }
440
441 if (end >= fam10h_mmconf_start &&
442 end <= fam10h_mmconf_end) {
443 end = fam10h_mmconf_start - 1;
444 changed = 1;
445 }
446
447 if (start < fam10h_mmconf_start &&
448 end > fam10h_mmconf_end) {
449 /* we got a hole */
450 endx = fam10h_mmconf_start - 1;
451 update_res(info, start, endx, IORESOURCE_MEM, 0);
452 update_range(range, start, endx);
453 printk(KERN_CONT " ==> [%llx, %llx]", (u64)start, endx);
454 start = fam10h_mmconf_end + 1;
455 changed = 1;
456 }
457 if (changed) {
458 if (start <= end) {
459 printk(KERN_CONT " %s [%llx, %llx]", endx?"and":"==>", (u64)start, (u64)end);
460 } else {
461 printk(KERN_CONT "%s\n", endx?"":" ==> none");
462 continue;
463 }
76 } 464 }
77 } 465 }
466
467 update_res(info, start, end, IORESOURCE_MEM, 1);
468 update_range(range, start, end);
469 printk(KERN_CONT "\n");
470 }
471
472 /* need to take out [4G, TOM2) for RAM*/
473 /* SYS_CFG */
474 address = MSR_K8_SYSCFG;
475 rdmsrl(address, val);
476 /* TOP_MEM2 is enabled? */
477 if (val & (1<<21)) {
478 /* TOP_MEM2 */
479 address = MSR_K8_TOP_MEM2;
480 rdmsrl(address, val);
481 end = (val & 0xffffff8000000ULL);
482 printk(KERN_INFO "TOM2: %016lx aka %ldM\n", end, end>>20);
483 update_range(range, 1ULL<<32, end - 1);
484 }
485
486 /*
487 * add left over mmio range to def node/link ?
488 * that is tricky, just record range in from start_min to 4G
489 */
490 for (j = 0; j < pci_root_num; j++) {
491 info = &pci_root_info[j];
492 if (info->node == def_node && info->link == def_link)
493 break;
494 }
495 if (j < pci_root_num) {
496 info = &pci_root_info[j];
497
498 for (i = 0; i < RANGE_NUM; i++) {
499 if (!range[i].end)
500 continue;
501
502 update_res(info, range[i].start, range[i].end,
503 IORESOURCE_MEM, 1);
504 }
505 }
506
507#ifdef CONFIG_NUMA
508 for (i = 0; i < BUS_NR; i++) {
509 node = mp_bus_to_node[i];
510 if (node >= 0)
511 printk(KERN_DEBUG "bus: %02x to node: %02x\n", i, node);
512 }
513#endif
514
515 for (i = 0; i < pci_root_num; i++) {
516 int res_num;
517 int busnum;
518
519 info = &pci_root_info[i];
520 res_num = info->res_num;
521 busnum = info->bus_min;
522 printk(KERN_DEBUG "bus: [%02x,%02x] on node %x link %x\n",
523 info->bus_min, info->bus_max, info->node, info->link);
524 for (j = 0; j < res_num; j++) {
525 res = &info->res[j];
526 printk(KERN_DEBUG "bus: %02x index %x %s: [%llx, %llx]\n",
527 busnum, j,
528 (res->flags & IORESOURCE_IO)?"io port":"mmio",
529 res->start, res->end);
530 }
78 } 531 }
79 532
80 return 0; 533 return 0;
81} 534}
82 535
83fs_initcall(fill_mp_bus_to_cpumask); 536postcore_initcall(early_fill_mp_bus_info);
diff --git a/arch/x86/pci/legacy.c b/arch/x86/pci/legacy.c
index e041ced0ce13..a67921ce60af 100644
--- a/arch/x86/pci/legacy.c
+++ b/arch/x86/pci/legacy.c
@@ -12,6 +12,7 @@
12static void __devinit pcibios_fixup_peer_bridges(void) 12static void __devinit pcibios_fixup_peer_bridges(void)
13{ 13{
14 int n, devfn; 14 int n, devfn;
15 long node;
15 16
16 if (pcibios_last_bus <= 0 || pcibios_last_bus >= 0xff) 17 if (pcibios_last_bus <= 0 || pcibios_last_bus >= 0xff)
17 return; 18 return;
@@ -21,12 +22,13 @@ static void __devinit pcibios_fixup_peer_bridges(void)
21 u32 l; 22 u32 l;
22 if (pci_find_bus(0, n)) 23 if (pci_find_bus(0, n))
23 continue; 24 continue;
25 node = get_mp_bus_to_node(n);
24 for (devfn = 0; devfn < 256; devfn += 8) { 26 for (devfn = 0; devfn < 256; devfn += 8) {
25 if (!raw_pci_read(0, n, devfn, PCI_VENDOR_ID, 2, &l) && 27 if (!raw_pci_read(0, n, devfn, PCI_VENDOR_ID, 2, &l) &&
26 l != 0x0000 && l != 0xffff) { 28 l != 0x0000 && l != 0xffff) {
27 DBG("Found device at %02x:%02x [%04x]\n", n, devfn, l); 29 DBG("Found device at %02x:%02x [%04x]\n", n, devfn, l);
28 printk(KERN_INFO "PCI: Discovered peer bus %02x\n", n); 30 printk(KERN_INFO "PCI: Discovered peer bus %02x\n", n);
29 pci_scan_bus_with_sysdata(n); 31 pci_scan_bus_on_node(n, &pci_root_ops, node);
30 break; 32 break;
31 } 33 }
32 } 34 }
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
index 8d54df4dfaad..0cfebecf2a8f 100644
--- a/arch/x86/pci/mmconfig-shared.c
+++ b/arch/x86/pci/mmconfig-shared.c
@@ -28,7 +28,7 @@ static int __initdata pci_mmcfg_resources_inserted;
28static const char __init *pci_mmcfg_e7520(void) 28static const char __init *pci_mmcfg_e7520(void)
29{ 29{
30 u32 win; 30 u32 win;
31 pci_direct_conf1.read(0, 0, PCI_DEVFN(0,0), 0xce, 2, &win); 31 raw_pci_ops->read(0, 0, PCI_DEVFN(0, 0), 0xce, 2, &win);
32 32
33 win = win & 0xf000; 33 win = win & 0xf000;
34 if(win == 0x0000 || win == 0xf000) 34 if(win == 0x0000 || win == 0xf000)
@@ -53,7 +53,7 @@ static const char __init *pci_mmcfg_intel_945(void)
53 53
54 pci_mmcfg_config_num = 1; 54 pci_mmcfg_config_num = 1;
55 55
56 pci_direct_conf1.read(0, 0, PCI_DEVFN(0,0), 0x48, 4, &pciexbar); 56 raw_pci_ops->read(0, 0, PCI_DEVFN(0, 0), 0x48, 4, &pciexbar);
57 57
58 /* Enable bit */ 58 /* Enable bit */
59 if (!(pciexbar & 1)) 59 if (!(pciexbar & 1))
@@ -100,33 +100,102 @@ static const char __init *pci_mmcfg_intel_945(void)
100 return "Intel Corporation 945G/GZ/P/PL Express Memory Controller Hub"; 100 return "Intel Corporation 945G/GZ/P/PL Express Memory Controller Hub";
101} 101}
102 102
103static const char __init *pci_mmcfg_amd_fam10h(void)
104{
105 u32 low, high, address;
106 u64 base, msr;
107 int i;
108 unsigned segnbits = 0, busnbits;
109
110 if (!(pci_probe & PCI_CHECK_ENABLE_AMD_MMCONF))
111 return NULL;
112
113 address = MSR_FAM10H_MMIO_CONF_BASE;
114 if (rdmsr_safe(address, &low, &high))
115 return NULL;
116
117 msr = high;
118 msr <<= 32;
119 msr |= low;
120
121 /* mmconfig is not enable */
122 if (!(msr & FAM10H_MMIO_CONF_ENABLE))
123 return NULL;
124
125 base = msr & (FAM10H_MMIO_CONF_BASE_MASK<<FAM10H_MMIO_CONF_BASE_SHIFT);
126
127 busnbits = (msr >> FAM10H_MMIO_CONF_BUSRANGE_SHIFT) &
128 FAM10H_MMIO_CONF_BUSRANGE_MASK;
129
130 /*
131 * only handle bus 0 ?
132 * need to skip it
133 */
134 if (!busnbits)
135 return NULL;
136
137 if (busnbits > 8) {
138 segnbits = busnbits - 8;
139 busnbits = 8;
140 }
141
142 pci_mmcfg_config_num = (1 << segnbits);
143 pci_mmcfg_config = kzalloc(sizeof(pci_mmcfg_config[0]) *
144 pci_mmcfg_config_num, GFP_KERNEL);
145 if (!pci_mmcfg_config)
146 return NULL;
147
148 for (i = 0; i < (1 << segnbits); i++) {
149 pci_mmcfg_config[i].address = base + (1<<28) * i;
150 pci_mmcfg_config[i].pci_segment = i;
151 pci_mmcfg_config[i].start_bus_number = 0;
152 pci_mmcfg_config[i].end_bus_number = (1 << busnbits) - 1;
153 }
154
155 return "AMD Family 10h NB";
156}
157
103struct pci_mmcfg_hostbridge_probe { 158struct pci_mmcfg_hostbridge_probe {
159 u32 bus;
160 u32 devfn;
104 u32 vendor; 161 u32 vendor;
105 u32 device; 162 u32 device;
106 const char *(*probe)(void); 163 const char *(*probe)(void);
107}; 164};
108 165
109static struct pci_mmcfg_hostbridge_probe pci_mmcfg_probes[] __initdata = { 166static struct pci_mmcfg_hostbridge_probe pci_mmcfg_probes[] __initdata = {
110 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, pci_mmcfg_e7520 }, 167 { 0, PCI_DEVFN(0, 0), PCI_VENDOR_ID_INTEL,
111 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82945G_HB, pci_mmcfg_intel_945 }, 168 PCI_DEVICE_ID_INTEL_E7520_MCH, pci_mmcfg_e7520 },
169 { 0, PCI_DEVFN(0, 0), PCI_VENDOR_ID_INTEL,
170 PCI_DEVICE_ID_INTEL_82945G_HB, pci_mmcfg_intel_945 },
171 { 0, PCI_DEVFN(0x18, 0), PCI_VENDOR_ID_AMD,
172 0x1200, pci_mmcfg_amd_fam10h },
173 { 0xff, PCI_DEVFN(0, 0), PCI_VENDOR_ID_AMD,
174 0x1200, pci_mmcfg_amd_fam10h },
112}; 175};
113 176
114static int __init pci_mmcfg_check_hostbridge(void) 177static int __init pci_mmcfg_check_hostbridge(void)
115{ 178{
116 u32 l; 179 u32 l;
180 u32 bus, devfn;
117 u16 vendor, device; 181 u16 vendor, device;
118 int i; 182 int i;
119 const char *name; 183 const char *name;
120 184
121 pci_direct_conf1.read(0, 0, PCI_DEVFN(0,0), 0, 4, &l); 185 if (!raw_pci_ops)
122 vendor = l & 0xffff; 186 return 0;
123 device = (l >> 16) & 0xffff;
124 187
125 pci_mmcfg_config_num = 0; 188 pci_mmcfg_config_num = 0;
126 pci_mmcfg_config = NULL; 189 pci_mmcfg_config = NULL;
127 name = NULL; 190 name = NULL;
128 191
129 for (i = 0; !name && i < ARRAY_SIZE(pci_mmcfg_probes); i++) { 192 for (i = 0; !name && i < ARRAY_SIZE(pci_mmcfg_probes); i++) {
193 bus = pci_mmcfg_probes[i].bus;
194 devfn = pci_mmcfg_probes[i].devfn;
195 raw_pci_ops->read(0, bus, devfn, 0, 4, &l);
196 vendor = l & 0xffff;
197 device = (l >> 16) & 0xffff;
198
130 if (pci_mmcfg_probes[i].vendor == vendor && 199 if (pci_mmcfg_probes[i].vendor == vendor &&
131 pci_mmcfg_probes[i].device == device) 200 pci_mmcfg_probes[i].device == device)
132 name = pci_mmcfg_probes[i].probe(); 201 name = pci_mmcfg_probes[i].probe();
@@ -173,9 +242,78 @@ static void __init pci_mmcfg_insert_resources(unsigned long resource_flags)
173 pci_mmcfg_resources_inserted = 1; 242 pci_mmcfg_resources_inserted = 1;
174} 243}
175 244
176static void __init pci_mmcfg_reject_broken(int type) 245static acpi_status __init check_mcfg_resource(struct acpi_resource *res,
246 void *data)
247{
248 struct resource *mcfg_res = data;
249 struct acpi_resource_address64 address;
250 acpi_status status;
251
252 if (res->type == ACPI_RESOURCE_TYPE_FIXED_MEMORY32) {
253 struct acpi_resource_fixed_memory32 *fixmem32 =
254 &res->data.fixed_memory32;
255 if (!fixmem32)
256 return AE_OK;
257 if ((mcfg_res->start >= fixmem32->address) &&
258 (mcfg_res->end < (fixmem32->address +
259 fixmem32->address_length))) {
260 mcfg_res->flags = 1;
261 return AE_CTRL_TERMINATE;
262 }
263 }
264 if ((res->type != ACPI_RESOURCE_TYPE_ADDRESS32) &&
265 (res->type != ACPI_RESOURCE_TYPE_ADDRESS64))
266 return AE_OK;
267
268 status = acpi_resource_to_address64(res, &address);
269 if (ACPI_FAILURE(status) ||
270 (address.address_length <= 0) ||
271 (address.resource_type != ACPI_MEMORY_RANGE))
272 return AE_OK;
273
274 if ((mcfg_res->start >= address.minimum) &&
275 (mcfg_res->end < (address.minimum + address.address_length))) {
276 mcfg_res->flags = 1;
277 return AE_CTRL_TERMINATE;
278 }
279 return AE_OK;
280}
281
282static acpi_status __init find_mboard_resource(acpi_handle handle, u32 lvl,
283 void *context, void **rv)
284{
285 struct resource *mcfg_res = context;
286
287 acpi_walk_resources(handle, METHOD_NAME__CRS,
288 check_mcfg_resource, context);
289
290 if (mcfg_res->flags)
291 return AE_CTRL_TERMINATE;
292
293 return AE_OK;
294}
295
296static int __init is_acpi_reserved(unsigned long start, unsigned long end)
297{
298 struct resource mcfg_res;
299
300 mcfg_res.start = start;
301 mcfg_res.end = end;
302 mcfg_res.flags = 0;
303
304 acpi_get_devices("PNP0C01", find_mboard_resource, &mcfg_res, NULL);
305
306 if (!mcfg_res.flags)
307 acpi_get_devices("PNP0C02", find_mboard_resource, &mcfg_res,
308 NULL);
309
310 return mcfg_res.flags;
311}
312
313static void __init pci_mmcfg_reject_broken(int early)
177{ 314{
178 typeof(pci_mmcfg_config[0]) *cfg; 315 typeof(pci_mmcfg_config[0]) *cfg;
316 int i;
179 317
180 if ((pci_mmcfg_config_num == 0) || 318 if ((pci_mmcfg_config_num == 0) ||
181 (pci_mmcfg_config == NULL) || 319 (pci_mmcfg_config == NULL) ||
@@ -184,51 +322,80 @@ static void __init pci_mmcfg_reject_broken(int type)
184 322
185 cfg = &pci_mmcfg_config[0]; 323 cfg = &pci_mmcfg_config[0];
186 324
187 /* 325 for (i = 0; i < pci_mmcfg_config_num; i++) {
188 * Handle more broken MCFG tables on Asus etc. 326 int valid = 0;
189 * They only contain a single entry for bus 0-0. 327 u32 size = (cfg->end_bus_number + 1) << 20;
190 */ 328 cfg = &pci_mmcfg_config[i];
191 if (pci_mmcfg_config_num == 1 && 329 printk(KERN_NOTICE "PCI: MCFG configuration %d: base %lx "
192 cfg->pci_segment == 0 && 330 "segment %hu buses %u - %u\n",
193 (cfg->start_bus_number | cfg->end_bus_number) == 0) { 331 i, (unsigned long)cfg->address, cfg->pci_segment,
194 printk(KERN_ERR "PCI: start and end of bus number is 0. " 332 (unsigned int)cfg->start_bus_number,
195 "Rejected as broken MCFG.\n"); 333 (unsigned int)cfg->end_bus_number);
196 goto reject; 334
335 if (!early &&
336 is_acpi_reserved(cfg->address, cfg->address + size - 1)) {
337 printk(KERN_NOTICE "PCI: MCFG area at %Lx reserved "
338 "in ACPI motherboard resources\n",
339 cfg->address);
340 valid = 1;
341 }
342
343 if (valid)
344 continue;
345
346 if (!early)
347 printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %Lx is not"
348 " reserved in ACPI motherboard resources\n",
349 cfg->address);
350 /* Don't try to do this check unless configuration
351 type 1 is available. how about type 2 ?*/
352 if (raw_pci_ops && e820_all_mapped(cfg->address,
353 cfg->address + size - 1,
354 E820_RESERVED)) {
355 printk(KERN_NOTICE
356 "PCI: MCFG area at %Lx reserved in E820\n",
357 cfg->address);
358 valid = 1;
359 }
360
361 if (!valid)
362 goto reject;
197 } 363 }
198 364
199 /*
200 * Only do this check when type 1 works. If it doesn't work
201 * assume we run on a Mac and always use MCFG
202 */
203 if (type == 1 && !e820_all_mapped(cfg->address,
204 cfg->address + MMCONFIG_APER_MIN,
205 E820_RESERVED)) {
206 printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %Lx is not"
207 " E820-reserved\n", cfg->address);
208 goto reject;
209 }
210 return; 365 return;
211 366
212reject: 367reject:
213 printk(KERN_ERR "PCI: Not using MMCONFIG.\n"); 368 printk(KERN_ERR "PCI: Not using MMCONFIG.\n");
369 pci_mmcfg_arch_free();
214 kfree(pci_mmcfg_config); 370 kfree(pci_mmcfg_config);
215 pci_mmcfg_config = NULL; 371 pci_mmcfg_config = NULL;
216 pci_mmcfg_config_num = 0; 372 pci_mmcfg_config_num = 0;
217} 373}
218 374
219void __init pci_mmcfg_init(int type) 375static int __initdata known_bridge;
220{
221 int known_bridge = 0;
222 376
377void __init __pci_mmcfg_init(int early)
378{
379 /* MMCONFIG disabled */
223 if ((pci_probe & PCI_PROBE_MMCONF) == 0) 380 if ((pci_probe & PCI_PROBE_MMCONF) == 0)
224 return; 381 return;
225 382
226 if (type == 1 && pci_mmcfg_check_hostbridge()) 383 /* MMCONFIG already enabled */
227 known_bridge = 1; 384 if (!early && !(pci_probe & PCI_PROBE_MASK & ~PCI_PROBE_MMCONF))
385 return;
386
387 /* for late to exit */
388 if (known_bridge)
389 return;
390
391 if (early) {
392 if (pci_mmcfg_check_hostbridge())
393 known_bridge = 1;
394 }
228 395
229 if (!known_bridge) { 396 if (!known_bridge) {
230 acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg); 397 acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg);
231 pci_mmcfg_reject_broken(type); 398 pci_mmcfg_reject_broken(early);
232 } 399 }
233 400
234 if ((pci_mmcfg_config_num == 0) || 401 if ((pci_mmcfg_config_num == 0) ||
@@ -249,6 +416,16 @@ void __init pci_mmcfg_init(int type)
249 } 416 }
250} 417}
251 418
419void __init pci_mmcfg_early_init(void)
420{
421 __pci_mmcfg_init(1);
422}
423
424void __init pci_mmcfg_late_init(void)
425{
426 __pci_mmcfg_init(0);
427}
428
252static int __init pci_mmcfg_late_insert_resources(void) 429static int __init pci_mmcfg_late_insert_resources(void)
253{ 430{
254 /* 431 /*
diff --git a/arch/x86/pci/mmconfig_32.c b/arch/x86/pci/mmconfig_32.c
index 081816ada057..f3c761dce695 100644
--- a/arch/x86/pci/mmconfig_32.c
+++ b/arch/x86/pci/mmconfig_32.c
@@ -136,3 +136,7 @@ int __init pci_mmcfg_arch_init(void)
136 raw_pci_ext_ops = &pci_mmcfg; 136 raw_pci_ext_ops = &pci_mmcfg;
137 return 1; 137 return 1;
138} 138}
139
140void __init pci_mmcfg_arch_free(void)
141{
142}
diff --git a/arch/x86/pci/mmconfig_64.c b/arch/x86/pci/mmconfig_64.c
index 9207fd49233c..a1994163c99d 100644
--- a/arch/x86/pci/mmconfig_64.c
+++ b/arch/x86/pci/mmconfig_64.c
@@ -127,7 +127,7 @@ static void __iomem * __init mcfg_ioremap(struct acpi_mcfg_allocation *cfg)
127int __init pci_mmcfg_arch_init(void) 127int __init pci_mmcfg_arch_init(void)
128{ 128{
129 int i; 129 int i;
130 pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * 130 pci_mmcfg_virt = kzalloc(sizeof(*pci_mmcfg_virt) *
131 pci_mmcfg_config_num, GFP_KERNEL); 131 pci_mmcfg_config_num, GFP_KERNEL);
132 if (pci_mmcfg_virt == NULL) { 132 if (pci_mmcfg_virt == NULL) {
133 printk(KERN_ERR "PCI: Can not allocate memory for mmconfig structures\n"); 133 printk(KERN_ERR "PCI: Can not allocate memory for mmconfig structures\n");
@@ -141,9 +141,29 @@ int __init pci_mmcfg_arch_init(void)
141 printk(KERN_ERR "PCI: Cannot map mmconfig aperture for " 141 printk(KERN_ERR "PCI: Cannot map mmconfig aperture for "
142 "segment %d\n", 142 "segment %d\n",
143 pci_mmcfg_config[i].pci_segment); 143 pci_mmcfg_config[i].pci_segment);
144 pci_mmcfg_arch_free();
144 return 0; 145 return 0;
145 } 146 }
146 } 147 }
147 raw_pci_ext_ops = &pci_mmcfg; 148 raw_pci_ext_ops = &pci_mmcfg;
148 return 1; 149 return 1;
149} 150}
151
152void __init pci_mmcfg_arch_free(void)
153{
154 int i;
155
156 if (pci_mmcfg_virt == NULL)
157 return;
158
159 for (i = 0; i < pci_mmcfg_config_num; ++i) {
160 if (pci_mmcfg_virt[i].virt) {
161 iounmap(pci_mmcfg_virt[i].virt);
162 pci_mmcfg_virt[i].virt = NULL;
163 pci_mmcfg_virt[i].cfg = NULL;
164 }
165 }
166
167 kfree(pci_mmcfg_virt);
168 pci_mmcfg_virt = NULL;
169}
diff --git a/arch/x86/pci/mp_bus_to_node.c b/arch/x86/pci/mp_bus_to_node.c
new file mode 100644
index 000000000000..022943999b84
--- /dev/null
+++ b/arch/x86/pci/mp_bus_to_node.c
@@ -0,0 +1,23 @@
1#include <linux/pci.h>
2#include <linux/init.h>
3#include <linux/topology.h>
4
5#define BUS_NR 256
6
7static unsigned char mp_bus_to_node[BUS_NR];
8
9void set_mp_bus_to_node(int busnum, int node)
10{
11 if (busnum >= 0 && busnum < BUS_NR)
12 mp_bus_to_node[busnum] = (unsigned char) node;
13}
14
15int get_mp_bus_to_node(int busnum)
16{
17 int node;
18
19 if (busnum < 0 || busnum > (BUS_NR - 1))
20 return 0;
21 node = mp_bus_to_node[busnum];
22 return node;
23}
diff --git a/arch/x86/pci/pci.h b/arch/x86/pci/pci.h
index 7d84e813e958..c58805a92db5 100644
--- a/arch/x86/pci/pci.h
+++ b/arch/x86/pci/pci.h
@@ -26,6 +26,7 @@
26#define PCI_ASSIGN_ALL_BUSSES 0x4000 26#define PCI_ASSIGN_ALL_BUSSES 0x4000
27#define PCI_CAN_SKIP_ISA_ALIGN 0x8000 27#define PCI_CAN_SKIP_ISA_ALIGN 0x8000
28#define PCI_USE__CRS 0x10000 28#define PCI_USE__CRS 0x10000
29#define PCI_CHECK_ENABLE_AMD_MMCONF 0x20000
29 30
30extern unsigned int pci_probe; 31extern unsigned int pci_probe;
31extern unsigned long pirq_table_addr; 32extern unsigned long pirq_table_addr;
@@ -97,12 +98,12 @@ extern struct pci_raw_ops pci_direct_conf1;
97extern int pci_direct_probe(void); 98extern int pci_direct_probe(void);
98extern void pci_direct_init(int type); 99extern void pci_direct_init(int type);
99extern void pci_pcbios_init(void); 100extern void pci_pcbios_init(void);
100extern void pci_mmcfg_init(int type);
101extern void pci_olpc_init(void); 101extern void pci_olpc_init(void);
102 102
103/* pci-mmconfig.c */ 103/* pci-mmconfig.c */
104 104
105extern int __init pci_mmcfg_arch_init(void); 105extern int __init pci_mmcfg_arch_init(void);
106extern void __init pci_mmcfg_arch_free(void);
106 107
107/* 108/*
108 * AMD Fam10h CPUs are buggy, and cannot access MMIO config space 109 * AMD Fam10h CPUs are buggy, and cannot access MMIO config space