linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] x86: Add PCI extended config space access for AMD Barcelona
  2008-05-26 18:06     ` Robert Richter
@ 2007-09-03  8:17       ` Robert Richter
  2008-05-28 19:02         ` Arjan van de Ven
                           ` (2 more replies)
  0 siblings, 3 replies; 27+ messages in thread
From: Robert Richter @ 2007-09-03  8:17 UTC (permalink / raw)
  To: Arjan van de Ven
  Cc: Yinghai Lu, Thomas Gleixner, Ingo Molnar, LKML, Andi Kleen

This patch implements PCI extended configuration space access for
AMD's Barcelona CPUs. It extends the method using CF8/CFC IO
addresses. An x86 capability bit has been introduced that is set for
CPUs supporting PCI extended config space accesses.

Signed-off-by: Robert Richter <robert.richter@amd.com>
---
 arch/x86/kernel/cpu/amd.c    |    4 ++++
 arch/x86/kernel/setup.c      |   13 +++++++++++++
 arch/x86/kernel/setup.h      |   26 ++++++++++++++++++++++++++
 arch/x86/kernel/setup_64.c   |    5 +++++
 arch/x86/pci/direct.c        |   21 +++++++++++++++------
 include/asm-x86/cpufeature.h |    2 ++
 6 files changed, 65 insertions(+), 6 deletions(-)
 create mode 100644 arch/x86/kernel/setup.h

diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index 2458668..99221f9 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -6,6 +6,7 @@
 #include <asm/apic.h>
 
 #include <mach_apic.h>
+#include "../setup.h"
 #include "cpu.h"
 
 /*
@@ -308,6 +309,9 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
 
 	if (cpu_has_xmm2)
 		set_cpu_cap(c, X86_FEATURE_MFENCE_RDTSC);
+
+	if (c->x86 == 0x10)
+		amd_enable_pci_ext_cfg(c);
 }
 
 static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 *c, unsigned int size)
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 6f80b85..d8f1712 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -136,4 +136,17 @@ void __init setup_per_cpu_areas(void)
 	setup_cpumask_of_cpu();
 }
 
+#define ENABLE_CF8_EXT_CFG      (1ULL << 46)
+
+void __cpuinit amd_enable_pci_ext_cfg(struct cpuinfo_x86 *c)
+{
+	u64 reg;
+	rdmsrl(MSR_AMD64_NB_CFG, reg);
+	if (!(reg & ENABLE_CF8_EXT_CFG)) {
+		reg |= ENABLE_CF8_EXT_CFG;
+		wrmsrl(MSR_AMD64_NB_CFG, reg);
+	}
+	set_cpu_cap(c, X86_FEATURE_PCI_EXT_CFG);
+}
+
 #endif
diff --git a/arch/x86/kernel/setup.h b/arch/x86/kernel/setup.h
new file mode 100644
index 0000000..66cc2c7
--- /dev/null
+++ b/arch/x86/kernel/setup.h
@@ -0,0 +1,26 @@
+/*
+ * Internal declarations for shared x86 setup code.
+ *
+ * Copyright (c) 2008 Advanced Micro Devices, Inc.
+ * Contributed by Robert Richter <robert.richter@amd.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307 USA
+ */
+
+#ifndef _ARCH_X86_KERNEL_SETUP_H
+
+extern void __cpuinit amd_enable_pci_ext_cfg(struct cpuinfo_x86 *c);
+
+#endif	/* _ARCH_X86_KERNEL_SETUP_H */
diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c
index 6dff128..fdd2469 100644
--- a/arch/x86/kernel/setup_64.c
+++ b/arch/x86/kernel/setup_64.c
@@ -72,6 +72,8 @@
 #include <asm/trampoline.h>
 #include <asm/pat.h>
 
+#include "setup.h"
+
 #include <mach_apic.h>
 #ifdef CONFIG_PARAVIRT
 #include <asm/paravirt.h>
@@ -790,6 +792,9 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
 	if (c->x86 == 0x10)
 		fam10h_check_enable_mmcfg();
 
+	if (c->x86 == 0x10)
+		amd_enable_pci_ext_cfg(c);
+
 	if (amd_apic_timer_broken())
 		disable_apic_timer = 1;
 
diff --git a/arch/x86/pci/direct.c b/arch/x86/pci/direct.c
index 21d1e0e..27d61b6 100644
--- a/arch/x86/pci/direct.c
+++ b/arch/x86/pci/direct.c
@@ -8,18 +8,21 @@
 #include "pci.h"
 
 /*
- * Functions for accessing PCI configuration space with type 1 accesses
+ * Functions for accessing PCI base (first 256 bytes) and extended
+ * (4096 bytes per PCI function) configuration space with type 1
+ * accesses.
  */
 
 #define PCI_CONF1_ADDRESS(bus, devfn, reg) \
-	(0x80000000 | (bus << 16) | (devfn << 8) | (reg & ~3))
+	(0x80000000 | ((reg & 0xF00) << 16) | (bus << 16) \
+	| (devfn << 8) | (reg & 0xFC))
 
 static int pci_conf1_read(unsigned int seg, unsigned int bus,
 			  unsigned int devfn, int reg, int len, u32 *value)
 {
 	unsigned long flags;
 
-	if ((bus > 255) || (devfn > 255) || (reg > 255)) {
+	if ((bus > 255) || (devfn > 255) || (reg > 4095)) {
 		*value = -1;
 		return -EINVAL;
 	}
@@ -50,7 +53,7 @@ static int pci_conf1_write(unsigned int seg, unsigned int bus,
 {
 	unsigned long flags;
 
-	if ((bus > 255) || (devfn > 255) || (reg > 255)) 
+	if ((bus > 255) || (devfn > 255) || (reg > 4095))
 		return -EINVAL;
 
 	spin_lock_irqsave(&pci_config_lock, flags);
@@ -260,10 +263,16 @@ void __init pci_direct_init(int type)
 		return;
 	printk(KERN_INFO "PCI: Using configuration type %d for base access\n",
 		 type);
-	if (type == 1)
+	if (type == 1) {
 		raw_pci_ops = &pci_direct_conf1;
-	else
+		if (!raw_pci_ext_ops && cpu_has_pci_ext_cfg) {
+			printk(KERN_INFO "PCI: Using configuration type 1 "
+			       "for extended access\n");
+			raw_pci_ext_ops = &pci_direct_conf1;
+		}
+	} else {
 		raw_pci_ops = &pci_direct_conf2;
+	}
 }
 
 int __init pci_direct_probe(void)
diff --git a/include/asm-x86/cpufeature.h b/include/asm-x86/cpufeature.h
index 0d609c8..40fcbba 100644
--- a/include/asm-x86/cpufeature.h
+++ b/include/asm-x86/cpufeature.h
@@ -79,6 +79,7 @@
 #define X86_FEATURE_REP_GOOD	(3*32+16) /* rep microcode works well on this CPU */
 #define X86_FEATURE_MFENCE_RDTSC (3*32+17) /* Mfence synchronizes RDTSC */
 #define X86_FEATURE_LFENCE_RDTSC (3*32+18) /* Lfence synchronizes RDTSC */
+#define X86_FEATURE_PCI_EXT_CFG	(3*32+19) /* PCI extended cfg access */
 
 /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
 #define X86_FEATURE_XMM3	(4*32+ 0) /* Streaming SIMD Extensions-3 */
@@ -187,6 +188,7 @@ extern const char * const x86_power_flags[32];
 #define cpu_has_gbpages		boot_cpu_has(X86_FEATURE_GBPAGES)
 #define cpu_has_arch_perfmon	boot_cpu_has(X86_FEATURE_ARCH_PERFMON)
 #define cpu_has_pat		boot_cpu_has(X86_FEATURE_PAT)
+#define cpu_has_pci_ext_cfg	boot_cpu_has(X86_FEATURE_PCI_EXT_CFG)
 
 #if defined(CONFIG_X86_INVLPG) || defined(CONFIG_X86_64)
 # define cpu_has_invlpg		1
-- 
1.5.3.7



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Enable mmconf access to PCI ECS for all AMD fam10h systems
@ 2008-05-23 12:46 Robert Richter
  2008-05-23 17:57 ` Yinghai Lu
  0 siblings, 1 reply; 27+ messages in thread
From: Robert Richter @ 2008-05-23 12:46 UTC (permalink / raw)
  To: Yinghai Lu, Thomas Gleixner; +Cc: Ingo Molnar, LKML

Yinghai,

We would like to enable ECS for all fam10h systems. What was the
reason for patch 5f0b2976 that enables it for Sun systems only? If
there are no objections, this patch should be reverted.

Thomas,

is there a chance to revert the patch for 2.6.26?

Thanks,

-Robert

-- 
Advanced Micro Devices, Inc.
Operating System Research Center
email: robert.richter@amd.com


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Enable mmconf access to PCI ECS for all AMD fam10h systems
  2008-05-23 12:46 Enable mmconf access to PCI ECS for all AMD fam10h systems Robert Richter
@ 2008-05-23 17:57 ` Yinghai Lu
  2008-05-23 18:18   ` Arjan van de Ven
  0 siblings, 1 reply; 27+ messages in thread
From: Yinghai Lu @ 2008-05-23 17:57 UTC (permalink / raw)
  To: Robert Richter
  Cc: Thomas Gleixner, Ingo Molnar, LKML, Arjan van de Ven, Andi Kleen

On Fri, May 23, 2008 at 5:46 AM, Robert Richter <robert.richter@amd.com> wrote:
> Yinghai,
>
> We would like to enable ECS for all fam10h systems. What was the
> reason for patch 5f0b2976 that enables it for Sun systems only? If
> there are no objections, this patch should be reverted.

Someone express the concern about touching MSR. Arjan or Andi?

for those of system that doesn't have MCFG table there, they could use
pci=check_enable_amd_mmconf to enable it forcely.

YH

>
> Thomas,
>
> is there a chance to revert the patch for 2.6.26?
>
> Thanks,
>
> -Robert
>
> --
> Advanced Micro Devices, Inc.
> Operating System Research Center
> email: robert.richter@amd.com
>
>

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Enable mmconf access to PCI ECS for all AMD fam10h systems
  2008-05-23 17:57 ` Yinghai Lu
@ 2008-05-23 18:18   ` Arjan van de Ven
  2008-05-23 19:06     ` Yinghai Lu
  2008-05-26 18:06     ` Robert Richter
  0 siblings, 2 replies; 27+ messages in thread
From: Arjan van de Ven @ 2008-05-23 18:18 UTC (permalink / raw)
  To: Yinghai Lu; +Cc: Robert Richter, Thomas Gleixner, Ingo Molnar, LKML, Andi Kleen

On Fri, 23 May 2008 10:57:22 -0700
"Yinghai Lu" <yhlu.kernel@gmail.com> wrote:

> On Fri, May 23, 2008 at 5:46 AM, Robert Richter
> <robert.richter@amd.com> wrote:
> > Yinghai,
> >
> > We would like to enable ECS for all fam10h systems. What was the
> > reason for patch 5f0b2976 that enables it for Sun systems only? If
> > there are no objections, this patch should be reverted.
> 
> Someone express the concern about touching MSR. Arjan or Andi?
> 
> for those of system that doesn't have MCFG table there, they could use
> pci=check_enable_amd_mmconf to enable it forcely.

using MMIO if the bios doesn't allow it via MCFG is a huge mistake and
shouldn't be done.

Using the extended port IO version is actually perfectly reasonable to
me and I would encourage that to be in the kernel (and be used in favor
of MCFG if the port IO method is there)


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Enable mmconf access to PCI ECS for all AMD fam10h systems
  2008-05-23 18:18   ` Arjan van de Ven
@ 2008-05-23 19:06     ` Yinghai Lu
  2008-05-26 18:06     ` Robert Richter
  1 sibling, 0 replies; 27+ messages in thread
From: Yinghai Lu @ 2008-05-23 19:06 UTC (permalink / raw)
  To: Arjan van de Ven
  Cc: Robert Richter, Thomas Gleixner, Ingo Molnar, LKML, Andi Kleen

On Fri, May 23, 2008 at 11:18 AM, Arjan van de Ven <arjan@infradead.org> wrote:
> On Fri, 23 May 2008 10:57:22 -0700
> "Yinghai Lu" <yhlu.kernel@gmail.com> wrote:
>
>> On Fri, May 23, 2008 at 5:46 AM, Robert Richter
>> <robert.richter@amd.com> wrote:
>> > Yinghai,
>> >
>> > We would like to enable ECS for all fam10h systems. What was the
>> > reason for patch 5f0b2976 that enables it for Sun systems only? If
>> > there are no objections, this patch should be reverted.
>>
>> Someone express the concern about touching MSR. Arjan or Andi?
>>
>> for those of system that doesn't have MCFG table there, they could use
>> pci=check_enable_amd_mmconf to enable it forcely.
>
> using MMIO if the bios doesn't allow it via MCFG is a huge mistake and
> shouldn't be done.
>
> Using the extended port IO version is actually perfectly reasonable to
> me and I would encourage that to be in the kernel (and be used in favor
> of MCFG if the port IO method is there)

that extend access via port IO on AMD Fam10h doesn't support pci
domain other than domain 0.

YH

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Enable mmconf access to PCI ECS for all AMD fam10h systems
  2008-05-23 18:18   ` Arjan van de Ven
  2008-05-23 19:06     ` Yinghai Lu
@ 2008-05-26 18:06     ` Robert Richter
  2007-09-03  8:17       ` [PATCH] x86: Add PCI extended config space access for AMD Barcelona Robert Richter
  1 sibling, 1 reply; 27+ messages in thread
From: Robert Richter @ 2008-05-26 18:06 UTC (permalink / raw)
  To: Arjan van de Ven
  Cc: Yinghai Lu, Thomas Gleixner, Ingo Molnar, LKML, Andi Kleen

Thanks Yinghai and Arjan,

On 23.05.08 11:18:25, Arjan van de Ven wrote:
> On Fri, 23 May 2008 10:57:22 -0700
> "Yinghai Lu" <yhlu.kernel@gmail.com> wrote:
> > Someone express the concern about touching MSR. Arjan or Andi?
> > 
> > for those of system that doesn't have MCFG table there, they could use
> > pci=check_enable_amd_mmconf to enable it forcely.
> 
> using MMIO if the bios doesn't allow it via MCFG is a huge mistake and
> shouldn't be done.

I see your concerns here, though it could possibly be save for access
to processor config space only. Andi also stated before the BIOS
should do the work.

> Using the extended port IO version is actually perfectly reasonable to
> me and I would encourage that to be in the kernel (and be used in favor
> of MCFG if the port IO method is there)

Glad to hear that IO access code is also accepted to access ECS, at
least for segment 0. I already submitted patches for this some times
ago and will send an update. This would ensure access to ECS of
processor config space if MMCONFIG is disabled. Also, this could be a
solution for 32bit code.

-Robert

-- 
Advanced Micro Devices, Inc.
Operating System Research Center
email: robert.richter@amd.com


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH] x86: Add PCI extended config space access for AMD Barcelona
  2007-09-03  8:17       ` [PATCH] x86: Add PCI extended config space access for AMD Barcelona Robert Richter
@ 2008-05-28 19:02         ` Arjan van de Ven
  2008-06-02 14:19           ` Robert Richter
  2008-06-02  9:09         ` [PATCH] x86: Add PCI extended config space access for AMD Barcelona Ingo Molnar
  2008-06-02 20:31         ` Yinghai Lu
  2 siblings, 1 reply; 27+ messages in thread
From: Arjan van de Ven @ 2008-05-28 19:02 UTC (permalink / raw)
  To: Robert Richter; +Cc: Yinghai Lu, Thomas Gleixner, Ingo Molnar, LKML, Andi Kleen

On Mon, 3 Sep 2007 10:17:39 +0200
Robert Richter <robert.richter@amd.com> wrote:

Hi,

As said before, I like the general approach. I have two comments below
though...

>  
> -	if ((bus > 255) || (devfn > 255) || (reg > 255)) 
> +	if ((bus > 255) || (devfn > 255) || (reg > 4095))
>  		return -EINVAL;
>  

Comment 1:
Can we make the 256/4096 thing conditional on actually having the
feature somehow? (while not making the code TOO ugly)

Comment 2: 
The cpu_has_XXX is a bit dubious; while it's dependent on your cpu
model right now, I'm a bit hesitant to consider a PCI feature something
that belongs in the cpu_has_XXX namespace. (Yes I know PCI is moving
into the cpu package, but on a logical level it seems just the wrong
place).
Do we need a platform_has_XXX namespace for things like this?


-- 
If you want to reach me at my work email, use arjan@linux.intel.com
For development, discussion and tips for power savings, 
visit http://www.lesswatts.org

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH] x86: Add PCI extended config space access for AMD Barcelona
  2007-09-03  8:17       ` [PATCH] x86: Add PCI extended config space access for AMD Barcelona Robert Richter
  2008-05-28 19:02         ` Arjan van de Ven
@ 2008-06-02  9:09         ` Ingo Molnar
  2008-06-02 13:56           ` Robert Richter
  2008-06-02 20:31         ` Yinghai Lu
  2 siblings, 1 reply; 27+ messages in thread
From: Ingo Molnar @ 2008-06-02  9:09 UTC (permalink / raw)
  To: Robert Richter
  Cc: Arjan van de Ven, Yinghai Lu, Thomas Gleixner, LKML, Andi Kleen


* Robert Richter <robert.richter@amd.com> wrote:

> This patch implements PCI extended configuration space access for 
> AMD's Barcelona CPUs. It extends the method using CF8/CFC IO 
> addresses. An x86 capability bit has been introduced that is set for 
> CPUs supporting PCI extended config space accesses.

applied to -tip for more testing, thanks Robert. It needed some porting 
(64-bit setup code got restructured in -tip) and the trivial build fix 
below.

	Ingo

------------->
commit fe8aef82b5040c39fb3bee28047db5c896421382
Author: Ingo Molnar <mingo@elte.hu>
Date:   Mon Jun 2 10:54:16 2008 +0200

    fix build bug in "x86: add PCI extended config space access for AMD Barcelona"
    
    Signed-off-by: Ingo Molnar <mingo@elte.hu>

diff --git a/include/asm-x86/mmconfig.h b/include/asm-x86/mmconfig.h
index 95beda0..46d6bb1 100644
--- a/include/asm-x86/mmconfig.h
+++ b/include/asm-x86/mmconfig.h
@@ -9,4 +9,6 @@ static inline void fam10h_check_enable_mmcfg(void) { }
 static inline void check_enable_amd_mmconf_dmi(void) { }
 #endif
 
+extern void __cpuinit amd_enable_pci_ext_cfg(struct cpuinfo_x86 *c);
+
 #endif

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PATCH] x86: Add PCI extended config space access for AMD Barcelona
  2008-06-02  9:09         ` [PATCH] x86: Add PCI extended config space access for AMD Barcelona Ingo Molnar
@ 2008-06-02 13:56           ` Robert Richter
  0 siblings, 0 replies; 27+ messages in thread
From: Robert Richter @ 2008-06-02 13:56 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Arjan van de Ven, Yinghai Lu, Thomas Gleixner, LKML, Andi Kleen

On 02.06.08 11:09:47, Ingo Molnar wrote:
> diff --git a/include/asm-x86/mmconfig.h b/include/asm-x86/mmconfig.h
> index 95beda0..46d6bb1 100644
> --- a/include/asm-x86/mmconfig.h
> +++ b/include/asm-x86/mmconfig.h
> @@ -9,4 +9,6 @@ static inline void fam10h_check_enable_mmcfg(void) { }
>  static inline void check_enable_amd_mmconf_dmi(void) { }
>  #endif
>  
> +extern void __cpuinit amd_enable_pci_ext_cfg(struct cpuinfo_x86 *c);
> +
>  #endif

It's better to add #include "../setup.h" to arch/x86/kernel/cpu/amd_64.c
since this is already defined there and it is actually no mmconf code.

-Robert

-- 
Advanced Micro Devices, Inc.
Operating System Research Center
email: robert.richter@amd.com


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH] x86: Add PCI extended config space access for AMD Barcelona
  2008-05-28 19:02         ` Arjan van de Ven
@ 2008-06-02 14:19           ` Robert Richter
  2008-06-03  2:35             ` Arjan van de Ven
  0 siblings, 1 reply; 27+ messages in thread
From: Robert Richter @ 2008-06-02 14:19 UTC (permalink / raw)
  To: Arjan van de Ven
  Cc: Yinghai Lu, Thomas Gleixner, Ingo Molnar, LKML, Andi Kleen

Arjan,

On 28.05.08 12:02:53, Arjan van de Ven wrote:
> Comment 1:
> Can we make the 256/4096 thing conditional on actually having the
> feature somehow? (while not making the code TOO ugly)

In the first version I had 2 functions also. The patch have had lots
of duplicate code or inline functions. Since the conditional check is
already in raw_pci_* I decided to not implement an additional check
and use only one function.

int raw_pci_read(unsigned int domain, unsigned int bus, unsigned int devfn,
                                                int reg, int len, u32 *val)
{
	if (reg < 256 && raw_pci_ops)
	   return raw_pci_ops->read(domain, bus, devfn, reg, len, val);
	   if (raw_pci_ext_ops)
	      return raw_pci_ext_ops->read(domain, bus, devfn, reg, len, val);
	      return -EINVAL;
}

That leaves as a difference to the basic access is the shift left of
bits 8:11 in the PCI_CONF1_ADDRESS macro. Functional the new macro is
the same and the overhead for this is small. So I see keeping all code
in one function as the best solution.

> Comment 2: 
> The cpu_has_XXX is a bit dubious; while it's dependent on your cpu
> model right now, I'm a bit hesitant to consider a PCI feature something
> that belongs in the cpu_has_XXX namespace. (Yes I know PCI is moving
> into the cpu package, but on a logical level it seems just the wrong
> place).
> Do we need a platform_has_XXX namespace for things like this?

An alternative implementation would be here to use a check something
like pci_probe & PCI_HAS_EXT_CFG. If needed, I will send an updated
patch.

-Robert

-- 
Advanced Micro Devices, Inc.
Operating System Research Center
email: robert.richter@amd.com


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH] x86: Add PCI extended config space access for AMD Barcelona
  2007-09-03  8:17       ` [PATCH] x86: Add PCI extended config space access for AMD Barcelona Robert Richter
  2008-05-28 19:02         ` Arjan van de Ven
  2008-06-02  9:09         ` [PATCH] x86: Add PCI extended config space access for AMD Barcelona Ingo Molnar
@ 2008-06-02 20:31         ` Yinghai Lu
  2008-06-03  7:35           ` Robert Richter
  2 siblings, 1 reply; 27+ messages in thread
From: Yinghai Lu @ 2008-06-02 20:31 UTC (permalink / raw)
  To: Robert Richter
  Cc: Arjan van de Ven, Thomas Gleixner, Ingo Molnar, LKML, Andi Kleen

On Mon, Sep 3, 2007 at 1:17 AM, Robert Richter <robert.richter@amd.com> wrote:
> This patch implements PCI extended configuration space access for
> AMD's Barcelona CPUs. It extends the method using CF8/CFC IO
> addresses. An x86 capability bit has been introduced that is set for
> CPUs supporting PCI extended config space accesses.
>
> Signed-off-by: Robert Richter <robert.richter@amd.com>
> ---
>  arch/x86/kernel/cpu/amd.c    |    4 ++++
>  arch/x86/kernel/setup.c      |   13 +++++++++++++
>  arch/x86/kernel/setup.h      |   26 ++++++++++++++++++++++++++
>  arch/x86/kernel/setup_64.c   |    5 +++++
>  arch/x86/pci/direct.c        |   21 +++++++++++++++------
>  include/asm-x86/cpufeature.h |    2 ++
>  6 files changed, 65 insertions(+), 6 deletions(-)
>  create mode 100644 arch/x86/kernel/setup.h
>
> diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
> index 2458668..99221f9 100644
> --- a/arch/x86/kernel/cpu/amd.c
> +++ b/arch/x86/kernel/cpu/amd.c
> @@ -6,6 +6,7 @@
>  #include <asm/apic.h>
>
>  #include <mach_apic.h>
> +#include "../setup.h"
>  #include "cpu.h"
>
>  /*
> @@ -308,6 +309,9 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
>
>        if (cpu_has_xmm2)
>                set_cpu_cap(c, X86_FEATURE_MFENCE_RDTSC);
> +
> +       if (c->x86 == 0x10)
> +               amd_enable_pci_ext_cfg(c);
>  }
>
>  static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 *c, unsigned int size)
> diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
> index 6f80b85..d8f1712 100644
> --- a/arch/x86/kernel/setup.c
> +++ b/arch/x86/kernel/setup.c
> @@ -136,4 +136,17 @@ void __init setup_per_cpu_areas(void)
>        setup_cpumask_of_cpu();
>  }
>
> +#define ENABLE_CF8_EXT_CFG      (1ULL << 46)
> +
> +void __cpuinit amd_enable_pci_ext_cfg(struct cpuinfo_x86 *c)
> +{
> +       u64 reg;
> +       rdmsrl(MSR_AMD64_NB_CFG, reg);
> +       if (!(reg & ENABLE_CF8_EXT_CFG)) {
> +               reg |= ENABLE_CF8_EXT_CFG;
> +               wrmsrl(MSR_AMD64_NB_CFG, reg);
> +       }
> +       set_cpu_cap(c, X86_FEATURE_PCI_EXT_CFG);
> +}
> +
>  #endif
> diff --git a/arch/x86/kernel/setup.h b/arch/x86/kernel/setup.h
> new file mode 100644
> index 0000000..66cc2c7
> --- /dev/null
> +++ b/arch/x86/kernel/setup.h
> @@ -0,0 +1,26 @@
> +/*
> + * Internal declarations for shared x86 setup code.
> + *
> + * Copyright (c) 2008 Advanced Micro Devices, Inc.
> + * Contributed by Robert Richter <robert.richter@amd.com>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of version 2 of the GNU General Public
> + * License as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
> + * 02111-1307 USA
> + */
> +
> +#ifndef _ARCH_X86_KERNEL_SETUP_H
> +
> +extern void __cpuinit amd_enable_pci_ext_cfg(struct cpuinfo_x86 *c);
> +
> +#endif /* _ARCH_X86_KERNEL_SETUP_H */
> diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c
> index 6dff128..fdd2469 100644
> --- a/arch/x86/kernel/setup_64.c
> +++ b/arch/x86/kernel/setup_64.c
> @@ -72,6 +72,8 @@
>  #include <asm/trampoline.h>
>  #include <asm/pat.h>
>
> +#include "setup.h"
> +
>  #include <mach_apic.h>
>  #ifdef CONFIG_PARAVIRT
>  #include <asm/paravirt.h>
> @@ -790,6 +792,9 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
>        if (c->x86 == 0x10)
>                fam10h_check_enable_mmcfg();
>
> +       if (c->x86 == 0x10)
> +               amd_enable_pci_ext_cfg(c);
> +
>        if (amd_apic_timer_broken())
>                disable_apic_timer = 1;
>
> diff --git a/arch/x86/pci/direct.c b/arch/x86/pci/direct.c
> index 21d1e0e..27d61b6 100644
> --- a/arch/x86/pci/direct.c
> +++ b/arch/x86/pci/direct.c
> @@ -8,18 +8,21 @@
>  #include "pci.h"
>
>  /*
> - * Functions for accessing PCI configuration space with type 1 accesses
> + * Functions for accessing PCI base (first 256 bytes) and extended
> + * (4096 bytes per PCI function) configuration space with type 1
> + * accesses.
>  */
>
>  #define PCI_CONF1_ADDRESS(bus, devfn, reg) \
> -       (0x80000000 | (bus << 16) | (devfn << 8) | (reg & ~3))
> +       (0x80000000 | ((reg & 0xF00) << 16) | (bus << 16) \
> +       | (devfn << 8) | (reg & 0xFC))
>
>  static int pci_conf1_read(unsigned int seg, unsigned int bus,
>                          unsigned int devfn, int reg, int len, u32 *value)
>  {
>        unsigned long flags;
>
> -       if ((bus > 255) || (devfn > 255) || (reg > 255)) {
> +       if ((bus > 255) || (devfn > 255) || (reg > 4095)) {
>                *value = -1;
>                return -EINVAL;
>        }
> @@ -50,7 +53,7 @@ static int pci_conf1_write(unsigned int seg, unsigned int bus,
>  {
>        unsigned long flags;
>
> -       if ((bus > 255) || (devfn > 255) || (reg > 255))
> +       if ((bus > 255) || (devfn > 255) || (reg > 4095))
>                return -EINVAL;
>
>        spin_lock_irqsave(&pci_config_lock, flags);
> @@ -260,10 +263,16 @@ void __init pci_direct_init(int type)
>                return;
>        printk(KERN_INFO "PCI: Using configuration type %d for base access\n",
>                 type);
> -       if (type == 1)
> +       if (type == 1) {
>                raw_pci_ops = &pci_direct_conf1;
> -       else
> +               if (!raw_pci_ext_ops && cpu_has_pci_ext_cfg) {
> +                       printk(KERN_INFO "PCI: Using configuration type 1 "
> +                              "for extended access\n");
> +                       raw_pci_ext_ops = &pci_direct_conf1;

can you add extra pci_direct_ext_conf1 intead?

so don't need change reg size in pci_direct_conf1

also if could avoid cpu_has_pci_ext_cfg, it would be great...

YH

> +               }
> +       } else {
>                raw_pci_ops = &pci_direct_conf2;
> +       }
>  }
>
>  int __init pci_direct_probe(void)
> diff --git a/include/asm-x86/cpufeature.h b/include/asm-x86/cpufeature.h
> index 0d609c8..40fcbba 100644
> --- a/include/asm-x86/cpufeature.h
> +++ b/include/asm-x86/cpufeature.h
> @@ -79,6 +79,7 @@
>  #define X86_FEATURE_REP_GOOD   (3*32+16) /* rep microcode works well on this CPU */
>  #define X86_FEATURE_MFENCE_RDTSC (3*32+17) /* Mfence synchronizes RDTSC */
>  #define X86_FEATURE_LFENCE_RDTSC (3*32+18) /* Lfence synchronizes RDTSC */
> +#define X86_FEATURE_PCI_EXT_CFG        (3*32+19) /* PCI extended cfg access */
>
>  /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
>  #define X86_FEATURE_XMM3       (4*32+ 0) /* Streaming SIMD Extensions-3 */
> @@ -187,6 +188,7 @@ extern const char * const x86_power_flags[32];
>  #define cpu_has_gbpages                boot_cpu_has(X86_FEATURE_GBPAGES)
>  #define cpu_has_arch_perfmon   boot_cpu_has(X86_FEATURE_ARCH_PERFMON)
>  #define cpu_has_pat            boot_cpu_has(X86_FEATURE_PAT)
> +#define cpu_has_pci_ext_cfg    boot_cpu_has(X86_FEATURE_PCI_EXT_CFG)
>
>  #if defined(CONFIG_X86_INVLPG) || defined(CONFIG_X86_64)
>  # define cpu_has_invlpg                1
> --
> 1.5.3.7
>
>
>

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH] x86: Add PCI extended config space access for AMD Barcelona
  2008-06-02 14:19           ` Robert Richter
@ 2008-06-03  2:35             ` Arjan van de Ven
  2008-06-03  7:25               ` Robert Richter
  0 siblings, 1 reply; 27+ messages in thread
From: Arjan van de Ven @ 2008-06-03  2:35 UTC (permalink / raw)
  To: Robert Richter; +Cc: Yinghai Lu, Thomas Gleixner, Ingo Molnar, LKML, Andi Kleen

On Mon, 2 Jun 2008 16:19:29 +0200
Robert Richter <robert.richter@amd.com> wrote:

> Arjan,
> 
> On 28.05.08 12:02:53, Arjan van de Ven wrote:
> > Comment 1:
> > Can we make the 256/4096 thing conditional on actually having the
> > feature somehow? (while not making the code TOO ugly)
> 
> In the first version I had 2 functions also. The patch have had lots
> of duplicate code or inline functions. Since the conditional check is
> already in raw_pci_* I decided to not implement an additional check
> and use only one function.

ok fair enough.

> 
> > Comment 2: 
> > The cpu_has_XXX is a bit dubious; while it's dependent on your cpu
> > model right now, I'm a bit hesitant to consider a PCI feature
> > something that belongs in the cpu_has_XXX namespace. (Yes I know
> > PCI is moving into the cpu package, but on a logical level it seems
> > just the wrong place).
> > Do we need a platform_has_XXX namespace for things like this?
> 
> An alternative implementation would be here to use a check something
> like pci_probe & PCI_HAS_EXT_CFG. If needed, I will send an updated
> patch.

I kind of prefer this, since logically this is a PCI not a CPU property.
Would you mind doing this ?
(not that your current patch is wrong, it's just nicer to keep CPU
stuff with the CPU and PCI stuff with PCI :)
(This wouldn't need to stop inclusion of your current patch, it can
just be an incremental cleanup)

-- 
If you want to reach me at my work email, use arjan@linux.intel.com
For development, discussion and tips for power savings, 
visit http://www.lesswatts.org

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH] x86: Add PCI extended config space access for AMD Barcelona
  2008-06-03  2:35             ` Arjan van de Ven
@ 2008-06-03  7:25               ` Robert Richter
  2008-06-12 18:19                 ` [PATCH 1/2] x86/pci: Renaming k8-bus_64.c to amd_bus.c Robert Richter
  2008-06-12 18:19                 ` [PATCH 2/2] x86: Move PCI IO ECS code to x86/pci Robert Richter
  0 siblings, 2 replies; 27+ messages in thread
From: Robert Richter @ 2008-06-03  7:25 UTC (permalink / raw)
  To: Arjan van de Ven
  Cc: Yinghai Lu, Thomas Gleixner, Ingo Molnar, LKML, Andi Kleen

On 02.06.08 19:35:27, Arjan van de Ven wrote:
> > An alternative implementation would be here to use a check something
> > like pci_probe & PCI_HAS_EXT_CFG. If needed, I will send an updated
> > patch.
> 
> I kind of prefer this, since logically this is a PCI not a CPU property.
> Would you mind doing this ?
> (not that your current patch is wrong, it's just nicer to keep CPU
> stuff with the CPU and PCI stuff with PCI :)
> (This wouldn't need to stop inclusion of your current patch, it can
> just be an incremental cleanup)

Ok, I will send a follow on patch of this.

-Robert

-- 
Advanced Micro Devices, Inc.
Operating System Research Center
email: robert.richter@amd.com


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH] x86: Add PCI extended config space access for AMD Barcelona
  2008-06-02 20:31         ` Yinghai Lu
@ 2008-06-03  7:35           ` Robert Richter
  0 siblings, 0 replies; 27+ messages in thread
From: Robert Richter @ 2008-06-03  7:35 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Arjan van de Ven, Thomas Gleixner, Ingo Molnar, LKML, Andi Kleen

On 02.06.08 13:31:38, Yinghai Lu wrote:
> > +               if (!raw_pci_ext_ops && cpu_has_pci_ext_cfg) {
> > +                       printk(KERN_INFO "PCI: Using configuration type 1 "
> > +                              "for extended access\n");
> > +                       raw_pci_ext_ops = &pci_direct_conf1;
> 
> can you add extra pci_direct_ext_conf1 intead?
> 
> so don't need change reg size in pci_direct_conf1

The reg size check is already in raw_pci_*. Both functions would be
almost identical. See my previous mail.

> also if could avoid cpu_has_pci_ext_cfg, it would be great...

I intend to implement pci_probe & PCI_HAS_EXT_CFG in a follow on patch
instead.

-Robert

-- 
Advanced Micro Devices, Inc.
Operating System Research Center
email: robert.richter@amd.com


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 1/2] x86/pci: Renaming k8-bus_64.c to amd_bus.c
  2008-06-03  7:25               ` Robert Richter
@ 2008-06-12 18:19                 ` Robert Richter
  2008-06-12 19:51                   ` Yinghai Lu
                                     ` (2 more replies)
  2008-06-12 18:19                 ` [PATCH 2/2] x86: Move PCI IO ECS code to x86/pci Robert Richter
  1 sibling, 3 replies; 27+ messages in thread
From: Robert Richter @ 2008-06-12 18:19 UTC (permalink / raw)
  To: Arjan van de Ven
  Cc: Yinghai Lu, Thomas Gleixner, Ingo Molnar, LKML, Andi Kleen,
	Robert Richter

The name fits better since this is code not only for K8.

Signed-off-by: Robert Richter <robert.richter@amd.com>
---
 arch/x86/pci/Makefile_64 |    2 +-
 arch/x86/pci/amd_bus.c   |  528 ++++++++++++++++++++++++++++++++++++++++++++++
 arch/x86/pci/k8-bus_64.c |  528 ----------------------------------------------
 3 files changed, 529 insertions(+), 529 deletions(-)
 create mode 100644 arch/x86/pci/amd_bus.c
 delete mode 100644 arch/x86/pci/k8-bus_64.c

diff --git a/arch/x86/pci/Makefile_64 b/arch/x86/pci/Makefile_64
index 8fbd198..fd47068 100644
--- a/arch/x86/pci/Makefile_64
+++ b/arch/x86/pci/Makefile_64
@@ -13,5 +13,5 @@ obj-y			+= legacy.o irq.o common.o early.o
 # mmconfig has a 64bit special
 obj-$(CONFIG_PCI_MMCONFIG) += mmconfig_64.o direct.o mmconfig-shared.o
 
-obj-y		+= k8-bus_64.o
+obj-y		+= amd_bus.o
 
diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c
new file mode 100644
index 0000000..5c2799c
--- /dev/null
+++ b/arch/x86/pci/amd_bus.c
@@ -0,0 +1,528 @@
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <asm/pci-direct.h>
+#include <asm/mpspec.h>
+#include <linux/cpumask.h>
+#include <linux/topology.h>
+
+/*
+ * This discovers the pcibus <-> node mapping on AMD K8.
+ * also get peer root bus resource for io,mmio
+ */
+
+
+/*
+ * sub bus (transparent) will use entres from 3 to store extra from root,
+ * so need to make sure have enought slot there, increase PCI_BUS_NUM_RESOURCES?
+ */
+#define RES_NUM 16
+struct pci_root_info {
+	char name[12];
+	unsigned int res_num;
+	struct resource res[RES_NUM];
+	int bus_min;
+	int bus_max;
+	int node;
+	int link;
+};
+
+/* 4 at this time, it may become to 32 */
+#define PCI_ROOT_NR 4
+static int pci_root_num;
+static struct pci_root_info pci_root_info[PCI_ROOT_NR];
+
+#ifdef CONFIG_NUMA
+
+#define BUS_NR 256
+
+static int mp_bus_to_node[BUS_NR];
+
+void set_mp_bus_to_node(int busnum, int node)
+{
+	if (busnum >= 0 &&  busnum < BUS_NR)
+		mp_bus_to_node[busnum] = node;
+}
+
+int get_mp_bus_to_node(int busnum)
+{
+	int node = -1;
+
+	if (busnum < 0 || busnum > (BUS_NR - 1))
+		return node;
+
+	node = mp_bus_to_node[busnum];
+
+	/*
+	 * let numa_node_id to decide it later in dma_alloc_pages
+	 * if there is no ram on that node
+	 */
+	if (node != -1 && !node_online(node))
+		node = -1;
+
+	return node;
+}
+#endif
+
+void set_pci_bus_resources_arch_default(struct pci_bus *b)
+{
+	int i;
+	int j;
+	struct pci_root_info *info;
+
+	/* if only one root bus, don't need to anything */
+	if (pci_root_num < 2)
+		return;
+
+	for (i = 0; i < pci_root_num; i++) {
+		if (pci_root_info[i].bus_min == b->number)
+			break;
+	}
+
+	if (i == pci_root_num)
+		return;
+
+	info = &pci_root_info[i];
+	for (j = 0; j < info->res_num; j++) {
+		struct resource *res;
+		struct resource *root;
+
+		res = &info->res[j];
+		b->resource[j] = res;
+		if (res->flags & IORESOURCE_IO)
+			root = &ioport_resource;
+		else
+			root = &iomem_resource;
+		insert_resource(root, res);
+	}
+}
+
+#define RANGE_NUM 16
+
+struct res_range {
+	size_t start;
+	size_t end;
+};
+
+static void __init update_range(struct res_range *range, size_t start,
+				size_t end)
+{
+	int i;
+	int j;
+
+	for (j = 0; j < RANGE_NUM; j++) {
+		if (!range[j].end)
+			continue;
+
+		if (start <= range[j].start && end >= range[j].end) {
+			range[j].start = 0;
+			range[j].end = 0;
+			continue;
+		}
+
+		if (start <= range[j].start && end < range[j].end && range[j].start < end + 1) {
+			range[j].start = end + 1;
+			continue;
+		}
+
+
+		if (start > range[j].start && end >= range[j].end && range[j].end > start - 1) {
+			range[j].end = start - 1;
+			continue;
+		}
+
+		if (start > range[j].start && end < range[j].end) {
+			/* find the new spare */
+			for (i = 0; i < RANGE_NUM; i++) {
+				if (range[i].end == 0)
+					break;
+			}
+			if (i < RANGE_NUM) {
+				range[i].end = range[j].end;
+				range[i].start = end + 1;
+			} else {
+				printk(KERN_ERR "run of slot in ranges\n");
+			}
+			range[j].end = start - 1;
+			continue;
+		}
+	}
+}
+
+static void __init update_res(struct pci_root_info *info, size_t start,
+			      size_t end, unsigned long flags, int merge)
+{
+	int i;
+	struct resource *res;
+
+	if (!merge)
+		goto addit;
+
+	/* try to merge it with old one */
+	for (i = 0; i < info->res_num; i++) {
+		size_t final_start, final_end;
+		size_t common_start, common_end;
+
+		res = &info->res[i];
+		if (res->flags != flags)
+			continue;
+
+		common_start = max((size_t)res->start, start);
+		common_end = min((size_t)res->end, end);
+		if (common_start > common_end + 1)
+			continue;
+
+		final_start = min((size_t)res->start, start);
+		final_end = max((size_t)res->end, end);
+
+		res->start = final_start;
+		res->end = final_end;
+		return;
+	}
+
+addit:
+
+	/* need to add that */
+	if (info->res_num >= RES_NUM)
+		return;
+
+	res = &info->res[info->res_num];
+	res->name = info->name;
+	res->flags = flags;
+	res->start = start;
+	res->end = end;
+	res->child = NULL;
+	info->res_num++;
+}
+
+struct pci_hostbridge_probe {
+	u32 bus;
+	u32 slot;
+	u32 vendor;
+	u32 device;
+};
+
+static struct pci_hostbridge_probe pci_probes[] __initdata = {
+	{ 0, 0x18, PCI_VENDOR_ID_AMD, 0x1100 },
+	{ 0, 0x18, PCI_VENDOR_ID_AMD, 0x1200 },
+	{ 0xff, 0, PCI_VENDOR_ID_AMD, 0x1200 },
+	{ 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;
+}
+
+/**
+ * early_fill_mp_bus_to_node()
+ * called before pcibios_scan_root and pci_scan_bus
+ * fills the mp_bus_to_cpumask array based according to the LDT Bus Number
+ * Registers found in the K8 northbridge
+ */
+static int __init early_fill_mp_bus_info(void)
+{
+	int i;
+	int j;
+	unsigned bus;
+	unsigned slot;
+	int found;
+	int node;
+	int link;
+	int def_node;
+	int def_link;
+	struct pci_root_info *info;
+	u32 reg;
+	struct resource *res;
+	size_t start;
+	size_t end;
+	struct res_range range[RANGE_NUM];
+	u64 val;
+	u32 address;
+
+#ifdef CONFIG_NUMA
+	for (i = 0; i < BUS_NR; i++)
+		mp_bus_to_node[i] = -1;
+#endif
+
+	if (!early_pci_allowed())
+		return -1;
+
+	found = 0;
+	for (i = 0; i < ARRAY_SIZE(pci_probes); i++) {
+		u32 id;
+		u16 device;
+		u16 vendor;
+
+		bus = pci_probes[i].bus;
+		slot = pci_probes[i].slot;
+		id = read_pci_config(bus, slot, 0, PCI_VENDOR_ID);
+
+		vendor = id & 0xffff;
+		device = (id>>16) & 0xffff;
+		if (pci_probes[i].vendor == vendor &&
+		    pci_probes[i].device == device) {
+			found = 1;
+			break;
+		}
+	}
+
+	if (!found)
+		return 0;
+
+	pci_root_num = 0;
+	for (i = 0; i < 4; i++) {
+		int min_bus;
+		int max_bus;
+		reg = read_pci_config(bus, slot, 1, 0xe0 + (i << 2));
+
+		/* Check if that register is enabled for bus range */
+		if ((reg & 7) != 3)
+			continue;
+
+		min_bus = (reg >> 16) & 0xff;
+		max_bus = (reg >> 24) & 0xff;
+		node = (reg >> 4) & 0x07;
+#ifdef CONFIG_NUMA
+		for (j = min_bus; j <= max_bus; j++)
+			mp_bus_to_node[j] = (unsigned char) node;
+#endif
+		link = (reg >> 8) & 0x03;
+
+		info = &pci_root_info[pci_root_num];
+		info->bus_min = min_bus;
+		info->bus_max = max_bus;
+		info->node = node;
+		info->link = link;
+		sprintf(info->name, "PCI Bus #%02x", min_bus);
+		pci_root_num++;
+	}
+
+	/* get the default node and link for left over res */
+	reg = read_pci_config(bus, slot, 0, 0x60);
+	def_node = (reg >> 8) & 0x07;
+	reg = read_pci_config(bus, slot, 0, 0x64);
+	def_link = (reg >> 8) & 0x03;
+
+	memset(range, 0, sizeof(range));
+	range[0].end = 0xffff;
+	/* io port resource */
+	for (i = 0; i < 4; i++) {
+		reg = read_pci_config(bus, slot, 1, 0xc0 + (i << 3));
+		if (!(reg & 3))
+			continue;
+
+		start = reg & 0xfff000;
+		reg = read_pci_config(bus, slot, 1, 0xc4 + (i << 3));
+		node = reg & 0x07;
+		link = (reg >> 4) & 0x03;
+		end = (reg & 0xfff000) | 0xfff;
+
+		/* find the position */
+		for (j = 0; j < pci_root_num; j++) {
+			info = &pci_root_info[j];
+			if (info->node == node && info->link == link)
+				break;
+		}
+		if (j == pci_root_num)
+			continue; /* not found */
+
+		info = &pci_root_info[j];
+		printk(KERN_DEBUG "node %d link %d: io port [%llx, %llx]\n",
+		       node, link, (u64)start, (u64)end);
+
+		/* kernel only handle 16 bit only */
+		if (end > 0xffff)
+			end = 0xffff;
+		update_res(info, start, end, IORESOURCE_IO, 1);
+		update_range(range, start, end);
+	}
+	/* add left over io port range to def node/link, [0, 0xffff] */
+	/* find the position */
+	for (j = 0; j < pci_root_num; j++) {
+		info = &pci_root_info[j];
+		if (info->node == def_node && info->link == def_link)
+			break;
+	}
+	if (j < pci_root_num) {
+		info = &pci_root_info[j];
+		for (i = 0; i < RANGE_NUM; i++) {
+			if (!range[i].end)
+				continue;
+
+			update_res(info, range[i].start, range[i].end,
+				   IORESOURCE_IO, 1);
+		}
+	}
+
+	memset(range, 0, sizeof(range));
+	/* 0xfd00000000-0xffffffffff for HT */
+	range[0].end = (0xfdULL<<32) - 1;
+
+	/* need to take out [0, TOM) for RAM*/
+	address = MSR_K8_TOP_MEM1;
+	rdmsrl(address, val);
+	end = (val & 0xffffff8000000ULL);
+	printk(KERN_INFO "TOM: %016lx aka %ldM\n", end, end>>20);
+	if (end < (1ULL<<32))
+		update_range(range, 0, end - 1);
+
+	/* get mmconfig */
+	get_pci_mmcfg_amd_fam10h_range();
+	/* 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);
+		update_range(range, fam10h_mmconf_start, fam10h_mmconf_end);
+	}
+
+	/* mmio resource */
+	for (i = 0; i < 8; i++) {
+		reg = read_pci_config(bus, slot, 1, 0x80 + (i << 3));
+		if (!(reg & 3))
+			continue;
+
+		start = reg & 0xffffff00; /* 39:16 on 31:8*/
+		start <<= 8;
+		reg = read_pci_config(bus, slot, 1, 0x84 + (i << 3));
+		node = reg & 0x07;
+		link = (reg >> 4) & 0x03;
+		end = (reg & 0xffffff00);
+		end <<= 8;
+		end |= 0xffff;
+
+		/* find the position */
+		for (j = 0; j < pci_root_num; j++) {
+			info = &pci_root_info[j];
+			if (info->node == node && info->link == link)
+				break;
+		}
+		if (j == pci_root_num)
+			continue; /* not found */
+
+		info = &pci_root_info[j];
+
+		printk(KERN_DEBUG "node %d link %d: mmio [%llx, %llx]",
+		       node, link, (u64)start, (u64)end);
+		/*
+		 * some sick allocation would have range overlap with fam10h
+		 * mmconf range, so need to update start and end.
+		 */
+		if (fam10h_mmconf_end) {
+			int changed = 0;
+			u64 endx = 0;
+			if (start >= fam10h_mmconf_start &&
+			    start <= fam10h_mmconf_end) {
+				start = fam10h_mmconf_end + 1;
+				changed = 1;
+			}
+
+			if (end >= fam10h_mmconf_start &&
+			    end <= fam10h_mmconf_end) {
+				end = fam10h_mmconf_start - 1;
+				changed = 1;
+			}
+
+			if (start < fam10h_mmconf_start &&
+			    end > fam10h_mmconf_end) {
+				/* we got a hole */
+				endx = fam10h_mmconf_start - 1;
+				update_res(info, start, endx, IORESOURCE_MEM, 0);
+				update_range(range, start, endx);
+				printk(KERN_CONT " ==> [%llx, %llx]", (u64)start, endx);
+				start = fam10h_mmconf_end + 1;
+				changed = 1;
+			}
+			if (changed) {
+				if (start <= end) {
+					printk(KERN_CONT " %s [%llx, %llx]", endx?"and":"==>", (u64)start, (u64)end);
+				} else {
+					printk(KERN_CONT "%s\n", endx?"":" ==> none");
+					continue;
+				}
+			}
+		}
+
+		update_res(info, start, end, IORESOURCE_MEM, 1);
+		update_range(range, start, end);
+		printk(KERN_CONT "\n");
+	}
+
+	/* need to take out [4G, TOM2) for RAM*/
+	/* SYS_CFG */
+	address = MSR_K8_SYSCFG;
+	rdmsrl(address, val);
+	/* TOP_MEM2 is enabled? */
+	if (val & (1<<21)) {
+		/* TOP_MEM2 */
+		address = MSR_K8_TOP_MEM2;
+		rdmsrl(address, val);
+		end = (val & 0xffffff8000000ULL);
+		printk(KERN_INFO "TOM2: %016lx aka %ldM\n", end, end>>20);
+		update_range(range, 1ULL<<32, end - 1);
+	}
+
+	/*
+	 * add left over mmio range to def node/link ?
+	 * that is tricky, just record range in from start_min to 4G
+	 */
+	for (j = 0; j < pci_root_num; j++) {
+		info = &pci_root_info[j];
+		if (info->node == def_node && info->link == def_link)
+			break;
+	}
+	if (j < pci_root_num) {
+		info = &pci_root_info[j];
+
+		for (i = 0; i < RANGE_NUM; i++) {
+			if (!range[i].end)
+				continue;
+
+			update_res(info, range[i].start, range[i].end,
+				   IORESOURCE_MEM, 1);
+		}
+	}
+
+	for (i = 0; i < pci_root_num; i++) {
+		int res_num;
+		int busnum;
+
+		info = &pci_root_info[i];
+		res_num = info->res_num;
+		busnum = info->bus_min;
+		printk(KERN_DEBUG "bus: [%02x,%02x] on node %x link %x\n",
+		       info->bus_min, info->bus_max, info->node, info->link);
+		for (j = 0; j < res_num; j++) {
+			res = &info->res[j];
+			printk(KERN_DEBUG "bus: %02x index %x %s: [%llx, %llx]\n",
+			       busnum, j,
+			       (res->flags & IORESOURCE_IO)?"io port":"mmio",
+			       res->start, res->end);
+		}
+	}
+
+	return 0;
+}
+
+postcore_initcall(early_fill_mp_bus_info);
diff --git a/arch/x86/pci/k8-bus_64.c b/arch/x86/pci/k8-bus_64.c
deleted file mode 100644
index 5c2799c..0000000
--- a/arch/x86/pci/k8-bus_64.c
+++ /dev/null
@@ -1,528 +0,0 @@
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <asm/pci-direct.h>
-#include <asm/mpspec.h>
-#include <linux/cpumask.h>
-#include <linux/topology.h>
-
-/*
- * This discovers the pcibus <-> node mapping on AMD K8.
- * also get peer root bus resource for io,mmio
- */
-
-
-/*
- * sub bus (transparent) will use entres from 3 to store extra from root,
- * so need to make sure have enought slot there, increase PCI_BUS_NUM_RESOURCES?
- */
-#define RES_NUM 16
-struct pci_root_info {
-	char name[12];
-	unsigned int res_num;
-	struct resource res[RES_NUM];
-	int bus_min;
-	int bus_max;
-	int node;
-	int link;
-};
-
-/* 4 at this time, it may become to 32 */
-#define PCI_ROOT_NR 4
-static int pci_root_num;
-static struct pci_root_info pci_root_info[PCI_ROOT_NR];
-
-#ifdef CONFIG_NUMA
-
-#define BUS_NR 256
-
-static int mp_bus_to_node[BUS_NR];
-
-void set_mp_bus_to_node(int busnum, int node)
-{
-	if (busnum >= 0 &&  busnum < BUS_NR)
-		mp_bus_to_node[busnum] = node;
-}
-
-int get_mp_bus_to_node(int busnum)
-{
-	int node = -1;
-
-	if (busnum < 0 || busnum > (BUS_NR - 1))
-		return node;
-
-	node = mp_bus_to_node[busnum];
-
-	/*
-	 * let numa_node_id to decide it later in dma_alloc_pages
-	 * if there is no ram on that node
-	 */
-	if (node != -1 && !node_online(node))
-		node = -1;
-
-	return node;
-}
-#endif
-
-void set_pci_bus_resources_arch_default(struct pci_bus *b)
-{
-	int i;
-	int j;
-	struct pci_root_info *info;
-
-	/* if only one root bus, don't need to anything */
-	if (pci_root_num < 2)
-		return;
-
-	for (i = 0; i < pci_root_num; i++) {
-		if (pci_root_info[i].bus_min == b->number)
-			break;
-	}
-
-	if (i == pci_root_num)
-		return;
-
-	info = &pci_root_info[i];
-	for (j = 0; j < info->res_num; j++) {
-		struct resource *res;
-		struct resource *root;
-
-		res = &info->res[j];
-		b->resource[j] = res;
-		if (res->flags & IORESOURCE_IO)
-			root = &ioport_resource;
-		else
-			root = &iomem_resource;
-		insert_resource(root, res);
-	}
-}
-
-#define RANGE_NUM 16
-
-struct res_range {
-	size_t start;
-	size_t end;
-};
-
-static void __init update_range(struct res_range *range, size_t start,
-				size_t end)
-{
-	int i;
-	int j;
-
-	for (j = 0; j < RANGE_NUM; j++) {
-		if (!range[j].end)
-			continue;
-
-		if (start <= range[j].start && end >= range[j].end) {
-			range[j].start = 0;
-			range[j].end = 0;
-			continue;
-		}
-
-		if (start <= range[j].start && end < range[j].end && range[j].start < end + 1) {
-			range[j].start = end + 1;
-			continue;
-		}
-
-
-		if (start > range[j].start && end >= range[j].end && range[j].end > start - 1) {
-			range[j].end = start - 1;
-			continue;
-		}
-
-		if (start > range[j].start && end < range[j].end) {
-			/* find the new spare */
-			for (i = 0; i < RANGE_NUM; i++) {
-				if (range[i].end == 0)
-					break;
-			}
-			if (i < RANGE_NUM) {
-				range[i].end = range[j].end;
-				range[i].start = end + 1;
-			} else {
-				printk(KERN_ERR "run of slot in ranges\n");
-			}
-			range[j].end = start - 1;
-			continue;
-		}
-	}
-}
-
-static void __init update_res(struct pci_root_info *info, size_t start,
-			      size_t end, unsigned long flags, int merge)
-{
-	int i;
-	struct resource *res;
-
-	if (!merge)
-		goto addit;
-
-	/* try to merge it with old one */
-	for (i = 0; i < info->res_num; i++) {
-		size_t final_start, final_end;
-		size_t common_start, common_end;
-
-		res = &info->res[i];
-		if (res->flags != flags)
-			continue;
-
-		common_start = max((size_t)res->start, start);
-		common_end = min((size_t)res->end, end);
-		if (common_start > common_end + 1)
-			continue;
-
-		final_start = min((size_t)res->start, start);
-		final_end = max((size_t)res->end, end);
-
-		res->start = final_start;
-		res->end = final_end;
-		return;
-	}
-
-addit:
-
-	/* need to add that */
-	if (info->res_num >= RES_NUM)
-		return;
-
-	res = &info->res[info->res_num];
-	res->name = info->name;
-	res->flags = flags;
-	res->start = start;
-	res->end = end;
-	res->child = NULL;
-	info->res_num++;
-}
-
-struct pci_hostbridge_probe {
-	u32 bus;
-	u32 slot;
-	u32 vendor;
-	u32 device;
-};
-
-static struct pci_hostbridge_probe pci_probes[] __initdata = {
-	{ 0, 0x18, PCI_VENDOR_ID_AMD, 0x1100 },
-	{ 0, 0x18, PCI_VENDOR_ID_AMD, 0x1200 },
-	{ 0xff, 0, PCI_VENDOR_ID_AMD, 0x1200 },
-	{ 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;
-}
-
-/**
- * early_fill_mp_bus_to_node()
- * called before pcibios_scan_root and pci_scan_bus
- * fills the mp_bus_to_cpumask array based according to the LDT Bus Number
- * Registers found in the K8 northbridge
- */
-static int __init early_fill_mp_bus_info(void)
-{
-	int i;
-	int j;
-	unsigned bus;
-	unsigned slot;
-	int found;
-	int node;
-	int link;
-	int def_node;
-	int def_link;
-	struct pci_root_info *info;
-	u32 reg;
-	struct resource *res;
-	size_t start;
-	size_t end;
-	struct res_range range[RANGE_NUM];
-	u64 val;
-	u32 address;
-
-#ifdef CONFIG_NUMA
-	for (i = 0; i < BUS_NR; i++)
-		mp_bus_to_node[i] = -1;
-#endif
-
-	if (!early_pci_allowed())
-		return -1;
-
-	found = 0;
-	for (i = 0; i < ARRAY_SIZE(pci_probes); i++) {
-		u32 id;
-		u16 device;
-		u16 vendor;
-
-		bus = pci_probes[i].bus;
-		slot = pci_probes[i].slot;
-		id = read_pci_config(bus, slot, 0, PCI_VENDOR_ID);
-
-		vendor = id & 0xffff;
-		device = (id>>16) & 0xffff;
-		if (pci_probes[i].vendor == vendor &&
-		    pci_probes[i].device == device) {
-			found = 1;
-			break;
-		}
-	}
-
-	if (!found)
-		return 0;
-
-	pci_root_num = 0;
-	for (i = 0; i < 4; i++) {
-		int min_bus;
-		int max_bus;
-		reg = read_pci_config(bus, slot, 1, 0xe0 + (i << 2));
-
-		/* Check if that register is enabled for bus range */
-		if ((reg & 7) != 3)
-			continue;
-
-		min_bus = (reg >> 16) & 0xff;
-		max_bus = (reg >> 24) & 0xff;
-		node = (reg >> 4) & 0x07;
-#ifdef CONFIG_NUMA
-		for (j = min_bus; j <= max_bus; j++)
-			mp_bus_to_node[j] = (unsigned char) node;
-#endif
-		link = (reg >> 8) & 0x03;
-
-		info = &pci_root_info[pci_root_num];
-		info->bus_min = min_bus;
-		info->bus_max = max_bus;
-		info->node = node;
-		info->link = link;
-		sprintf(info->name, "PCI Bus #%02x", min_bus);
-		pci_root_num++;
-	}
-
-	/* get the default node and link for left over res */
-	reg = read_pci_config(bus, slot, 0, 0x60);
-	def_node = (reg >> 8) & 0x07;
-	reg = read_pci_config(bus, slot, 0, 0x64);
-	def_link = (reg >> 8) & 0x03;
-
-	memset(range, 0, sizeof(range));
-	range[0].end = 0xffff;
-	/* io port resource */
-	for (i = 0; i < 4; i++) {
-		reg = read_pci_config(bus, slot, 1, 0xc0 + (i << 3));
-		if (!(reg & 3))
-			continue;
-
-		start = reg & 0xfff000;
-		reg = read_pci_config(bus, slot, 1, 0xc4 + (i << 3));
-		node = reg & 0x07;
-		link = (reg >> 4) & 0x03;
-		end = (reg & 0xfff000) | 0xfff;
-
-		/* find the position */
-		for (j = 0; j < pci_root_num; j++) {
-			info = &pci_root_info[j];
-			if (info->node == node && info->link == link)
-				break;
-		}
-		if (j == pci_root_num)
-			continue; /* not found */
-
-		info = &pci_root_info[j];
-		printk(KERN_DEBUG "node %d link %d: io port [%llx, %llx]\n",
-		       node, link, (u64)start, (u64)end);
-
-		/* kernel only handle 16 bit only */
-		if (end > 0xffff)
-			end = 0xffff;
-		update_res(info, start, end, IORESOURCE_IO, 1);
-		update_range(range, start, end);
-	}
-	/* add left over io port range to def node/link, [0, 0xffff] */
-	/* find the position */
-	for (j = 0; j < pci_root_num; j++) {
-		info = &pci_root_info[j];
-		if (info->node == def_node && info->link == def_link)
-			break;
-	}
-	if (j < pci_root_num) {
-		info = &pci_root_info[j];
-		for (i = 0; i < RANGE_NUM; i++) {
-			if (!range[i].end)
-				continue;
-
-			update_res(info, range[i].start, range[i].end,
-				   IORESOURCE_IO, 1);
-		}
-	}
-
-	memset(range, 0, sizeof(range));
-	/* 0xfd00000000-0xffffffffff for HT */
-	range[0].end = (0xfdULL<<32) - 1;
-
-	/* need to take out [0, TOM) for RAM*/
-	address = MSR_K8_TOP_MEM1;
-	rdmsrl(address, val);
-	end = (val & 0xffffff8000000ULL);
-	printk(KERN_INFO "TOM: %016lx aka %ldM\n", end, end>>20);
-	if (end < (1ULL<<32))
-		update_range(range, 0, end - 1);
-
-	/* get mmconfig */
-	get_pci_mmcfg_amd_fam10h_range();
-	/* 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);
-		update_range(range, fam10h_mmconf_start, fam10h_mmconf_end);
-	}
-
-	/* mmio resource */
-	for (i = 0; i < 8; i++) {
-		reg = read_pci_config(bus, slot, 1, 0x80 + (i << 3));
-		if (!(reg & 3))
-			continue;
-
-		start = reg & 0xffffff00; /* 39:16 on 31:8*/
-		start <<= 8;
-		reg = read_pci_config(bus, slot, 1, 0x84 + (i << 3));
-		node = reg & 0x07;
-		link = (reg >> 4) & 0x03;
-		end = (reg & 0xffffff00);
-		end <<= 8;
-		end |= 0xffff;
-
-		/* find the position */
-		for (j = 0; j < pci_root_num; j++) {
-			info = &pci_root_info[j];
-			if (info->node == node && info->link == link)
-				break;
-		}
-		if (j == pci_root_num)
-			continue; /* not found */
-
-		info = &pci_root_info[j];
-
-		printk(KERN_DEBUG "node %d link %d: mmio [%llx, %llx]",
-		       node, link, (u64)start, (u64)end);
-		/*
-		 * some sick allocation would have range overlap with fam10h
-		 * mmconf range, so need to update start and end.
-		 */
-		if (fam10h_mmconf_end) {
-			int changed = 0;
-			u64 endx = 0;
-			if (start >= fam10h_mmconf_start &&
-			    start <= fam10h_mmconf_end) {
-				start = fam10h_mmconf_end + 1;
-				changed = 1;
-			}
-
-			if (end >= fam10h_mmconf_start &&
-			    end <= fam10h_mmconf_end) {
-				end = fam10h_mmconf_start - 1;
-				changed = 1;
-			}
-
-			if (start < fam10h_mmconf_start &&
-			    end > fam10h_mmconf_end) {
-				/* we got a hole */
-				endx = fam10h_mmconf_start - 1;
-				update_res(info, start, endx, IORESOURCE_MEM, 0);
-				update_range(range, start, endx);
-				printk(KERN_CONT " ==> [%llx, %llx]", (u64)start, endx);
-				start = fam10h_mmconf_end + 1;
-				changed = 1;
-			}
-			if (changed) {
-				if (start <= end) {
-					printk(KERN_CONT " %s [%llx, %llx]", endx?"and":"==>", (u64)start, (u64)end);
-				} else {
-					printk(KERN_CONT "%s\n", endx?"":" ==> none");
-					continue;
-				}
-			}
-		}
-
-		update_res(info, start, end, IORESOURCE_MEM, 1);
-		update_range(range, start, end);
-		printk(KERN_CONT "\n");
-	}
-
-	/* need to take out [4G, TOM2) for RAM*/
-	/* SYS_CFG */
-	address = MSR_K8_SYSCFG;
-	rdmsrl(address, val);
-	/* TOP_MEM2 is enabled? */
-	if (val & (1<<21)) {
-		/* TOP_MEM2 */
-		address = MSR_K8_TOP_MEM2;
-		rdmsrl(address, val);
-		end = (val & 0xffffff8000000ULL);
-		printk(KERN_INFO "TOM2: %016lx aka %ldM\n", end, end>>20);
-		update_range(range, 1ULL<<32, end - 1);
-	}
-
-	/*
-	 * add left over mmio range to def node/link ?
-	 * that is tricky, just record range in from start_min to 4G
-	 */
-	for (j = 0; j < pci_root_num; j++) {
-		info = &pci_root_info[j];
-		if (info->node == def_node && info->link == def_link)
-			break;
-	}
-	if (j < pci_root_num) {
-		info = &pci_root_info[j];
-
-		for (i = 0; i < RANGE_NUM; i++) {
-			if (!range[i].end)
-				continue;
-
-			update_res(info, range[i].start, range[i].end,
-				   IORESOURCE_MEM, 1);
-		}
-	}
-
-	for (i = 0; i < pci_root_num; i++) {
-		int res_num;
-		int busnum;
-
-		info = &pci_root_info[i];
-		res_num = info->res_num;
-		busnum = info->bus_min;
-		printk(KERN_DEBUG "bus: [%02x,%02x] on node %x link %x\n",
-		       info->bus_min, info->bus_max, info->node, info->link);
-		for (j = 0; j < res_num; j++) {
-			res = &info->res[j];
-			printk(KERN_DEBUG "bus: %02x index %x %s: [%llx, %llx]\n",
-			       busnum, j,
-			       (res->flags & IORESOURCE_IO)?"io port":"mmio",
-			       res->start, res->end);
-		}
-	}
-
-	return 0;
-}
-
-postcore_initcall(early_fill_mp_bus_info);
-- 
1.5.5.3



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 2/2] x86: Move PCI IO ECS code to x86/pci
  2008-06-03  7:25               ` Robert Richter
  2008-06-12 18:19                 ` [PATCH 1/2] x86/pci: Renaming k8-bus_64.c to amd_bus.c Robert Richter
@ 2008-06-12 18:19                 ` Robert Richter
  2008-06-12 19:50                   ` Yinghai Lu
                                     ` (2 more replies)
  1 sibling, 3 replies; 27+ messages in thread
From: Robert Richter @ 2008-06-12 18:19 UTC (permalink / raw)
  To: Arjan van de Ven
  Cc: Yinghai Lu, Thomas Gleixner, Ingo Molnar, LKML, Andi Kleen,
	Robert Richter

"Form follows function". Code is now where it belongs to.

Signed-off-by: Robert Richter <robert.richter@amd.com>
---
 arch/x86/kernel/cpu/amd.c    |    3 ---
 arch/x86/kernel/cpu/amd_64.c |    4 ----
 arch/x86/kernel/cpu/cpu.h    |    2 --
 arch/x86/kernel/setup.c      |   13 -------------
 arch/x86/pci/Makefile_32     |    1 +
 arch/x86/pci/amd_bus.c       |   32 ++++++++++++++++++++++++++++++++
 arch/x86/pci/direct.c        |   16 +++++++++-------
 arch/x86/pci/pci.h           |    1 +
 include/asm-x86/cpufeature.h |    2 --
 9 files changed, 43 insertions(+), 31 deletions(-)

diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index acc891a..81a07ca 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -266,9 +266,6 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
 
 	if (cpu_has_xmm2)
 		set_cpu_cap(c, X86_FEATURE_MFENCE_RDTSC);
-
-	if (c->x86 == 0x10)
-		amd_enable_pci_ext_cfg(c);
 }
 
 static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 *c, unsigned int size)
diff --git a/arch/x86/kernel/cpu/amd_64.c b/arch/x86/kernel/cpu/amd_64.c
index f8d2058..250bfe6 100644
--- a/arch/x86/kernel/cpu/amd_64.c
+++ b/arch/x86/kernel/cpu/amd_64.c
@@ -6,7 +6,6 @@
 #include <asm/cacheflush.h>
 
 #include <mach_apic.h>
-#include "cpu.h"
 
 extern int __cpuinit get_model_name(struct cpuinfo_x86 *c);
 extern void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c);
@@ -187,9 +186,6 @@ void __cpuinit init_amd(struct cpuinfo_x86 *c)
 	if (c->x86 == 0x10)
 		fam10h_check_enable_mmcfg();
 
-	if (c->x86 == 0x10)
-		amd_enable_pci_ext_cfg(c);
-
 	if (c == &boot_cpu_data && c->x86 >= 0xf && c->x86 <= 0x11) {
 		unsigned long long tseg;
 
diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h
index f5d5bb1..40ad189 100644
--- a/arch/x86/kernel/cpu/cpu.h
+++ b/arch/x86/kernel/cpu/cpu.h
@@ -39,5 +39,3 @@ extern int get_model_name(struct cpuinfo_x86 *c);
 extern void display_cacheinfo(struct cpuinfo_x86 *c);
 
 #endif /* CONFIG_X86_32 */
-
-extern void __cpuinit amd_enable_pci_ext_cfg(struct cpuinfo_x86 *c);
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 20e14db..6f80b85 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -137,16 +137,3 @@ void __init setup_per_cpu_areas(void)
 }
 
 #endif
-#define ENABLE_CF8_EXT_CFG      (1ULL << 46)
-
-void __cpuinit amd_enable_pci_ext_cfg(struct cpuinfo_x86 *c)
-{
-	u64 reg;
-	rdmsrl(MSR_AMD64_NB_CFG, reg);
-	if (!(reg & ENABLE_CF8_EXT_CFG)) {
-		reg |= ENABLE_CF8_EXT_CFG;
-		wrmsrl(MSR_AMD64_NB_CFG, reg);
-	}
-	set_cpu_cap(c, X86_FEATURE_PCI_EXT_CFG);
-}
-
diff --git a/arch/x86/pci/Makefile_32 b/arch/x86/pci/Makefile_32
index 89ec35d..f647e7e 100644
--- a/arch/x86/pci/Makefile_32
+++ b/arch/x86/pci/Makefile_32
@@ -22,3 +22,4 @@ pci-$(CONFIG_X86_NUMAQ)		:= numa.o irq.o
 pci-$(CONFIG_NUMA)		+= mp_bus_to_node.o
 
 obj-y				+= $(pci-y) common.o early.o
+obj-y				+= amd_bus.o
diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c
index 5c2799c..15f505d 100644
--- a/arch/x86/pci/amd_bus.c
+++ b/arch/x86/pci/amd_bus.c
@@ -1,5 +1,9 @@
 #include <linux/init.h>
 #include <linux/pci.h>
+#include "pci.h"
+
+#ifdef CONFIG_X86_64
+
 #include <asm/pci-direct.h>
 #include <asm/mpspec.h>
 #include <linux/cpumask.h>
@@ -526,3 +530,31 @@ static int __init early_fill_mp_bus_info(void)
 }
 
 postcore_initcall(early_fill_mp_bus_info);
+
+#endif
+
+/* common 32/64 bit code */
+
+#define ENABLE_CF8_EXT_CFG      (1ULL << 46)
+
+static void enable_pci_io_ecs_per_cpu(void *unused)
+{
+	u64 reg;
+	rdmsrl(MSR_AMD64_NB_CFG, reg);
+	if (!(reg & ENABLE_CF8_EXT_CFG)) {
+		reg |= ENABLE_CF8_EXT_CFG;
+		wrmsrl(MSR_AMD64_NB_CFG, reg);
+	}
+}
+
+static int __init enable_pci_io_ecs(void)
+{
+	/* assume all cpus from fam10h have IO ECS */
+        if (boot_cpu_data.x86 < 0x10)
+		return 0;
+	on_each_cpu(enable_pci_io_ecs_per_cpu, NULL, 1, 1);
+	pci_probe |= PCI_HAS_IO_ECS;
+	return 0;
+}
+
+postcore_initcall(enable_pci_io_ecs);
diff --git a/arch/x86/pci/direct.c b/arch/x86/pci/direct.c
index 27d61b6..9915293 100644
--- a/arch/x86/pci/direct.c
+++ b/arch/x86/pci/direct.c
@@ -265,14 +265,16 @@ void __init pci_direct_init(int type)
 		 type);
 	if (type == 1) {
 		raw_pci_ops = &pci_direct_conf1;
-		if (!raw_pci_ext_ops && cpu_has_pci_ext_cfg) {
-			printk(KERN_INFO "PCI: Using configuration type 1 "
-			       "for extended access\n");
-			raw_pci_ext_ops = &pci_direct_conf1;
-		}
-	} else {
-		raw_pci_ops = &pci_direct_conf2;
+		if (raw_pci_ext_ops)
+			return;
+		if (!(pci_probe & PCI_HAS_IO_ECS))
+			return;
+		printk(KERN_INFO "PCI: Using configuration type 1 "
+		       "for extended access\n");
+		raw_pci_ext_ops = &pci_direct_conf1;
+		return;
 	}
+	raw_pci_ops = &pci_direct_conf2;
 }
 
 int __init pci_direct_probe(void)
diff --git a/arch/x86/pci/pci.h b/arch/x86/pci/pci.h
index f3972b1..fd53db5 100644
--- a/arch/x86/pci/pci.h
+++ b/arch/x86/pci/pci.h
@@ -27,6 +27,7 @@
 #define PCI_CAN_SKIP_ISA_ALIGN	0x8000
 #define PCI_USE__CRS		0x10000
 #define PCI_CHECK_ENABLE_AMD_MMCONF	0x20000
+#define PCI_HAS_IO_ECS		0x40000
 
 extern unsigned int pci_probe;
 extern unsigned long pirq_table_addr;
diff --git a/include/asm-x86/cpufeature.h b/include/asm-x86/cpufeature.h
index 40fcbba..0d609c8 100644
--- a/include/asm-x86/cpufeature.h
+++ b/include/asm-x86/cpufeature.h
@@ -79,7 +79,6 @@
 #define X86_FEATURE_REP_GOOD	(3*32+16) /* rep microcode works well on this CPU */
 #define X86_FEATURE_MFENCE_RDTSC (3*32+17) /* Mfence synchronizes RDTSC */
 #define X86_FEATURE_LFENCE_RDTSC (3*32+18) /* Lfence synchronizes RDTSC */
-#define X86_FEATURE_PCI_EXT_CFG	(3*32+19) /* PCI extended cfg access */
 
 /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
 #define X86_FEATURE_XMM3	(4*32+ 0) /* Streaming SIMD Extensions-3 */
@@ -188,7 +187,6 @@ extern const char * const x86_power_flags[32];
 #define cpu_has_gbpages		boot_cpu_has(X86_FEATURE_GBPAGES)
 #define cpu_has_arch_perfmon	boot_cpu_has(X86_FEATURE_ARCH_PERFMON)
 #define cpu_has_pat		boot_cpu_has(X86_FEATURE_PAT)
-#define cpu_has_pci_ext_cfg	boot_cpu_has(X86_FEATURE_PCI_EXT_CFG)
 
 #if defined(CONFIG_X86_INVLPG) || defined(CONFIG_X86_64)
 # define cpu_has_invlpg		1
-- 
1.5.5.3



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PATCH 2/2] x86: Move PCI IO ECS code to x86/pci
  2008-06-12 18:19                 ` [PATCH 2/2] x86: Move PCI IO ECS code to x86/pci Robert Richter
@ 2008-06-12 19:50                   ` Yinghai Lu
  2008-06-13 16:19                     ` Robert Richter
  2008-06-13 17:02                   ` Glauber Costa
  2008-06-18  7:47                   ` Ingo Molnar
  2 siblings, 1 reply; 27+ messages in thread
From: Yinghai Lu @ 2008-06-12 19:50 UTC (permalink / raw)
  To: Robert Richter
  Cc: Arjan van de Ven, Thomas Gleixner, Ingo Molnar, LKML, Andi Kleen

On Thu, Jun 12, 2008 at 11:19 AM, Robert Richter <robert.richter@amd.com> wrote:
> "Form follows function". Code is now where it belongs to.
>
> Signed-off-by: Robert Richter <robert.richter@amd.com>
> ---
>  arch/x86/kernel/cpu/amd.c    |    3 ---
>  arch/x86/kernel/cpu/amd_64.c |    4 ----
>  arch/x86/kernel/cpu/cpu.h    |    2 --
>  arch/x86/kernel/setup.c      |   13 -------------
>  arch/x86/pci/Makefile_32     |    1 +
>  arch/x86/pci/amd_bus.c       |   32 ++++++++++++++++++++++++++++++++
>  arch/x86/pci/direct.c        |   16 +++++++++-------
>  arch/x86/pci/pci.h           |    1 +
>  include/asm-x86/cpufeature.h |    2 --
>  9 files changed, 43 insertions(+), 31 deletions(-)
>
> diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
> index acc891a..81a07ca 100644
> --- a/arch/x86/kernel/cpu/amd.c
> +++ b/arch/x86/kernel/cpu/amd.c
> @@ -266,9 +266,6 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
>
>        if (cpu_has_xmm2)
>                set_cpu_cap(c, X86_FEATURE_MFENCE_RDTSC);
> -
> -       if (c->x86 == 0x10)
> -               amd_enable_pci_ext_cfg(c);
>  }
>
>  static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 *c, unsigned int size)
> diff --git a/arch/x86/kernel/cpu/amd_64.c b/arch/x86/kernel/cpu/amd_64.c
> index f8d2058..250bfe6 100644
> --- a/arch/x86/kernel/cpu/amd_64.c
> +++ b/arch/x86/kernel/cpu/amd_64.c
> @@ -6,7 +6,6 @@
>  #include <asm/cacheflush.h>
>
>  #include <mach_apic.h>
> -#include "cpu.h"
>
>  extern int __cpuinit get_model_name(struct cpuinfo_x86 *c);
>  extern void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c);
> @@ -187,9 +186,6 @@ void __cpuinit init_amd(struct cpuinfo_x86 *c)
>        if (c->x86 == 0x10)
>                fam10h_check_enable_mmcfg();
>
> -       if (c->x86 == 0x10)
> -               amd_enable_pci_ext_cfg(c);
> -
>        if (c == &boot_cpu_data && c->x86 >= 0xf && c->x86 <= 0x11) {
>                unsigned long long tseg;
>
> diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h
> index f5d5bb1..40ad189 100644
> --- a/arch/x86/kernel/cpu/cpu.h
> +++ b/arch/x86/kernel/cpu/cpu.h
> @@ -39,5 +39,3 @@ extern int get_model_name(struct cpuinfo_x86 *c);
>  extern void display_cacheinfo(struct cpuinfo_x86 *c);
>
>  #endif /* CONFIG_X86_32 */
> -
> -extern void __cpuinit amd_enable_pci_ext_cfg(struct cpuinfo_x86 *c);
> diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
> index 20e14db..6f80b85 100644
> --- a/arch/x86/kernel/setup.c
> +++ b/arch/x86/kernel/setup.c
> @@ -137,16 +137,3 @@ void __init setup_per_cpu_areas(void)
>  }
>
>  #endif
> -#define ENABLE_CF8_EXT_CFG      (1ULL << 46)
> -
> -void __cpuinit amd_enable_pci_ext_cfg(struct cpuinfo_x86 *c)
> -{
> -       u64 reg;
> -       rdmsrl(MSR_AMD64_NB_CFG, reg);
> -       if (!(reg & ENABLE_CF8_EXT_CFG)) {
> -               reg |= ENABLE_CF8_EXT_CFG;
> -               wrmsrl(MSR_AMD64_NB_CFG, reg);
> -       }
> -       set_cpu_cap(c, X86_FEATURE_PCI_EXT_CFG);
> -}
> -
> diff --git a/arch/x86/pci/Makefile_32 b/arch/x86/pci/Makefile_32
> index 89ec35d..f647e7e 100644
> --- a/arch/x86/pci/Makefile_32
> +++ b/arch/x86/pci/Makefile_32
> @@ -22,3 +22,4 @@ pci-$(CONFIG_X86_NUMAQ)               := numa.o irq.o
>  pci-$(CONFIG_NUMA)             += mp_bus_to_node.o
>
>  obj-y                          += $(pci-y) common.o early.o
> +obj-y                          += amd_bus.o
> diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c
> index 5c2799c..15f505d 100644
> --- a/arch/x86/pci/amd_bus.c
> +++ b/arch/x86/pci/amd_bus.c
> @@ -1,5 +1,9 @@
>  #include <linux/init.h>
>  #include <linux/pci.h>
> +#include "pci.h"
> +
> +#ifdef CONFIG_X86_64
> +
>  #include <asm/pci-direct.h>
>  #include <asm/mpspec.h>
>  #include <linux/cpumask.h>
> @@ -526,3 +530,31 @@ static int __init early_fill_mp_bus_info(void)
>  }
>
>  postcore_initcall(early_fill_mp_bus_info);
> +
> +#endif
> +
> +/* common 32/64 bit code */
> +
> +#define ENABLE_CF8_EXT_CFG      (1ULL << 46)
> +
> +static void enable_pci_io_ecs_per_cpu(void *unused)
> +{
> +       u64 reg;
> +       rdmsrl(MSR_AMD64_NB_CFG, reg);
> +       if (!(reg & ENABLE_CF8_EXT_CFG)) {
> +               reg |= ENABLE_CF8_EXT_CFG;
> +               wrmsrl(MSR_AMD64_NB_CFG, reg);
> +       }
> +}
> +
> +static int __init enable_pci_io_ecs(void)
> +{
> +       /* assume all cpus from fam10h have IO ECS */
> +        if (boot_cpu_data.x86 < 0x10)
> +               return 0;
> +       on_each_cpu(enable_pci_io_ecs_per_cpu, NULL, 1, 1);

how about some cpu hotplug? i mean if you limit that when booting and
later use "echo 1 > /sys/.../online" etc to get it online.

YH

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 1/2] x86/pci: Renaming k8-bus_64.c to amd_bus.c
  2008-06-12 18:19                 ` [PATCH 1/2] x86/pci: Renaming k8-bus_64.c to amd_bus.c Robert Richter
@ 2008-06-12 19:51                   ` Yinghai Lu
  2008-06-13 12:47                     ` Robert Richter
  2008-06-18  7:46                   ` Ingo Molnar
  2008-06-19 16:02                   ` Robert Richter
  2 siblings, 1 reply; 27+ messages in thread
From: Yinghai Lu @ 2008-06-12 19:51 UTC (permalink / raw)
  To: Robert Richter
  Cc: Arjan van de Ven, Thomas Gleixner, Ingo Molnar, LKML, Andi Kleen

On Thu, Jun 12, 2008 at 11:19 AM, Robert Richter <robert.richter@amd.com> wrote:
> The name fits better since this is code not only for K8.
>
> Signed-off-by: Robert Richter <robert.richter@amd.com>
> ---
>  arch/x86/pci/Makefile_64 |    2 +-
>  arch/x86/pci/amd_bus.c   |  528 ++++++++++++++++++++++++++++++++++++++++++++++
>  arch/x86/pci/k8-bus_64.c |  528 ----------------------------------------------
>  3 files changed, 529 insertions(+), 529 deletions(-)
>  create mode 100644 arch/x86/pci/amd_bus.c
>  delete mode 100644 arch/x86/pci/k8-bus_64.c
>
> diff --git a/arch/x86/pci/Makefile_64 b/arch/x86/pci/Makefile_64
> index 8fbd198..fd47068 100644
> --- a/arch/x86/pci/Makefile_64
> +++ b/arch/x86/pci/Makefile_64
> @@ -13,5 +13,5 @@ obj-y                 += legacy.o irq.o common.o early.o
>  # mmconfig has a 64bit special
>  obj-$(CONFIG_PCI_MMCONFIG) += mmconfig_64.o direct.o mmconfig-shared.o
>
> -obj-y          += k8-bus_64.o
> +obj-y          += amd_bus.o

can we keep the _64?

It is used by 64bit only at this time.

YH

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 1/2] x86/pci: Renaming k8-bus_64.c to amd_bus.c
  2008-06-12 19:51                   ` Yinghai Lu
@ 2008-06-13 12:47                     ` Robert Richter
  0 siblings, 0 replies; 27+ messages in thread
From: Robert Richter @ 2008-06-13 12:47 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Arjan van de Ven, Thomas Gleixner, Ingo Molnar, LKML, Andi Kleen

On 12.06.08 12:51:36, Yinghai Lu wrote:
> > -obj-y          += k8-bus_64.o
> > +obj-y          += amd_bus.o
> 
> can we keep the _64?
> 
> It is used by 64bit only at this time.

Patch 2/2 will introduce code that works also for 32 bit.

-Robert

-- 
Advanced Micro Devices, Inc.
Operating System Research Center
email: robert.richter@amd.com


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 2/2] x86: Move PCI IO ECS code to x86/pci
  2008-06-12 19:50                   ` Yinghai Lu
@ 2008-06-13 16:19                     ` Robert Richter
  0 siblings, 0 replies; 27+ messages in thread
From: Robert Richter @ 2008-06-13 16:19 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Arjan van de Ven, Thomas Gleixner, Ingo Molnar, LKML, Andi Kleen

On 12.06.08 12:50:10, Yinghai Lu wrote:
> > +static int __init enable_pci_io_ecs(void)
> > +{
> > +       /* assume all cpus from fam10h have IO ECS */
> > +        if (boot_cpu_data.x86 < 0x10)
> > +               return 0;
> > +       on_each_cpu(enable_pci_io_ecs_per_cpu, NULL, 1, 1);
> 
> how about some cpu hotplug? i mean if you limit that when booting and
> later use "echo 1 > /sys/.../online" etc to get it online.

Yinghai, will look at this.

Thanks,

-Robert

-- 
Advanced Micro Devices, Inc.
Operating System Research Center
email: robert.richter@amd.com


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 2/2] x86: Move PCI IO ECS code to x86/pci
  2008-06-12 18:19                 ` [PATCH 2/2] x86: Move PCI IO ECS code to x86/pci Robert Richter
  2008-06-12 19:50                   ` Yinghai Lu
@ 2008-06-13 17:02                   ` Glauber Costa
  2008-06-13 18:16                     ` Robert Richter
  2008-06-18  7:47                   ` Ingo Molnar
  2 siblings, 1 reply; 27+ messages in thread
From: Glauber Costa @ 2008-06-13 17:02 UTC (permalink / raw)
  To: Robert Richter
  Cc: Arjan van de Ven, Yinghai Lu, Thomas Gleixner, Ingo Molnar, LKML,
	Andi Kleen

On Thu, Jun 12, 2008 at 3:19 PM, Robert Richter <robert.richter@amd.com> wrote:
> "Form follows function". Code is now where it belongs to.
>
> Signed-off-by: Robert Richter <robert.richter@amd.com>
> ---
>  arch/x86/kernel/cpu/amd.c    |    3 ---
>  arch/x86/kernel/cpu/amd_64.c |    4 ----
>  arch/x86/kernel/cpu/cpu.h    |    2 --
>  arch/x86/kernel/setup.c      |   13 -------------
>  arch/x86/pci/Makefile_32     |    1 +
>  arch/x86/pci/amd_bus.c       |   32 ++++++++++++++++++++++++++++++++
>  arch/x86/pci/direct.c        |   16 +++++++++-------
>  arch/x86/pci/pci.h           |    1 +
>  include/asm-x86/cpufeature.h |    2 --
>  9 files changed, 43 insertions(+), 31 deletions(-)
>
> diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
> index acc891a..81a07ca 100644
> --- a/arch/x86/kernel/cpu/amd.c
> +++ b/arch/x86/kernel/cpu/amd.c
> @@ -266,9 +266,6 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
>
>        if (cpu_has_xmm2)
>                set_cpu_cap(c, X86_FEATURE_MFENCE_RDTSC);
> -
> -       if (c->x86 == 0x10)
> -               amd_enable_pci_ext_cfg(c);
>  }
>
>  static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 *c, unsigned int size)
> diff --git a/arch/x86/kernel/cpu/amd_64.c b/arch/x86/kernel/cpu/amd_64.c
> index f8d2058..250bfe6 100644
> --- a/arch/x86/kernel/cpu/amd_64.c
> +++ b/arch/x86/kernel/cpu/amd_64.c
> @@ -6,7 +6,6 @@
>  #include <asm/cacheflush.h>
>
>  #include <mach_apic.h>
> -#include "cpu.h"
>
>  extern int __cpuinit get_model_name(struct cpuinfo_x86 *c);
>  extern void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c);
> @@ -187,9 +186,6 @@ void __cpuinit init_amd(struct cpuinfo_x86 *c)
>        if (c->x86 == 0x10)
>                fam10h_check_enable_mmcfg();
>
> -       if (c->x86 == 0x10)
> -               amd_enable_pci_ext_cfg(c);
> -
>        if (c == &boot_cpu_data && c->x86 >= 0xf && c->x86 <= 0x11) {
>                unsigned long long tseg;
>
> diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h
> index f5d5bb1..40ad189 100644
> --- a/arch/x86/kernel/cpu/cpu.h
> +++ b/arch/x86/kernel/cpu/cpu.h
> @@ -39,5 +39,3 @@ extern int get_model_name(struct cpuinfo_x86 *c);
>  extern void display_cacheinfo(struct cpuinfo_x86 *c);
>
>  #endif /* CONFIG_X86_32 */
> -
> -extern void __cpuinit amd_enable_pci_ext_cfg(struct cpuinfo_x86 *c);
> diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
> index 20e14db..6f80b85 100644
> --- a/arch/x86/kernel/setup.c
> +++ b/arch/x86/kernel/setup.c
> @@ -137,16 +137,3 @@ void __init setup_per_cpu_areas(void)
>  }
>
>  #endif
> -#define ENABLE_CF8_EXT_CFG      (1ULL << 46)
> -
> -void __cpuinit amd_enable_pci_ext_cfg(struct cpuinfo_x86 *c)
> -{
> -       u64 reg;
> -       rdmsrl(MSR_AMD64_NB_CFG, reg);
> -       if (!(reg & ENABLE_CF8_EXT_CFG)) {
> -               reg |= ENABLE_CF8_EXT_CFG;
> -               wrmsrl(MSR_AMD64_NB_CFG, reg);
> -       }
> -       set_cpu_cap(c, X86_FEATURE_PCI_EXT_CFG);
> -}
> -
> diff --git a/arch/x86/pci/Makefile_32 b/arch/x86/pci/Makefile_32
> index 89ec35d..f647e7e 100644
> --- a/arch/x86/pci/Makefile_32
> +++ b/arch/x86/pci/Makefile_32
> @@ -22,3 +22,4 @@ pci-$(CONFIG_X86_NUMAQ)               := numa.o irq.o
>  pci-$(CONFIG_NUMA)             += mp_bus_to_node.o
>
>  obj-y                          += $(pci-y) common.o early.o
> +obj-y                          += amd_bus.o
> diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c
> index 5c2799c..15f505d 100644
> --- a/arch/x86/pci/amd_bus.c
> +++ b/arch/x86/pci/amd_bus.c
> @@ -1,5 +1,9 @@
>  #include <linux/init.h>
>  #include <linux/pci.h>
> +#include "pci.h"
> +
> +#ifdef CONFIG_X86_64

Please, don't do that. We are in an ongoing effort to cleanup the
remaining ifdefs in x86 code, and adding more of them would just make
it harder.
If you really need it, move the common part to a separate file (avoid
the _32 and _64 naming), and have it compiled conditionally on your
architecture.

>  #include <asm/pci-direct.h>
>  #include <asm/mpspec.h>
>  #include <linux/cpumask.h>
> @@ -526,3 +530,31 @@ static int __init early_fill_mp_bus_info(void)
>  }
>
>  postcore_initcall(early_fill_mp_bus_info);
> +
> +#endif
> +
> +/* common 32/64 bit code */
> +
> +#define ENABLE_CF8_EXT_CFG      (1ULL << 46)
> +
> +static void enable_pci_io_ecs_per_cpu(void *unused)
> +{
> +       u64 reg;
> +       rdmsrl(MSR_AMD64_NB_CFG, reg);
> +       if (!(reg & ENABLE_CF8_EXT_CFG)) {
> +               reg |= ENABLE_CF8_EXT_CFG;
> +               wrmsrl(MSR_AMD64_NB_CFG, reg);
> +       }
> +}
> +
> +static int __init enable_pci_io_ecs(void)
> +{
> +       /* assume all cpus from fam10h have IO ECS */
> +        if (boot_cpu_data.x86 < 0x10)
> +               return 0;
> +       on_each_cpu(enable_pci_io_ecs_per_cpu, NULL, 1, 1);
> +       pci_probe |= PCI_HAS_IO_ECS;
> +       return 0;
> +}
> +
> +postcore_initcall(enable_pci_io_ecs);
> diff --git a/arch/x86/pci/direct.c b/arch/x86/pci/direct.c
> index 27d61b6..9915293 100644
> --- a/arch/x86/pci/direct.c
> +++ b/arch/x86/pci/direct.c
> @@ -265,14 +265,16 @@ void __init pci_direct_init(int type)
>                 type);
>        if (type == 1) {
>                raw_pci_ops = &pci_direct_conf1;
> -               if (!raw_pci_ext_ops && cpu_has_pci_ext_cfg) {
> -                       printk(KERN_INFO "PCI: Using configuration type 1 "
> -                              "for extended access\n");
> -                       raw_pci_ext_ops = &pci_direct_conf1;
> -               }
> -       } else {
> -               raw_pci_ops = &pci_direct_conf2;
> +               if (raw_pci_ext_ops)
> +                       return;
> +               if (!(pci_probe & PCI_HAS_IO_ECS))
> +                       return;
> +               printk(KERN_INFO "PCI: Using configuration type 1 "
> +                      "for extended access\n");
> +               raw_pci_ext_ops = &pci_direct_conf1;
> +               return;
>        }
> +       raw_pci_ops = &pci_direct_conf2;
>  }
>
>  int __init pci_direct_probe(void)
> diff --git a/arch/x86/pci/pci.h b/arch/x86/pci/pci.h
> index f3972b1..fd53db5 100644
> --- a/arch/x86/pci/pci.h
> +++ b/arch/x86/pci/pci.h
> @@ -27,6 +27,7 @@
>  #define PCI_CAN_SKIP_ISA_ALIGN 0x8000
>  #define PCI_USE__CRS           0x10000
>  #define PCI_CHECK_ENABLE_AMD_MMCONF    0x20000
> +#define PCI_HAS_IO_ECS         0x40000
>
>  extern unsigned int pci_probe;
>  extern unsigned long pirq_table_addr;
> diff --git a/include/asm-x86/cpufeature.h b/include/asm-x86/cpufeature.h
> index 40fcbba..0d609c8 100644
> --- a/include/asm-x86/cpufeature.h
> +++ b/include/asm-x86/cpufeature.h
> @@ -79,7 +79,6 @@
>  #define X86_FEATURE_REP_GOOD   (3*32+16) /* rep microcode works well on this CPU */
>  #define X86_FEATURE_MFENCE_RDTSC (3*32+17) /* Mfence synchronizes RDTSC */
>  #define X86_FEATURE_LFENCE_RDTSC (3*32+18) /* Lfence synchronizes RDTSC */
> -#define X86_FEATURE_PCI_EXT_CFG        (3*32+19) /* PCI extended cfg access */
>
>  /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
>  #define X86_FEATURE_XMM3       (4*32+ 0) /* Streaming SIMD Extensions-3 */
> @@ -188,7 +187,6 @@ extern const char * const x86_power_flags[32];
>  #define cpu_has_gbpages                boot_cpu_has(X86_FEATURE_GBPAGES)
>  #define cpu_has_arch_perfmon   boot_cpu_has(X86_FEATURE_ARCH_PERFMON)
>  #define cpu_has_pat            boot_cpu_has(X86_FEATURE_PAT)
> -#define cpu_has_pci_ext_cfg    boot_cpu_has(X86_FEATURE_PCI_EXT_CFG)
>
>  #if defined(CONFIG_X86_INVLPG) || defined(CONFIG_X86_64)
>  # define cpu_has_invlpg                1
> --
> 1.5.5.3
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
>



-- 
Glauber  Costa.
"Free as in Freedom"
http://glommer.net

"The less confident you are, the more serious you have to act."

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 2/2] x86: Move PCI IO ECS code to x86/pci
  2008-06-13 17:02                   ` Glauber Costa
@ 2008-06-13 18:16                     ` Robert Richter
  2008-06-13 18:26                       ` Glauber Costa
  2008-06-18  7:51                       ` Ingo Molnar
  0 siblings, 2 replies; 27+ messages in thread
From: Robert Richter @ 2008-06-13 18:16 UTC (permalink / raw)
  To: Glauber Costa
  Cc: Arjan van de Ven, Yinghai Lu, Thomas Gleixner, Ingo Molnar, LKML,
	Andi Kleen

On 13.06.08 14:02:46, Glauber Costa wrote:
> > diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c
> > index 5c2799c..15f505d 100644
> > --- a/arch/x86/pci/amd_bus.c
> > +++ b/arch/x86/pci/amd_bus.c
> > @@ -1,5 +1,9 @@
> >  #include <linux/init.h>
> >  #include <linux/pci.h>
> > +#include "pci.h"
> > +
> > +#ifdef CONFIG_X86_64
> 
> Please, don't do that. We are in an ongoing effort to cleanup the
> remaining ifdefs in x86 code, and adding more of them would just make
> it harder.
> If you really need it, move the common part to a separate file (avoid
> the _32 and _64 naming), and have it compiled conditionally on your
> architecture.

Ok, so what about shared code? Keep all this in separate files:
amd_bus.c, (amd_bus_32.c), amd_bus_64.c, (amd_bus.h)?

Is the strategy to avoid #ifdefs and instead use the flags in
Makefiles? My intention was to coalesce the files. Maybe I was wrong
here.

-Robert

-- 
Advanced Micro Devices, Inc.
Operating System Research Center
email: robert.richter@amd.com


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 2/2] x86: Move PCI IO ECS code to x86/pci
  2008-06-13 18:16                     ` Robert Richter
@ 2008-06-13 18:26                       ` Glauber Costa
  2008-06-18  7:51                       ` Ingo Molnar
  1 sibling, 0 replies; 27+ messages in thread
From: Glauber Costa @ 2008-06-13 18:26 UTC (permalink / raw)
  To: Robert Richter
  Cc: Arjan van de Ven, Yinghai Lu, Thomas Gleixner, Ingo Molnar, LKML,
	Andi Kleen

On Fri, Jun 13, 2008 at 3:16 PM, Robert Richter <robert.richter@amd.com> wrote:
> On 13.06.08 14:02:46, Glauber Costa wrote:
>> > diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c
>> > index 5c2799c..15f505d 100644
>> > --- a/arch/x86/pci/amd_bus.c
>> > +++ b/arch/x86/pci/amd_bus.c
>> > @@ -1,5 +1,9 @@
>> >  #include <linux/init.h>
>> >  #include <linux/pci.h>
>> > +#include "pci.h"
>> > +
>> > +#ifdef CONFIG_X86_64
>>
>> Please, don't do that. We are in an ongoing effort to cleanup the
>> remaining ifdefs in x86 code, and adding more of them would just make
>> it harder.
>> If you really need it, move the common part to a separate file (avoid
>> the _32 and _64 naming), and have it compiled conditionally on your
>> architecture.
>
> Ok, so what about shared code? Keep all this in separate files:
> amd_bus.c, (amd_bus_32.c), amd_bus_64.c, (amd_bus.h)?
>
> Is the strategy to avoid #ifdefs and instead use the flags in
> Makefiles? My intention was to coalesce the files. Maybe I was wrong
> here.

The strategy is to coalesce the files if they do the same thing. If
you can find an implementation that is shared
between both, it is surely the most preferable option among them all.
Even if it takes more time.

For some of them, this is obviously not intrinsically possible. That's
the case for example, of the .S files that touch deep details of the
architectures. (ok, ok, _some_ of that code might well be shared in
the future). Another example, is the page headers. Part of it
were kept in page_32.h and page_64.h.

If not, ifdefs in the .h file are probably okay, if they can be used
to avoid them in .c code.

But of course, those things are not carved in stone. If you really
think that ifdef should go there, feel free to do it, with a good
justification.

-- 
Glauber  Costa.
"Free as in Freedom"
http://glommer.net

"The less confident you are, the more serious you have to act."

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 1/2] x86/pci: Renaming k8-bus_64.c to amd_bus.c
  2008-06-12 18:19                 ` [PATCH 1/2] x86/pci: Renaming k8-bus_64.c to amd_bus.c Robert Richter
  2008-06-12 19:51                   ` Yinghai Lu
@ 2008-06-18  7:46                   ` Ingo Molnar
  2008-06-19 16:02                   ` Robert Richter
  2 siblings, 0 replies; 27+ messages in thread
From: Ingo Molnar @ 2008-06-18  7:46 UTC (permalink / raw)
  To: Robert Richter
  Cc: Arjan van de Ven, Yinghai Lu, Thomas Gleixner, LKML, Andi Kleen


* Robert Richter <robert.richter@amd.com> wrote:

> The name fits better since this is code not only for K8.
> 
> Signed-off-by: Robert Richter <robert.richter@amd.com>

applied to tip/x86/cpu, thanks Robert.

	Ingo

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 2/2] x86: Move PCI IO ECS code to x86/pci
  2008-06-12 18:19                 ` [PATCH 2/2] x86: Move PCI IO ECS code to x86/pci Robert Richter
  2008-06-12 19:50                   ` Yinghai Lu
  2008-06-13 17:02                   ` Glauber Costa
@ 2008-06-18  7:47                   ` Ingo Molnar
  2 siblings, 0 replies; 27+ messages in thread
From: Ingo Molnar @ 2008-06-18  7:47 UTC (permalink / raw)
  To: Robert Richter
  Cc: Arjan van de Ven, Yinghai Lu, Thomas Gleixner, LKML, Andi Kleen


* Robert Richter <robert.richter@amd.com> wrote:

> "Form follows function". Code is now where it belongs to.

applied to tip/x86/cpu - thanks.

	Ingo

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 2/2] x86: Move PCI IO ECS code to x86/pci
  2008-06-13 18:16                     ` Robert Richter
  2008-06-13 18:26                       ` Glauber Costa
@ 2008-06-18  7:51                       ` Ingo Molnar
  1 sibling, 0 replies; 27+ messages in thread
From: Ingo Molnar @ 2008-06-18  7:51 UTC (permalink / raw)
  To: Robert Richter
  Cc: Glauber Costa, Arjan van de Ven, Yinghai Lu, Thomas Gleixner,
	LKML, Andi Kleen, the arch/x86 maintainers


* Robert Richter <robert.richter@amd.com> wrote:

> Ok, so what about shared code? Keep all this in separate files: 
> amd_bus.c, (amd_bus_32.c), amd_bus_64.c, (amd_bus.h)?
> 
> Is the strategy to avoid #ifdefs and instead use the flags in 
> Makefiles? My intention was to coalesce the files. Maybe I was wrong 
> here.

What you did is fine - first step is to move the variants as close to 
each other as possible, in an as obvious and mechanic step as possible.

If anything breaks due to your patches then they were probably too 
large, but lets be optimistic and try your current splitup first :)

Then we can start eliminating any leftover #ifdefs, step by step. Please 
send very, very small patches for that (put them into a git tree on 
kernel.org if there's more than say a dozen of them), we'll test them, 
and if the changes break anything it's all bisectable to an individual 
change.

	Ingo

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 1/2] x86/pci: Renaming k8-bus_64.c to amd_bus.c
  2008-06-12 18:19                 ` [PATCH 1/2] x86/pci: Renaming k8-bus_64.c to amd_bus.c Robert Richter
  2008-06-12 19:51                   ` Yinghai Lu
  2008-06-18  7:46                   ` Ingo Molnar
@ 2008-06-19 16:02                   ` Robert Richter
  2 siblings, 0 replies; 27+ messages in thread
From: Robert Richter @ 2008-06-19 16:02 UTC (permalink / raw)
  To: Arjan van de Ven
  Cc: Yinghai Lu, Thomas Gleixner, Ingo Molnar, LKML, Andi Kleen

On 12.06.08 20:19:22, Robert Richter wrote:
> The name fits better since this is code not only for K8.
> 
> Signed-off-by: Robert Richter <robert.richter@amd.com>
> ---
>  arch/x86/pci/Makefile_64 |    2 +-
>  arch/x86/pci/amd_bus.c   |  528 ++++++++++++++++++++++++++++++++++++++++++++++
>  arch/x86/pci/k8-bus_64.c |  528 ----------------------------------------------
>  3 files changed, 529 insertions(+), 529 deletions(-)
>  create mode 100644 arch/x86/pci/amd_bus.c
>  delete mode 100644 arch/x86/pci/k8-bus_64.c

I accidentally resent the patches, please igore.

Thanks,

-Robert

-- 
Advanced Micro Devices, Inc.
Operating System Research Center
email: robert.richter@amd.com


^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2008-06-19 16:02 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-05-23 12:46 Enable mmconf access to PCI ECS for all AMD fam10h systems Robert Richter
2008-05-23 17:57 ` Yinghai Lu
2008-05-23 18:18   ` Arjan van de Ven
2008-05-23 19:06     ` Yinghai Lu
2008-05-26 18:06     ` Robert Richter
2007-09-03  8:17       ` [PATCH] x86: Add PCI extended config space access for AMD Barcelona Robert Richter
2008-05-28 19:02         ` Arjan van de Ven
2008-06-02 14:19           ` Robert Richter
2008-06-03  2:35             ` Arjan van de Ven
2008-06-03  7:25               ` Robert Richter
2008-06-12 18:19                 ` [PATCH 1/2] x86/pci: Renaming k8-bus_64.c to amd_bus.c Robert Richter
2008-06-12 19:51                   ` Yinghai Lu
2008-06-13 12:47                     ` Robert Richter
2008-06-18  7:46                   ` Ingo Molnar
2008-06-19 16:02                   ` Robert Richter
2008-06-12 18:19                 ` [PATCH 2/2] x86: Move PCI IO ECS code to x86/pci Robert Richter
2008-06-12 19:50                   ` Yinghai Lu
2008-06-13 16:19                     ` Robert Richter
2008-06-13 17:02                   ` Glauber Costa
2008-06-13 18:16                     ` Robert Richter
2008-06-13 18:26                       ` Glauber Costa
2008-06-18  7:51                       ` Ingo Molnar
2008-06-18  7:47                   ` Ingo Molnar
2008-06-02  9:09         ` [PATCH] x86: Add PCI extended config space access for AMD Barcelona Ingo Molnar
2008-06-02 13:56           ` Robert Richter
2008-06-02 20:31         ` Yinghai Lu
2008-06-03  7:35           ` Robert Richter

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).