This source file includes following definitions.
- update_mask
- interrupt_unmask
- interrupt_mask
- interrupt_setup
- interrupt_handler
- interrupt_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 #include <sys/ipl.h>
35 #include <kernel.h>
36 #include <irq.h>
37 #include <cpufunc.h>
38 #include <context.h>
39 #include <locore.h>
40 #include <hal.h>
41
42
43
44 #define NIRQS 16
45
46
47 #define PIC_M 0x20
48 #define PIC_S 0xa0
49
50
51 #define ELCR 0x4d0
52
53
54
55
56
57
58
59
60 static volatile int irq_level;
61
62
63
64
65 static int ipl_table[NIRQS];
66 static u_int mask_table[NIPLS];
67
68
69
70
71 static void
72 update_mask(void)
73 {
74 u_int mask = mask_table[irq_level];
75
76 outb(PIC_M + 1, mask & 0xff);
77 outb(PIC_S + 1, mask >> 8);
78 }
79
80
81
82
83
84
85 void
86 interrupt_unmask(int vector, int level)
87 {
88 u_int unmask = (u_int)~(1 << vector);
89 int i, s;
90
91 s = splhigh();
92 ipl_table[vector] = level;
93
94
95
96
97 for (i = 0; i < level; i++)
98 mask_table[i] &= unmask;
99 update_mask();
100 splx(s);
101 }
102
103
104
105
106
107 void
108 interrupt_mask(int vector)
109 {
110 u_int mask = (u_int)(1 << vector);
111 int i, level, s;
112
113 s = splhigh();
114 level = ipl_table[vector];
115 for (i = 0; i < level; i++)
116 mask_table[i] |= mask;
117 ipl_table[vector] = IPL_NONE;
118 update_mask();
119 splx(s);
120 }
121
122
123
124
125
126 void
127 interrupt_setup(int vector, int mode)
128 {
129 int port, s;
130 u_int bit;
131 u_char val;
132
133 s = splhigh();
134 port = vector < 8 ? ELCR : ELCR + 1;
135 bit = (u_int)(1 << (vector & 7));
136
137 val = inb(port);
138 if (mode == IMODE_LEVEL)
139 val |= bit;
140 else
141 val &= ~bit;
142 outb(port, val);
143 splx(s);
144 }
145
146
147
148
149
150
151
152
153
154
155 void
156 interrupt_handler(struct cpu_regs *regs)
157 {
158 int vector = (int)regs->trap_no;
159 int old_ipl, new_ipl;
160
161
162 old_ipl = irq_level;
163 new_ipl = ipl_table[vector];
164 if (new_ipl > old_ipl)
165 irq_level = new_ipl;
166 update_mask();
167
168
169 if (vector & 8)
170 outb(PIC_S, 0x20);
171 outb(PIC_M, 0x20);
172
173
174 splon();
175 irq_handler(vector);
176 sploff();
177
178
179 irq_level = old_ipl;
180 update_mask();
181 }
182
183
184
185
186
187 void
188 interrupt_init(void)
189 {
190 int i;
191
192 irq_level = IPL_NONE;
193
194 for (i = 0; i < NIRQS; i++)
195 ipl_table[i] = IPL_NONE;
196
197 for (i = 0; i < NIPLS; i++)
198 mask_table[i] = 0xfffb;
199
200 outb_p(PIC_M, 0x11);
201 outb_p(PIC_M + 1, 0x20);
202 outb_p(PIC_M + 1, 0x04);
203 outb_p(PIC_M + 1, 0x01);
204
205 outb_p(PIC_S, 0x11);
206 outb_p(PIC_S + 1, 0x28);
207 outb_p(PIC_S + 1, 0x02);
208 outb_p(PIC_S + 1, 0x01);
209
210 outb(PIC_S + 1, 0xff);
211 outb(PIC_M + 1, 0xfb);
212 }
|