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