mirror of
https://github.com/torvalds/linux.git
synced 2024-11-15 16:41:58 +00:00
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>
This commit is contained in:
parent
0b64ad7123
commit
05c58b8ac7
@ -241,7 +241,7 @@ static int __init is_acpi_reserved(unsigned long start, unsigned long end)
|
|||||||
return mcfg_res.flags;
|
return mcfg_res.flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __init pci_mmcfg_reject_broken(void)
|
static void __init pci_mmcfg_reject_broken(int type, int early)
|
||||||
{
|
{
|
||||||
typeof(pci_mmcfg_config[0]) *cfg;
|
typeof(pci_mmcfg_config[0]) *cfg;
|
||||||
int i;
|
int i;
|
||||||
@ -266,34 +266,43 @@ static void __init pci_mmcfg_reject_broken(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < pci_mmcfg_config_num; i++) {
|
for (i = 0; i < pci_mmcfg_config_num; i++) {
|
||||||
|
int valid = 0;
|
||||||
u32 size = (cfg->end_bus_number + 1) << 20;
|
u32 size = (cfg->end_bus_number + 1) << 20;
|
||||||
cfg = &pci_mmcfg_config[i];
|
cfg = &pci_mmcfg_config[i];
|
||||||
printk(KERN_NOTICE "PCI: MCFG configuration %d: base %lu "
|
printk(KERN_NOTICE "PCI: MCFG configuration %d: base %lx "
|
||||||
"segment %hu buses %u - %u\n",
|
"segment %hu buses %u - %u\n",
|
||||||
i, (unsigned long)cfg->address, cfg->pci_segment,
|
i, (unsigned long)cfg->address, cfg->pci_segment,
|
||||||
(unsigned int)cfg->start_bus_number,
|
(unsigned int)cfg->start_bus_number,
|
||||||
(unsigned int)cfg->end_bus_number);
|
(unsigned int)cfg->end_bus_number);
|
||||||
if (is_acpi_reserved(cfg->address, cfg->address + size - 1)) {
|
|
||||||
|
if (!early &&
|
||||||
|
is_acpi_reserved(cfg->address, cfg->address + size - 1)) {
|
||||||
printk(KERN_NOTICE "PCI: MCFG area at %Lx reserved "
|
printk(KERN_NOTICE "PCI: MCFG area at %Lx reserved "
|
||||||
"in ACPI motherboard resources\n",
|
"in ACPI motherboard resources\n",
|
||||||
cfg->address);
|
cfg->address);
|
||||||
} else {
|
valid = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valid)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!early)
|
||||||
printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %Lx is not"
|
printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %Lx is not"
|
||||||
" reserved in ACPI motherboard resources\n",
|
" reserved in ACPI motherboard resources\n",
|
||||||
cfg->address);
|
cfg->address);
|
||||||
/* Don't try to do this check unless configuration
|
/* Don't try to do this check unless configuration
|
||||||
type 1 is available. */
|
type 1 is available. */
|
||||||
if ((pci_probe & PCI_PROBE_CONF1) &&
|
if (type == 1 && e820_all_mapped(cfg->address,
|
||||||
e820_all_mapped(cfg->address,
|
cfg->address + size - 1,
|
||||||
cfg->address + size - 1,
|
E820_RESERVED)) {
|
||||||
E820_RESERVED))
|
printk(KERN_NOTICE
|
||||||
printk(KERN_NOTICE
|
"PCI: MCFG area at %Lx reserved in E820\n",
|
||||||
"PCI: MCFG area at %Lx reserved in "
|
cfg->address);
|
||||||
"E820\n",
|
valid = 1;
|
||||||
cfg->address);
|
|
||||||
else
|
|
||||||
goto reject;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!valid)
|
||||||
|
goto reject;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -306,46 +315,31 @@ reject:
|
|||||||
pci_mmcfg_config_num = 0;
|
pci_mmcfg_config_num = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __init pci_mmcfg_early_init(int type)
|
static int __initdata known_bridge;
|
||||||
|
|
||||||
|
void __init __pci_mmcfg_init(int type, int early)
|
||||||
{
|
{
|
||||||
if ((pci_probe & PCI_PROBE_MMCONF) == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* If type 1 access is available, no need to enable MMCONFIG yet, we can
|
|
||||||
defer until later when the ACPI interpreter is available to better
|
|
||||||
validate things. */
|
|
||||||
if (type == 1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg);
|
|
||||||
|
|
||||||
if ((pci_mmcfg_config_num == 0) ||
|
|
||||||
(pci_mmcfg_config == NULL) ||
|
|
||||||
(pci_mmcfg_config[0].address == 0))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (pci_mmcfg_arch_init())
|
|
||||||
pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
|
|
||||||
}
|
|
||||||
|
|
||||||
void __init pci_mmcfg_late_init(void)
|
|
||||||
{
|
|
||||||
int known_bridge = 0;
|
|
||||||
|
|
||||||
/* MMCONFIG disabled */
|
/* MMCONFIG disabled */
|
||||||
if ((pci_probe & PCI_PROBE_MMCONF) == 0)
|
if ((pci_probe & PCI_PROBE_MMCONF) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* MMCONFIG already enabled */
|
/* MMCONFIG already enabled */
|
||||||
if (!(pci_probe & PCI_PROBE_MASK & ~PCI_PROBE_MMCONF))
|
if (!early && !(pci_probe & PCI_PROBE_MASK & ~PCI_PROBE_MMCONF))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ((pci_probe & PCI_PROBE_CONF1) && pci_mmcfg_check_hostbridge())
|
/* for late to exit */
|
||||||
known_bridge = 1;
|
if (known_bridge)
|
||||||
else
|
return;
|
||||||
acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg);
|
|
||||||
|
|
||||||
pci_mmcfg_reject_broken();
|
if (early && type == 1) {
|
||||||
|
if (pci_mmcfg_check_hostbridge())
|
||||||
|
known_bridge = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!known_bridge) {
|
||||||
|
acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg);
|
||||||
|
pci_mmcfg_reject_broken(type, early);
|
||||||
|
}
|
||||||
|
|
||||||
if ((pci_mmcfg_config_num == 0) ||
|
if ((pci_mmcfg_config_num == 0) ||
|
||||||
(pci_mmcfg_config == NULL) ||
|
(pci_mmcfg_config == NULL) ||
|
||||||
@ -365,6 +359,21 @@ void __init pci_mmcfg_late_init(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void __init pci_mmcfg_early_init(int type)
|
||||||
|
{
|
||||||
|
__pci_mmcfg_init(type, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __init pci_mmcfg_late_init(void)
|
||||||
|
{
|
||||||
|
int type = 0;
|
||||||
|
|
||||||
|
if (pci_probe & PCI_PROBE_CONF1)
|
||||||
|
type = 1;
|
||||||
|
|
||||||
|
__pci_mmcfg_init(type, 0);
|
||||||
|
}
|
||||||
|
|
||||||
static int __init pci_mmcfg_late_insert_resources(void)
|
static int __init pci_mmcfg_late_insert_resources(void)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user