FreeBSD/Linux Kernel Cross Reference
sys/i386/pic.c
1 /*
2 * Mach Operating System
3 * Copyright (c) 1993,1991,1990,1989 Carnegie Mellon University
4 * All Rights Reserved.
5 *
6 * Permission to use, copy, modify and distribute this software and its
7 * documentation is hereby granted, provided that both the copyright
8 * notice and this permission notice appear in all copies of the
9 * software, derivative works or modified versions, and any portions
10 * thereof, and that both notices appear in supporting documentation.
11 *
12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15 *
16 * Carnegie Mellon requests users of this software to return to
17 *
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
22 *
23 * any improvements or extensions that they make and grant Carnegie Mellon
24 * the rights to redistribute these changes.
25 */
26 /*
27 * HISTORY
28 * $Log: pic.c,v $
29 * Revision 2.15 93/11/17 16:38:09 dbg
30 * curr_ipl is now the PIC mask in effect, not the SPL level.
31 * Simplify initialization code: both the PIC ports and the
32 * initialization control words are static.
33 * [93/11/01 dbg]
34 *
35 * Revision 2.14 93/05/15 19:30:35 mrt
36 * machparam.h -> machspl.h
37 *
38 * Revision 2.13 93/05/10 21:18:36 rvb
39 * spl_t fixes.
40 * [93/05/06 11:15:36 af]
41 *
42 * Revision 2.12 93/02/04 07:56:44 danner
43 * Take care of PS2!
44 * [93/01/25 rvb]
45 *
46 * Revision 2.10 91/06/19 11:55:21 rvb
47 * cputypes.h->platforms.h
48 * [91/06/12 13:45:08 rvb]
49 *
50 * Revision 2.9 91/05/14 16:13:44 mrt
51 * Correcting copyright
52 *
53 * Revision 2.8 91/05/08 12:41:18 dbg
54 * Use platforms.h for CPU names.
55 * [91/04/26 14:37:37 dbg]
56 *
57 * Revision 2.7 91/02/05 17:13:46 mrt
58 * Changed to new Mach copyright
59 * [91/02/01 17:36:48 mrt]
60 *
61 * Revision 2.6 90/12/04 14:46:22 jsb
62 * iPSC2 -> iPSC386.
63 * [90/12/04 11:17:35 jsb]
64 *
65 * Revision 2.5 90/11/26 14:48:37 rvb
66 * Change Prime copyright as per Peter J. Weyman authorization.
67 * [90/11/19 rvb]
68 *
69 * Revision 2.2.1.3 90/07/10 11:42:31 rvb
70 * Split out i386 part from bus part.
71 * [90/06/16 rvb]
72 *
73 * Restructure ivect and intpri to be dynamically filled in.
74 * Add iunit for unit no for corresponding pic slot.
75 * [90/06/15 rvb]
76 *
77 * Revision 2.2.1.2 90/03/16 18:14:48 rvb
78 * tidy up some typo's [cameron]
79 * Support 3com 501 ether [bernadat]
80 *
81 * Revision 2.2.1.1 89/10/22 11:31:19 rvb
82 * Flush stuff that belongs in pic.c -- undoe damage of Prime merge.
83 * [89/10/20 rvb]
84 *
85 * Revision 2.2 89/09/25 12:32:30 rvb
86 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Prime Computer, Inc.
87 * [89/09/23 rvb]
88 *
89 */
90
91 /*
92 Copyright (c) 1988,1989 Prime Computer, Inc. Natick, MA 01760
93 All Rights Reserved.
94
95 Permission to use, copy, modify, and distribute this
96 software and its documentation for any purpose and
97 without fee is hereby granted, provided that the above
98 copyright notice appears in all copies and that both the
99 copyright notice and this permission notice appear in
100 supporting documentation, and that the name of Prime
101 Computer, Inc. not be used in advertising or publicity
102 pertaining to distribution of the software without
103 specific, written prior permission.
104
105 THIS SOFTWARE IS PROVIDED "AS IS", AND PRIME COMPUTER,
106 INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
107 SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
108 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN
109 NO EVENT SHALL PRIME COMPUTER, INC. BE LIABLE FOR ANY
110 SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
111 DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
112 PROFITS, WHETHER IN ACTION OF CONTRACT, NEGLIGENCE, OR
113 OTHER TORTIOUS ACTION, ARISING OUR OF OR IN CONNECTION
114 WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
115 */
116
117 #include <platforms.h>
118
119 #include <kern/kern_io.h>
120 #include <i386/ipl.h>
121 #include <i386/pic.h>
122 #include <i386/pio.h>
123 #include <i386/machspl.h>
124
125 unsigned short pic_mask[SPLHI+1] = {
126 /* spl0 */ 0,
127 /* spl1 */ 0,
128 /* spl2 */ 0,
129 /* spl3 */ 0,
130 /* spl4 */ 0,
131 /* spl5 */ 0,
132 /* spl6 */ 0,
133 /* spl7 */ 0,
134 /* SPLHI */0xffff
135 };
136
137 /*
138 * curr_ipl bits 15..0 contain the PIC mask currently
139 * loaded. Bit 31 is 1 if interrupts are masked at
140 * the CPU (IF is set in EFlags).
141 */
142 spl_t curr_ipl;
143
144 #define SPL_IF_CLEAR 0x80000000U
145
146 int iunit[NINTR] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
147
148 int nintr = NINTR;
149 int npics = NPICS;
150
151 /*
152 ** picinit() - This routine
153 ** * Establishes a table of interrupt vectors
154 ** * Establishes a table of interrupt priority levels
155 ** * Establishes a table of interrupt masks to be put
156 ** in the PICs.
157 ** * Establishes location of PICs in the system
158 ** * Initialises them
159 **
160 ** At this stage the interrupt functionality of this system should be
161 ** coplete.
162 **
163 */
164
165
166 /*
167 ** 1. First we form a table of PIC masks - rather than calling form_pic_mask()
168 ** each time there is a change of interrupt level - we will form a table
169 ** of pic masks, as there are only 7 interrupt priority levels.
170 **
171 ** 2. The next thing we must do is to determine which of the PIC interrupt
172 ** request lines have to be masked out, this is done by calling
173 ** form_pic_mask() with a (int_lev) of zero, this will find all the
174 ** interrupt lines that have priority 0, (ie to be ignored).
175 ** Then we split this up for the master/slave PICs.
176 **
177 ** 2. Initialise the PICs , master first, then the slave.
178 ** All the register field definitions are described in pic_jh.h, also
179 ** the settings of these fields for the various registers are selected.
180 **
181 */
182 void form_pic_mask(void); /* forward */
183
184 void picinit(void)
185 {
186 asm("cli");
187
188 /*
189 ** 1. Form pic mask table
190 */
191 #if 0
192 printf (" Let the console driver screw up this line ! \n");
193 #endif
194
195 form_pic_mask();
196
197 /*
198 ** 1a. Select current SPL: block all interrupts.
199 */
200
201 curr_ipl = SPL_IF_CLEAR | pic_mask[SPLHI];
202
203 #ifdef PS2
204 #else /* PS2 */
205 /*
206 ** 3. Select options for each ICW and each OCW for each PIC.
207 */
208
209 #define PICM_ICW1 \
210 (ICW_TEMPLATE | EDGE_TRIGGER | ADDR_INTRVL8 | CASCADE_MODE | ICW4__NEEDED)
211
212 #define PICS_ICW1 \
213 (ICW_TEMPLATE | EDGE_TRIGGER | ADDR_INTRVL8 | CASCADE_MODE | ICW4__NEEDED)
214
215 #define PICM_ICW2 PICM_VECTBASE
216 #define PICS_ICW2 PICS_VECTBASE
217
218 #ifdef AT386
219 #define PICM_ICW3 ( SLAVE_ON_IR2 )
220 #define PICS_ICW3 ( I_AM_SLAVE_2 )
221 #endif /* AT386 */
222
223 #ifdef iPSC386
224 #define PICM_ICW3 ( SLAVE_ON_IR7 )
225 #define PICS_ICW3 ( I_AM_SLAVE_7 )
226 #endif /* iPSC386 */
227
228 #ifdef iPSC386
229 /* Use Buffered mode for iPSC386 */
230 #define PICM_ICW4 \
231 (SNF_MODE_DIS | BUFFERD_MODE | I_AM_A_MASTR | NRML_EOI_MOD | I8086_EMM_MOD)
232 #define PICS_ICW4 \
233 (SNF_MODE_DIS | BUFFERD_MODE | I_AM_A_SLAVE | NRML_EOI_MOD | I8086_EMM_MOD)
234 #else /* iPSC386 */
235 #define PICM_ICW4 \
236 (SNF_MODE_DIS | NONBUFD_MODE | NRML_EOI_MOD | I8086_EMM_MOD)
237 #define PICS_ICW4 \
238 (SNF_MODE_DIS | NONBUFD_MODE | NRML_EOI_MOD | I8086_EMM_MOD)
239 #endif /* iPSC386 */
240
241 #define PICM_OCW1 (curr_ipl & 0x00FF)
242 #define PICS_OCW1 ((curr_ipl & 0xFF00)>>8)
243
244 #define PICM_OCW2 NON_SPEC_EOI
245 #define PICS_OCW2 NON_SPEC_EOI
246
247 #define PICM_OCW3 (OCW_TEMPLATE | READ_NEXT_RD | READ_IS_ONRD )
248 #define PICS_OCW3 (OCW_TEMPLATE | READ_NEXT_RD | READ_IS_ONRD )
249
250
251 /*
252 ** 4. Initialise master - send commands to master PIC
253 */
254
255 outb ( MASTER_ICW, PICM_ICW1 );
256 outb ( MASTER_OCW, PICM_ICW2 );
257 outb ( MASTER_OCW, PICM_ICW3 );
258 outb ( MASTER_OCW, PICM_ICW4 );
259
260 outb ( MASTER_OCW, PICM_MASK );
261 outb ( MASTER_ICW, PICM_OCW3 );
262
263 /*
264 ** 5. Initialise slave - send commands to slave PIC
265 */
266
267 outb ( SLAVE_ICW, PICS_ICW1 );
268 outb ( SLAVE_OCW, PICS_ICW2 );
269 outb ( SLAVE_OCW, PICS_ICW3 );
270 outb ( SLAVE_OCW, PICS_ICW4 );
271
272
273 outb ( SLAVE_OCW, PICS_OCW1 );
274 outb ( SLAVE_ICW, PICS_OCW3 );
275
276 /*
277 ** 6. Initialise interrupts
278 */
279 outb ( MASTER_OCW, PICM_OCW1 );
280
281 #endif /* PS2 */
282
283 #if 0
284 printf(" spl set to %x pic_mask set to %x \n", curr_ipl, curr_pic_mask);
285 #endif
286
287 }
288
289
290 /*
291 ** form_pic_mask(int_lvl)
292 **
293 ** For a given interrupt priority level (int_lvl), this routine goes out
294 ** and scans through the interrupt level table, and forms a mask based on the
295 ** entries it finds there that have the same or lower interrupt priority level
296 ** as (int_lvl). It returns a 16-bit mask which will have to be split up between
297 ** the 2 pics.
298 **
299 */
300
301 #if defined(AT386) || defined(PS2)
302 #define SLAVEMASK (0xFFFF ^ SLAVE_ON_IR2)
303 #endif /* defined(AT386) || defined(PS2) */
304 #ifdef iPSC386
305 #define SLAVEMASK (0xFFFF ^ SLAVE_ON_IR7)
306 #endif iPSC386
307
308 #define SLAVEACTV 0xFF00
309
310 void form_pic_mask(void)
311 {
312 unsigned short i, j, bit, mask;
313
314 for (i=SPL0; i < SPLHI; i++) {
315 for (j=0x00, bit=0x01, mask = 0; j < NINTR; j++, bit<<=1)
316 if (intpri[j] <= i)
317 mask |= bit;
318
319 if ((mask & SLAVEACTV) != SLAVEACTV )
320 mask &= SLAVEMASK;
321
322 pic_mask[i] = mask;
323 }
324 }
325
326 void intnull(int unit_dev)
327 {
328 printf("intnull(%d)\n", unit_dev);
329 }
330
331 int prtnull_count = 0;
332 void prtnull(int unit)
333 {
334 ++prtnull_count;
335 }
Cache object: c5f3e5f7058e778493b6af219aad1137
|