x86 interrupt entry cleanup
PATCH 1/1 x86 interrupt entry cleanup
This patch cleans up the creation of the interrupt entry asm stubs, moving them to their proper place in entry.S. Note that the old code put the stubs in the .data section instead on the .text section.
Signature · 1 line
Brian Gerst
arch/i386/kernel/entry.S +77 -1
@@ -45,6 +45,7 @@ #include <linux/linkage.h> #include <asm/segment.h> #include <asm/smp.h> +#include <asm/hw_irq.h> EBX = 0x00 ECX = 0x04
@@ -132,6 +133,9 @@ movl $-8192, reg; \ andl %esp, reg +/* + * Call gate entry points + */ ENTRY(lcall7) pushfl # We get a different stack layout with call gates, pushl %eax # which has to be cleaned up later..
@@ -185,6 +189,8 @@ jmp ret_from_sys_call /* + * System call entry point (int $0x80) + * * Return to user mode is not as complex as all this looks, * but we want the default path for a system call return to * go as quickly as possible which is why some of this is
@@ -244,8 +250,15 @@ movl $-ENOSYS,EAX(%esp) jmp ret_from_sys_call +/* + * Interrupt entry points. orig_eax is used to + * specify which vector was called. + */ ALIGN -ENTRY(ret_from_intr) +common_interrupt: + SAVE_ALL + call SYMBOL_NAME(do_IRQ) +ret_from_intr: GET_CURRENT(%ebx) ret_from_exception: movl EFLAGS(%esp),%eax # mix EFLAGS and CS
@@ -254,11 +267,74 @@ jne ret_from_sys_call jmp restore_all +/* + * Build the entries and pointer table with some assembler black magic. + */ +.data +ENTRY(interrupt) +.previous + +irq_vector=0 +ENTRY(irq_entries_start) +.rept NR_IRQS + ALIGN +1: pushl $irq_vector-256 + jmp common_interrupt +.data + .long 1b +.previous + irq_vector=irq_vector+1 +.endr + +#define BUILD_SMP_INTERRUPT(name, nr) \ +ENTRY(name) \ + pushl $nr-256; \ + SAVE_ALL \ + call SYMBOL_NAME(smp_/**/name); \ + jmp ret_from_intr; + +#define BUILD_SMP_TIMER_INTERRUPT(name, nr) \ +ENTRY(name) \ + pushl $nr-256; \ + SAVE_ALL \ + movl %esp,%eax; \ + pushl %eax; \ + call SYMBOL_NAME(smp_/**/name); \ + addl $4,%esp; \ + jmp ret_from_intr; + +/* + * The following vectors are part of the Linux architecture, there + * is no hardware IRQ pin equivalent for them, they are triggered + * through the ICC by us (IPIs) + */ +#ifdef CONFIG_SMP +BUILD_SMP_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR) +BUILD_SMP_INTERRUPT(invalidate_interrupt,INVALIDATE_TLB_VECTOR) +BUILD_SMP_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR) +#endif + +/* + * every pentium local APIC has two 'local interrupts', with a + * soft-definable vector attached to both interrupts, one of + * which is a timer interrupt, the other one is error counter + * overflow. Linux uses the local APIC timer interrupt to get + * a much simpler SMP time architecture: + */ +#ifdef CONFIG_X86_LOCAL_APIC +BUILD_SMP_TIMER_INTERRUPT(apic_timer_interrupt,LOCAL_TIMER_VECTOR) +BUILD_SMP_INTERRUPT(error_interrupt,ERROR_APIC_VECTOR) +BUILD_SMP_INTERRUPT(spurious_interrupt,SPURIOUS_APIC_VECTOR) +#endif + ALIGN reschedule: call SYMBOL_NAME(schedule) # test jmp ret_from_sys_call +/* + * Trap and fault entry points + */ ENTRY(divide_error) pushl $0 # no error code pushl $ SYMBOL_NAME(do_divide_error)
arch/i386/kernel/i8259.c +0 -96
102 lines not on this page · raw message
arch/i386/kernel/io_apic.c +0 -1
@@ -577,7 +577,6 @@return current_vector; } -extern void (*interrupt[NR_IRQS ])(void );static struct hw_interrupt_type ioapic_level_irq_type;static struct hw_interrupt_type ioapic_edge_irq_type;
include/asm-i386/hw_irq.h +21 -92
142 lines not on this page · raw message
include/asm-i386/irq.h +8 -0
@@ -23,7 +23,13 @@* Since vectors 0x00-0x1f are used/reserved for the CPU, * the usable vector space is 0x20-0xff (224 vectors) */ +#ifdef CONFIG_X86_IO_APIC #define NR_IRQS 224 +#else +#define NR_IRQS 16 +#endif + +#ifndef __ASSEMBLY__static __inline__int irq_cannonicalize (int irq) {
@@ -33,6 +39,8 @@extern void disable_irq (unsigned int );extern void disable_irq_nosync (unsigned int );extern void enable_irq (unsigned int ); + +#endif /* __ASSEMBLY__ */ #ifdef CONFIG_X86_LOCAL_APIC #define ARCH_HAS_NMI_WATCHDOG /* See include/linux/nmi.h */