OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [include/] [asm-i386/] [irq.h] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
#ifndef _ASM_IRQ_H
2
#define _ASM_IRQ_H
3
 
4
/*
5
 *      linux/include/asm/irq.h
6
 *
7
 *      (C) 1992, 1993 Linus Torvalds
8
 *
9
 *      IRQ/IPI changes taken from work by Thomas Radke <tomsoft@informatik.tu-chemnitz.de>
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
 * SAVE_MOST/RESTORE_MOST is used for the faster version of IRQ handlers,
48
 * installed by using the SA_INTERRUPT flag. These kinds of IRQ's don't
49
 * call the routines that do signal handling etc on return, and can have
50
 * more relaxed register-saving etc. They are also atomic, and are thus
51
 * suited for small, fast interrupts like the serial lines or the harddisk
52
 * drivers, which don't actually need signal handling etc.
53
 *
54
 * Also note that we actually save only those registers that are used in
55
 * C subroutines (%eax, %edx and %ecx), so if you do something weird,
56
 * you're on your own. The only segments that are saved (not counting the
57
 * automatic stack and code segment handling) are %ds and %es, and they
58
 * point to kernel space. No messing around with %fs here.
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
 * The "inb" instructions are not needed, but seem to change the timings
81
 * a bit - without them it seems that the harddisk driver won't work on
82
 * all hardware. Arghh.
83
 */
84
#define ACK_FIRST(mask,nr) \
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,nr) \
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
/* do not modify the ISR nor the cache_A1 variable */
112
#define MSGACK_SECOND(mask,nr) \
113
        "inb $0xA1,%al\n\t" \
114
        "jmp 1f\n" \
115
        "1:\tjmp 1f\n" \
116
        "1:\tmovb $0x20,%al\n\t" \
117
        "outb %al,$0xA0\n\t" \
118
        "jmp 1f\n" \
119
        "1:\tjmp 1f\n" \
120
        "1:\toutb %al,$0x20\n\t"
121
 
122
#define UNBLK_FIRST(mask) \
123
        "inb $0x21,%al\n\t" \
124
        "jmp 1f\n" \
125
        "1:\tjmp 1f\n" \
126
        "1:\tandb $~(" #mask "),"SYMBOL_NAME_STR(cache_21)"\n\t" \
127
        "movb "SYMBOL_NAME_STR(cache_21)",%al\n\t" \
128
        "outb %al,$0x21\n\t"
129
 
130
#define UNBLK_SECOND(mask) \
131
        "inb $0xA1,%al\n\t" \
132
        "jmp 1f\n" \
133
        "1:\tjmp 1f\n" \
134
        "1:\tandb $~(" #mask "),"SYMBOL_NAME_STR(cache_A1)"\n\t" \
135
        "movb "SYMBOL_NAME_STR(cache_A1)",%al\n\t" \
136
        "outb %al,$0xA1\n\t"
137
 
138
#define IRQ_NAME2(nr) nr##_interrupt(void)
139
#define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
140
#define FAST_IRQ_NAME(nr) IRQ_NAME2(fast_IRQ##nr)
141
#define BAD_IRQ_NAME(nr) IRQ_NAME2(bad_IRQ##nr)
142
 
143
#ifdef  __SMP__
144
 
145
#ifndef __SMP_PROF__
146
#define SMP_PROF_INT_SPINS 
147
#define SMP_PROF_IPI_CNT 
148
#else
149
#define SMP_PROF_INT_SPINS "incl "SYMBOL_NAME_STR(smp_spins)"(,%eax,4)\n\t"
150
#define SMP_PROF_IPI_CNT "incl "SYMBOL_NAME_STR(ipi_count)"\n\t" 
151
#endif
152
 
153
#define GET_PROCESSOR_ID \
154
        "movl "SYMBOL_NAME_STR(apic_reg)", %edx\n\t" \
155
        "movl 32(%edx), %eax\n\t" \
156
        "shrl $24,%eax\n\t" \
157
        "andl $0x0F,%eax\n"
158
 
159
#define ENTER_KERNEL \
160
        "pushl %eax\n\t" \
161
        "pushl %ebx\n\t" \
162
        "pushl %ecx\n\t" \
163
        "pushl %edx\n\t" \
164
        "pushfl\n\t" \
165
        "cli\n\t" \
166
        "movl $6000, %ebx\n\t" \
167
        "movl "SYMBOL_NAME_STR(smp_loops_per_tick)", %ecx\n\t" \
168
        GET_PROCESSOR_ID \
169
        "btsl $" STR(SMP_FROM_INT) ","SYMBOL_NAME_STR(smp_proc_in_lock)"(,%eax,4)\n\t" \
170
        "1: " \
171
        "lock\n\t" \
172
        "btsl $0, "SYMBOL_NAME_STR(kernel_flag)"\n\t" \
173
        "jnc 3f\n\t" \
174
        "cmpb "SYMBOL_NAME_STR(active_kernel_processor)", %al\n\t" \
175
        "je 4f\n\t" \
176
        "cmpb "SYMBOL_NAME_STR(boot_cpu_id)", %al\n\t" \
177
        "jne 2f\n\t" \
178
        "movb $1, "SYMBOL_NAME_STR(smp_blocked_interrupt_pending)"\n\t" \
179
        "2: " \
180
        SMP_PROF_INT_SPINS \
181
        "btl %eax, "SYMBOL_NAME_STR(smp_invalidate_needed)"\n\t" \
182
        "jnc 5f\n\t" \
183
        "lock\n\t" \
184
        "btrl %eax, "SYMBOL_NAME_STR(smp_invalidate_needed)"\n\t" \
185
        "jnc 5f\n\t" \
186
        "movl %cr3,%edx\n\t" \
187
        "movl %edx,%cr3\n" \
188
        "5: btl $0, "SYMBOL_NAME_STR(kernel_flag)"\n\t" \
189
        "jnc 1b\n\t" \
190
        "cmpb "SYMBOL_NAME_STR(active_kernel_processor)", %al\n\t" \
191
        "je 4f\n\t" \
192
        "decl %ecx\n\t" \
193
        "jne 2b\n\t" \
194
        "decl %ebx\n\t" \
195
        "jne 6f\n\t" \
196
        "call "SYMBOL_NAME_STR(irq_deadlock_detected)"\n\t" \
197
        "6: movl "SYMBOL_NAME_STR(smp_loops_per_tick)", %ecx\n\t" \
198
        "cmpb "SYMBOL_NAME_STR(boot_cpu_id)", %al\n\t" \
199
        "jne 2b\n\t" \
200
        "incl "SYMBOL_NAME_STR(jiffies)"\n\t" \
201
        "jmp 2b\n\t" \
202
        "3: " \
203
        "movb %al, "SYMBOL_NAME_STR(active_kernel_processor)"\n\t" \
204
        "4: " \
205
        "incl "SYMBOL_NAME_STR(kernel_counter)"\n\t" \
206
        "cmpb "SYMBOL_NAME_STR(boot_cpu_id)", %al\n\t" \
207
        "jne 7f\n\t" \
208
        "movb $0, "SYMBOL_NAME_STR(smp_blocked_interrupt_pending)"\n\t" \
209
        "7: " \
210
        "popfl\n\t" \
211
        "popl %edx\n\t" \
212
        "popl %ecx\n\t" \
213
        "popl %ebx\n\t" \
214
        "popl %eax\n\t"
215
 
216
#define LEAVE_KERNEL \
217
        GET_PROCESSOR_ID \
218
        "btrl $" STR(SMP_FROM_INT) ","SYMBOL_NAME_STR(smp_proc_in_lock)"(,%eax,4)\n\t" \
219
        "pushfl\n\t" \
220
        "cli\n\t" \
221
        "decl "SYMBOL_NAME_STR(kernel_counter)"\n\t" \
222
        "jnz 1f\n\t" \
223
        "movb "SYMBOL_NAME_STR(saved_active_kernel_processor)",%al\n\t" \
224
        "movb %al,"SYMBOL_NAME_STR(active_kernel_processor)"\n\t" \
225
        "cmpb $" STR (NO_PROC_ID) ",%al\n\t" \
226
        "jne 1f\n\t" \
227
        "lock\n\t" \
228
        "btrl $0, "SYMBOL_NAME_STR(kernel_flag)"\n\t" \
229
        "1: " \
230
        "popfl\n\t"
231
 
232
 
233
/*
234
 *      the syscall count inc is a gross hack because ret_from_syscall is used by both irq and
235
 *      syscall return paths (urghh).
236
 */
237
 
238
#define BUILD_IRQ(chip,nr,mask) \
239
asmlinkage void IRQ_NAME(nr); \
240
asmlinkage void FAST_IRQ_NAME(nr); \
241
asmlinkage void BAD_IRQ_NAME(nr); \
242
__asm__( \
243
"\n"__ALIGN_STR"\n" \
244
SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
245
        "pushl $-"#nr"-2\n\t" \
246
        SAVE_ALL \
247
        ENTER_KERNEL \
248
        ACK_##chip(mask,(nr&7)) \
249
        "incl "SYMBOL_NAME_STR(intr_count)"\n\t"\
250
        "sti\n\t" \
251
        "movl %esp,%ebx\n\t" \
252
        "pushl %ebx\n\t" \
253
        "pushl $" #nr "\n\t" \
254
        "call "SYMBOL_NAME_STR(do_IRQ)"\n\t" \
255
        "addl $8,%esp\n\t" \
256
        "cli\n\t" \
257
        UNBLK_##chip(mask) \
258
        "decl "SYMBOL_NAME_STR(intr_count)"\n\t" \
259
        "incl "SYMBOL_NAME_STR(syscall_count)"\n\t" \
260
        "jmp ret_from_sys_call\n" \
261
"\n"__ALIGN_STR"\n" \
262
SYMBOL_NAME_STR(fast_IRQ) #nr "_interrupt:\n\t" \
263
        SAVE_MOST \
264
        ENTER_KERNEL \
265
        ACK_##chip(mask,(nr&7)) \
266
        "incl "SYMBOL_NAME_STR(intr_count)"\n\t" \
267
        "pushl $" #nr "\n\t" \
268
        "call "SYMBOL_NAME_STR(do_fast_IRQ)"\n\t" \
269
        "addl $4,%esp\n\t" \
270
        "cli\n\t" \
271
        UNBLK_##chip(mask) \
272
        "decl "SYMBOL_NAME_STR(intr_count)"\n\t" \
273
        LEAVE_KERNEL \
274
        RESTORE_MOST \
275
"\n"__ALIGN_STR"\n" \
276
SYMBOL_NAME_STR(bad_IRQ) #nr "_interrupt:\n\t" \
277
        SAVE_MOST \
278
        ENTER_KERNEL \
279
        ACK_##chip(mask,(nr&7)) \
280
        LEAVE_KERNEL \
281
        RESTORE_MOST);
282
 
283
 
284
#define BUILD_TIMER_IRQ(chip,nr,mask) \
285
asmlinkage void IRQ_NAME(nr); \
286
asmlinkage void FAST_IRQ_NAME(nr); \
287
asmlinkage void BAD_IRQ_NAME(nr); \
288
__asm__( \
289
"\n"__ALIGN_STR"\n" \
290
SYMBOL_NAME_STR(fast_IRQ) #nr "_interrupt:\n\t" \
291
SYMBOL_NAME_STR(bad_IRQ) #nr "_interrupt:\n\t" \
292
SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
293
        "pushl $-"#nr"-2\n\t" \
294
        SAVE_ALL \
295
        ENTER_KERNEL \
296
        ACK_##chip(mask,(nr&7)) \
297
        "incl "SYMBOL_NAME_STR(intr_count)"\n\t"\
298
        "movl %esp,%ebx\n\t" \
299
        "pushl %ebx\n\t" \
300
        "pushl $" #nr "\n\t" \
301
        "call "SYMBOL_NAME_STR(do_IRQ)"\n\t" \
302
        "addl $8,%esp\n\t" \
303
        "cli\n\t" \
304
        UNBLK_##chip(mask) \
305
        "decl "SYMBOL_NAME_STR(intr_count)"\n\t" \
306
        "incl "SYMBOL_NAME_STR(syscall_count)"\n\t" \
307
        "jmp ret_from_sys_call\n");
308
 
309
 
310
/*
311
 *      Message pass must be a fast IRQ..
312
 */
313
 
314
#define BUILD_MSGIRQ(chip,nr,mask) \
315
asmlinkage void IRQ_NAME(nr); \
316
asmlinkage void FAST_IRQ_NAME(nr); \
317
asmlinkage void BAD_IRQ_NAME(nr); \
318
__asm__( \
319
"\n"__ALIGN_STR"\n" \
320
SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
321
SYMBOL_NAME_STR(fast_IRQ) #nr "_interrupt:\n\t" \
322
        SAVE_MOST \
323
        MSGACK_##chip(mask,(nr&7)) \
324
        SMP_PROF_IPI_CNT \
325
        "pushl $" #nr "\n\t" \
326
        "call "SYMBOL_NAME_STR(do_fast_IRQ)"\n\t" \
327
        "addl $4,%esp\n\t" \
328
        "cli\n\t" \
329
        RESTORE_MOST \
330
"\n"__ALIGN_STR"\n" \
331
SYMBOL_NAME_STR(bad_IRQ) #nr "_interrupt:\n\t" \
332
        SAVE_MOST \
333
        ACK_##chip(mask,(nr&7)) \
334
        RESTORE_MOST);
335
 
336
#define BUILD_RESCHEDIRQ(nr) \
337
asmlinkage void 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
        ENTER_KERNEL \
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(smp_reschedule_irq)"\n\t" \
350
        "addl $8,%esp\n\t" \
351
        "cli\n\t" \
352
        "decl "SYMBOL_NAME_STR(intr_count)"\n\t" \
353
        "incl "SYMBOL_NAME_STR(syscall_count)"\n\t" \
354
        "jmp ret_from_sys_call\n");
355
#else
356
 
357
#define BUILD_IRQ(chip,nr,mask) \
358
asmlinkage void IRQ_NAME(nr); \
359
asmlinkage void FAST_IRQ_NAME(nr); \
360
asmlinkage void BAD_IRQ_NAME(nr); \
361
__asm__( \
362
"\n"__ALIGN_STR"\n" \
363
SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
364
        "pushl $-"#nr"-2\n\t" \
365
        SAVE_ALL \
366
        ACK_##chip(mask,(nr&7)) \
367
        "incl "SYMBOL_NAME_STR(intr_count)"\n\t"\
368
        "sti\n\t" \
369
        "movl %esp,%ebx\n\t" \
370
        "pushl %ebx\n\t" \
371
        "pushl $" #nr "\n\t" \
372
        "call "SYMBOL_NAME_STR(do_IRQ)"\n\t" \
373
        "addl $8,%esp\n\t" \
374
        "cli\n\t" \
375
        UNBLK_##chip(mask) \
376
        "decl "SYMBOL_NAME_STR(intr_count)"\n\t" \
377
        "jmp ret_from_sys_call\n" \
378
"\n"__ALIGN_STR"\n" \
379
SYMBOL_NAME_STR(fast_IRQ) #nr "_interrupt:\n\t" \
380
        SAVE_MOST \
381
        ACK_##chip(mask,(nr&7)) \
382
        "incl "SYMBOL_NAME_STR(intr_count)"\n\t" \
383
        "pushl $" #nr "\n\t" \
384
        "call "SYMBOL_NAME_STR(do_fast_IRQ)"\n\t" \
385
        "addl $4,%esp\n\t" \
386
        "cli\n\t" \
387
        UNBLK_##chip(mask) \
388
        "decl "SYMBOL_NAME_STR(intr_count)"\n\t" \
389
        RESTORE_MOST \
390
"\n"__ALIGN_STR"\n" \
391
SYMBOL_NAME_STR(bad_IRQ) #nr "_interrupt:\n\t" \
392
        SAVE_MOST \
393
        ACK_##chip(mask,(nr&7)) \
394
        RESTORE_MOST);
395
 
396
#define BUILD_TIMER_IRQ(chip,nr,mask) \
397
asmlinkage void IRQ_NAME(nr); \
398
asmlinkage void FAST_IRQ_NAME(nr); \
399
asmlinkage void BAD_IRQ_NAME(nr); \
400
__asm__( \
401
"\n"__ALIGN_STR"\n" \
402
SYMBOL_NAME_STR(fast_IRQ) #nr "_interrupt:\n\t" \
403
SYMBOL_NAME_STR(bad_IRQ) #nr "_interrupt:\n\t" \
404
SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
405
        "pushl $-"#nr"-2\n\t" \
406
        SAVE_ALL \
407
        ACK_##chip(mask,(nr&7)) \
408
        "incl "SYMBOL_NAME_STR(intr_count)"\n\t"\
409
        "movl %esp,%ebx\n\t" \
410
        "pushl %ebx\n\t" \
411
        "pushl $" #nr "\n\t" \
412
        "call "SYMBOL_NAME_STR(do_IRQ)"\n\t" \
413
        "addl $8,%esp\n\t" \
414
        "cli\n\t" \
415
        UNBLK_##chip(mask) \
416
        "decl "SYMBOL_NAME_STR(intr_count)"\n\t" \
417
        "jmp ret_from_sys_call\n");
418
 
419
#endif
420
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.