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 extern "C" void IRQ_NAME(nr); \
121 extern "C" void FAST_IRQ_NAME(nr); \
122 extern "C" 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 "jmp ret_from_sys_call\n" \
140 "\n.align 4\n" \
141 "_fast_IRQ" #nr "_interrupt:\n\t" \
142 SAVE_MOST \
143 ACK_##chip(mask) \
144 "incl _intr_count\n\t" \
145 "pushl $" #nr "\n\t" \
146 "call _do_fast_IRQ\n\t" \
147 "addl $4,%esp\n\t" \
148 "cli\n\t" \
149 UNBLK_##chip(mask) \
150 "decl _intr_count\n\t" \
151 RESTORE_MOST \
152 "\n\n.align 4\n" \
153 "_bad_IRQ" #nr "_interrupt:\n\t" \
154 SAVE_MOST \
155 ACK_##chip(mask) \
156 RESTORE_MOST);
157
158 #endif