5 * Various low-level irq details needed by irq.c and smp.c 7 * Interrupt entry/exit code at both C and assembly level 10 #define IO_APIC_GATE_OFFSET 0x51 12 voidmask_irq(unsigned int irq
); 13 voidunmask_irq(unsigned int irq
); 14 voidenable_IO_APIC_irq(unsigned int irq
); 15 voiddisable_IO_APIC_irq(unsigned int irq
); 16 voidset_8259A_irq_mask(unsigned int irq
); 17 voidack_APIC_irq(void); 18 voidsetup_IO_APIC(void); 19 voidinit_IO_APIC_traps(void); 20 intIO_APIC_get_PCI_irq_vector(int bus
,int slot
,int fn
); 21 voidmake_8259A_irq(unsigned int irq
); 23 externunsigned int io_apic_irqs
; 25 #define MAX_IRQ_SOURCES 128 26 #define MAX_MP_BUSSES 32 31 externint mp_bus_id_to_type
[MAX_MP_BUSSES
]; 32 externint mp_bus_id_to_pci_bus
[MAX_MP_BUSSES
]; 33 externchar ioapic_OEM_ID
[16]; 34 externchar ioapic_Product_ID
[16]; 36 extern spinlock_t irq_controller_lock
;/* 37 * Protects both the 8259 and the 43 #include <asm/atomic.h> 45 staticinlinevoidirq_enter(int cpu
,unsigned int irq
) 48 while(test_bit(0,&global_irq_lock
)) { 53 staticinlinevoidirq_exit(int cpu
,unsigned int irq
) 59 #define IO_APIC_IRQ(x) ((1<<x) & io_apic_irqs) 63 #define irq_enter(cpu, irq) (++local_irq_count[cpu]) 64 #define irq_exit(cpu, irq) (--local_irq_count[cpu]) 66 /* Make these no-ops when not using SMP */ 67 #define enable_IO_APIC_irq(x) do { } while (0) 68 #define disable_IO_APIC_irq(x) do { } while (0) 70 #define IO_APIC_IRQ(x) (0) 75 #define STR(x) __STR(x) 88 "movl $" STR(__KERNEL_DS)",%edx\n\t" \ 92 #define IRQ_NAME2(nr) nr##_interrupt(void) 93 #define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr) 96 "movl %esp, %ebx\n\t" \ 97 "andl $-8192, %ebx\n\t" 102 * SMP has a few special interrupts for IPI messages 105 #define BUILD_SMP_INTERRUPT(x) \ 106 asmlinkage void x(void); \ 108 "\n"__ALIGN_STR"\n" \ 109 SYMBOL_NAME_STR(x)":\n\t" \ 112 "call "SYMBOL_NAME_STR(smp_##x)"\n\t" \ 113 "jmp ret_from_intr\n"); 115 #define BUILD_SMP_TIMER_INTERRUPT(x) \ 116 asmlinkage void x(struct pt_regs * regs); \ 118 "\n"__ALIGN_STR"\n" \ 119 SYMBOL_NAME_STR(x)":\n\t" \ 122 "movl %esp,%eax\n\t" \ 124 "call "SYMBOL_NAME_STR(smp_##x)"\n\t" \ 126 "jmp ret_from_intr\n"); 130 #define BUILD_COMMON_IRQ() \ 132 "\n" __ALIGN_STR"\n" \ 133 "common_interrupt:\n\t" \ 135 "pushl $ret_from_intr\n\t" \ 136 "jmp "SYMBOL_NAME_STR(do_IRQ)); 138 #define BUILD_IRQ(nr) \ 139 asmlinkage void IRQ_NAME(nr); \ 141 "\n"__ALIGN_STR"\n" \ 142 SYMBOL_NAME_STR(IRQ) #nr"_interrupt:\n\t" \ 143 "pushl $"#nr"-256\n\t" \ 144 "jmp common_interrupt"); 147 * x86 profiling function, SMP safe. We might want to do this in 150 staticinlinevoidx86_do_profile(unsigned long eip
) 152 if(prof_buffer
&& current
->pid
) { 154 eip
-= (unsigned long) &_stext
; 157 * Dont ignore out-of-bounds EIP values silently, 158 * put them into the last histogram slot, so if 159 * present, they will show up as a sharp peak. 163 atomic_inc((atomic_t
*)&prof_buffer
[eip
]);