1 #ifndef _ASM_IRQ_H
2 #define _ASM_IRQ_H
3
4
5
6
7
8
9
10 #include <linux/segment.h>
11 #include <linux/linkage.h>
12
13 extern void disable_irq(unsigned int);
14 extern void enable_irq(unsigned int);
15
16 #define __STR(x) #x
17 #define STR(x) __STR(x)
18
19 #define SAVE_ALL \
20 "cld\n\t" \
21 "push %gs\n\t" \
22 "push %fs\n\t" \
23 "push %es\n\t" \
24 "push %ds\n\t" \
25 "pushl %eax\n\t" \
26 "pushl %ebp\n\t" \
27 "pushl %edi\n\t" \
28 "pushl %esi\n\t" \
29 "pushl %edx\n\t" \
30 "pushl %ecx\n\t" \
31 "pushl %ebx\n\t" \
32 "movl $" STR(KERNEL_DS) ",%edx\n\t" \
33 "mov %dx,%ds\n\t" \
34 "mov %dx,%es\n\t" \
35 "movl $" STR(USER_DS) ",%edx\n\t" \
36 "mov %dx,%fs\n\t"
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 #define SAVE_MOST \
53 "cld\n\t" \
54 "push %es\n\t" \
55 "push %ds\n\t" \
56 "pushl %eax\n\t" \
57 "pushl %edx\n\t" \
58 "pushl %ecx\n\t" \
59 "movl $" STR(KERNEL_DS) ",%edx\n\t" \
60 "mov %dx,%ds\n\t" \
61 "mov %dx,%es\n\t"
62
63 #define RESTORE_MOST \
64 "popl %ecx\n\t" \
65 "popl %edx\n\t" \
66 "popl %eax\n\t" \
67 "pop %ds\n\t" \
68 "pop %es\n\t" \
69 "iret"
70
71
72
73
74
75
76 #define ACK_FIRST(mask) \
77 "inb $0x21,%al\n\t" \
78 "jmp 1f\n" \
79 "1:\tjmp 1f\n" \
80 "1:\torb $" #mask ",_cache_21\n\t" \
81 "movb _cache_21,%al\n\t" \
82 "outb %al,$0x21\n\t" \
83 "jmp 1f\n" \
84 "1:\tjmp 1f\n" \
85 "1:\tmovb $0x20,%al\n\t" \
86 "outb %al,$0x20\n\t"
87
88 #define ACK_SECOND(mask) \
89 "inb $0xA1,%al\n\t" \
90 "jmp 1f\n" \
91 "1:\tjmp 1f\n" \
92 "1:\torb $" #mask ",_cache_A1\n\t" \
93 "movb _cache_A1,%al\n\t" \
94 "outb %al,$0xA1\n\t" \
95 "jmp 1f\n" \
96 "1:\tjmp 1f\n" \
97 "1:\tmovb $0x20,%al\n\t" \
98 "outb %al,$0xA0\n\t" \
99 "jmp 1f\n" \
100 "1:\tjmp 1f\n" \
101 "1:\toutb %al,$0x20\n\t"
102
103 #define UNBLK_FIRST(mask) \
104 "inb $0x21,%al\n\t" \
105 "jmp 1f\n" \
106 "1:\tjmp 1f\n" \
107 "1:\tandb $~(" #mask "),_cache_21\n\t" \
108 "movb _cache_21,%al\n\t" \
109 "outb %al,$0x21\n\t"
110
111 #define UNBLK_SECOND(mask) \
112 "inb $0xA1,%al\n\t" \
113 "jmp 1f\n" \
114 "1:\tjmp 1f\n" \
115 "1:\tandb $~(" #mask "),_cache_A1\n\t" \
116 "movb _cache_A1,%al\n\t" \
117 "outb %al,$0xA1\n\t"
118
119 #define IRQ_NAME2(nr) nr##_interrupt(void)
120 #define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
121 #define FAST_IRQ_NAME(nr) IRQ_NAME2(fast_IRQ##nr)
122 #define BAD_IRQ_NAME(nr) IRQ_NAME2(bad_IRQ##nr)
123
124 #define BUILD_IRQ(chip,nr,mask) \
125 asmlinkage void IRQ_NAME(nr); \
126 asmlinkage void FAST_IRQ_NAME(nr); \
127 asmlinkage void BAD_IRQ_NAME(nr); \
128 __asm__( \
129 "\n.align 4\n" \
130 "_IRQ" #nr "_interrupt:\n\t" \
131 "pushl $-"#nr"-2\n\t" \
132 SAVE_ALL \
133 ACK_##chip(mask) \
134 "incl _intr_count\n\t"\
135 "sti\n\t" \
136 "movl %esp,%ebx\n\t" \
137 "pushl %ebx\n\t" \
138 "pushl $" #nr "\n\t" \
139 "call _do_IRQ\n\t" \
140 "addl $8,%esp\n\t" \
141 "cli\n\t" \
142 UNBLK_##chip(mask) \
143 "decl _intr_count\n\t" \
144 "jmp ret_from_sys_call\n" \
145 "\n.align 4\n" \
146 "_fast_IRQ" #nr "_interrupt:\n\t" \
147 SAVE_MOST \
148 ACK_##chip(mask) \
149 "incl _intr_count\n\t" \
150 "pushl $" #nr "\n\t" \
151 "call _do_fast_IRQ\n\t" \
152 "addl $4,%esp\n\t" \
153 "cli\n\t" \
154 UNBLK_##chip(mask) \
155 "decl _intr_count\n\t" \
156 RESTORE_MOST \
157 "\n\n.align 4\n" \
158 "_bad_IRQ" #nr "_interrupt:\n\t" \
159 SAVE_MOST \
160 ACK_##chip(mask) \
161 RESTORE_MOST);
162
163 #endif