diff options
author | Robert Richter <robert.richter@amd.com> | 2007-09-03 04:17:39 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-06-02 05:51:19 -0400 |
commit | 831d991821daedd4839073dbca55514432ef1768 (patch) | |
tree | f3b9772709fd948c5df7b3e0535d9f62737e7702 /arch/x86/pci/direct.c | |
parent | 1c47cd638e8302bc38be1f6d81067950e038ebd3 (diff) |
x86: add PCI extended config space access for AMD Barcelona
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>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/pci/direct.c')
-rw-r--r-- | arch/x86/pci/direct.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/arch/x86/pci/direct.c b/arch/x86/pci/direct.c index 21d1e0e0d535..27d61b63def6 100644 --- a/arch/x86/pci/direct.c +++ b/arch/x86/pci/direct.c | |||
@@ -8,18 +8,21 @@ | |||
8 | #include "pci.h" | 8 | #include "pci.h" |
9 | 9 | ||
10 | /* | 10 | /* |
11 | * Functions for accessing PCI configuration space with type 1 accesses | 11 | * Functions for accessing PCI base (first 256 bytes) and extended |
12 | * (4096 bytes per PCI function) configuration space with type 1 | ||
13 | * accesses. | ||
12 | */ | 14 | */ |
13 | 15 | ||
14 | #define PCI_CONF1_ADDRESS(bus, devfn, reg) \ | 16 | #define PCI_CONF1_ADDRESS(bus, devfn, reg) \ |
15 | (0x80000000 | (bus << 16) | (devfn << 8) | (reg & ~3)) | 17 | (0x80000000 | ((reg & 0xF00) << 16) | (bus << 16) \ |
18 | | (devfn << 8) | (reg & 0xFC)) | ||
16 | 19 | ||
17 | static int pci_conf1_read(unsigned int seg, unsigned int bus, | 20 | static int pci_conf1_read(unsigned int seg, unsigned int bus, |
18 | unsigned int devfn, int reg, int len, u32 *value) | 21 | unsigned int devfn, int reg, int len, u32 *value) |
19 | { | 22 | { |
20 | unsigned long flags; | 23 | unsigned long flags; |
21 | 24 | ||
22 | if ((bus > 255) || (devfn > 255) || (reg > 255)) { | 25 | if ((bus > 255) || (devfn > 255) || (reg > 4095)) { |
23 | *value = -1; | 26 | *value = -1; |
24 | return -EINVAL; | 27 | return -EINVAL; |
25 | } | 28 | } |
@@ -50,7 +53,7 @@ static int pci_conf1_write(unsigned int seg, unsigned int bus, | |||
50 | { | 53 | { |
51 | unsigned long flags; | 54 | unsigned long flags; |
52 | 55 | ||
53 | if ((bus > 255) || (devfn > 255) || (reg > 255)) | 56 | if ((bus > 255) || (devfn > 255) || (reg > 4095)) |
54 | return -EINVAL; | 57 | return -EINVAL; |
55 | 58 | ||
56 | spin_lock_irqsave(&pci_config_lock, flags); | 59 | spin_lock_irqsave(&pci_config_lock, flags); |
@@ -260,10 +263,16 @@ void __init pci_direct_init(int type) | |||
260 | return; | 263 | return; |
261 | printk(KERN_INFO "PCI: Using configuration type %d for base access\n", | 264 | printk(KERN_INFO "PCI: Using configuration type %d for base access\n", |
262 | type); | 265 | type); |
263 | if (type == 1) | 266 | if (type == 1) { |
264 | raw_pci_ops = &pci_direct_conf1; | 267 | raw_pci_ops = &pci_direct_conf1; |
265 | else | 268 | if (!raw_pci_ext_ops && cpu_has_pci_ext_cfg) { |
269 | printk(KERN_INFO "PCI: Using configuration type 1 " | ||
270 | "for extended access\n"); | ||
271 | raw_pci_ext_ops = &pci_direct_conf1; | ||
272 | } | ||
273 | } else { | ||
266 | raw_pci_ops = &pci_direct_conf2; | 274 | raw_pci_ops = &pci_direct_conf2; |
275 | } | ||
267 | } | 276 | } |
268 | 277 | ||
269 | int __init pci_direct_probe(void) | 278 | int __init pci_direct_probe(void) |