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 "inb $0x21,%al\n\t" \
64 "jmp 1f\n" \
65 "1:\tjmp 1f\n" \
66 "1:\torb $" #mask ",%al\n\t" \
67 "outb %al,$0x21\n\t" \
68 "jmp 1f\n" \
69 "1:\tjmp 1f\n" \
70 "1:\tmovb $0x20,%al\n\t" \
71 "outb %al,$0x20\n\t"
72
73 #define ACK_SECOND(mask) \
74 "inb $0xA1,%al\n\t" \
75 "jmp 1f\n" \
76 "1:\tjmp 1f\n" \
77 "1:\torb $" #mask ",%al\n\t" \
78 "outb %al,$0xA1\n\t" \
79 "jmp 1f\n" \
80 "1:\tjmp 1f\n" \
81 "1:\tmovb $0x20,%al\n\t" \
82 "outb %al,$0xA0\n\t" \
83 "jmp 1f\n" \
84 "1:\tjmp 1f\n" \
85 "1:\toutb %al,$0x20\n\t"
86
87 #define UNBLK_FIRST(mask) \
88 "inb $0x21,%al\n\t" \
89 "jmp 1f\n" \
90 "1:\tjmp 1f\n" \
91 "1:\tandb $~(" #mask "),%al\n\t" \
92 "outb %al,$0x21\n\t"
93
94 #define UNBLK_SECOND(mask) \
95 "inb $0xA1,%al\n\t" \
96 "jmp 1f\n" \
97 "1:\tjmp 1f\n" \
98 "1:\tandb $~(" #mask "),%al\n\t" \
99 "outb %al,$0xA1\n\t"
100
101 #define IRQ_NAME2(nr) nr##_interrupt()
102 #define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
103 #define FAST_IRQ_NAME(nr) IRQ_NAME2(fast_IRQ##nr)
104 #define BAD_IRQ_NAME(nr) IRQ_NAME2(bad_IRQ##nr)
105
106 #define BUILD_IRQ(chip,nr,mask) \
107 void IRQ_NAME(nr); \
108 void FAST_IRQ_NAME(nr); \
109 void BAD_IRQ_NAME(nr); \
110 __asm__( \
111 "\n.align 2\n" \
112 "_IRQ" #nr "_interrupt:\n\t" \
113 "pushl $-1\n\t" \
114 SAVE_ALL \
115 ACK_##chip(mask) \
116 "sti\n\t" \
117 "movl %esp,%ebx\n\t" \
118 "pushl %ebx\n\t" \
119 "pushl $" #nr "\n\t" \
120 "call _do_IRQ\n\t" \
121 "addl $8,%esp\n\t" \
122 "testl %eax,%eax\n\t" \
123 "jne ret_from_sys_call\n\t" \
124 "cli\n\t" \
125 UNBLK_##chip(mask) \
126 "jmp ret_from_sys_call\n" \
127 "\n.align 2\n" \
128 "_fast_IRQ" #nr "_interrupt:\n\t" \
129 SAVE_MOST \
130 ACK_##chip(mask) \
131 "pushl $" #nr "\n\t" \
132 "call _do_fast_IRQ\n\t" \
133 "addl $4,%esp\n\t" \
134 "testl %eax,%eax\n\t" \
135 "jne 2f\n\t" \
136 "cli\n\t" \
137 UNBLK_##chip(mask) \
138 "\n2:\t" \
139 RESTORE_MOST \
140 "\n\n.align 2\n" \
141 "_bad_IRQ" #nr "_interrupt:\n\t" \
142 "pushl %eax\n\t" \
143 ACK_##chip(mask) \
144 "popl %eax\n\t" \
145 "iret");
146
147 #endif