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