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