Skip to content

Commit

Permalink
x86: add PCI extended config space access for AMD Barcelona
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Robert Richter authored and Ingo Molnar committed Jun 2, 2008
1 parent 1c47cd6 commit 831d991
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 6 deletions.
4 changes: 4 additions & 0 deletions arch/x86/kernel/cpu/amd.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <asm/apic.h>

#include <mach_apic.h>
#include "../setup.h"
#include "cpu.h"

/*
Expand Down Expand Up @@ -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)
Expand Down
3 changes: 3 additions & 0 deletions arch/x86/kernel/cpu/amd_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,9 @@ 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;

Expand Down
13 changes: 13 additions & 0 deletions arch/x86/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
26 changes: 26 additions & 0 deletions arch/x86/kernel/setup.h
Original file line number Diff line number Diff line change
@@ -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 */
2 changes: 2 additions & 0 deletions arch/x86/kernel/setup_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@
#include <asm/pat.h>
#include <asm/mmconfig.h>

#include "setup.h"

#include <mach_apic.h>
#ifdef CONFIG_PARAVIRT
#include <asm/paravirt.h>
Expand Down
21 changes: 15 additions & 6 deletions arch/x86/pci/direct.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions include/asm-x86/cpufeature.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 831d991

Please sign in to comment.