X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fi386%2Fkernel%2Fapic-xen.c;h=d9122b7e242a0e828f588885ca3639ba3a2f8f96;hb=refs%2Fheads%2Fvserver;hp=ecd4b69f02c3af746fa46e6927760d5dc984b933;hpb=1db395853d4f30d6120458bd279ede1f882a8525;p=linux-2.6.git diff --git a/arch/i386/kernel/apic-xen.c b/arch/i386/kernel/apic-xen.c index ecd4b69f0..d9122b7e2 100644 --- a/arch/i386/kernel/apic-xen.c +++ b/arch/i386/kernel/apic-xen.c @@ -14,7 +14,6 @@ * Mikael Pettersson : PM converted to driver model. */ -#include #include #include @@ -36,6 +35,7 @@ #include #include #include +#include #include #include @@ -54,14 +54,25 @@ static cpumask_t timer_bcast_ipi; /* * Knob to control our willingness to enable the local APIC. */ -int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */ +static int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */ + +static inline void lapic_disable(void) +{ + enable_local_apic = -1; + clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); +} + +static inline void lapic_enable(void) +{ + enable_local_apic = 1; +} /* * Debug level */ int apic_verbosity; -int modern_apic(void) +static int modern_apic(void) { #ifndef CONFIG_XEN unsigned int lvr, version; @@ -97,6 +108,43 @@ void ack_bad_irq(unsigned int irq) ack_APIC_irq(); } +#ifndef CONFIG_XEN +void __init apic_intr_init(void) +{ +#ifdef CONFIG_SMP + smp_intr_init(); +#endif + /* self generated IPI for local APIC timer */ + set_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt); + + /* IPI vectors for APIC spurious and error interrupts */ + set_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt); + set_intr_gate(ERROR_APIC_VECTOR, error_interrupt); + + /* thermal monitor LVT interrupt */ +#ifdef CONFIG_X86_MCE_P4THERMAL + set_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt); +#endif +} + +/* Using APIC to generate smp_local_timer_interrupt? */ +int using_apic_timer __read_mostly = 0; + +static int enabled_via_apicbase; + +void enable_NMI_through_LVT0 (void * dummy) +{ + unsigned int v, ver; + + ver = apic_read(APIC_LVR); + ver = GET_APIC_VERSION(ver); + v = APIC_DM_NMI; /* unmask and set to NMI */ + if (!APIC_INTEGRATED(ver)) /* 82489DX */ + v |= APIC_LVT_LEVEL_TRIGGER; + apic_write_around(APIC_LVT0, v); +} +#endif /* !CONFIG_XEN */ + int get_physical_broadcast(void) { if (modern_apic()) @@ -107,7 +155,7 @@ int get_physical_broadcast(void) #ifndef CONFIG_XEN #ifndef CONFIG_SMP -static void up_apic_timer_interrupt_call(struct pt_regs *regs) +static void up_apic_timer_interrupt_call(void) { int cpu = smp_processor_id(); @@ -116,11 +164,11 @@ static void up_apic_timer_interrupt_call(struct pt_regs *regs) */ per_cpu(irq_stat, cpu).apic_timer_irqs++; - smp_local_timer_interrupt(regs); + smp_local_timer_interrupt(); } #endif -void smp_send_timer_broadcast_ipi(struct pt_regs *regs) +void smp_send_timer_broadcast_ipi(void) { cpumask_t mask; @@ -133,7 +181,7 @@ void smp_send_timer_broadcast_ipi(struct pt_regs *regs) * We can directly call the apic timer interrupt handler * in UP case. Minus all irq related functions */ - up_apic_timer_interrupt_call(regs); + up_apic_timer_interrupt_call(); #endif } } @@ -158,3 +206,18 @@ int __init APIC_init_uniprocessor (void) return 0; } + +static int __init parse_lapic(char *arg) +{ + lapic_enable(); + return 0; +} +early_param("lapic", parse_lapic); + +static int __init parse_nolapic(char *arg) +{ + lapic_disable(); + return 0; +} +early_param("nolapic", parse_nolapic); +