x86: add x2apic config

Impact: cleanup

so could deselect x2apic
and INTR_REMAP will select x2apic

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
Yinghai Lu 2009-02-16 17:29:58 -08:00 committed by Ingo Molnar
parent 9f361c2219
commit 06cd9a7dc8
8 changed files with 51 additions and 21 deletions

View file

@ -235,6 +235,20 @@ config SMP
If you don't know what to do here, say N. If you don't know what to do here, say N.
config X86_X2APIC
bool "Support x2apic"
depends on X86_LOCAL_APIC && X86_64
---help---
This enables x2apic support on CPUs that have this feature.
This allows 32-bit apic IDs (so it can support very large systems),
and accesses the local apic via MSRs not via mmio.
( On certain CPU models you may need to enable INTR_REMAP too,
to get functional x2apic mode. )
If you don't know what to do here, say N.
config SPARSE_IRQ config SPARSE_IRQ
bool "Support sparse irq numbering" bool "Support sparse irq numbering"
depends on PCI_MSI || HT_IRQ depends on PCI_MSI || HT_IRQ
@ -1828,6 +1842,7 @@ config DMAR_FLOPPY_WA
config INTR_REMAP config INTR_REMAP
bool "Support for Interrupt Remapping (EXPERIMENTAL)" bool "Support for Interrupt Remapping (EXPERIMENTAL)"
depends on X86_64 && X86_IO_APIC && PCI_MSI && ACPI && EXPERIMENTAL depends on X86_64 && X86_IO_APIC && PCI_MSI && ACPI && EXPERIMENTAL
select X86_X2APIC
---help--- ---help---
Supports Interrupt remapping for IO-APIC and MSI devices. Supports Interrupt remapping for IO-APIC and MSI devices.
To use x2apic mode in the CPU's which support x2APIC enhancements or To use x2apic mode in the CPU's which support x2APIC enhancements or

View file

@ -112,7 +112,7 @@ static inline u32 native_apic_msr_read(u32 reg)
return low; return low;
} }
#ifndef CONFIG_X86_32 #ifdef CONFIG_X86_X2APIC
extern int x2apic; extern int x2apic;
extern void check_x2apic(void); extern void check_x2apic(void);
extern void enable_x2apic(void); extern void enable_x2apic(void);
@ -131,7 +131,19 @@ static inline int x2apic_enabled(void)
return 0; return 0;
} }
#else #else
#define x2apic_enabled() 0 static inline void check_x2apic(void)
{
}
static inline void enable_x2apic(void)
{
}
static inline void enable_IR_x2apic(void)
{
}
static inline int x2apic_enabled(void)
{
return 0;
}
#endif #endif
struct apic_ops { struct apic_ops {
@ -177,7 +189,7 @@ static inline u32 safe_apic_wait_icr_idle(void)
extern int get_physical_broadcast(void); extern int get_physical_broadcast(void);
#ifdef CONFIG_X86_64 #ifdef CONFIG_X86_X2APIC
static inline void ack_x2APIC_irq(void) static inline void ack_x2APIC_irq(void)
{ {
/* Docs say use 0 for future compatibility */ /* Docs say use 0 for future compatibility */

View file

@ -117,8 +117,8 @@ obj-$(CONFIG_SWIOTLB) += pci-swiotlb_64.o # NB rename without _64
# 64 bit specific files # 64 bit specific files
ifeq ($(CONFIG_X86_64),y) ifeq ($(CONFIG_X86_64),y)
obj-y += genapic_64.o genapic_flat_64.o obj-y += genapic_64.o genapic_flat_64.o
obj-y += genx2apic_cluster.o obj-$(CONFIG_X86_X2APIC) += genx2apic_cluster.o
obj-y += genx2apic_phys.o obj-$(CONFIG_X86_X2APIC) += genx2apic_phys.o
obj-$(CONFIG_X86_UV) += genx2apic_uv_x.o tlb_uv.o obj-$(CONFIG_X86_UV) += genx2apic_uv_x.o tlb_uv.o
obj-$(CONFIG_X86_UV) += bios_uv.o uv_irq.o uv_sysfs.o obj-$(CONFIG_X86_UV) += bios_uv.o uv_irq.o uv_sysfs.o
obj-$(CONFIG_X86_PM_TIMER) += pmtimer_64.o obj-$(CONFIG_X86_PM_TIMER) += pmtimer_64.o

View file

@ -112,11 +112,7 @@ static __init int setup_apicpmtimer(char *s)
__setup("apicpmtimer", setup_apicpmtimer); __setup("apicpmtimer", setup_apicpmtimer);
#endif #endif
#ifdef CONFIG_X86_64 #ifdef CONFIG_X86_X2APIC
#define HAVE_X2APIC
#endif
#ifdef HAVE_X2APIC
int x2apic; int x2apic;
/* x2apic enabled before OS handover */ /* x2apic enabled before OS handover */
static int x2apic_preenabled; static int x2apic_preenabled;
@ -269,7 +265,7 @@ static struct apic_ops xapic_ops = {
struct apic_ops __read_mostly *apic_ops = &xapic_ops; struct apic_ops __read_mostly *apic_ops = &xapic_ops;
EXPORT_SYMBOL_GPL(apic_ops); EXPORT_SYMBOL_GPL(apic_ops);
#ifdef HAVE_X2APIC #ifdef CONFIG_X86_X2APIC
static void x2apic_wait_icr_idle(void) static void x2apic_wait_icr_idle(void)
{ {
/* no need to wait for icr idle in x2apic */ /* no need to wait for icr idle in x2apic */
@ -1320,11 +1316,14 @@ void __cpuinit end_local_APIC_setup(void)
apic_pm_activate(); apic_pm_activate();
} }
#ifdef HAVE_X2APIC #ifdef CONFIG_X86_X2APIC
void check_x2apic(void) void check_x2apic(void)
{ {
int msr, msr2; int msr, msr2;
if (!cpu_has_x2apic)
return;
rdmsr(MSR_IA32_APICBASE, msr, msr2); rdmsr(MSR_IA32_APICBASE, msr, msr2);
if (msr & X2APIC_ENABLE) { if (msr & X2APIC_ENABLE) {
@ -1338,6 +1337,9 @@ void enable_x2apic(void)
{ {
int msr, msr2; int msr, msr2;
if (!x2apic)
return;
rdmsr(MSR_IA32_APICBASE, msr, msr2); rdmsr(MSR_IA32_APICBASE, msr, msr2);
if (!(msr & X2APIC_ENABLE)) { if (!(msr & X2APIC_ENABLE)) {
pr_info("Enabling x2apic\n"); pr_info("Enabling x2apic\n");
@ -1439,7 +1441,7 @@ void __init enable_IR_x2apic(void)
return; return;
} }
#endif /* HAVE_X2APIC */ #endif /* CONFIG_X86_X2APIC */
#ifdef CONFIG_X86_64 #ifdef CONFIG_X86_64
/* /*
@ -1570,7 +1572,7 @@ void __init early_init_lapic_mapping(void)
*/ */
void __init init_apic_mappings(void) void __init init_apic_mappings(void)
{ {
#ifdef HAVE_X2APIC #ifdef CONFIG_X86_X2APIC
if (x2apic) { if (x2apic) {
boot_cpu_physical_apicid = read_apic_id(); boot_cpu_physical_apicid = read_apic_id();
return; return;
@ -1634,9 +1636,7 @@ int __init APIC_init_uniprocessor(void)
} }
#endif #endif
#ifdef HAVE_X2APIC
enable_IR_x2apic(); enable_IR_x2apic();
#endif
#ifdef CONFIG_X86_64 #ifdef CONFIG_X86_64
default_setup_apic_routing(); default_setup_apic_routing();
#endif #endif
@ -2021,7 +2021,7 @@ static int lapic_resume(struct sys_device *dev)
local_irq_save(flags); local_irq_save(flags);
#ifdef HAVE_X2APIC #ifdef CONFIG_X86_X2APIC
if (x2apic) if (x2apic)
enable_x2apic(); enable_x2apic();
else else

View file

@ -1051,7 +1051,7 @@ void __cpuinit cpu_init(void)
barrier(); barrier();
check_efer(); check_efer();
if (cpu != 0 && x2apic) if (cpu != 0)
enable_x2apic(); enable_x2apic();
/* /*

View file

@ -35,8 +35,10 @@ static struct genapic *apic_probe[] __initdata = {
#ifdef CONFIG_X86_UV #ifdef CONFIG_X86_UV
&apic_x2apic_uv_x, &apic_x2apic_uv_x,
#endif #endif
#ifdef CONFIG_X86_X2APIC
&apic_x2apic_phys, &apic_x2apic_phys,
&apic_x2apic_cluster, &apic_x2apic_cluster,
#endif
&apic_physflat, &apic_physflat,
NULL, NULL,
}; };
@ -46,10 +48,12 @@ static struct genapic *apic_probe[] __initdata = {
*/ */
void __init default_setup_apic_routing(void) void __init default_setup_apic_routing(void)
{ {
#ifdef CONFIG_X86_X2APIC
if (apic == &apic_x2apic_phys || apic == &apic_x2apic_cluster) { if (apic == &apic_x2apic_phys || apic == &apic_x2apic_cluster) {
if (!intr_remapping_enabled) if (!intr_remapping_enabled)
apic = &apic_flat; apic = &apic_flat;
} }
#endif
if (apic == &apic_flat) { if (apic == &apic_flat) {
if (max_physical_apicid >= 8) if (max_physical_apicid >= 8)

View file

@ -836,7 +836,6 @@ void __init setup_arch(char **cmdline_p)
#else #else
num_physpages = max_pfn; num_physpages = max_pfn;
if (cpu_has_x2apic)
check_x2apic(); check_x2apic();
/* How many end-of-memory variables you have, grandma! */ /* How many end-of-memory variables you have, grandma! */

View file

@ -1128,8 +1128,8 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
current_thread_info()->cpu = 0; /* needed? */ current_thread_info()->cpu = 0; /* needed? */
set_cpu_sibling_map(0); set_cpu_sibling_map(0);
#ifdef CONFIG_X86_64
enable_IR_x2apic(); enable_IR_x2apic();
#ifdef CONFIG_X86_64
default_setup_apic_routing(); default_setup_apic_routing();
#endif #endif