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 #define ACK_FIRST(mask) \
63 "orb $" #mask ",_cache_21\n\t" \
64 "movb _cache_21,%al\n\t" \
65 "outb %al,$0x21\n\t" \
66 "jmp 1f\n" \
67 "1:\tjmp 1f\n" \
68 "1:\tmovb $0x20,%al\n\t" \
69 "outb %al,$0x20\n\t"
70
71 #define ACK_SECOND(mask) \
72 "orb $" #mask ",_cache_A1\n\t" \
73 "movb _cache_A1,%al\n\t" \
74 "outb %al,$0xA1\n\t" \
75 "jmp 1f\n" \
76 "1:\tjmp 1f\n" \
77 "1:\tmovb $0x20,%al\n\t" \
78 "outb %al,$0xA0\n\t" \
79 "jmp 1f\n" \
80 "1:\tjmp 1f\n" \
81 "1:\toutb %al,$0x20\n\t"
82
83 #define UNBLK_FIRST(mask) \
84 "andb $~(" #mask "),_cache_21\n\t" \
85 "movb _cache_21,%al\n\t" \
86 "outb %al,$0x21\n\t"
87
88 #define UNBLK_SECOND(mask) \
89 "andb $~(" #mask "),_cache_A1\n\t" \
90 "movb _cache_A1,%al\n\t" \
91 "outb %al,$0xA1\n\t"
92
93 #define IRQ_NAME2(nr) nr##_interrupt()
94 #define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
95 #define FAST_IRQ_NAME(nr) IRQ_NAME2(fast_IRQ##nr)
96 #define BAD_IRQ_NAME(nr) IRQ_NAME2(bad_IRQ##nr)
97
98 #define BUILD_IRQ(chip,nr,mask) \
99 void IRQ_NAME(nr); \
100 void FAST_IRQ_NAME(nr); \
101 void BAD_IRQ_NAME(nr); \
102 __asm__( \
103 "\n.align 4\n" \
104 "_IRQ" #nr "_interrupt:\n\t" \
105 "pushl $-"#nr"-2\n\t" \
106 SAVE_ALL \
107 ACK_##chip(mask) \
108 "incl _intr_count\n\t"\
109 "sti\n\t" \
110 "movl %esp,%ebx\n\t" \
111 "pushl %ebx\n\t" \
112 "pushl $" #nr "\n\t" \
113 "call _do_IRQ\n\t" \
114 "addl $8,%esp\n\t" \
115 "cli\n\t" \
116 UNBLK_##chip(mask) \
117 "decl _intr_count\n\t" \
118 "jne ret_from_sys_call\n\t" \
119 "movl _bh_mask,%eax\n\t" \
120 "andl _bh_active,%eax\n\t" \
121 "je ret_from_sys_call\n\t" \
122 "incl _intr_count\n\t" \
123 "sti\n\t" \
124 "bsfl %eax,%eax\n\t" \
125 "btrl %eax,_bh_active\n\t" \
126 "pushl %eax\n\t" \
127 "call _do_bottom_half\n\t" \
128 "addl $4,%esp\n\t" \
129 "cli\n\t" \
130 "decl _intr_count\n\t" \
131 "jmp ret_from_sys_call\n" \
132 "\n.align 4\n" \
133 "_fast_IRQ" #nr "_interrupt:\n\t" \
134 SAVE_MOST \
135 ACK_##chip(mask) \
136 "incl _intr_count\n\t" \
137 "pushl $" #nr "\n\t" \
138 "call _do_fast_IRQ\n\t" \
139 "addl $4,%esp\n\t" \
140 "cli\n\t" \
141 UNBLK_##chip(mask) \
142 "decl _intr_count\n\t" \
143 "jne 1f\n\t" \
144 "movl _bh_mask,%eax\n\t" \
145 "andl _bh_active,%eax\n\t" \
146 "jne 2f\n" \
147 "1:\t" \
148 RESTORE_MOST \
149 "\n.align 4\n" \
150 "2:\tincl _intr_count\n\t" \
151 "sti\n\t" \
152 "bsfl %eax,%eax\n\t" \
153 "btrl %eax,_bh_active\n\t" \
154 "pushl %eax\n\t" \
155 "call _do_bottom_half\n\t" \
156 "addl $4,%esp\n\t" \
157 "cli\n\t" \
158 "decl _intr_count\n\t" \
159 RESTORE_MOST \
160 "\n\n.align 4\n" \
161 "_bad_IRQ" #nr "_interrupt:\n\t" \
162 "pushl %eax\n\t" \
163 ACK_##chip(mask) \
164 "popl %eax\n\t" \
165 "iret");
166
167 #endif