Commit b78673944b22b662b270c8bba5c198f19e4ee4e1
Committed by
Andi Kleen
1 parent
2e188938ab
Exists in
master
and in
4 other branches
[PATCH] mmconfig: Share parts of mmconfig code between i386 and x86-64
i386 and x86-64 pci mmconfig code have a lot in common. So share what's shareable between the two. Signed-off-by: Olivier Galibert <galibert@pobox.com> Signed-off-by: Andi Kleen <ak@suse.de> Cc: Andi Kleen <ak@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org>
Showing 6 changed files with 111 additions and 136 deletions Side-by-side Diff
arch/i386/pci/Makefile
arch/i386/pci/mmconfig-shared.c
1 | +/* | |
2 | + * mmconfig-shared.c - Low-level direct PCI config space access via | |
3 | + * MMCONFIG - common code between i386 and x86-64. | |
4 | + * | |
5 | + * This code does: | |
6 | + * - ACPI decoding and validation | |
7 | + * | |
8 | + * Per-architecture code takes care of the mappings and accesses | |
9 | + * themselves. | |
10 | + */ | |
11 | + | |
12 | +#include <linux/pci.h> | |
13 | +#include <linux/init.h> | |
14 | +#include <linux/acpi.h> | |
15 | +#include <linux/bitmap.h> | |
16 | +#include <asm/e820.h> | |
17 | + | |
18 | +#include "pci.h" | |
19 | + | |
20 | +/* aperture is up to 256MB but BIOS may reserve less */ | |
21 | +#define MMCONFIG_APER_MIN (2 * 1024*1024) | |
22 | +#define MMCONFIG_APER_MAX (256 * 1024*1024) | |
23 | + | |
24 | +/* Verify the first 16 busses. We assume that systems with more busses | |
25 | + get MCFG right. */ | |
26 | +#define PCI_MMCFG_MAX_CHECK_BUS 16 | |
27 | + | |
28 | +DECLARE_BITMAP(pci_mmcfg_fallback_slots, 32*PCI_MMCFG_MAX_CHECK_BUS); | |
29 | + | |
30 | +/* K8 systems have some devices (typically in the builtin northbridge) | |
31 | + that are only accessible using type1 | |
32 | + Normally this can be expressed in the MCFG by not listing them | |
33 | + and assigning suitable _SEGs, but this isn't implemented in some BIOS. | |
34 | + Instead try to discover all devices on bus 0 that are unreachable using MM | |
35 | + and fallback for them. */ | |
36 | +static __init void unreachable_devices(void) | |
37 | +{ | |
38 | + int i, k; | |
39 | + /* Use the max bus number from ACPI here? */ | |
40 | + for (k = 0; k < PCI_MMCFG_MAX_CHECK_BUS; k++) { | |
41 | + for (i = 0; i < 32; i++) { | |
42 | + u32 val1, val2; | |
43 | + | |
44 | + pci_conf1_read(0, k, PCI_DEVFN(i,0), 0, 4, &val1); | |
45 | + if (val1 == 0xffffffff) | |
46 | + continue; | |
47 | + | |
48 | + raw_pci_ops->read(0, k, PCI_DEVFN(i, 0), 0, 4, &val2); | |
49 | + if (val1 != val2) { | |
50 | + set_bit(i + 32*k, pci_mmcfg_fallback_slots); | |
51 | + printk(KERN_NOTICE "PCI: No mmconfig possible" | |
52 | + " on device %02x:%02x\n", k, i); | |
53 | + } | |
54 | + } | |
55 | + } | |
56 | +} | |
57 | + | |
58 | +void __init pci_mmcfg_init(int type) | |
59 | +{ | |
60 | + if ((pci_probe & PCI_PROBE_MMCONF) == 0) | |
61 | + return; | |
62 | + | |
63 | + acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg); | |
64 | + | |
65 | + if ((pci_mmcfg_config_num == 0) || | |
66 | + (pci_mmcfg_config == NULL) || | |
67 | + (pci_mmcfg_config[0].address == 0)) | |
68 | + return; | |
69 | + | |
70 | + /* Only do this check when type 1 works. If it doesn't work | |
71 | + assume we run on a Mac and always use MCFG */ | |
72 | + if (type == 1 && | |
73 | + !e820_all_mapped(pci_mmcfg_config[0].address, | |
74 | + pci_mmcfg_config[0].address + MMCONFIG_APER_MIN, | |
75 | + E820_RESERVED)) { | |
76 | + printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %Lx is not E820-reserved\n", | |
77 | + pci_mmcfg_config[0].address); | |
78 | + printk(KERN_ERR "PCI: Not using MMCONFIG.\n"); | |
79 | + return; | |
80 | + } | |
81 | + | |
82 | + if (pci_mmcfg_arch_init()) { | |
83 | + unreachable_devices(); | |
84 | + pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; | |
85 | + } | |
86 | +} |
arch/i386/pci/mmconfig.c
... | ... | @@ -15,21 +15,13 @@ |
15 | 15 | #include <asm/e820.h> |
16 | 16 | #include "pci.h" |
17 | 17 | |
18 | -/* aperture is up to 256MB but BIOS may reserve less */ | |
19 | -#define MMCONFIG_APER_MIN (2 * 1024*1024) | |
20 | -#define MMCONFIG_APER_MAX (256 * 1024*1024) | |
21 | - | |
22 | 18 | /* Assume systems with more busses have correct MCFG */ |
23 | -#define MAX_CHECK_BUS 16 | |
24 | - | |
25 | 19 | #define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG)) |
26 | 20 | |
27 | 21 | /* The base address of the last MMCONFIG device accessed */ |
28 | 22 | static u32 mmcfg_last_accessed_device; |
29 | 23 | static int mmcfg_last_accessed_cpu; |
30 | 24 | |
31 | -static DECLARE_BITMAP(fallback_slots, MAX_CHECK_BUS*32); | |
32 | - | |
33 | 25 | /* |
34 | 26 | * Functions for accessing PCI configuration space with MMCONFIG accesses |
35 | 27 | */ |
... | ... | @@ -38,8 +30,8 @@ |
38 | 30 | int cfg_num = -1; |
39 | 31 | struct acpi_mcfg_allocation *cfg; |
40 | 32 | |
41 | - if (seg == 0 && bus < MAX_CHECK_BUS && | |
42 | - test_bit(PCI_SLOT(devfn) + 32*bus, fallback_slots)) | |
33 | + if (seg == 0 && bus < PCI_MMCFG_MAX_CHECK_BUS && | |
34 | + test_bit(PCI_SLOT(devfn) + 32*bus, pci_mmcfg_fallback_slots)) | |
43 | 35 | return 0; |
44 | 36 | |
45 | 37 | while (1) { |
46 | 38 | |
47 | 39 | |
... | ... | @@ -158,68 +150,10 @@ |
158 | 150 | .write = pci_mmcfg_write, |
159 | 151 | }; |
160 | 152 | |
161 | -/* K8 systems have some devices (typically in the builtin northbridge) | |
162 | - that are only accessible using type1 | |
163 | - Normally this can be expressed in the MCFG by not listing them | |
164 | - and assigning suitable _SEGs, but this isn't implemented in some BIOS. | |
165 | - Instead try to discover all devices on bus 0 that are unreachable using MM | |
166 | - and fallback for them. */ | |
167 | -static __init void unreachable_devices(void) | |
153 | +int __init pci_mmcfg_arch_init(void) | |
168 | 154 | { |
169 | - int i, k; | |
170 | - unsigned long flags; | |
171 | - | |
172 | - for (k = 0; k < MAX_CHECK_BUS; k++) { | |
173 | - for (i = 0; i < 32; i++) { | |
174 | - u32 val1; | |
175 | - u32 addr; | |
176 | - | |
177 | - pci_conf1_read(0, k, PCI_DEVFN(i, 0), 0, 4, &val1); | |
178 | - if (val1 == 0xffffffff) | |
179 | - continue; | |
180 | - | |
181 | - /* Locking probably not needed, but safer */ | |
182 | - spin_lock_irqsave(&pci_config_lock, flags); | |
183 | - addr = get_base_addr(0, k, PCI_DEVFN(i, 0)); | |
184 | - if (addr != 0) | |
185 | - pci_exp_set_dev_base(addr, k, PCI_DEVFN(i, 0)); | |
186 | - if (addr == 0 || | |
187 | - readl((u32 __iomem *)mmcfg_virt_addr) != val1) { | |
188 | - set_bit(i + 32*k, fallback_slots); | |
189 | - printk(KERN_NOTICE | |
190 | - "PCI: No mmconfig possible on %x:%x\n", k, i); | |
191 | - } | |
192 | - spin_unlock_irqrestore(&pci_config_lock, flags); | |
193 | - } | |
194 | - } | |
195 | -} | |
196 | - | |
197 | -void __init pci_mmcfg_init(int type) | |
198 | -{ | |
199 | - if ((pci_probe & PCI_PROBE_MMCONF) == 0) | |
200 | - return; | |
201 | - | |
202 | - acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg); | |
203 | - if ((pci_mmcfg_config_num == 0) || | |
204 | - (pci_mmcfg_config == NULL) || | |
205 | - (pci_mmcfg_config[0].address == 0)) | |
206 | - return; | |
207 | - | |
208 | - /* Only do this check when type 1 works. If it doesn't work | |
209 | - assume we run on a Mac and always use MCFG */ | |
210 | - if (type == 1 && !e820_all_mapped(pci_mmcfg_config[0].address, | |
211 | - pci_mmcfg_config[0].address + MMCONFIG_APER_MIN, | |
212 | - E820_RESERVED)) { | |
213 | - printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %lx is not E820-reserved\n", | |
214 | - (unsigned long)pci_mmcfg_config[0].address); | |
215 | - printk(KERN_ERR "PCI: Not using MMCONFIG.\n"); | |
216 | - return; | |
217 | - } | |
218 | - | |
219 | 155 | printk(KERN_INFO "PCI: Using MMCONFIG\n"); |
220 | 156 | raw_pci_ops = &pci_mmcfg; |
221 | - pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; | |
222 | - | |
223 | - unreachable_devices(); | |
157 | + return 1; | |
224 | 158 | } |
arch/i386/pci/pci.h
... | ... | @@ -93,4 +93,11 @@ |
93 | 93 | extern void pci_pcbios_init(void); |
94 | 94 | extern void pci_mmcfg_init(int type); |
95 | 95 | extern void pcibios_sort(void); |
96 | + | |
97 | +/* pci-mmconfig.c */ | |
98 | + | |
99 | +#define PCI_MMCFG_MAX_CHECK_BUS 16 | |
100 | +extern DECLARE_BITMAP(pci_mmcfg_fallback_slots, 32*PCI_MMCFG_MAX_CHECK_BUS); | |
101 | + | |
102 | +extern int pci_mmcfg_arch_init(void); |
arch/x86_64/pci/Makefile
... | ... | @@ -11,7 +11,7 @@ |
11 | 11 | obj-$(CONFIG_ACPI) += acpi.o |
12 | 12 | obj-y += legacy.o irq.o common.o early.o |
13 | 13 | # mmconfig has a 64bit special |
14 | -obj-$(CONFIG_PCI_MMCONFIG) += mmconfig.o direct.o | |
14 | +obj-$(CONFIG_PCI_MMCONFIG) += mmconfig.o direct.o mmconfig-shared.o | |
15 | 15 | |
16 | 16 | obj-$(CONFIG_NUMA) += k8-bus.o |
17 | 17 | |
... | ... | @@ -24,4 +24,5 @@ |
24 | 24 | i386-y += ../../i386/pci/i386.o |
25 | 25 | init-y += ../../i386/pci/init.o |
26 | 26 | early-y += ../../i386/pci/early.o |
27 | +mmconfig-shared-y += ../../i386/pci/mmconfig-shared.o |
arch/x86_64/pci/mmconfig.c
... | ... | @@ -19,10 +19,8 @@ |
19 | 19 | |
20 | 20 | /* Verify the first 16 busses. We assume that systems with more busses |
21 | 21 | get MCFG right. */ |
22 | -#define MAX_CHECK_BUS 16 | |
22 | +#define PCI_MMCFG_MAX_CHECK_BUS 16 | |
23 | 23 | |
24 | -static DECLARE_BITMAP(fallback_slots, 32*MAX_CHECK_BUS); | |
25 | - | |
26 | 24 | /* Static virtual mapping of the MMCONFIG aperture */ |
27 | 25 | struct mmcfg_virt { |
28 | 26 | struct acpi_mcfg_allocation *cfg; |
... | ... | @@ -63,8 +61,8 @@ |
63 | 61 | static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn) |
64 | 62 | { |
65 | 63 | char __iomem *addr; |
66 | - if (seg == 0 && bus < MAX_CHECK_BUS && | |
67 | - test_bit(32*bus + PCI_SLOT(devfn), fallback_slots)) | |
64 | + if (seg == 0 && bus < PCI_MMCFG_MAX_CHECK_BUS && | |
65 | + test_bit(32*bus + PCI_SLOT(devfn), pci_mmcfg_fallback_slots)) | |
68 | 66 | return NULL; |
69 | 67 | addr = get_virt(seg, bus); |
70 | 68 | if (!addr) |
71 | 69 | |
72 | 70 | |
73 | 71 | |
74 | 72 | |
... | ... | @@ -135,63 +133,16 @@ |
135 | 133 | .write = pci_mmcfg_write, |
136 | 134 | }; |
137 | 135 | |
138 | -/* K8 systems have some devices (typically in the builtin northbridge) | |
139 | - that are only accessible using type1 | |
140 | - Normally this can be expressed in the MCFG by not listing them | |
141 | - and assigning suitable _SEGs, but this isn't implemented in some BIOS. | |
142 | - Instead try to discover all devices on bus 0 that are unreachable using MM | |
143 | - and fallback for them. */ | |
144 | -static __init void unreachable_devices(void) | |
136 | +int __init pci_mmcfg_arch_init(void) | |
145 | 137 | { |
146 | - int i, k; | |
147 | - /* Use the max bus number from ACPI here? */ | |
148 | - for (k = 0; k < MAX_CHECK_BUS; k++) { | |
149 | - for (i = 0; i < 32; i++) { | |
150 | - u32 val1; | |
151 | - char __iomem *addr; | |
152 | - | |
153 | - pci_conf1_read(0, k, PCI_DEVFN(i,0), 0, 4, &val1); | |
154 | - if (val1 == 0xffffffff) | |
155 | - continue; | |
156 | - addr = pci_dev_base(0, k, PCI_DEVFN(i, 0)); | |
157 | - if (addr == NULL|| readl(addr) != val1) { | |
158 | - set_bit(i + 32*k, fallback_slots); | |
159 | - printk(KERN_NOTICE "PCI: No mmconfig possible" | |
160 | - " on device %02x:%02x\n", k, i); | |
161 | - } | |
162 | - } | |
163 | - } | |
164 | -} | |
165 | - | |
166 | -void __init pci_mmcfg_init(int type) | |
167 | -{ | |
168 | 138 | int i; |
169 | - | |
170 | - if ((pci_probe & PCI_PROBE_MMCONF) == 0) | |
171 | - return; | |
172 | - | |
173 | - acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg); | |
174 | - if ((pci_mmcfg_config_num == 0) || | |
175 | - (pci_mmcfg_config == NULL) || | |
176 | - (pci_mmcfg_config[0].address == 0)) | |
177 | - return; | |
178 | - | |
179 | - /* Only do this check when type 1 works. If it doesn't work | |
180 | - assume we run on a Mac and always use MCFG */ | |
181 | - if (type == 1 && !e820_all_mapped(pci_mmcfg_config[0].address, | |
182 | - pci_mmcfg_config[0].address + MMCONFIG_APER_MIN, | |
183 | - E820_RESERVED)) { | |
184 | - printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %lx is not E820-reserved\n", | |
185 | - (unsigned long)pci_mmcfg_config[0].address); | |
186 | - printk(KERN_ERR "PCI: Not using MMCONFIG.\n"); | |
187 | - return; | |
188 | - } | |
189 | - | |
190 | - pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL); | |
139 | + pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * | |
140 | + pci_mmcfg_config_num, GFP_KERNEL); | |
191 | 141 | if (pci_mmcfg_virt == NULL) { |
192 | 142 | printk(KERN_ERR "PCI: Can not allocate memory for mmconfig structures\n"); |
193 | - return; | |
143 | + return 0; | |
194 | 144 | } |
145 | + | |
195 | 146 | for (i = 0; i < pci_mmcfg_config_num; ++i) { |
196 | 147 | pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i]; |
197 | 148 | pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].address, |
198 | 149 | |
199 | 150 | |
200 | 151 | |
... | ... | @@ -200,15 +151,12 @@ |
200 | 151 | printk(KERN_ERR "PCI: Cannot map mmconfig aperture for " |
201 | 152 | "segment %d\n", |
202 | 153 | pci_mmcfg_config[i].pci_segment); |
203 | - return; | |
154 | + return 0; | |
204 | 155 | } |
205 | - printk(KERN_INFO "PCI: Using MMCONFIG at %lx\n", | |
206 | - (unsigned long)pci_mmcfg_config[i].address); | |
156 | + printk(KERN_INFO "PCI: Using MMCONFIG at %Lx\n", | |
157 | + pci_mmcfg_config[i].address); | |
207 | 158 | } |
208 | - | |
209 | - unreachable_devices(); | |
210 | - | |
211 | 159 | raw_pci_ops = &pci_mmcfg; |
212 | - pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; | |
160 | + return 1; | |
213 | 161 | } |