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