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