1 #ifndef _ASM_IRQ_H
2 #define _ASM_IRQ_H
3
4
5
6
7
8
9
10
11
12 #include <linux/linkage.h>
13 #include <asm/segment.h>
14
15 #define NR_IRQS 16
16
17 #define TIMER_IRQ 0
18
19 extern void disable_irq(unsigned int);
20 extern void enable_irq(unsigned int);
21
22 #define __STR(x) #x
23 #define STR(x) __STR(x)
24
25 #define SAVE_ALL \
26 "cld\n\t" \
27 "push %gs\n\t" \
28 "push %fs\n\t" \
29 "push %es\n\t" \
30 "push %ds\n\t" \
31 "pushl %eax\n\t" \
32 "pushl %ebp\n\t" \
33 "pushl %edi\n\t" \
34 "pushl %esi\n\t" \
35 "pushl %edx\n\t" \
36 "pushl %ecx\n\t" \
37 "pushl %ebx\n\t" \
38 "movl $" STR(KERNEL_DS) ",%edx\n\t" \
39 "mov %dx,%ds\n\t" \
40 "mov %dx,%es\n\t" \
41 "movl $" STR(USER_DS) ",%edx\n\t" \
42 "mov %dx,%fs\n\t" \
43 "movl $0,%edx\n\t" \
44 "movl %edx,%db7\n\t"
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 #define SAVE_MOST \
61 "cld\n\t" \
62 "push %es\n\t" \
63 "push %ds\n\t" \
64 "pushl %eax\n\t" \
65 "pushl %edx\n\t" \
66 "pushl %ecx\n\t" \
67 "movl $" STR(KERNEL_DS) ",%edx\n\t" \
68 "mov %dx,%ds\n\t" \
69 "mov %dx,%es\n\t"
70
71 #define RESTORE_MOST \
72 "popl %ecx\n\t" \
73 "popl %edx\n\t" \
74 "popl %eax\n\t" \
75 "pop %ds\n\t" \
76 "pop %es\n\t" \
77 "iret"
78
79
80
81
82
83
84 #define ACK_FIRST(mask) \
85 "inb $0x21,%al\n\t" \
86 "jmp 1f\n" \
87 "1:\tjmp 1f\n" \
88 "1:\torb $" #mask ","SYMBOL_NAME_STR(cache_21)"\n\t" \
89 "movb "SYMBOL_NAME_STR(cache_21)",%al\n\t" \
90 "outb %al,$0x21\n\t" \
91 "jmp 1f\n" \
92 "1:\tjmp 1f\n" \
93 "1:\tmovb $0x20,%al\n\t" \
94 "outb %al,$0x20\n\t"
95
96 #define ACK_SECOND(mask) \
97 "inb $0xA1,%al\n\t" \
98 "jmp 1f\n" \
99 "1:\tjmp 1f\n" \
100 "1:\torb $" #mask ","SYMBOL_NAME_STR(cache_A1)"\n\t" \
101 "movb "SYMBOL_NAME_STR(cache_A1)",%al\n\t" \
102 "outb %al,$0xA1\n\t" \
103 "jmp 1f\n" \
104 "1:\tjmp 1f\n" \
105 "1:\tmovb $0x20,%al\n\t" \
106 "outb %al,$0xA0\n\t" \
107 "jmp 1f\n" \
108 "1:\tjmp 1f\n" \
109 "1:\toutb %al,$0x20\n\t"
110
111 #define UNBLK_FIRST(mask) \
112 "inb $0x21,%al\n\t" \
113 "jmp 1f\n" \
114 "1:\tjmp 1f\n" \
115 "1:\tandb $~(" #mask "),"SYMBOL_NAME_STR(cache_21)"\n\t" \
116 "movb "SYMBOL_NAME_STR(cache_21)",%al\n\t" \
117 "outb %al,$0x21\n\t"
118
119 #define UNBLK_SECOND(mask) \
120 "inb $0xA1,%al\n\t" \
121 "jmp 1f\n" \
122 "1:\tjmp 1f\n" \
123 "1:\tandb $~(" #mask "),"SYMBOL_NAME_STR(cache_A1)"\n\t" \
124 "movb "SYMBOL_NAME_STR(cache_A1)",%al\n\t" \
125 "outb %al,$0xA1\n\t"
126
127 #define IRQ_NAME2(nr) nr##_interrupt(void)
128 #define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
129 #define FAST_IRQ_NAME(nr) IRQ_NAME2(fast_IRQ##nr)
130 #define BAD_IRQ_NAME(nr) IRQ_NAME2(bad_IRQ##nr)
131
132 #ifdef __SMP__
133
134 #ifndef __SMP_PROF__
135 #define SMP_PROF_INT_SPINS
136 #define SMP_PROF_IPI_CNT
137 #else
138 #define SMP_PROF_INT_SPINS "incl "SYMBOL_NAME_STR(smp_spins)"(,%eax,4)\n\t"
139 #define SMP_PROF_IPI_CNT "incl "SYMBOL_NAME_STR(ipi_count)"\n\t"
140 #endif
141
142 #define GET_PROCESSOR_ID \
143 "movl "SYMBOL_NAME_STR(apic_reg)", %edx\n\t" \
144 "movl 32(%edx), %eax\n\t" \
145 "shrl $24,%eax\n\t" \
146 "andb $0x0F,%al\n"
147
148 #define ENTER_KERNEL \
149 "pushl %eax\n\t" \
150 "pushl %edx\n\t" \
151 "pushfl\n\t" \
152 "cli\n\t" \
153 GET_PROCESSOR_ID \
154 "1: " \
155 "lock\n\t" \
156 "btsl $0, "SYMBOL_NAME_STR(kernel_flag)"\n\t" \
157 "jnc 3f\n\t" \
158 "cmpb "SYMBOL_NAME_STR(active_kernel_processor)", %al\n\t" \
159 "je 4f\n\t" \
160 "2: " \
161 SMP_PROF_INT_SPINS \
162 "btl %al, "SYMBOL_NAME_STR(smp_invalidate_needed)"\n\t" \
163 "jnc 5f\n\t" \
164 "lock\n\t" \
165 "btrl %al, "SYMBOL_NAME_STR(smp_invalidate_needed)"\n\t" \
166 "jnc 5f\n\t" \
167 "movl %cr3,%edx\n\t" \
168 "movl %edx,%cr3\n" \
169 "5: btl $0, "SYMBOL_NAME_STR(kernel_flag)"\n\t" \
170 "jc 2b\n\t" \
171 "jmp 1b\n\t" \
172 "3: " \
173 "movb %al, "SYMBOL_NAME_STR(active_kernel_processor)"\n\t" \
174 "4: " \
175 "incl "SYMBOL_NAME_STR(kernel_counter)"\n\t" \
176 "popfl\n\t" \
177 "popl %edx\n\t" \
178 "popl %eax\n\t"
179
180 #define LEAVE_KERNEL \
181 "pushfl\n\t" \
182 "cli\n\t" \
183 "decl "SYMBOL_NAME_STR(kernel_counter)"\n\t" \
184 "jnz 1f\n\t" \
185 "movb $" STR (NO_PROC_ID) ", "SYMBOL_NAME_STR(active_kernel_processor)"\n\t" \
186 "lock\n\t" \
187 "btrl $0, "SYMBOL_NAME_STR(kernel_flag)"\n\t" \
188 "1: " \
189 "popfl\n\t"
190
191
192
193
194
195
196
197 #define BUILD_IRQ(chip,nr,mask) \
198 asmlinkage void IRQ_NAME(nr); \
199 asmlinkage void FAST_IRQ_NAME(nr); \
200 asmlinkage void BAD_IRQ_NAME(nr); \
201 __asm__( \
202 "\n"__ALIGN_STR"\n" \
203 SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
204 "pushl $-"#nr"-2\n\t" \
205 SAVE_ALL \
206 ENTER_KERNEL \
207 ACK_##chip(mask) \
208 "incl "SYMBOL_NAME_STR(intr_count)"\n\t"\
209 "sti\n\t" \
210 "movl %esp,%ebx\n\t" \
211 "pushl %ebx\n\t" \
212 "pushl $" #nr "\n\t" \
213 "call "SYMBOL_NAME_STR(do_IRQ)"\n\t" \
214 "addl $8,%esp\n\t" \
215 "cli\n\t" \
216 UNBLK_##chip(mask) \
217 "decl "SYMBOL_NAME_STR(intr_count)"\n\t" \
218 "incl "SYMBOL_NAME_STR(syscall_count)"\n\t" \
219 "jmp ret_from_sys_call\n" \
220 "\n"__ALIGN_STR"\n" \
221 SYMBOL_NAME_STR(fast_IRQ) #nr "_interrupt:\n\t" \
222 SAVE_MOST \
223 ENTER_KERNEL \
224 ACK_##chip(mask) \
225 "incl "SYMBOL_NAME_STR(intr_count)"\n\t" \
226 "pushl $" #nr "\n\t" \
227 "call "SYMBOL_NAME_STR(do_fast_IRQ)"\n\t" \
228 "addl $4,%esp\n\t" \
229 "cli\n\t" \
230 UNBLK_##chip(mask) \
231 "decl "SYMBOL_NAME_STR(intr_count)"\n\t" \
232 LEAVE_KERNEL \
233 RESTORE_MOST \
234 "\n"__ALIGN_STR"\n" \
235 SYMBOL_NAME_STR(bad_IRQ) #nr "_interrupt:\n\t" \
236 SAVE_MOST \
237 ENTER_KERNEL \
238 ACK_##chip(mask) \
239 LEAVE_KERNEL \
240 RESTORE_MOST);
241
242
243 #define BUILD_TIMER_IRQ(chip,nr,mask) \
244 asmlinkage void IRQ_NAME(nr); \
245 asmlinkage void FAST_IRQ_NAME(nr); \
246 asmlinkage void BAD_IRQ_NAME(nr); \
247 __asm__( \
248 "\n"__ALIGN_STR"\n" \
249 SYMBOL_NAME_STR(fast_IRQ) #nr "_interrupt:\n\t" \
250 SYMBOL_NAME_STR(bad_IRQ) #nr "_interrupt:\n\t" \
251 SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
252 "pushl $-"#nr"-2\n\t" \
253 SAVE_ALL \
254 ENTER_KERNEL \
255 ACK_##chip(mask) \
256 "incl "SYMBOL_NAME_STR(intr_count)"\n\t"\
257 "movl %esp,%ebx\n\t" \
258 "pushl %ebx\n\t" \
259 "pushl $" #nr "\n\t" \
260 "call "SYMBOL_NAME_STR(do_IRQ)"\n\t" \
261 "addl $8,%esp\n\t" \
262 "cli\n\t" \
263 UNBLK_##chip(mask) \
264 "decl "SYMBOL_NAME_STR(intr_count)"\n\t" \
265 "incl "SYMBOL_NAME_STR(syscall_count)"\n\t" \
266 "jmp ret_from_sys_call\n");
267
268
269
270
271
272
273 #define BUILD_MSGIRQ(chip,nr,mask) \
274 asmlinkage void IRQ_NAME(nr); \
275 asmlinkage void FAST_IRQ_NAME(nr); \
276 asmlinkage void BAD_IRQ_NAME(nr); \
277 __asm__( \
278 "\n"__ALIGN_STR"\n" \
279 SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
280 "pushl $-"#nr"-2\n\t" \
281 SAVE_ALL \
282 ENTER_KERNEL \
283 ACK_##chip(mask) \
284 "incl "SYMBOL_NAME_STR(intr_count)"\n\t"\
285 "sti\n\t" \
286 "movl %esp,%ebx\n\t" \
287 "pushl %ebx\n\t" \
288 "pushl $" #nr "\n\t" \
289 "call "SYMBOL_NAME_STR(do_IRQ)"\n\t" \
290 "addl $8,%esp\n\t" \
291 "cli\n\t" \
292 UNBLK_##chip(mask) \
293 "decl "SYMBOL_NAME_STR(intr_count)"\n\t" \
294 "incl "SYMBOL_NAME_STR(syscall_count)"\n\t" \
295 "jmp ret_from_sys_call\n" \
296 "\n"__ALIGN_STR"\n" \
297 SYMBOL_NAME_STR(fast_IRQ) #nr "_interrupt:\n\t" \
298 SAVE_MOST \
299 ACK_##chip(mask) \
300 SMP_PROF_IPI_CNT \
301 "pushl $" #nr "\n\t" \
302 "call "SYMBOL_NAME_STR(do_fast_IRQ)"\n\t" \
303 "addl $4,%esp\n\t" \
304 "cli\n\t" \
305 UNBLK_##chip(mask) \
306 RESTORE_MOST \
307 "\n"__ALIGN_STR"\n" \
308 SYMBOL_NAME_STR(bad_IRQ) #nr "_interrupt:\n\t" \
309 SAVE_MOST \
310 ACK_##chip(mask) \
311 RESTORE_MOST);
312
313 #define BUILD_RESCHEDIRQ(nr) \
314 asmlinkage void IRQ_NAME(nr); \
315 __asm__( \
316 "\n"__ALIGN_STR"\n" \
317 SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
318 "pushl $-"#nr"-2\n\t" \
319 SAVE_ALL \
320 ENTER_KERNEL \
321 "incl "SYMBOL_NAME_STR(intr_count)"\n\t"\
322 "sti\n\t" \
323 "movl %esp,%ebx\n\t" \
324 "pushl %ebx\n\t" \
325 "pushl $" #nr "\n\t" \
326 "call "SYMBOL_NAME_STR(smp_reschedule_irq)"\n\t" \
327 "addl $8,%esp\n\t" \
328 "cli\n\t" \
329 "decl "SYMBOL_NAME_STR(intr_count)"\n\t" \
330 "incl "SYMBOL_NAME_STR(syscall_count)"\n\t" \
331 "jmp ret_from_sys_call\n");
332 #else
333
334 #define BUILD_IRQ(chip,nr,mask) \
335 asmlinkage void IRQ_NAME(nr); \
336 asmlinkage void FAST_IRQ_NAME(nr); \
337 asmlinkage void BAD_IRQ_NAME(nr); \
338 __asm__( \
339 "\n"__ALIGN_STR"\n" \
340 SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
341 "pushl $-"#nr"-2\n\t" \
342 SAVE_ALL \
343 ACK_##chip(mask) \
344 "incl "SYMBOL_NAME_STR(intr_count)"\n\t"\
345 "sti\n\t" \
346 "movl %esp,%ebx\n\t" \
347 "pushl %ebx\n\t" \
348 "pushl $" #nr "\n\t" \
349 "call "SYMBOL_NAME_STR(do_IRQ)"\n\t" \
350 "addl $8,%esp\n\t" \
351 "cli\n\t" \
352 UNBLK_##chip(mask) \
353 "decl "SYMBOL_NAME_STR(intr_count)"\n\t" \
354 "jmp ret_from_sys_call\n" \
355 "\n"__ALIGN_STR"\n" \
356 SYMBOL_NAME_STR(fast_IRQ) #nr "_interrupt:\n\t" \
357 SAVE_MOST \
358 ACK_##chip(mask) \
359 "incl "SYMBOL_NAME_STR(intr_count)"\n\t" \
360 "pushl $" #nr "\n\t" \
361 "call "SYMBOL_NAME_STR(do_fast_IRQ)"\n\t" \
362 "addl $4,%esp\n\t" \
363 "cli\n\t" \
364 UNBLK_##chip(mask) \
365 "decl "SYMBOL_NAME_STR(intr_count)"\n\t" \
366 RESTORE_MOST \
367 "\n"__ALIGN_STR"\n" \
368 SYMBOL_NAME_STR(bad_IRQ) #nr "_interrupt:\n\t" \
369 SAVE_MOST \
370 ACK_##chip(mask) \
371 RESTORE_MOST);
372
373 #define BUILD_TIMER_IRQ(chip,nr,mask) \
374 asmlinkage void IRQ_NAME(nr); \
375 asmlinkage void FAST_IRQ_NAME(nr); \
376 asmlinkage void BAD_IRQ_NAME(nr); \
377 __asm__( \
378 "\n"__ALIGN_STR"\n" \
379 SYMBOL_NAME_STR(fast_IRQ) #nr "_interrupt:\n\t" \
380 SYMBOL_NAME_STR(bad_IRQ) #nr "_interrupt:\n\t" \
381 SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
382 "pushl $-"#nr"-2\n\t" \
383 SAVE_ALL \
384 ACK_##chip(mask) \
385 "incl "SYMBOL_NAME_STR(intr_count)"\n\t"\
386 "movl %esp,%ebx\n\t" \
387 "pushl %ebx\n\t" \
388 "pushl $" #nr "\n\t" \
389 "call "SYMBOL_NAME_STR(do_IRQ)"\n\t" \
390 "addl $8,%esp\n\t" \
391 "cli\n\t" \
392 UNBLK_##chip(mask) \
393 "decl "SYMBOL_NAME_STR(intr_count)"\n\t" \
394 "jmp ret_from_sys_call\n");
395
396 #endif
397 #endif