Import 2.1.81
[davej-history.git] / arch / i386 / kernel / irq.h
blobf1e2edea530cdb387fe3eaed1c01c610beb0d5fb
1 #ifndef __irq_h
2 #define __irq_h
4 /*
5 * Various low-level irq details needed by irq.c and smp.c
7 * Interrupt entry/exit code at both C and assembly level
8 */
10 #define IO_APIC_GATE_OFFSET 0x51
12 void mask_irq(unsigned int irq_nr);
13 void unmask_irq(unsigned int irq_nr);
14 void enable_IO_APIC_irq (int irq);
15 void disable_IO_APIC_irq (int irq);
16 void set_8259A_irq_mask(int irq_nr);
17 void setup_IO_APIC_irq (int irq);
18 void ack_APIC_irq (void);
19 void setup_IO_APIC (void);
20 void init_IO_APIC_traps(void);
22 #ifdef __SMP__
23 extern unsigned int io_apic_irqs;
24 #else
25 extern const unsigned int io_apic_irqs;
26 #endif
28 #define IO_APIC_IRQ(x) ((1<<x) & io_apic_irqs)
30 #define MAX_IRQ_SOURCES 128
31 #define MAX_MP_BUSSES 32
32 enum mp_bustype {
33 MP_BUS_ISA,
34 MP_BUS_PCI
36 extern int mp_bus_id_to_type [MAX_MP_BUSSES];
38 extern spinlock_t irq_controller_lock; /*
39 * Protects both the 8259 and the
40 * IO-APIC
43 #ifdef __SMP__
45 #include <asm/atomic.h>
47 static inline void irq_enter(int cpu, int irq)
49 hardirq_enter(cpu);
50 while (test_bit(0,&global_irq_lock)) {
51 /* nothing */;
55 static inline void irq_exit(int cpu, int irq)
57 hardirq_exit(cpu);
58 release_irqlock(cpu);
61 #else
63 #define irq_enter(cpu, irq) (++local_irq_count[cpu])
64 #define irq_exit(cpu, irq) (--local_irq_count[cpu])
66 #endif
68 #define __STR(x) #x
69 #define STR(x) __STR(x)
71 #define SAVE_ALL \
72 "cld\n\t" \
73 "push %es\n\t" \
74 "push %ds\n\t" \
75 "pushl %eax\n\t" \
76 "pushl %ebp\n\t" \
77 "pushl %edi\n\t" \
78 "pushl %esi\n\t" \
79 "pushl %edx\n\t" \
80 "pushl %ecx\n\t" \
81 "pushl %ebx\n\t" \
82 "movl $" STR(__KERNEL_DS) ",%edx\n\t" \
83 "mov %dx,%ds\n\t" \
84 "mov %dx,%es\n\t"
86 #define IRQ_NAME2(nr) nr##_interrupt(void)
87 #define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
89 #define GET_CURRENT \
90 "movl %esp, %ebx\n\t" \
91 "andl $-8192, %ebx\n\t"
93 #ifdef __SMP__
96 * SMP has a few special interrupts for IPI messages
99 #define BUILD_SMP_INTERRUPT(x) \
100 asmlinkage void x(void); \
101 __asm__( \
102 "\n"__ALIGN_STR"\n" \
103 SYMBOL_NAME_STR(x) ":\n\t" \
104 "pushl $-1\n\t" \
105 SAVE_ALL \
106 "call "SYMBOL_NAME_STR(smp_##x)"\n\t" \
107 "jmp ret_from_intr\n");
109 #define BUILD_SMP_TIMER_INTERRUPT(x) \
110 asmlinkage void x(struct pt_regs * regs); \
111 __asm__( \
112 "\n"__ALIGN_STR"\n" \
113 SYMBOL_NAME_STR(x) ":\n\t" \
114 "pushl $-1\n\t" \
115 SAVE_ALL \
116 "movl %esp,%eax\n\t" \
117 "pushl %eax\n\t" \
118 "call "SYMBOL_NAME_STR(smp_##x)"\n\t" \
119 "addl $4,%esp\n\t" \
120 "jmp ret_from_intr\n");
122 #endif /* __SMP__ */
124 #define BUILD_COMMON_IRQ() \
125 __asm__( \
126 "\n" __ALIGN_STR"\n" \
127 "common_interrupt:\n\t" \
128 SAVE_ALL \
129 "pushl $ret_from_intr\n\t" \
130 "jmp "SYMBOL_NAME_STR(do_IRQ));
132 #define BUILD_IRQ(nr) \
133 asmlinkage void IRQ_NAME(nr); \
134 __asm__( \
135 "\n"__ALIGN_STR"\n" \
136 SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
137 "pushl $"#nr"-256\n\t" \
138 "jmp common_interrupt");
141 * x86 profiling function, SMP safe. We might want to do this in
142 * assembly totally?
144 static inline void x86_do_profile (unsigned long eip)
146 if (prof_buffer && current->pid) {
147 extern int _stext;
148 eip -= (unsigned long) &_stext;
149 eip >>= prof_shift;
151 * Dont ignore out-of-bounds EIP values silently,
152 * put them into the last histogram slot, so if
153 * present, they will show up as a sharp peak.
155 if (eip > prof_len-1)
156 eip = prof_len-1;
157 atomic_inc((atomic_t *)&prof_buffer[eip]);
161 #endif