for AMD Fam10h, it we read mmconf from MSR early, we should just trust it because we check it and correct it already. so add it to e820 Signed-off-by: Yinghai Lu <yinghai@xxxxxxxxxx> --- arch/x86/kernel/mmconf-fam10h_64.c | 40 ++++++++++++++++++++--------------- 1 files changed, 23 insertions(+), 17 deletions(-) diff --git a/arch/x86/kernel/mmconf-fam10h_64.c b/arch/x86/kernel/mmconf-fam10h_64.c index 7182580..645d78a 100644 --- a/arch/x86/kernel/mmconf-fam10h_64.c +++ b/arch/x86/kernel/mmconf-fam10h_64.c @@ -16,6 +16,7 @@ #include <asm/acpi.h> #include <asm/mmconfig.h> #include <asm/pci_x86.h> +#include <asm/e820.h> struct pci_hostbridge_probe { u32 bus; @@ -27,23 +28,26 @@ struct pci_hostbridge_probe { static u64 __cpuinitdata fam10h_pci_mmconf_base; static int __cpuinitdata fam10h_pci_mmconf_base_status; +/* only on BSP */ +static void __init_refok e820_add_mmconf_range(int busnbits) +{ + u64 end; + + end = fam10h_pci_mmconf_base + (1ULL<<(busnbits + 20)) - 1; + if (!e820_all_mapped(fam10h_pci_mmconf_base, end+1, E820_RESERVED)) { + printk(KERN_DEBUG "Fam 10h mmconf [%llx, %llx]\n", + fam10h_pci_mmconf_base, end); + e820_add_region(fam10h_pci_mmconf_base, 1ULL<<(busnbits + 20), + E820_RESERVED); + sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map); + } +} + static struct pci_hostbridge_probe pci_probes[] __cpuinitdata = { { 0, 0x18, PCI_VENDOR_ID_AMD, 0x1200 }, { 0xff, 0, PCI_VENDOR_ID_AMD, 0x1200 }, }; -static int __cpuinit cmp_range(const void *x1, const void *x2) -{ - const struct range *r1 = x1; - const struct range *r2 = x2; - int start1, start2; - - start1 = r1->start >> 32; - start2 = r2->start >> 32; - - return start1 - start2; -} - /*[47:0] */ /* need to avoid (0xfd<<32) and (0xfe<<32), ht used space */ #define FAM10H_PCI_MMCONF_BASE (0xfcULL<<32) @@ -115,6 +119,7 @@ static void __cpuinit get_fam10h_pci_mmconf_base(void) * above 4G */ hi_mmio_num = 0; + memset(range, 0, sizeof(range)); for (i = 0; i < 8; i++) { u32 reg; u64 start; @@ -130,16 +135,14 @@ static void __cpuinit get_fam10h_pci_mmconf_base(void) if (!end) continue; - range[hi_mmio_num].start = start; - range[hi_mmio_num].end = end; - hi_mmio_num++; + hi_mmio_num = add_range(range, 8, hi_mmio_num, start, end); } if (!hi_mmio_num) goto out; /* sort the range */ - sort(range, hi_mmio_num, sizeof(struct range), cmp_range, NULL); + sort_range(range, hi_mmio_num); if (range[hi_mmio_num - 1].end < base) goto out; @@ -169,6 +172,7 @@ fail: out: fam10h_pci_mmconf_base = base; fam10h_pci_mmconf_base_status = 1; + e820_add_mmconf_range(8); } void __cpuinit fam10h_check_enable_mmcfg(void) @@ -191,10 +195,12 @@ void __cpuinit fam10h_check_enable_mmcfg(void) /* only trust the one handle 256 buses, if acpi=off */ if (!acpi_pci_disabled || busnbits >= 8) { u64 base; - base = val & (0xffffULL << 32); + base = val & (FAM10H_MMIO_CONF_BASE_MASK << + FAM10H_MMIO_CONF_BASE_SHIFT); if (fam10h_pci_mmconf_base_status <= 0) { fam10h_pci_mmconf_base = base; fam10h_pci_mmconf_base_status = 1; + e820_add_mmconf_range(busnbits); return; } else if (fam10h_pci_mmconf_base == base) return; -- 1.6.4.2 -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html