xref: /openbmc/linux/arch/x86/pci/mmconfig-shared.c (revision fb9aa6f1)
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  * - known chipset handling
7  * - ACPI decoding and validation
8  *
9  * Per-architecture code takes care of the mappings and accesses
10  * themselves.
11  */
12 
13 #include <linux/pci.h>
14 #include <linux/init.h>
15 #include <linux/acpi.h>
16 #include <linux/bitmap.h>
17 #include <asm/e820.h>
18 
19 #include "pci.h"
20 
21 /* aperture is up to 256MB but BIOS may reserve less */
22 #define MMCONFIG_APER_MIN	(2 * 1024*1024)
23 #define MMCONFIG_APER_MAX	(256 * 1024*1024)
24 
25 DECLARE_BITMAP(pci_mmcfg_fallback_slots, 32*PCI_MMCFG_MAX_CHECK_BUS);
26 
27 /* Indicate if the mmcfg resources have been placed into the resource table. */
28 static int __initdata pci_mmcfg_resources_inserted;
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 void __init unreachable_devices(void)
37 {
38 	int i, bus;
39 	/* Use the max bus number from ACPI here? */
40 	for (bus = 0; bus < PCI_MMCFG_MAX_CHECK_BUS; bus++) {
41 		for (i = 0; i < 32; i++) {
42 			unsigned int devfn = PCI_DEVFN(i, 0);
43 			u32 val1, val2;
44 
45 			pci_conf1_read(0, bus, devfn, 0, 4, &val1);
46 			if (val1 == 0xffffffff)
47 				continue;
48 
49 			if (pci_mmcfg_arch_reachable(0, bus, devfn)) {
50 				raw_pci_ops->read(0, bus, devfn, 0, 4, &val2);
51 				if (val1 == val2)
52 					continue;
53 			}
54 			set_bit(i + 32 * bus, pci_mmcfg_fallback_slots);
55 			printk(KERN_NOTICE "PCI: No mmconfig possible on device"
56 			       " %02x:%02x\n", bus, i);
57 		}
58 	}
59 }
60 
61 static const char __init *pci_mmcfg_e7520(void)
62 {
63 	u32 win;
64 	pci_conf1_read(0, 0, PCI_DEVFN(0,0), 0xce, 2, &win);
65 
66 	win = win & 0xf000;
67 	if(win == 0x0000 || win == 0xf000)
68 		pci_mmcfg_config_num = 0;
69 	else {
70 		pci_mmcfg_config_num = 1;
71 		pci_mmcfg_config = kzalloc(sizeof(pci_mmcfg_config[0]), GFP_KERNEL);
72 		if (!pci_mmcfg_config)
73 			return NULL;
74 		pci_mmcfg_config[0].address = win << 16;
75 		pci_mmcfg_config[0].pci_segment = 0;
76 		pci_mmcfg_config[0].start_bus_number = 0;
77 		pci_mmcfg_config[0].end_bus_number = 255;
78 	}
79 
80 	return "Intel Corporation E7520 Memory Controller Hub";
81 }
82 
83 static const char __init *pci_mmcfg_intel_945(void)
84 {
85 	u32 pciexbar, mask = 0, len = 0;
86 
87 	pci_mmcfg_config_num = 1;
88 
89 	pci_conf1_read(0, 0, PCI_DEVFN(0,0), 0x48, 4, &pciexbar);
90 
91 	/* Enable bit */
92 	if (!(pciexbar & 1))
93 		pci_mmcfg_config_num = 0;
94 
95 	/* Size bits */
96 	switch ((pciexbar >> 1) & 3) {
97 	case 0:
98 		mask = 0xf0000000U;
99 		len  = 0x10000000U;
100 		break;
101 	case 1:
102 		mask = 0xf8000000U;
103 		len  = 0x08000000U;
104 		break;
105 	case 2:
106 		mask = 0xfc000000U;
107 		len  = 0x04000000U;
108 		break;
109 	default:
110 		pci_mmcfg_config_num = 0;
111 	}
112 
113 	/* Errata #2, things break when not aligned on a 256Mb boundary */
114 	/* Can only happen in 64M/128M mode */
115 
116 	if ((pciexbar & mask) & 0x0fffffffU)
117 		pci_mmcfg_config_num = 0;
118 
119 	/* Don't hit the APIC registers and their friends */
120 	if ((pciexbar & mask) >= 0xf0000000U)
121 		pci_mmcfg_config_num = 0;
122 
123 	if (pci_mmcfg_config_num) {
124 		pci_mmcfg_config = kzalloc(sizeof(pci_mmcfg_config[0]), GFP_KERNEL);
125 		if (!pci_mmcfg_config)
126 			return NULL;
127 		pci_mmcfg_config[0].address = pciexbar & mask;
128 		pci_mmcfg_config[0].pci_segment = 0;
129 		pci_mmcfg_config[0].start_bus_number = 0;
130 		pci_mmcfg_config[0].end_bus_number = (len >> 20) - 1;
131 	}
132 
133 	return "Intel Corporation 945G/GZ/P/PL Express Memory Controller Hub";
134 }
135 
136 struct pci_mmcfg_hostbridge_probe {
137 	u32 vendor;
138 	u32 device;
139 	const char *(*probe)(void);
140 };
141 
142 static struct pci_mmcfg_hostbridge_probe pci_mmcfg_probes[] __initdata = {
143 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, pci_mmcfg_e7520 },
144 	{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82945G_HB, pci_mmcfg_intel_945 },
145 };
146 
147 static int __init pci_mmcfg_check_hostbridge(void)
148 {
149 	u32 l;
150 	u16 vendor, device;
151 	int i;
152 	const char *name;
153 
154 	pci_conf1_read(0, 0, PCI_DEVFN(0,0), 0, 4, &l);
155 	vendor = l & 0xffff;
156 	device = (l >> 16) & 0xffff;
157 
158 	pci_mmcfg_config_num = 0;
159 	pci_mmcfg_config = NULL;
160 	name = NULL;
161 
162 	for (i = 0; !name && i < ARRAY_SIZE(pci_mmcfg_probes); i++) {
163 		if (pci_mmcfg_probes[i].vendor == vendor &&
164 		    pci_mmcfg_probes[i].device == device)
165 			name = pci_mmcfg_probes[i].probe();
166 	}
167 
168 	if (name) {
169 		printk(KERN_INFO "PCI: Found %s %s MMCONFIG support.\n",
170 		       name, pci_mmcfg_config_num ? "with" : "without");
171 	}
172 
173 	return name != NULL;
174 }
175 
176 static void __init pci_mmcfg_insert_resources(unsigned long resource_flags)
177 {
178 #define PCI_MMCFG_RESOURCE_NAME_LEN 19
179 	int i;
180 	struct resource *res;
181 	char *names;
182 	unsigned num_buses;
183 
184 	res = kcalloc(PCI_MMCFG_RESOURCE_NAME_LEN + sizeof(*res),
185 			pci_mmcfg_config_num, GFP_KERNEL);
186 	if (!res) {
187 		printk(KERN_ERR "PCI: Unable to allocate MMCONFIG resources\n");
188 		return;
189 	}
190 
191 	names = (void *)&res[pci_mmcfg_config_num];
192 	for (i = 0; i < pci_mmcfg_config_num; i++, res++) {
193 		struct acpi_mcfg_allocation *cfg = &pci_mmcfg_config[i];
194 		num_buses = cfg->end_bus_number - cfg->start_bus_number + 1;
195 		res->name = names;
196 		snprintf(names, PCI_MMCFG_RESOURCE_NAME_LEN, "PCI MMCONFIG %u",
197 			 cfg->pci_segment);
198 		res->start = cfg->address;
199 		res->end = res->start + (num_buses << 20) - 1;
200 		res->flags = IORESOURCE_MEM | resource_flags;
201 		insert_resource(&iomem_resource, res);
202 		names += PCI_MMCFG_RESOURCE_NAME_LEN;
203 	}
204 
205 	/* Mark that the resources have been inserted. */
206 	pci_mmcfg_resources_inserted = 1;
207 }
208 
209 static void __init pci_mmcfg_reject_broken(int type)
210 {
211 	typeof(pci_mmcfg_config[0]) *cfg;
212 
213 	if ((pci_mmcfg_config_num == 0) ||
214 	    (pci_mmcfg_config == NULL) ||
215 	    (pci_mmcfg_config[0].address == 0))
216 		return;
217 
218 	cfg = &pci_mmcfg_config[0];
219 
220 	/*
221 	 * Handle more broken MCFG tables on Asus etc.
222 	 * They only contain a single entry for bus 0-0.
223 	 */
224 	if (pci_mmcfg_config_num == 1 &&
225 	    cfg->pci_segment == 0 &&
226 	    (cfg->start_bus_number | cfg->end_bus_number) == 0) {
227 		printk(KERN_ERR "PCI: start and end of bus number is 0. "
228 		       "Rejected as broken MCFG.\n");
229 		goto reject;
230 	}
231 
232 	/*
233 	 * Only do this check when type 1 works. If it doesn't work
234 	 * assume we run on a Mac and always use MCFG
235 	 */
236 	if (type == 1 && !e820_all_mapped(cfg->address,
237 					  cfg->address + MMCONFIG_APER_MIN,
238 					  E820_RESERVED)) {
239 		printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %Lx is not"
240 		       " E820-reserved\n", cfg->address);
241 		goto reject;
242 	}
243 	return;
244 
245 reject:
246 	printk(KERN_ERR "PCI: Not using MMCONFIG.\n");
247 	kfree(pci_mmcfg_config);
248 	pci_mmcfg_config = NULL;
249 	pci_mmcfg_config_num = 0;
250 }
251 
252 void __init pci_mmcfg_init(int type)
253 {
254 	int known_bridge = 0;
255 
256 	if ((pci_probe & PCI_PROBE_MMCONF) == 0)
257 		return;
258 
259 	if (type == 1 && pci_mmcfg_check_hostbridge())
260 		known_bridge = 1;
261 
262 	if (!known_bridge) {
263 		acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg);
264 		pci_mmcfg_reject_broken(type);
265 	}
266 
267 	if ((pci_mmcfg_config_num == 0) ||
268 	    (pci_mmcfg_config == NULL) ||
269 	    (pci_mmcfg_config[0].address == 0))
270 		return;
271 
272 	if (pci_mmcfg_arch_init()) {
273 		if (type == 1)
274 			unreachable_devices();
275 		if (known_bridge)
276 			pci_mmcfg_insert_resources(IORESOURCE_BUSY);
277 		pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
278 	} else {
279 		/*
280 		 * Signal not to attempt to insert mmcfg resources because
281 		 * the architecture mmcfg setup could not initialize.
282 		 */
283 		pci_mmcfg_resources_inserted = 1;
284 	}
285 }
286 
287 static int __init pci_mmcfg_late_insert_resources(void)
288 {
289 	/*
290 	 * If resources are already inserted or we are not using MMCONFIG,
291 	 * don't insert the resources.
292 	 */
293 	if ((pci_mmcfg_resources_inserted == 1) ||
294 	    (pci_probe & PCI_PROBE_MMCONF) == 0 ||
295 	    (pci_mmcfg_config_num == 0) ||
296 	    (pci_mmcfg_config == NULL) ||
297 	    (pci_mmcfg_config[0].address == 0))
298 		return 1;
299 
300 	/*
301 	 * Attempt to insert the mmcfg resources but not with the busy flag
302 	 * marked so it won't cause request errors when __request_region is
303 	 * called.
304 	 */
305 	pci_mmcfg_insert_resources(0);
306 
307 	return 0;
308 }
309 
310 /*
311  * Perform MMCONFIG resource insertion after PCI initialization to allow for
312  * misprogrammed MCFG tables that state larger sizes but actually conflict
313  * with other system resources.
314  */
315 late_initcall(pci_mmcfg_late_insert_resources);
316