1 /*
2 * Mach Operating System
3 * Copyright (c) 1991,1990,1989 Carnegie Mellon University
4 * Copyright (c) 1991 IBM Corporation
5 * All Rights Reserved.
6 *
7 * Permission to use, copy, modify and distribute this software and its
8 * documentation is hereby granted, provided that both the copyright
9 * notice and this permission notice appear in all copies of the
10 * software, derivative works or modified versions, and any portions
11 * thereof, and that both notices appear in supporting documentation,
12 * and that the name IBM not be used in advertising or publicity
13 * pertaining to distribution of the software without specific, written
14 * prior permission.
15 *
16 * CARNEGIE MELLON AND IBM ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
17 * CONDITION. CARNEGIE MELLON AND IBM DISCLAIM ANY LIABILITY OF ANY KIND FOR
18 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
19 *
20 * Carnegie Mellon requests users of this software to return to
21 *
22 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
23 * School of Computer Science
24 * Carnegie Mellon University
25 * Pittsburgh PA 15213-3890
26 *
27 * any improvements or extensions that they make and grant Carnegie Mellon
28 * the rights to redistribute these changes.
29 */
30
31 /*
32 * HISTORY
33 * $Log: autoconf.c,v $
34 * Revision 2.2 93/02/04 07:58:55 danner
35 * Integrate PS2 code from IBM.
36 * [93/01/18 prithvi]
37 *
38 * Revision 1.7.1.8 90/11/27 13:40:50 rvb
39 * Synched 2.5 & 3.0 at I386q (r1.7.1.8) & XMK35 (r2.4)
40 * [90/11/15 rvb]
41 *
42 * Revision 2.3 90/10/01 14:22:53 jeffreyh
43 * added wd ethernet driver
44 * [90/09/27 18:23:07 jeffreyh]
45 *
46 * Revision 1.7.1.7 90/08/25 15:42:34 rvb
47 * Define take_<>_irq() vs direct manipulations of ivect and friends.
48 * Replace single Ctlr[] with one per Ctlr type.
49 * [90/08/20 rvb]
50 *
51 * Added parallel port printer driver.
52 * [90/08/14 mg32]
53 *
54 * Revision 1.7.1.6 90/07/27 11:22:57 rvb
55 * Move wd8003 IRQ to IRQ9.
56 * [90/07/26 rvb]
57 *
58 * Revision 1.7.1.5 90/07/10 11:41:45 rvb
59 * iPSC2: subtype and call dcminit().
60 * [90/06/16 rvb]
61 *
62 * Rework probe and attach to be much more bsd flavored.
63 * [90/06/07 rvb]
64 *
65 * Revision 1.7.1.4 90/06/07 08:04:46 rvb
66 * updated for new hd driver probe/attach [eugene]
67 * (Temporarily disabled.)
68 *
69 * Revision 1.7.1.3 90/05/14 13:17:45 rvb
70 * Copy in slave_config() from loose_ends.c
71 * [90/04/23 rvb]
72 *
73 * Revision 2.2 90/05/03 15:40:37 dbg
74 * Converted for pure kernel.
75 * [90/04/23 dbg]
76 *
77 * Revision 1.7.1.2 90/03/16 18:14:51 rvb
78 * Add 3com 3c501 ether [bernadat]
79 * Also clean up things, at least for ether; there are NO
80 * controllers -- just devices.
81 *
82 * Revision 1.7.1.1 89/10/22 11:29:41 rvb
83 * Call setconf for generic kernels.
84 * [89/10/17 rvb]
85 *
86 * Revision 1.7 89/09/20 17:26:26 rvb
87 * Support ln for ORC
88 * [89/09/20 rvb]
89 *
90 * Revision 1.6 89/09/09 15:19:19 rvb
91 * pc586, qd and com are now configured based on the appropriate .h
92 * files and pccom -> com.
93 * [89/09/09 rvb]
94 *
95 * Revision 1.5 89/07/17 10:34:58 rvb
96 * Olivetti Changes to X79 upto 5/9/89:
97 * An almost legitimate probe routine().
98 * [89/07/11 rvb]
99 *
100 * Revision 1.4 89/02/26 12:25:02 gm0w
101 * Changes for cleanup.
102 *
103 */
104
105 #include <platforms.h>
106 #ifdef MACH_KERNEL
107 #include <sys/types.h>
108 #else MACH_KERNEL
109 #include <cpus.h>
110 #include <cputypes.h>
111 #include <generic.h>
112 #include <sys/param.h>
113 #include <mach/machine.h>
114 #include <machine/cpu.h>
115 #include <sys/dk.h>
116 #endif MACH_KERNEL
117 #include <i386/ipl.h>
118 #include <i386ps2/bus.h>
119
120 extern struct isa_dev Devs[];
121 extern struct isa_ctlr Ctlrs[];
122
123 /*
124 * probeio:
125 *
126 * Probe and subsequently attach devices out on the i386 bus.
127 *
128 * We do this by looking at the Devs array, and doing controller
129 * probe's for all the controllers that are pointed to by the
130 * devices. Strictly speaking we probably should use the Ctrl's
131 * array but this will suffice for now.
132 *
133 */
134 probeio()
135
136 {
137 struct isa_dev *dev_p;
138 struct isa_driver *drv_p;
139 struct isa_ctlr *ctl_p;
140 int result;
141 int dkn = 0;
142
143 /*
144 * loop the the controller structures and if probe returns
145 * that the device exists then it is available to
146 * have slaves attached to it.
147 */
148 for (ctl_p = Ctlrs; drv_p = ctl_p->ctlr_driver; ctl_p++) {
149 if ((*drv_p->driver_probe)(ctl_p->ctlr_addr, ctl_p))
150 ctl_p->ctlr_alive = 1;
151 else
152 continue;
153 if (drv_p->driver_minfo)
154 drv_p->driver_minfo[ctl_p->ctlr_ctlr] = ctl_p;
155 printf("%s%d controller at %x irq %d spl %d\n",
156 drv_p->driver_mname ? drv_p->driver_mname : "??",
157 ctl_p->ctlr_ctlr,
158 ctl_p->ctlr_addr,
159 ctl_p->ctlr_pic,
160 ctl_p->ctlr_spl);
161 }
162 for (dev_p = Devs; drv_p = dev_p->dev_driver; dev_p++) {
163 ctl_p = dev_p->dev_mi;
164 #ifdef DEBUG
165 printf("%s%d\n", drv_p->driver_dname, dev_p->dev_unit);
166 #endif DEBUG
167 /*
168 * if the device has a controller then skip it if the controller
169 * isn't alive.
170 */
171 if ((int)ctl_p && !ctl_p->ctlr_alive)
172 continue;
173 /*
174 * if it has a controller then we call the slave routine
175 * otherwise we call the probe routine. In either case if
176 * it is there we call the attach routine.
177 */
178 if ((int)ctl_p)
179 result = (*drv_p->driver_slave)(dev_p, dev_p->dev_addr);
180 else
181 result = (*drv_p->driver_probe)(dev_p->dev_addr, dev_p);
182 if (result) {
183 dev_p->dev_alive = 1;
184 if (drv_p->driver_dinfo)
185 drv_p->driver_dinfo[dev_p->dev_unit] = dev_p;
186 if (ctl_p) {
187 #ifndef MACH_KERNEL
188 if (dev_p->dev_dk && dkn < DK_NDRIVE)
189 dev_p->dev_dk = dkn++;
190 else
191 dev_p->dev_dk = -1;
192 #endif MACH_KERNEL
193
194 printf("%s%d at %s%d slave %d\n",
195 drv_p->driver_dname? drv_p->driver_dname : "??",
196 dev_p->dev_unit,
197 drv_p->driver_mname ? drv_p->driver_mname : "??",
198 dev_p->dev_ctlr,
199 dev_p->dev_slave);
200 } else {
201 printf("%s%d adapter at %x irq %d spl %d\n",
202 drv_p->driver_dname? drv_p->driver_dname : "??",
203 dev_p->dev_unit,
204 dev_p->dev_addr, dev_p->dev_pic,
205 dev_p->dev_spl);
206 }
207 (*drv_p->driver_attach)(dev_p);
208 }
209 }
210 }
211
212 take_dev_irq(dev)
213 struct isa_dev *dev;
214 {
215 take_irq(dev->dev_pic, dev->dev_unit, dev->dev_intr[0],
216 dev->dev_spl, dev->dev_driver->driver_dname);
217 }
218
219 take_ctlr_irq(ctlr)
220 struct isa_ctlr *ctlr;
221 {
222 take_irq(ctlr->ctlr_pic, ctlr->ctlr_ctlr, ctlr->ctlr_intr[0],
223 ctlr->ctlr_spl, ctlr->ctlr_driver->driver_mname);
224 }
225
226 take_irq(pic, unit, intr, spl, name)
227 int pic, unit, spl;
228 int (*intr)();
229 char *name;
230 {
231 if (name == 0)
232 name = "??";
233 if (pic < 0 || pic > 15) {
234 printf("The device %s%d has invalid IRQ %d; ignored\n", name, unit, pic);
235 return;
236 }
237 if (spl == SPL0)
238 printf("Warning: device %s%d is at SPL0! This doesn't inhibit interrupts.\n", name, unit);
239 if (spl == SPLHI)
240 printf("Warning: device %s%d is at SPLHI! Only the clock can be at SPLHI.\n", name, unit);
241 if (intpri[pic] == 0) {
242 iunit[pic] = unit;
243 ivect[pic] = intr;
244 intpri[pic] = spl;
245 form_pic_mask();
246 } else if (ivect[pic] == intr) {
247 printf("The device %s%d already has IRQ %d; ignored\n", name, unit, pic);
248 } else {
249 printf("The device %s%d will clobber IRQ %d.\n", name, unit, pic);
250 printf("You have two devices at the same IRQ. This won't work.\n");
251 printf("Reconfigure your hardware and try again.\n");
252 }
253 }
254
255 #ifdef MACH_KERNEL
256 #else MACH_KERNEL
257 /*
258 * Determine mass storage and memory configuration for a machine.
259 * Get cpu type, and then switch out to machine specific procedures
260 * which will probe adaptors to see what is out there.
261 */
262 configure()
263 {
264
265 master_cpu = 0;
266 set_cpu_number();
267 #if NCPUS > 1
268 printf("Master cpu at slot %d.\n", master_cpu);
269 #endif NCPUS > 1
270 machine_slot[master_cpu].is_cpu = TRUE;
271 machine_slot[master_cpu].running = TRUE;
272 machine_slot[master_cpu].cpu_type = CPU_TYPE_I386;
273 cpuspeed = 6;
274 #ifdef AT386
275 machine_slot[master_cpu].cpu_subtype = CPU_SUBTYPE_AT386;
276 probeio();
277 #endif AT386
278 #ifdef PS2
279 findspeed(); /* calculate the delays first */
280 microfind(); /* as we need them in the drivers */
281 machine_slot[master_cpu].cpu_subtype = CPU_SUBTYPE_PS2;
282 probeio();
283 #endif AT386
284
285 #if iPSC2
286 machine_slot[master_cpu].cpu_subtype = CPU_SUBTYPE_iPSC2;
287
288 /* Call DCM driver to initialize itself, interrupts are already
289 enabled at this point. We may want to change this later so that
290 we disable DCM interrupts during bootld and turn them back on
291 in dcminit().
292 */
293 dcminit();
294 #endif iPSC2
295
296 #if GENERIC > 0
297 setconf();
298 #endif GENERIC > 0
299 return;
300 }
301
302 /*
303 * slave_config is a temporary artifact which will go away as soon
304 * as kern/slave.c is made conditional on NCPUS > 1
305 */
306 slave_config()
307 {
308 }
309 #endif MACH_KERNEL
310
311 #ifdef PS2
312 /*
313 * get the POS registers information so that drivers can determine
314 * what adapters are out there.
315 */
316 pos_init()
317 {
318 int i, j;
319
320 outb(POS_DISABLE_VGA, 0xff); /* disable vga etc. */
321 for (i=0; i<MAX_POS_SLOTS; ++i) {
322 outb(POS_PORT, POS_ENABLE(i));
323 for (j=0; j<MAX_POS_BYTES; ++j)
324 slots[i].pos_data[j] = POS_GET_DATA(j);
325 #ifndef i386
326 /*
327 * on i386 we don't need to do anything because it is already handled
328 * by the union
329 */
330 slots[i].pos_id = (slots[i].pos_data[1] << 8) |
331 slots[i].pos_data[0];
332 #endif
333 }
334 outb(POS_PORT, POS_DISABLE);
335
336 #ifdef POS_DEBUG
337 for (i=0; i<MAX_POS_SLOTS; ++i) {
338 if (slots[i].pos_id == POS_ID_NONE)
339 continue;
340 printf("slot %d id %x", i, slots[i].pos_id);
341 for (j=0; j<MAX_POS_INFO; ++j)
342 printf(" %x", slots[i].pos_info[j]);
343 printf("\n");
344 }
345 #endif POS_DEBUG
346 }
347
348 /*
349 * function to lookup given adapter card id and return
350 * it's slot number. We are given the initial slot number
351 * to start at so we can find more than one card.
352 * we return -1 when we fail.
353 */
354 int pos_slot(card_id, slot)
355 u_short card_id;
356 int slot;
357 {
358 int i, j;
359
360 for (; slot >= 0 && slot<MAX_POS_SLOTS; ++slot)
361 if (card_id == slots[slot].pos_id)
362 return(slot);
363 return(-1);
364 }
365 #endif PS2
366
Cache object: 8a5a5c0a8cf10c4bff2600eb67495821
|