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