Skip to content

Commit

Permalink
x86: Use PCI method for enabling AMD extended config space before MSR…
Browse files Browse the repository at this point in the history
… method

While both methods should work equivalently well for the native
case, the Xen Dom0 case can't reliably work with the MSR one,
since there's no guarantee that the virtual CPUs it has
available fully cover all necessary physical ones.

As per the suggestion of Robert Richter the patch only adds the
PCI method, but leaves the MSR one as a fallback to cover new
systems the PCI IDs of which may not have got added to the code
base yet.

The only change in v2 is the breaking out of the new CPI
initialization method into a separate function, as requested by
Ingo.

Signed-off-by: Jan Beulich <jbeulich@novell.com>
Acked-by: Robert Richter <robert.richter@amd.com>
Cc: Andreas Herrmann3 <Andreas.Herrmann3@amd.com>
Cc: Joerg Roedel <joerg.roedel@amd.com>
Cc: Jeremy Fitzhardinge <jeremy@goop.org>
LKML-Reference: <4D2B3FD7020000780002B67D@vpn.id2.novell.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
  • Loading branch information
Jan Beulich authored and Ingo Molnar committed Jan 11, 2011
1 parent 29fe359 commit 24d9b70
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 28 deletions.
7 changes: 7 additions & 0 deletions arch/x86/include/asm/amd_nb.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@

#include <linux/pci.h>

struct amd_nb_bus_dev_range {
u8 bus;
u8 dev_base;
u8 dev_limit;
};

extern struct pci_device_id amd_nb_misc_ids[];
extern const struct amd_nb_bus_dev_range amd_nb_bus_dev_ranges[];
struct bootnode;

extern int early_is_amd_nb(u32 value);
Expand Down
7 changes: 7 additions & 0 deletions arch/x86/kernel/amd_nb.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ struct pci_device_id amd_nb_misc_ids[] = {
};
EXPORT_SYMBOL(amd_nb_misc_ids);

const struct amd_nb_bus_dev_range amd_nb_bus_dev_ranges[] __initconst = {
{ 0x00, 0x18, 0x20 },
{ 0xff, 0x00, 0x20 },
{ 0xfe, 0x00, 0x20 },
{ }
};

struct amd_northbridge_info amd_northbridges;
EXPORT_SYMBOL(amd_northbridges);

Expand Down
44 changes: 16 additions & 28 deletions arch/x86/kernel/aperture_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,6 @@ int fallback_aper_force __initdata;

int fix_aperture __initdata = 1;

struct bus_dev_range {
int bus;
int dev_base;
int dev_limit;
};

static struct bus_dev_range bus_dev_ranges[] __initdata = {
{ 0x00, 0x18, 0x20},
{ 0xff, 0x00, 0x20},
{ 0xfe, 0x00, 0x20}
};

static struct resource gart_resource = {
.name = "GART",
.flags = IORESOURCE_MEM,
Expand Down Expand Up @@ -294,13 +282,13 @@ void __init early_gart_iommu_check(void)
search_agp_bridge(&agp_aper_order, &valid_agp);

fix = 0;
for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) {
for (i = 0; amd_nb_bus_dev_ranges[i].dev_limit; i++) {
int bus;
int dev_base, dev_limit;

bus = bus_dev_ranges[i].bus;
dev_base = bus_dev_ranges[i].dev_base;
dev_limit = bus_dev_ranges[i].dev_limit;
bus = amd_nb_bus_dev_ranges[i].bus;
dev_base = amd_nb_bus_dev_ranges[i].dev_base;
dev_limit = amd_nb_bus_dev_ranges[i].dev_limit;

for (slot = dev_base; slot < dev_limit; slot++) {
if (!early_is_amd_nb(read_pci_config(bus, slot, 3, 0x00)))
Expand Down Expand Up @@ -349,13 +337,13 @@ void __init early_gart_iommu_check(void)
return;

/* disable them all at first */
for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) {
for (i = 0; i < amd_nb_bus_dev_ranges[i].dev_limit; i++) {
int bus;
int dev_base, dev_limit;

bus = bus_dev_ranges[i].bus;
dev_base = bus_dev_ranges[i].dev_base;
dev_limit = bus_dev_ranges[i].dev_limit;
bus = amd_nb_bus_dev_ranges[i].bus;
dev_base = amd_nb_bus_dev_ranges[i].dev_base;
dev_limit = amd_nb_bus_dev_ranges[i].dev_limit;

for (slot = dev_base; slot < dev_limit; slot++) {
if (!early_is_amd_nb(read_pci_config(bus, slot, 3, 0x00)))
Expand Down Expand Up @@ -390,14 +378,14 @@ int __init gart_iommu_hole_init(void)

fix = 0;
node = 0;
for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) {
for (i = 0; i < amd_nb_bus_dev_ranges[i].dev_limit; i++) {
int bus;
int dev_base, dev_limit;
u32 ctl;

bus = bus_dev_ranges[i].bus;
dev_base = bus_dev_ranges[i].dev_base;
dev_limit = bus_dev_ranges[i].dev_limit;
bus = amd_nb_bus_dev_ranges[i].bus;
dev_base = amd_nb_bus_dev_ranges[i].dev_base;
dev_limit = amd_nb_bus_dev_ranges[i].dev_limit;

for (slot = dev_base; slot < dev_limit; slot++) {
if (!early_is_amd_nb(read_pci_config(bus, slot, 3, 0x00)))
Expand Down Expand Up @@ -505,7 +493,7 @@ int __init gart_iommu_hole_init(void)
}

/* Fix up the north bridges */
for (i = 0; i < ARRAY_SIZE(bus_dev_ranges); i++) {
for (i = 0; i < amd_nb_bus_dev_ranges[i].dev_limit; i++) {
int bus, dev_base, dev_limit;

/*
Expand All @@ -514,9 +502,9 @@ int __init gart_iommu_hole_init(void)
*/
u32 ctl = DISTLBWALKPRB | aper_order << 1;

bus = bus_dev_ranges[i].bus;
dev_base = bus_dev_ranges[i].dev_base;
dev_limit = bus_dev_ranges[i].dev_limit;
bus = amd_nb_bus_dev_ranges[i].bus;
dev_base = amd_nb_bus_dev_ranges[i].dev_base;
dev_limit = amd_nb_bus_dev_ranges[i].dev_limit;
for (slot = dev_base; slot < dev_limit; slot++) {
if (!early_is_amd_nb(read_pci_config(bus, slot, 3, 0x00)))
continue;
Expand Down
33 changes: 33 additions & 0 deletions arch/x86/pci/amd_bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <linux/cpu.h>
#include <linux/range.h>

#include <asm/amd_nb.h>
#include <asm/pci_x86.h>

#include <asm/pci-direct.h>
Expand Down Expand Up @@ -378,6 +379,34 @@ static struct notifier_block __cpuinitdata amd_cpu_notifier = {
.notifier_call = amd_cpu_notify,
};

static void __init pci_enable_pci_io_ecs(void)
{
#ifdef CONFIG_AMD_NB
unsigned int i, n;

for (n = i = 0; !n && amd_nb_bus_dev_ranges[i].dev_limit; ++i) {
u8 bus = amd_nb_bus_dev_ranges[i].bus;
u8 slot = amd_nb_bus_dev_ranges[i].dev_base;
u8 limit = amd_nb_bus_dev_ranges[i].dev_limit;

for (; slot < limit; ++slot) {
u32 val = read_pci_config(bus, slot, 3, 0);

if (!early_is_amd_nb(val))
continue;

val = read_pci_config(bus, slot, 3, 0x8c);
if (!(val & (ENABLE_CF8_EXT_CFG >> 32))) {
val |= ENABLE_CF8_EXT_CFG >> 32;
write_pci_config(bus, slot, 3, 0x8c, val);
}
++n;
}
}
pr_info("Extended Config Space enabled on %u nodes\n", n);
#endif
}

static int __init pci_io_ecs_init(void)
{
int cpu;
Expand All @@ -386,6 +415,10 @@ static int __init pci_io_ecs_init(void)
if (boot_cpu_data.x86 < 0x10)
return 0;

/* Try the PCI method first. */
if (early_pci_allowed())
pci_enable_pci_io_ecs();

register_cpu_notifier(&amd_cpu_notifier);
for_each_online_cpu(cpu)
amd_cpu_notify(&amd_cpu_notifier, (unsigned long)CPU_ONLINE,
Expand Down

0 comments on commit 24d9b70

Please sign in to comment.