From: Ingo Molnar Date: Fri, 18 Jul 2008 21:00:05 +0000 (+0200) Subject: Merge branch 'x86/apic' into x86/x2apic X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=453c1404c5273a30d715e5a83372a78cff70b6d9;p=linux-beck.git Merge branch 'x86/apic' into x86/x2apic Conflicts: arch/x86/kernel/paravirt.c arch/x86/kernel/smpboot.c arch/x86/kernel/vmi_32.c arch/x86/lguest/boot.c arch/x86/xen/enlighten.c include/asm-x86/apic.h include/asm-x86/paravirt.h Signed-off-by: Ingo Molnar --- 453c1404c5273a30d715e5a83372a78cff70b6d9 diff --cc arch/x86/kernel/io_apic_64.c index 39f0be37e9a1,64a46affd858..116aac365981 --- a/arch/x86/kernel/io_apic_64.c +++ b/arch/x86/kernel/io_apic_64.c @@@ -2049,18 -1735,15 +2051,17 @@@ static inline void __init check_timer(v clear_IO_APIC_pin(0, pin1); goto out; } + if (intr_remapping_enabled) + panic("timer doesn't work through Interrupt-remapped IO-APIC"); clear_IO_APIC_pin(apic1, pin1); if (!no_pin1) - apic_printk(APIC_QUIET,KERN_ERR "..MP-BIOS bug: " + apic_printk(APIC_QUIET, KERN_ERR "..MP-BIOS bug: " "8254 timer not connected to IO-APIC\n"); - apic_printk(APIC_VERBOSE,KERN_INFO - "...trying to set up timer (IRQ0) " - "through the 8259A ... "); - apic_printk(APIC_VERBOSE,"\n..... (found apic %d pin %d) ...", - apic2, pin2); + apic_printk(APIC_QUIET, KERN_INFO "...trying to set up timer " + "(IRQ0) through the 8259A ...\n"); + apic_printk(APIC_QUIET, KERN_INFO + "..... (found apic %d pin %d) ...\n", apic2, pin2); /* * legacy devices should be connected to IO APIC #0 */ diff --cc arch/x86/kernel/vmi_32.c index 237082833c14,0a1b1a9d922d..45c27c4e2a6e --- a/arch/x86/kernel/vmi_32.c +++ b/arch/x86/kernel/vmi_32.c @@@ -904,9 -904,8 +904,8 @@@ static inline int __init activate_vmi(v #endif #ifdef CONFIG_X86_LOCAL_APIC - para_fill(pv_apic_ops.apic_read, APICRead); - para_fill(pv_apic_ops.apic_write, APICWrite); + para_fill(apic_ops->read, APICRead); + para_fill(apic_ops->write, APICWrite); - para_fill(apic_ops->write_atomic, APICWrite); #endif /* diff --cc arch/x86/lguest/boot.c index 675ee7a6475e,0313a5eec412..35c4349cd668 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c @@@ -791,37 -791,6 +791,36 @@@ static u32 lguest_apic_read(u32 reg { return 0; } + +static u64 lguest_apic_icr_read(void) +{ + return 0; +} + +static void lguest_apic_icr_write(u32 low, u32 id) +{ + /* Warn to see if there's any stray references */ + WARN_ON(1); +} + +static void lguest_apic_wait_icr_idle(void) +{ + return; +} + +static u32 lguest_apic_safe_wait_icr_idle(void) +{ + return 0; +} + +static struct apic_ops lguest_basic_apic_ops = { + .read = lguest_apic_read, + .write = lguest_apic_write, - .write_atomic = lguest_apic_write, + .icr_read = lguest_apic_icr_read, + .icr_write = lguest_apic_icr_write, + .wait_icr_idle = lguest_apic_wait_icr_idle, + .safe_wait_icr_idle = lguest_apic_safe_wait_icr_idle, +}; #endif /* STOP! Until an interrupt comes in. */ diff --cc arch/x86/xen/enlighten.c index 402f3e2c7bee,7f26c3718777..008b7b69581e --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@@ -558,38 -558,6 +558,37 @@@ static void xen_apic_write(u32 reg, u3 /* Warn to see if there's any stray references */ WARN_ON(1); } + +static u64 xen_apic_icr_read(void) +{ + return 0; +} + +static void xen_apic_icr_write(u32 low, u32 id) +{ + /* Warn to see if there's any stray references */ + WARN_ON(1); +} + +static void xen_apic_wait_icr_idle(void) +{ + return; +} + +static u32 xen_safe_apic_wait_icr_idle(void) +{ + return 0; +} + +static struct apic_ops xen_basic_apic_ops = { + .read = xen_apic_read, + .write = xen_apic_write, - .write_atomic = xen_apic_write, + .icr_read = xen_apic_icr_read, + .icr_write = xen_apic_icr_write, + .wait_icr_idle = xen_apic_wait_icr_idle, + .safe_wait_icr_idle = xen_safe_apic_wait_icr_idle, +}; + #endif static void xen_flush_tlb(void) diff --cc include/asm-x86/apic.h index fcd2f01277b6,b96460a7190d..300b65e57240 --- a/include/asm-x86/apic.h +++ b/include/asm-x86/apic.h @@@ -55,90 -57,24 +57,77 @@@ extern int disable_apic extern int is_vsmp_box(void); -static inline void native_apic_write(unsigned long reg, u32 v) +static inline void native_apic_mem_write(u32 reg, u32 v) { - *((volatile u32 *)(APIC_BASE + reg)) = v; - } + volatile u32 *addr = (volatile u32 *)(APIC_BASE + reg); - static inline void native_apic_mem_write_atomic(u32 reg, u32 v) - { - (void)xchg((u32 *)(APIC_BASE + reg), v); + alternative_io("movl %0, %1", "xchgl %0, %1", X86_FEATURE_11AP, + ASM_OUTPUT2("=r" (v), "=m" (*addr)), + ASM_OUTPUT2("0" (v), "m" (*addr))); } -static inline u32 native_apic_read(unsigned long reg) +static inline u32 native_apic_mem_read(u32 reg) { return *((volatile u32 *)(APIC_BASE + reg)); } -extern void apic_wait_icr_idle(void); -extern u32 safe_apic_wait_icr_idle(void); +static inline void native_apic_msr_write(u32 reg, u32 v) +{ + if (reg == APIC_DFR || reg == APIC_ID || reg == APIC_LDR || + reg == APIC_LVR) + return; + + wrmsr(APIC_BASE_MSR + (reg >> 4), v, 0); +} + +static inline u32 native_apic_msr_read(u32 reg) +{ + u32 low, high; + + if (reg == APIC_DFR) + return -1; + + rdmsr(APIC_BASE_MSR + (reg >> 4), low, high); + return low; +} + +#ifndef CONFIG_X86_32 +extern int x2apic, x2apic_preenabled; +extern void check_x2apic(void); +extern void enable_x2apic(void); +extern void enable_IR_x2apic(void); +extern void x2apic_icr_write(u32 low, u32 id); +#endif + +struct apic_ops { + u32 (*read)(u32 reg); + void (*write)(u32 reg, u32 v); - void (*write_atomic)(u32 reg, u32 v); + u64 (*icr_read)(void); + void (*icr_write)(u32 low, u32 high); + void (*wait_icr_idle)(void); + u32 (*safe_wait_icr_idle)(void); +}; + +extern struct apic_ops *apic_ops; + +#define apic_read (apic_ops->read) +#define apic_write (apic_ops->write) - #define apic_write_atomic (apic_ops->write_atomic) +#define apic_icr_read (apic_ops->icr_read) +#define apic_icr_write (apic_ops->icr_write) +#define apic_wait_icr_idle (apic_ops->wait_icr_idle) +#define safe_apic_wait_icr_idle (apic_ops->safe_wait_icr_idle) + extern int get_physical_broadcast(void); - #ifdef CONFIG_X86_GOOD_APIC - # define FORCE_READ_AROUND_WRITE 0 - # define apic_read_around(x) - # define apic_write_around(x, y) apic_write((x), (y)) - #else - # define FORCE_READ_AROUND_WRITE 1 - # define apic_read_around(x) apic_read(x) - # define apic_write_around(x, y) apic_write_atomic((x), (y)) - #endif - +#ifdef CONFIG_X86_64 +static inline void ack_x2APIC_irq(void) +{ + /* Docs say use 0 for future compatibility */ + native_apic_msr_write(APIC_EOI, 0); +} +#endif + + static inline void ack_APIC_irq(void) { /* @@@ -149,11 -85,7 +138,11 @@@ */ /* Docs say use 0 for future compatibility */ +#ifdef CONFIG_X86_32 - apic_write_around(APIC_EOI, 0); + apic_write(APIC_EOI, 0); +#else + native_apic_mem_write(APIC_EOI, 0); +#endif } extern int lapic_get_maxlvt(void);