All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Robert Richter" <robert.richter@amd.com>
To: "Andi Kleen" <ak@suse.de>
Cc: patches@x86-64.org, linux-kernel@vger.kernel.org,
	"Robert Richter" <robert.richter@amd.com>
Subject: [patch 3/5] x86: Add PCI extended config space access for AMD Barcelona
Date: Mon, 03 Sep 2007 10:17:39 +0200	[thread overview]
Message-ID: <20070903081736.588599000@amd.com> (raw)
In-Reply-To: 20070903081736.288288000@amd.com

[-- Attachment #1: fam10h-pci-ext-cfg-io.diff --]
[-- Type: text/plain, Size: 7415 bytes --]

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/i386/kernel/cpu/amd.c    |   11 +++++-
 arch/i386/pci/direct.c        |   67 +++++++++++++++++++++++++++++++++++-------
 arch/x86_64/kernel/setup.c    |   12 ++++++-
 include/asm-i386/cpufeature.h |    2 +
 4 files changed, 77 insertions(+), 15 deletions(-)

Index: linux-2.6/arch/i386/pci/direct.c
===================================================================
--- linux-2.6.orig/arch/i386/pci/direct.c
+++ linux-2.6/arch/i386/pci/direct.c
@@ -8,18 +8,22 @@
 #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))
 
-int pci_conf1_read(unsigned int seg, unsigned int bus,
-			  unsigned int devfn, int reg, int len, u32 *value)
+static inline int
+_pci_conf1ext_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;
 	}
@@ -45,12 +49,29 @@ int pci_conf1_read(unsigned int seg, uns
 	return 0;
 }
 
-int pci_conf1_write(unsigned int seg, unsigned int bus,
-			   unsigned int devfn, int reg, int len, u32 value)
+int pci_conf1ext_read(unsigned int seg, unsigned int bus,
+		      unsigned int devfn, int reg, int len, u32 *value)
+{
+	return _pci_conf1ext_read(seg, bus, devfn, reg, len, value);
+}
+
+int pci_conf1_read(unsigned int seg, unsigned int bus,
+			  unsigned int devfn, int reg, int len, u32 *value)
+{
+	if (reg > 255) {
+		*value = -1;
+		return -EINVAL;
+	}
+	return _pci_conf1ext_read(seg, bus, devfn, reg, len, value);
+}
+
+static inline int
+_pci_conf1ext_write(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))
 		return -EINVAL;
 
 	spin_lock_irqsave(&pci_config_lock, flags);
@@ -74,6 +95,20 @@ int pci_conf1_write(unsigned int seg, un
 	return 0;
 }
 
+int pci_conf1ext_write(unsigned int seg, unsigned int bus,
+		       unsigned int devfn, int reg, int len, u32 value)
+{
+	return _pci_conf1ext_write(seg, bus, devfn, reg, len, value);
+}
+
+int pci_conf1_write(unsigned int seg, unsigned int bus,
+		 unsigned int devfn, int reg, int len, u32 value)
+{
+	if (reg > 255)
+		return -EINVAL;
+	return _pci_conf1ext_write(seg, bus, devfn, reg, len, value);
+}
+
 #undef PCI_CONF1_ADDRESS
 
 struct pci_raw_ops pci_direct_conf1 = {
@@ -81,6 +116,11 @@ struct pci_raw_ops pci_direct_conf1 = {
 	.write =	pci_conf1_write,
 };
 
+struct pci_raw_ops pci_direct_conf1ext = {
+	.read =		pci_conf1ext_read,
+	.write =	pci_conf1ext_write,
+};
+
 
 /*
  * Functions for accessing PCI configuration space with type 2 accesses
@@ -259,10 +299,15 @@ void __init pci_direct_init(int type)
 	if (type == 0)
 		return;
 	printk(KERN_INFO "PCI: Using configuration type %d\n", type);
-	if (type == 1)
-		raw_pci_ops = &pci_direct_conf1;
-	else
+	if (type != 1) {
 		raw_pci_ops = &pci_direct_conf2;
+	} else if (cpu_has_pci_ext_cfg) {
+		printk(KERN_INFO
+		       "PCI: Extended configuration space enabled\n");
+		raw_pci_ops = &pci_direct_conf1ext;
+	} else {
+		raw_pci_ops = &pci_direct_conf1;
+	}
 }
 
 int __init pci_direct_probe(void)
Index: linux-2.6/arch/x86_64/kernel/setup.c
===================================================================
--- linux-2.6.orig/arch/x86_64/kernel/setup.c
+++ linux-2.6/arch/x86_64/kernel/setup.c
@@ -65,6 +65,8 @@
 #include <asm/sections.h>
 #include <asm/dmi.h>
 
+#define ENABLE_CF8_EXT_CFG		(1ULL << 46)
+
 /*
  * Machine setup..
  */
@@ -549,10 +551,9 @@ static void __init amd_detect_cmp(struct
 static void __cpuinit init_amd(struct cpuinfo_x86 *c)
 {
 	unsigned level;
-
-#ifdef CONFIG_SMP
 	unsigned long value;
 
+#ifdef CONFIG_SMP
 	/*
 	 * Disable TLB flush filter by setting HWCR.FFDIS on K8
 	 * bit 6 of msr C001_0015
@@ -617,6 +618,13 @@ static void __cpuinit init_amd(struct cp
 	/* Family 10 doesn't support C states in MWAIT so don't use it */
 	if (c->x86 == 0x10 && !force_mwait)
 		clear_bit(X86_FEATURE_MWAIT, &c->x86_capability);
+
+	/* Access to PCI extended config space? */
+	if (c->x86 == 0x10) {
+		rdmsrl(MSR_AMD64_NB_CFG, value);
+		if (value & ENABLE_CF8_EXT_CFG)
+			set_bit(X86_FEATURE_PCI_EXT_CFG, &c->x86_capability);
+	}
 }
 
 static void __cpuinit detect_ht(struct cpuinfo_x86 *c)
Index: linux-2.6/include/asm-i386/cpufeature.h
===================================================================
--- linux-2.6.orig/include/asm-i386/cpufeature.h
+++ linux-2.6/include/asm-i386/cpufeature.h
@@ -82,6 +82,7 @@
 /* 14 free */
 #define X86_FEATURE_SYNC_RDTSC	(3*32+15)  /* RDTSC synchronizes the CPU */
 #define X86_FEATURE_REP_GOOD   (3*32+16) /* rep microcode works well on this CPU */
+#define X86_FEATURE_PCI_EXT_CFG	(3*32+17) /* 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 */
@@ -164,6 +165,7 @@
 #define cpu_has_pebs 		boot_cpu_has(X86_FEATURE_PEBS)
 #define cpu_has_clflush		boot_cpu_has(X86_FEATURE_CLFLSH)
 #define cpu_has_bts 		boot_cpu_has(X86_FEATURE_BTS)
+#define cpu_has_pci_ext_cfg	boot_cpu_has(X86_FEATURE_PCI_EXT_CFG)
 
 #endif /* __ASM_I386_CPUFEATURE_H */
 
Index: linux-2.6/arch/i386/kernel/cpu/amd.c
===================================================================
--- linux-2.6.orig/arch/i386/kernel/cpu/amd.c
+++ linux-2.6/arch/i386/kernel/cpu/amd.c
@@ -32,6 +32,7 @@ __asm__(".align 4\nvide: ret");
 #define CPUID_XFAM_11H          0x00200000
 #define CPUID_XMOD              0x000f0000
 #define CPUID_XMOD_REV_F        0x00040000
+#define ENABLE_CF8_EXT_CFG      (1ULL << 46)
 
 /* AMD systems with C1E don't have a working lAPIC timer. Check for that. */
 static __cpuinit int amd_apic_timer_broken(void)
@@ -63,10 +64,9 @@ static void __cpuinit init_amd(struct cp
 	u32 l, h;
 	int mbytes = num_physpages >> (20-PAGE_SHIFT);
 	int r;
-
-#ifdef CONFIG_SMP
 	unsigned long long value;
 
+#ifdef CONFIG_SMP
 	/* Disable TLB flush filter by setting HWCR.FFDIS on K8
 	 * bit 6 of msr C001_0015
 	 *
@@ -296,6 +296,13 @@ static void __cpuinit init_amd(struct cp
 	/* K6s reports MCEs but don't actually have all the MSRs */
 	if (c->x86 < 6)
 		clear_bit(X86_FEATURE_MCE, c->x86_capability);
+
+	/* Access to PCI extended config space? */
+	if (c->x86 == 0x10) {
+		rdmsrl(MSR_AMD64_NB_CFG, value);
+		if (value & ENABLE_CF8_EXT_CFG)
+			set_bit(X86_FEATURE_PCI_EXT_CFG, c->x86_capability);
+	}
 }
 
 static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 * c, unsigned int size)

-- 
AMD Saxony, Dresden, Germany
Operating System Research Center
email: robert.richter@amd.com




  parent reply	other threads:[~2007-09-03  8:20 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-09-03  8:17 [patch 0/5] (resent) x86: PCI extended config space access on AMD Barcelona CPUs Robert Richter
2007-09-03  8:17 ` [patch 1/5] x86: Add AMD64 Barcelona PMU MSR definitions Robert Richter
2007-09-03  8:17 ` [patch 2/5] x86: Add AMD64 Barcelona NB cfg " Robert Richter
2007-09-03  8:17 ` Robert Richter [this message]
2007-09-03  8:31   ` [patch 3/5] x86: Add PCI extended config space access for AMD Barcelona Arjan van de Ven
2007-09-03  9:17     ` [patches] " Andreas Herrmann
2007-09-03 11:33       ` Arjan van de Ven
2007-09-03 15:47         ` Andreas Herrmann
2007-09-05  5:58           ` H. Peter Anvin
2007-09-05  8:44             ` Robert Richter
2007-09-05 10:12               ` H. Peter Anvin
2007-09-05 10:35                 ` Robert Richter
2007-09-05 11:05                 ` Arne Georg Gleditsch
2007-09-05 16:13                   ` Andreas Herrmann
2007-09-05 22:42                     ` Yinghai Lu
2007-09-06  8:31                       ` Arne Georg Gleditsch
2007-09-06  9:48                         ` H. Peter Anvin
2007-09-06 17:41                           ` Jesse Barnes
2007-09-06 17:50                             ` Yinghai Lu
2007-09-06 17:48                               ` Jesse Barnes
2007-09-06 17:48                           ` Yinghai Lu
2007-09-05 15:00             ` Andreas Herrmann
2007-09-06 10:14               ` Arjan van de Ven
2007-09-03  8:17 ` [patch 4/5] x86: Add PCI IDs for AMD Barcelona PCI devices Robert Richter
2007-09-03  8:17 ` [patch 5/5] x86: Set PCI config space size to extended for AMD Barcelona Robert Richter
2007-09-03 16:48   ` dean gaudet
2007-09-03 18:18     ` Robert Richter
2007-09-03 19:01     ` Martin Mares
     [not found] <20070830174311.221133000@amd.com>
     [not found] ` <20070830174311.536394000@amd.com>
2007-09-01 10:11   ` [patch 3/5] x86: Add PCI extended config space access " Andi Kleen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20070903081736.588599000@amd.com \
    --to=robert.richter@amd.com \
    --cc=ak@suse.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=patches@x86-64.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.