aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/pci/mmconfig-shared.c
diff options
context:
space:
mode:
authorYinghai Lu <Yinghai.Lu@Sun.COM>2008-02-15 04:30:14 -0500
committerIngo Molnar <mingo@elte.hu>2008-04-26 17:41:03 -0400
commit05c58b8ac77639c17205f0b2a2d9eb1971dc47ad (patch)
tree89dd703cb0905f981dd322e04f55f0c7905f385b /arch/x86/pci/mmconfig-shared.c
parent0b64ad7123eb013c3de26750f2d4c356cd566231 (diff)
x86: mmconf enable mcfg early
Patch "x86: validate against ACPI motherboard resources" changed the mmconf init sequence, and init MMCONF late in acpi_init. here change it back to old sequence: 1. check hostbridge in early 2. check MCFG with e820 in early 3. if all fail, will check MCFg with acpi _CRS in acpi_init So we can make MCONF working again when acpi=off is set if hostbridge support that. Signed-off-by: Yinghai Lu <yinghai.lu@sun.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Greg KH <greg@kroah.com> Cc: Greg KH <greg@kroah.com> Cc: Andi Kleen <ak@suse.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/pci/mmconfig-shared.c')
-rw-r--r--arch/x86/pci/mmconfig-shared.c101
1 files changed, 55 insertions, 46 deletions
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
index 8f204955427c..36a4a7514b05 100644
--- a/arch/x86/pci/mmconfig-shared.c
+++ b/arch/x86/pci/mmconfig-shared.c
@@ -241,7 +241,7 @@ static int __init is_acpi_reserved(unsigned long start, unsigned long end)
241 return mcfg_res.flags; 241 return mcfg_res.flags;
242} 242}
243 243
244static void __init pci_mmcfg_reject_broken(void) 244static void __init pci_mmcfg_reject_broken(int type, int early)
245{ 245{
246 typeof(pci_mmcfg_config[0]) *cfg; 246 typeof(pci_mmcfg_config[0]) *cfg;
247 int i; 247 int i;
@@ -266,34 +266,43 @@ static void __init pci_mmcfg_reject_broken(void)
266 } 266 }
267 267
268 for (i = 0; i < pci_mmcfg_config_num; i++) { 268 for (i = 0; i < pci_mmcfg_config_num; i++) {
269 int valid = 0;
269 u32 size = (cfg->end_bus_number + 1) << 20; 270 u32 size = (cfg->end_bus_number + 1) << 20;
270 cfg = &pci_mmcfg_config[i]; 271 cfg = &pci_mmcfg_config[i];
271 printk(KERN_NOTICE "PCI: MCFG configuration %d: base %lu " 272 printk(KERN_NOTICE "PCI: MCFG configuration %d: base %lx "
272 "segment %hu buses %u - %u\n", 273 "segment %hu buses %u - %u\n",
273 i, (unsigned long)cfg->address, cfg->pci_segment, 274 i, (unsigned long)cfg->address, cfg->pci_segment,
274 (unsigned int)cfg->start_bus_number, 275 (unsigned int)cfg->start_bus_number,
275 (unsigned int)cfg->end_bus_number); 276 (unsigned int)cfg->end_bus_number);
276 if (is_acpi_reserved(cfg->address, cfg->address + size - 1)) { 277
278 if (!early &&
279 is_acpi_reserved(cfg->address, cfg->address + size - 1)) {
277 printk(KERN_NOTICE "PCI: MCFG area at %Lx reserved " 280 printk(KERN_NOTICE "PCI: MCFG area at %Lx reserved "
278 "in ACPI motherboard resources\n", 281 "in ACPI motherboard resources\n",
279 cfg->address); 282 cfg->address);
280 } else { 283 valid = 1;
284 }
285
286 if (valid)
287 continue;
288
289 if (!early)
281 printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %Lx is not" 290 printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %Lx is not"
282 " reserved in ACPI motherboard resources\n", 291 " reserved in ACPI motherboard resources\n",
283 cfg->address); 292 cfg->address);
284 /* Don't try to do this check unless configuration 293 /* Don't try to do this check unless configuration
285 type 1 is available. */ 294 type 1 is available. */
286 if ((pci_probe & PCI_PROBE_CONF1) && 295 if (type == 1 && e820_all_mapped(cfg->address,
287 e820_all_mapped(cfg->address, 296 cfg->address + size - 1,
288 cfg->address + size - 1, 297 E820_RESERVED)) {
289 E820_RESERVED)) 298 printk(KERN_NOTICE
290 printk(KERN_NOTICE 299 "PCI: MCFG area at %Lx reserved in E820\n",
291 "PCI: MCFG area at %Lx reserved in " 300 cfg->address);
292 "E820\n", 301 valid = 1;
293 cfg->address);
294 else
295 goto reject;
296 } 302 }
303
304 if (!valid)
305 goto reject;
297 } 306 }
298 307
299 return; 308 return;
@@ -306,46 +315,31 @@ reject:
306 pci_mmcfg_config_num = 0; 315 pci_mmcfg_config_num = 0;
307} 316}
308 317
309void __init pci_mmcfg_early_init(int type) 318static int __initdata known_bridge;
310{
311 if ((pci_probe & PCI_PROBE_MMCONF) == 0)
312 return;
313
314 /* If type 1 access is available, no need to enable MMCONFIG yet, we can
315 defer until later when the ACPI interpreter is available to better
316 validate things. */
317 if (type == 1)
318 return;
319
320 acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg);
321
322 if ((pci_mmcfg_config_num == 0) ||
323 (pci_mmcfg_config == NULL) ||
324 (pci_mmcfg_config[0].address == 0))
325 return;
326 319
327 if (pci_mmcfg_arch_init()) 320void __init __pci_mmcfg_init(int type, int early)
328 pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
329}
330
331void __init pci_mmcfg_late_init(void)
332{ 321{
333 int known_bridge = 0;
334
335 /* MMCONFIG disabled */ 322 /* MMCONFIG disabled */
336 if ((pci_probe & PCI_PROBE_MMCONF) == 0) 323 if ((pci_probe & PCI_PROBE_MMCONF) == 0)
337 return; 324 return;
338 325
339 /* MMCONFIG already enabled */ 326 /* MMCONFIG already enabled */
340 if (!(pci_probe & PCI_PROBE_MASK & ~PCI_PROBE_MMCONF)) 327 if (!early && !(pci_probe & PCI_PROBE_MASK & ~PCI_PROBE_MMCONF))
341 return; 328 return;
342 329
343 if ((pci_probe & PCI_PROBE_CONF1) && pci_mmcfg_check_hostbridge()) 330 /* for late to exit */
344 known_bridge = 1; 331 if (known_bridge)
345 else 332 return;
346 acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg);
347 333
348 pci_mmcfg_reject_broken(); 334 if (early && type == 1) {
335 if (pci_mmcfg_check_hostbridge())
336 known_bridge = 1;
337 }
338
339 if (!known_bridge) {
340 acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg);
341 pci_mmcfg_reject_broken(type, early);
342 }
349 343
350 if ((pci_mmcfg_config_num == 0) || 344 if ((pci_mmcfg_config_num == 0) ||
351 (pci_mmcfg_config == NULL) || 345 (pci_mmcfg_config == NULL) ||
@@ -365,6 +359,21 @@ void __init pci_mmcfg_late_init(void)
365 } 359 }
366} 360}
367 361
362void __init pci_mmcfg_early_init(int type)
363{
364 __pci_mmcfg_init(type, 1);
365}
366
367void __init pci_mmcfg_late_init(void)
368{
369 int type = 0;
370
371 if (pci_probe & PCI_PROBE_CONF1)
372 type = 1;
373
374 __pci_mmcfg_init(type, 0);
375}
376
368static int __init pci_mmcfg_late_insert_resources(void) 377static int __init pci_mmcfg_late_insert_resources(void)
369{ 378{
370 /* 379 /*