Import 2.1.89
[davej-history.git] / arch / i386 / kernel / irq.h
blob6404bc9e338c26d588c4d90848e0bd8fbc618ed2
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 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
27 enum mp_bustype {
28 MP_BUS_ISA,
29 MP_BUS_PCI
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
38 * IO-APIC
41 #ifdef __SMP__
43 #include <asm/atomic.h>
45 staticinlinevoidirq_enter(int cpu,unsigned int irq)
47 hardirq_enter(cpu);
48 while(test_bit(0,&global_irq_lock)) {
49 /* nothing */;
53 staticinlinevoidirq_exit(int cpu,unsigned int irq)
55 hardirq_exit(cpu);
56 release_irqlock(cpu);
59 #define IO_APIC_IRQ(x) ((1<<x) & io_apic_irqs)
61 #else
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)
72 #endif
74 #define __STR(x) #x
75 #define STR(x) __STR(x)
77 #define SAVE_ALL \
78 "cld\n\t" \
79 "push %es\n\t" \
80 "push %ds\n\t" \
81 "pushl %eax\n\t" \
82 "pushl %ebp\n\t" \
83 "pushl %edi\n\t" \
84 "pushl %esi\n\t" \
85 "pushl %edx\n\t" \
86 "pushl %ecx\n\t" \
87 "pushl %ebx\n\t" \
88 "movl $" STR(__KERNEL_DS)",%edx\n\t" \
89 "mov %dx,%ds\n\t" \
90 "mov %dx,%es\n\t"
92 #define IRQ_NAME2(nr) nr##_interrupt(void)
93 #define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
95 #define GET_CURRENT \
96 "movl %esp, %ebx\n\t" \
97 "andl $-8192, %ebx\n\t"
99 #ifdef __SMP__
102 * SMP has a few special interrupts for IPI messages
105 #define BUILD_SMP_INTERRUPT(x) \
106 asmlinkage void x(void); \
107 __asm__( \
108 "\n"__ALIGN_STR"\n" \
109 SYMBOL_NAME_STR(x)":\n\t" \
110 "pushl $-1\n\t" \
111 SAVE_ALL \
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); \
117 __asm__( \
118 "\n"__ALIGN_STR"\n" \
119 SYMBOL_NAME_STR(x)":\n\t" \
120 "pushl $-1\n\t" \
121 SAVE_ALL \
122 "movl %esp,%eax\n\t" \
123 "pushl %eax\n\t" \
124 "call "SYMBOL_NAME_STR(smp_##x)"\n\t" \
125 "addl $4,%esp\n\t" \
126 "jmp ret_from_intr\n");
128 #endif/* __SMP__ */
130 #define BUILD_COMMON_IRQ() \
131 __asm__( \
132 "\n" __ALIGN_STR"\n" \
133 "common_interrupt:\n\t" \
134 SAVE_ALL \
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); \
140 __asm__( \
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
148 * assembly totally?
150 staticinlinevoidx86_do_profile(unsigned long eip)
152 if(prof_buffer && current->pid) {
153 externint _stext;
154 eip -= (unsigned long) &_stext;
155 eip >>= prof_shift;
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.
161 if(eip > prof_len-1)
162 eip = prof_len-1;
163 atomic_inc((atomic_t *)&prof_buffer[eip]);
167 #endif
close