* [PATCH v2 2/3] x86, amd: factor out MMCONFIG discovery
2012-01-09 22:43 [PATCH v2 1/3] x86/PCI: build amd_bus.o only when CONFIG_AMD_NB=y Bjorn Helgaas
@ 2012-01-09 22:43 ` Bjorn Helgaas
2012-01-09 22:43 ` [PATCH v2 3/3] PNP: work around Dell 1536/1546 BIOS MMCONFIG bug that breaks USB Bjorn Helgaas
2012-01-25 21:08 ` [PATCH v2 1/3] x86/PCI: build amd_bus.o only when CONFIG_AMD_NB=y Jesse Barnes
2 siblings, 0 replies; 5+ messages in thread
From: Bjorn Helgaas @ 2012-01-09 22:43 UTC (permalink / raw)
To: Jesse Barnes; +Cc: linux-pci, stable, Yinghai Lu, Borislav Petkov
This factors out the AMD native MMCONFIG discovery so we can use it
outside amd_bus.c.
amd_bus.c reads AMD MSRs so it can remove the MMCONFIG area from the
PCI resources. We may also need the MMCONFIG information to work
around BIOS defects in the ACPI MCFG table.
Cc: Borislav Petkov <borislav.petkov@amd.com>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: stable@kernel.org # 2.6.34+
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
arch/x86/include/asm/amd_nb.h | 2 ++
arch/x86/kernel/amd_nb.c | 31 ++++++++++++++++++++++++++++++
arch/x86/pci/amd_bus.c | 42 +++++++++++------------------------------
3 files changed, 44 insertions(+), 31 deletions(-)
diff --git a/arch/x86/include/asm/amd_nb.h b/arch/x86/include/asm/amd_nb.h
index 8e41071..49ad773 100644
--- a/arch/x86/include/asm/amd_nb.h
+++ b/arch/x86/include/asm/amd_nb.h
@@ -1,6 +1,7 @@
#ifndef _ASM_X86_AMD_NB_H
#define _ASM_X86_AMD_NB_H
+#include <linux/ioport.h>
#include <linux/pci.h>
struct amd_nb_bus_dev_range {
@@ -13,6 +14,7 @@ extern const struct pci_device_id amd_nb_misc_ids[];
extern const struct amd_nb_bus_dev_range amd_nb_bus_dev_ranges[];
extern bool early_is_amd_nb(u32 value);
+extern struct resource *amd_get_mmconfig_range(struct resource *res);
extern int amd_cache_northbridges(void);
extern void amd_flush_garts(void);
extern int amd_numa_init(void);
diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c
index 4c39baa..bae1efe 100644
--- a/arch/x86/kernel/amd_nb.c
+++ b/arch/x86/kernel/amd_nb.c
@@ -119,6 +119,37 @@ bool __init early_is_amd_nb(u32 device)
return false;
}
+struct resource *amd_get_mmconfig_range(struct resource *res)
+{
+ u32 address;
+ u64 base, msr;
+ unsigned segn_busn_bits;
+
+ if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
+ return NULL;
+
+ /* assume all cpus from fam10h have mmconfig */
+ if (boot_cpu_data.x86 < 0x10)
+ return NULL;
+
+ address = MSR_FAM10H_MMIO_CONF_BASE;
+ rdmsrl(address, msr);
+
+ /* mmconfig is not enabled */
+ if (!(msr & FAM10H_MMIO_CONF_ENABLE))
+ return NULL;
+
+ base = msr & (FAM10H_MMIO_CONF_BASE_MASK<<FAM10H_MMIO_CONF_BASE_SHIFT);
+
+ segn_busn_bits = (msr >> FAM10H_MMIO_CONF_BUSRANGE_SHIFT) &
+ FAM10H_MMIO_CONF_BUSRANGE_MASK;
+
+ res->flags = IORESOURCE_MEM;
+ res->start = base;
+ res->end = base + (1ULL<<(segn_busn_bits + 20)) - 1;
+ return res;
+}
+
int amd_get_subcaches(int cpu)
{
struct pci_dev *link = node_to_amd_nb(amd_get_nb_id(cpu))->link;
diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c
index 026e493..385a940 100644
--- a/arch/x86/pci/amd_bus.c
+++ b/arch/x86/pci/amd_bus.c
@@ -30,34 +30,6 @@ static struct pci_hostbridge_probe pci_probes[] __initdata = {
{ 0, 0x18, PCI_VENDOR_ID_AMD, 0x1300 },
};
-static u64 __initdata fam10h_mmconf_start;
-static u64 __initdata fam10h_mmconf_end;
-static void __init get_pci_mmcfg_amd_fam10h_range(void)
-{
- u32 address;
- u64 base, msr;
- unsigned segn_busn_bits;
-
- /* assume all cpus from fam10h have mmconf */
- if (boot_cpu_data.x86 < 0x10)
- return;
-
- address = MSR_FAM10H_MMIO_CONF_BASE;
- rdmsrl(address, msr);
-
- /* mmconfig is not enable */
- if (!(msr & FAM10H_MMIO_CONF_ENABLE))
- return;
-
- base = msr & (FAM10H_MMIO_CONF_BASE_MASK<<FAM10H_MMIO_CONF_BASE_SHIFT);
-
- segn_busn_bits = (msr >> FAM10H_MMIO_CONF_BUSRANGE_SHIFT) &
- FAM10H_MMIO_CONF_BUSRANGE_MASK;
-
- fam10h_mmconf_start = base;
- fam10h_mmconf_end = base + (1ULL<<(segn_busn_bits + 20)) - 1;
-}
-
#define RANGE_NUM 16
/**
@@ -85,6 +57,9 @@ static int __init early_fill_mp_bus_info(void)
u64 val;
u32 address;
bool found;
+ struct resource fam10h_mmconf_res, *fam10h_mmconf;
+ u64 fam10h_mmconf_start;
+ u64 fam10h_mmconf_end;
if (!early_pci_allowed())
return -1;
@@ -211,12 +186,17 @@ static int __init early_fill_mp_bus_info(void)
subtract_range(range, RANGE_NUM, 0, end);
/* get mmconfig */
- get_pci_mmcfg_amd_fam10h_range();
+ fam10h_mmconf = amd_get_mmconfig_range(&fam10h_mmconf_res);
/* need to take out mmconf range */
- if (fam10h_mmconf_end) {
- printk(KERN_DEBUG "Fam 10h mmconf [%llx, %llx]\n", fam10h_mmconf_start, fam10h_mmconf_end);
+ if (fam10h_mmconf) {
+ printk(KERN_DEBUG "Fam 10h mmconf %pR\n", fam10h_mmconf);
+ fam10h_mmconf_start = fam10h_mmconf->start;
+ fam10h_mmconf_end = fam10h_mmconf->end;
subtract_range(range, RANGE_NUM, fam10h_mmconf_start,
fam10h_mmconf_end + 1);
+ } else {
+ fam10h_mmconf_start = 0;
+ fam10h_mmconf_end = 0;
}
/* mmio resource */
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH v2 3/3] PNP: work around Dell 1536/1546 BIOS MMCONFIG bug that breaks USB
2012-01-09 22:43 [PATCH v2 1/3] x86/PCI: build amd_bus.o only when CONFIG_AMD_NB=y Bjorn Helgaas
2012-01-09 22:43 ` [PATCH v2 2/3] x86, amd: factor out MMCONFIG discovery Bjorn Helgaas
@ 2012-01-09 22:43 ` Bjorn Helgaas
2012-01-25 21:08 ` [PATCH v2 1/3] x86/PCI: build amd_bus.o only when CONFIG_AMD_NB=y Jesse Barnes
2 siblings, 0 replies; 5+ messages in thread
From: Bjorn Helgaas @ 2012-01-09 22:43 UTC (permalink / raw)
To: Jesse Barnes; +Cc: linux-pci, stable, thuban, Lisa Salimbas, dann frazier
Some Dell BIOSes have MCFG tables that don't report the entire
MMCONFIG area claimed by the chipset. If we move PCI devices into
that claimed-but-unreported area, they don't work.
This quirk reads the AMD MMCONFIG MSRs and adds PNP0C01 resources as
needed to cover the entire area.
Example problem scenario:
BIOS-e820: 00000000cfec5400 - 00000000d4000000 (reserved)
Fam 10h mmconf [d0000000, dfffffff]
PCI: MMCONFIG for domain 0000 [bus 00-3f] at [mem 0xd0000000-0xd3ffffff] (base 0xd0000000)
pnp 00:0c: [mem 0xd0000000-0xd3ffffff]
pci 0000:00:12.0: reg 10: [mem 0xffb00000-0xffb00fff]
pci 0000:00:12.0: no compatible bridge window for [mem 0xffb00000-0xffb00fff]
pci 0000:00:12.0: BAR 0: assigned [mem 0xd4000000-0xd40000ff]
Reported-by: Lisa Salimbas <lisa.salimbas@canonical.com>
Reported-by: <thuban@singularity.fr>
Tested-by: dann frazier <dann.frazier@canonical.com>
References: https://bugzilla.kernel.org/show_bug.cgi?id=31602
References: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/647043
References: https://bugzilla.redhat.com/show_bug.cgi?id=770308
Cc: stable@kernel.org # 2.6.34+
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
drivers/pnp/quirks.c | 42 ++++++++++++++++++++++++++++++++++++++++++
1 files changed, 42 insertions(+), 0 deletions(-)
diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c
index dfbd5a6..258fef2 100644
--- a/drivers/pnp/quirks.c
+++ b/drivers/pnp/quirks.c
@@ -295,6 +295,45 @@ static void quirk_system_pci_resources(struct pnp_dev *dev)
}
}
+#ifdef CONFIG_AMD_NB
+
+#include <asm/amd_nb.h>
+
+static void quirk_amd_mmconfig_area(struct pnp_dev *dev)
+{
+ resource_size_t start, end;
+ struct pnp_resource *pnp_res;
+ struct resource *res;
+ struct resource mmconfig_res, *mmconfig;
+
+ mmconfig = amd_get_mmconfig_range(&mmconfig_res);
+ if (!mmconfig)
+ return;
+
+ list_for_each_entry(pnp_res, &dev->resources, list) {
+ res = &pnp_res->res;
+ if (res->end < mmconfig->start || res->start > mmconfig->end ||
+ (res->start == mmconfig->start && res->end == mmconfig->end))
+ continue;
+
+ dev_info(&dev->dev, FW_BUG
+ "%pR covers only part of AMD MMCONFIG area %pR; adding more reservations\n",
+ res, mmconfig);
+ if (mmconfig->start < res->start) {
+ start = mmconfig->start;
+ end = res->start - 1;
+ pnp_add_mem_resource(dev, start, end, 0);
+ }
+ if (mmconfig->end > res->end) {
+ start = res->end + 1;
+ end = mmconfig->end;
+ pnp_add_mem_resource(dev, start, end, 0);
+ }
+ break;
+ }
+}
+#endif
+
/*
* PnP Quirks
* Cards or devices that need some tweaking due to incomplete resource info
@@ -322,6 +361,9 @@ static struct pnp_fixup pnp_fixups[] = {
/* PnP resources that might overlap PCI BARs */
{"PNP0c01", quirk_system_pci_resources},
{"PNP0c02", quirk_system_pci_resources},
+#ifdef CONFIG_AMD_NB
+ {"PNP0c01", quirk_amd_mmconfig_area},
+#endif
{""}
};
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH v2 1/3] x86/PCI: build amd_bus.o only when CONFIG_AMD_NB=y
2012-01-09 22:43 [PATCH v2 1/3] x86/PCI: build amd_bus.o only when CONFIG_AMD_NB=y Bjorn Helgaas
2012-01-09 22:43 ` [PATCH v2 2/3] x86, amd: factor out MMCONFIG discovery Bjorn Helgaas
2012-01-09 22:43 ` [PATCH v2 3/3] PNP: work around Dell 1536/1546 BIOS MMCONFIG bug that breaks USB Bjorn Helgaas
@ 2012-01-25 21:08 ` Jesse Barnes
2012-01-25 21:33 ` Bjorn Helgaas
2 siblings, 1 reply; 5+ messages in thread
From: Jesse Barnes @ 2012-01-25 21:08 UTC (permalink / raw)
To: Bjorn Helgaas; +Cc: linux-pci, Yinghai Lu
[-- Attachment #1: Type: text/plain, Size: 1173 bytes --]
On Mon, 09 Jan 2012 15:43:49 -0700
Bjorn Helgaas <bhelgaas@google.com> wrote:
> We only need amd_bus.o for AMD systems with PCI. arch/x86/pci/Makefile
> already depends on CONFIG_PCI=y, so this patch just adds the dependency
> on CONFIG_AMD_NB.
>
> CC: Yinghai Lu <yinghai@kernel.org>
> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
> ---
> arch/x86/pci/Makefile | 3 ++-
> 1 files changed, 2 insertions(+), 1 deletions(-)
>
> diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile
> index 6b8759f..d24d3da 100644
> --- a/arch/x86/pci/Makefile
> +++ b/arch/x86/pci/Makefile
> @@ -18,8 +18,9 @@ obj-$(CONFIG_X86_NUMAQ) += numaq_32.o
> obj-$(CONFIG_X86_MRST) += mrst.o
>
> obj-y += common.o early.o
> -obj-y += amd_bus.o bus_numa.o
> +obj-y += bus_numa.o
>
> +obj-$(CONFIG_AMD_NB) += amd_bus.o
> obj-$(CONFIG_PCI_CNB20LE_QUIRK) += broadcom_bus.o
>
> ifeq ($(CONFIG_PCI_DEBUG),y)
Arg sorry guys I've been totally swamped since sending in the pull
req. I'll do a review & merge pass on the outstanding stuff tomorrow.
Thanks for your patience.
--
Jesse Barnes, Intel Open Source Technology Center
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v2 1/3] x86/PCI: build amd_bus.o only when CONFIG_AMD_NB=y
2012-01-25 21:08 ` [PATCH v2 1/3] x86/PCI: build amd_bus.o only when CONFIG_AMD_NB=y Jesse Barnes
@ 2012-01-25 21:33 ` Bjorn Helgaas
0 siblings, 0 replies; 5+ messages in thread
From: Bjorn Helgaas @ 2012-01-25 21:33 UTC (permalink / raw)
To: Jesse Barnes; +Cc: linux-pci, Yinghai Lu
On Wed, Jan 25, 2012 at 2:08 PM, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
> On Mon, 09 Jan 2012 15:43:49 -0700
> Bjorn Helgaas <bhelgaas@google.com> wrote:
>
>> We only need amd_bus.o for AMD systems with PCI. arch/x86/pci/Makefile
>> already depends on CONFIG_PCI=y, so this patch just adds the dependency
>> on CONFIG_AMD_NB.
>>
>> CC: Yinghai Lu <yinghai@kernel.org>
>> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
>> ---
>> arch/x86/pci/Makefile | 3 ++-
>> 1 files changed, 2 insertions(+), 1 deletions(-)
>>
>> diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile
>> index 6b8759f..d24d3da 100644
>> --- a/arch/x86/pci/Makefile
>> +++ b/arch/x86/pci/Makefile
>> @@ -18,8 +18,9 @@ obj-$(CONFIG_X86_NUMAQ) += numaq_32.o
>> obj-$(CONFIG_X86_MRST) += mrst.o
>>
>> obj-y += common.o early.o
>> -obj-y += amd_bus.o bus_numa.o
>> +obj-y += bus_numa.o
>>
>> +obj-$(CONFIG_AMD_NB) += amd_bus.o
>> obj-$(CONFIG_PCI_CNB20LE_QUIRK) += broadcom_bus.o
>>
>> ifeq ($(CONFIG_PCI_DEBUG),y)
>
> Arg sorry guys I've been totally swamped since sending in the pull
> req. I'll do a review & merge pass on the outstanding stuff tomorrow.
Linus picked up this particular fix already (5cf9a4e69c1ff), so don't
worry about this one.
Bjorn
^ permalink raw reply [flat|nested] 5+ messages in thread