xref: /original-bsd/sys/hp300/hp300/autoconf.c (revision ca98dac2)
1 /*
2  * Copyright (c) 1988 University of Utah.
3  * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
4  * All rights reserved.
5  *
6  * This code is derived from software contributed to Berkeley by
7  * the Systems Programming Group of the University of Utah Computer
8  * Science Department.
9  *
10  * %sccs.include.redist.c%
11  *
12  * from: Utah $Hdr: autoconf.c 1.35 92/01/22$
13  *
14  *	@(#)autoconf.c	7.8 (Berkeley) 10/11/92
15  */
16 
17 /*
18  * Setup the system to run on the current machine.
19  *
20  * Configure() is called at boot time.  Available
21  * devices are determined (from possibilities mentioned in ioconf.c),
22  * and the drivers are initialized.
23  */
24 
25 #include <sys/param.h>
26 #include <sys/systm.h>
27 #include <sys/map.h>
28 #include <sys/buf.h>
29 #include <sys/dkstat.h>
30 #include <sys/conf.h>
31 #include <sys/dmap.h>
32 #include <sys/reboot.h>
33 
34 #include <machine/vmparam.h>
35 #include <machine/cpu.h>
36 #include <hp300/hp300/pte.h>
37 #include <hp300/hp300/isr.h>
38 #include <hp/dev/device.h>
39 #include <hp/dev/grfreg.h>
40 #include <hp/dev/hilreg.h>
41 
42 /*
43  * The following several variables are related to
44  * the configuration process, and are used in initializing
45  * the machine.
46  */
47 int	cold;		    /* if 1, still working on cold-start */
48 int	dkn;		    /* number of iostat dk numbers assigned so far */
49 int	cpuspeed = MHZ_8;   /* relative cpu speed */
50 struct	isr isrqueue[NISR];
51 struct	hp_hw sc_table[MAXCTLRS];
52 
53 /* XXX must be allocated statically because of early console init */
54 struct	map extiomap[EIOMAPSIZE/16];
55 
56 extern	caddr_t internalhpib;
57 extern	char *extiobase;
58 
59 #ifdef DEBUG
60 int	acdebug = 0;
61 #endif
62 
63 /*
64  * Determine mass storage and memory configuration for a machine.
65  */
66 configure()
67 {
68 	register struct hp_hw *hw;
69 	int found;
70 
71 	/*
72 	 * XXX: these should be consolidated into some kind of table
73 	 */
74 	hilsoftinit(0, HILADDR);
75 	hilinit(0, HILADDR);
76 	isrinit();
77 	dmainit();
78 
79 	/*
80 	 * Look over each hardware device actually found and attempt
81 	 * to match it with an ioconf.c table entry.
82 	 */
83 	for (hw = sc_table; hw->hw_type; hw++) {
84 		if (HW_ISCTLR(hw))
85 			found = find_controller(hw);
86 		else
87 			found = find_device(hw);
88 #ifdef DEBUG
89 		if (!found) {
90 			int sc = patosc(hw->hw_pa);
91 
92 			printf("unconfigured card id %x ", hw->hw_id);
93 			if (sc < 256)
94 				printf("at sc%d\n", sc);
95 			else
96 				printf("csr at %x\n", sc);
97 		}
98 #endif
99 	}
100 
101 #include "cd.h"
102 #if NCD > 0
103 	/*
104 	 * Now deal with concatenated disks
105 	 */
106 	find_cdevices();
107 #endif
108 
109 #if GENERIC
110 	if ((boothowto & RB_ASKNAME) == 0)
111 		setroot();
112 	setconf();
113 #else
114 	setroot();
115 #endif
116 	swapconf();
117 	cold = 0;
118 }
119 
120 #define dr_type(d, s)	\
121 	(strcmp((d)->d_name, (s)) == 0)
122 
123 #define same_hw_ctlr(hw, hc) \
124 	(HW_ISHPIB(hw) && dr_type((hc)->hp_driver, "hpib") || \
125 	 HW_ISSCSI(hw) && dr_type((hc)->hp_driver, "scsi"))
126 
127 find_controller(hw)
128 	register struct hp_hw *hw;
129 {
130 	register struct hp_ctlr *hc;
131 	struct hp_ctlr *match_c;
132 	caddr_t oaddr;
133 	int sc;
134 
135 #ifdef DEBUG
136 	if (acdebug)
137 		printf("find_controller: hw: id%x at sc%d (%x), type %x...",
138 		       hw->hw_id, hw->hw_sc, hw->hw_kva, hw->hw_type);
139 #endif
140 	sc = hw->hw_sc;
141 	match_c = NULL;
142 	for (hc = hp_cinit; hc->hp_driver; hc++) {
143 		if (hc->hp_alive)
144 			continue;
145 		/*
146 		 * Make sure we are looking at the right
147 		 * controller type.
148 		 */
149 		if (!same_hw_ctlr(hw, hc))
150 			continue;
151 		/*
152 		 * Exact match; all done
153 		 */
154 		if ((int)hc->hp_addr == sc) {
155 			match_c = hc;
156 			break;
157 		}
158 		/*
159 		 * Wildcard; possible match so remember first instance
160 		 * but continue looking for exact match.
161 		 */
162 		if (hc->hp_addr == NULL && match_c == NULL)
163 			match_c = hc;
164 	}
165 #ifdef DEBUG
166 	if (acdebug) {
167 		if (match_c)
168 			printf("found %s%d\n",
169 			       match_c->hp_driver->d_name,
170 			       match_c->hp_unit);
171 		else
172 			printf("not found\n");
173 	}
174 #endif
175 	/*
176 	 * Didn't find an ioconf entry for this piece of hardware,
177 	 * just ignore it.
178 	 */
179 	if (match_c == NULL)
180 		return(0);
181 	/*
182 	 * Found a match, attempt to initialize and configure all attached
183 	 * slaves.  Note, we can still fail if HW won't initialize.
184 	 */
185 	hc = match_c;
186 	oaddr = hc->hp_addr;
187 	hc->hp_addr = hw->hw_kva;
188 	if ((*hc->hp_driver->d_init)(hc)) {
189 		hc->hp_alive = 1;
190 		printf("%s%d", hc->hp_driver->d_name, hc->hp_unit);
191 		sc = patosc(hw->hw_pa);
192 		if (sc < 256)
193 			printf(" at sc%d,", sc);
194 		else
195 			printf(" csr 0x%x,", sc);
196 		printf(" ipl %d", hc->hp_ipl);
197 		if (hc->hp_flags)
198 			printf(" flags 0x%x", hc->hp_flags);
199 		printf("\n");
200 		find_slaves(hc);
201 	} else
202 		hc->hp_addr = oaddr;
203 	return(1);
204 }
205 
206 find_device(hw)
207 	register struct hp_hw *hw;
208 {
209 	register struct hp_device *hd;
210 	struct hp_device *match_d;
211 	caddr_t oaddr;
212 	int sc;
213 
214 #ifdef DEBUG
215 	if (acdebug)
216 		printf("find_device: hw: id%x at sc%d (%x), type %x...",
217 		       hw->hw_id, hw->hw_sc, hw->hw_kva, hw->hw_type);
218 #endif
219 	match_d = NULL;
220 	for (hd = hp_dinit; hd->hp_driver; hd++) {
221 		if (hd->hp_alive)
222 			continue;
223 		/* Must not be a slave */
224 		if (hd->hp_cdriver)
225 			continue;
226 		/*
227 		 * XXX: A graphics device that was found as part of the
228 		 * console init will have the hp_addr field already set
229 		 * (i.e. no longer the select code).  Gotta perform a
230 		 * slightly different check for an exact match.
231 		 */
232 		if (HW_ISDEV(hw, D_BITMAP) && hd->hp_addr >= intiobase) {
233 			/* must be an exact match */
234 			if (hd->hp_addr == hw->hw_kva) {
235 				match_d = hd;
236 				break;
237 			}
238 			continue;
239 		}
240 		sc = (int) hd->hp_addr;
241 		/*
242 		 * Exact match; all done.
243 		 */
244 		if (sc > 0 && sc == hw->hw_sc) {
245 			match_d = hd;
246 			break;
247 		}
248 		/*
249 		 * Wildcard; possible match so remember first instance
250 		 * but continue looking for exact match.
251 		 */
252 		if (sc == 0 && same_hw_device(hw, hd) && match_d == NULL)
253 			match_d = hd;
254 	}
255 #ifdef DEBUG
256 	if (acdebug) {
257 		if (match_d)
258 			printf("found %s%d\n",
259 			       match_d->hp_driver->d_name,
260 			       match_d->hp_unit);
261 		else
262 			printf("not found\n");
263 	}
264 #endif
265 	/*
266 	 * Didn't find an ioconf entry for this piece
267 	 * of hardware, just ignore it.
268 	 */
269 	if (match_d == NULL)
270 		return(0);
271 	/*
272 	 * Found a match, attempt to initialize.
273 	 * Note, we can still fail if HW won't initialize.
274 	 */
275 	hd = match_d;
276 	oaddr = hd->hp_addr;
277 	hd->hp_addr = hw->hw_kva;
278 	if ((*hd->hp_driver->d_init)(hd)) {
279 		hd->hp_alive = 1;
280 		printf("%s%d", hd->hp_driver->d_name, hd->hp_unit);
281 		sc = patosc(hw->hw_pa);
282 		if (sc < 256)
283 			printf(" at sc%d", sc);
284 		else
285 			printf(" csr 0x%x", sc);
286 		if (hd->hp_ipl)
287 			printf(", ipl %d", hd->hp_ipl);
288 		if (hd->hp_flags)
289 			printf(", flags 0x%x", hd->hp_flags);
290 		printf("\n");
291 	} else
292 		hd->hp_addr = oaddr;
293 	return(1);
294 }
295 
296 find_slaves(hc)
297 	struct hp_ctlr *hc;
298 {
299 	/*
300 	 * The SCSI bus is structured very much like the HP-IB
301 	 * except that the host adaptor is slave 7 so we only want
302 	 * to look at the first 6 slaves.
303 	 */
304 	if (dr_type(hc->hp_driver, "hpib"))
305 		find_busslaves(hc, MAXSLAVES);
306 	else if (dr_type(hc->hp_driver, "scsi"))
307 		find_busslaves(hc, MAXSLAVES-1);
308 }
309 
310 /*
311  * Search each BUS controller found for slaves attached to it.
312  * The bad news is that we don't know how to uniquely identify all slaves
313  * (e.g. PPI devices on HP-IB).  The good news is that we can at least
314  * differentiate those from slaves we can identify.  At worst (a totally
315  * wildcarded entry) this will cause us to locate such a slave at the first
316  * unused position instead of where it really is.  To save grief, non-
317  * identifing devices should always be fully qualified.
318  */
319 find_busslaves(hc, maxslaves)
320 	register struct hp_ctlr *hc;
321 	int maxslaves;
322 {
323 	register int s;
324 	register struct hp_device *hd;
325 	struct hp_device *match_s;
326 	int new_s, new_c, old_s, old_c;
327 	int rescan;
328 
329 #ifdef DEBUG
330 	if (acdebug)
331 		printf("find_busslaves: for %s%d\n",
332 		       hc->hp_driver->d_name, hc->hp_unit);
333 #endif
334 	for (s = 0; s < maxslaves; s++) {
335 		rescan = 1;
336 		match_s = NULL;
337 		for (hd = hp_dinit; hd->hp_driver; hd++) {
338 			/*
339 			 * Rule out the easy ones:
340 			 * 1. slave already assigned or not a slave
341 			 * 2. not of the proper type
342 			 * 3. controller specified but not this one
343 			 * 4. slave specified but not this one
344 			 */
345 			if (hd->hp_alive || hd->hp_cdriver == NULL)
346 				continue;
347 			if (!dr_type(hc->hp_driver, hd->hp_cdriver->d_name))
348 				continue;
349 			if (hd->hp_ctlr >= 0 && hd->hp_ctlr != hc->hp_unit)
350 				continue;
351 			if (hd->hp_slave >= 0 && hd->hp_slave != s)
352 				continue;
353 			/*
354 			 * Case 0: first possible match.
355 			 * Remember it and keep looking for better.
356 			 */
357 			if (match_s == NULL) {
358 				match_s = hd;
359 				new_c = hc->hp_unit;
360 				new_s = s;
361 				continue;
362 			}
363 			/*
364 			 * Case 1: exact match.
365 			 * All done.  Note that we do not attempt any other
366 			 * matches if this one fails.  This allows us to
367 			 * "reserve" locations for dynamic addition of
368 			 * disk/tape drives by fully qualifing the location.
369 			 */
370 			if (hd->hp_slave == s && hd->hp_ctlr == hc->hp_unit) {
371 				match_s = hd;
372 				rescan = 0;
373 				break;
374 			}
375 			/*
376 			 * Case 2: right controller, wildcarded slave.
377 			 * Remember first and keep looking for an exact match.
378 			 */
379 			if (hd->hp_ctlr == hc->hp_unit &&
380 			    match_s->hp_ctlr < 0) {
381 				match_s = hd;
382 				new_s = s;
383 				continue;
384 			}
385 			/*
386 			 * Case 3: right slave, wildcarded controller.
387 			 * Remember and keep looking for a better match.
388 			 */
389 			if (hd->hp_slave == s &&
390 			    match_s->hp_ctlr < 0 && match_s->hp_slave < 0) {
391 				match_s = hd;
392 				new_c = hc->hp_unit;
393 				continue;
394 			}
395 			/*
396 			 * OW: we had a totally wildcarded spec.
397 			 * If we got this far, we have found a possible
398 			 * match already (match_s != NULL) so there is no
399 			 * reason to remember this one.
400 			 */
401 			continue;
402 		}
403 		/*
404 		 * Found a match.  We need to set hp_ctlr/hp_slave properly
405 		 * for the init routines but we also need to remember all
406 		 * the old values in case this doesn't pan out.
407 		 */
408 		if (match_s) {
409 			hd = match_s;
410 			old_c = hd->hp_ctlr;
411 			old_s = hd->hp_slave;
412 			if (hd->hp_ctlr < 0)
413 				hd->hp_ctlr = new_c;
414 			if (hd->hp_slave < 0)
415 				hd->hp_slave = new_s;
416 #ifdef DEBUG
417 			if (acdebug)
418 				printf("looking for %s%d at slave %d...",
419 				       hd->hp_driver->d_name,
420 				       hd->hp_unit, hd->hp_slave);
421 #endif
422 
423 			if ((*hd->hp_driver->d_init)(hd)) {
424 #ifdef DEBUG
425 				if (acdebug)
426 					printf("found\n");
427 #endif
428 				printf("%s%d at %s%d, slave %d",
429 				       hd->hp_driver->d_name, hd->hp_unit,
430 				       hc->hp_driver->d_name, hd->hp_ctlr,
431 				       hd->hp_slave);
432 				if (hd->hp_flags)
433 					printf(" flags 0x%x", hd->hp_flags);
434 				printf("\n");
435 				hd->hp_alive = 1;
436 				if (hd->hp_dk && dkn < DK_NDRIVE)
437 					hd->hp_dk = dkn++;
438 				else
439 					hd->hp_dk = -1;
440 				rescan = 1;
441 			} else {
442 #ifdef DEBUG
443 				if (acdebug)
444 					printf("not found\n");
445 #endif
446 				hd->hp_ctlr = old_c;
447 				hd->hp_slave = old_s;
448 			}
449 			/*
450 			 * XXX: This should be handled better.
451 			 * Re-scan a slave.  There are two reasons to do this.
452 			 * 1. It is possible to have both a tape and disk
453 			 *    (e.g. 7946) or two disks (e.g. 9122) at the
454 			 *    same slave address.  Here we need to rescan
455 			 *    looking only at entries with a different
456 			 *    physical unit number (hp_flags).
457 			 * 2. It is possible that an init failed because the
458 			 *    slave was there but of the wrong type.  In this
459 			 *    case it may still be possible to match the slave
460 			 *    to another ioconf entry of a different type.
461 			 *    Here we need to rescan looking only at entries
462 			 *    of different types.
463 			 * In both cases we avoid looking at undesirable
464 			 * ioconf entries of the same type by setting their
465 			 * alive fields to -1.
466 			 */
467 			if (rescan) {
468 				for (hd = hp_dinit; hd->hp_driver; hd++) {
469 					if (hd->hp_alive)
470 						continue;
471 					if (match_s->hp_alive == 1) {	/* 1 */
472 						if (hd->hp_flags == match_s->hp_flags)
473 							hd->hp_alive = -1;
474 					} else {			/* 2 */
475 						if (hd->hp_driver == match_s->hp_driver)
476 							hd->hp_alive = -1;
477 					}
478 				}
479 				s--;
480 				continue;
481 			}
482 		}
483 		/*
484 		 * Reset bogon alive fields prior to attempting next slave
485 		 */
486 		for (hd = hp_dinit; hd->hp_driver; hd++)
487 			if (hd->hp_alive == -1)
488 				hd->hp_alive = 0;
489 	}
490 }
491 
492 caddr_t
493 sctopa(sc)
494 	register int sc;
495 {
496 	register caddr_t addr;
497 
498 	if (sc == 7 && internalhpib)
499 		addr = internalhpib;
500 	else if (sc < 32)
501 		addr = (caddr_t) (DIOBASE + sc * DIOCSIZE);
502 	else if (sc >= 132)
503 		addr = (caddr_t) (DIOIIBASE + (sc - 132) * DIOIICSIZE);
504 	else
505 		addr = 0;
506 	return(addr);
507 }
508 
509 patosc(addr)
510 	register caddr_t addr;
511 {
512 	if (addr == (caddr_t)0x478000)
513 		return(7);
514 	if (addr >= (caddr_t)DIOBASE && addr < (caddr_t)DIOTOP)
515 		return(((unsigned)addr - DIOBASE) / DIOCSIZE);
516 	if (addr >= (caddr_t)DIOIIBASE && addr < (caddr_t)DIOIITOP)
517 		return(((unsigned)addr - DIOIIBASE) / DIOIICSIZE + 132);
518 	return((int)addr);
519 }
520 
521 caddr_t
522 sctova(sc)
523 	register int sc;
524 {
525 	register struct hp_hw *hw;
526 
527 	for (hw = sc_table; hw->hw_type; hw++)
528 		if (sc == hw->hw_sc)
529 			return(hw->hw_kva);
530 	return((caddr_t)sc);
531 }
532 
533 vatosc(addr)
534 	register caddr_t addr;
535 {
536 	register struct hp_hw *hw;
537 
538 	for (hw = sc_table; hw->hw_type; hw++)
539 		if (addr == hw->hw_kva)
540 			return(hw->hw_sc);
541 	return((int)addr);
542 }
543 
544 same_hw_device(hw, hd)
545 	struct hp_hw *hw;
546 	struct hp_device *hd;
547 {
548 	int found = 0;
549 
550 	switch (hw->hw_type & ~B_MASK) {
551 	case C_HPIB:
552 		found = dr_type(hd->hp_driver, "hpib");
553 		break;
554 	case C_SCSI:
555 		found = dr_type(hd->hp_driver, "scsi");
556 		break;
557 	case D_BITMAP:
558 		found = dr_type(hd->hp_driver, "grf");
559 		break;
560 	case D_LAN:
561 		found = dr_type(hd->hp_driver, "le");
562 		break;
563 	case D_COMMDCA:
564 		found = dr_type(hd->hp_driver, "dca");
565 		break;
566 	case D_COMMDCL:
567 		found = dr_type(hd->hp_driver, "dcl");
568 		break;
569 	case D_COMMDCM:
570 		found = dr_type(hd->hp_driver, "dcm");
571 		break;
572 	default:
573 		break;
574 	}
575 	return(found);
576 }
577 
578 char notmappedmsg[] = "WARNING: no space to map IO card, ignored\n";
579 
580 /*
581  * Scan the IO space looking for devices.
582  */
583 find_devs()
584 {
585 	short sc;
586 	u_char *id_reg;
587 	register caddr_t addr;
588 	register struct hp_hw *hw;
589 	int didmap, sctop;
590 
591 	/*
592 	 * Initialize IO resource map for iomap().
593 	 */
594 	rminit(extiomap, (long)EIOMAPSIZE, (long)1, "extio", EIOMAPSIZE/16);
595 	hw = sc_table;
596 	/*
597 	 * Probe all select codes + internal display addr
598 	 */
599 	sctop = machineid == HP_320 ? 32 : 256;
600 	for (sc = -1; sc < sctop; sc++) {
601 		/*
602 		 * Invalid select codes
603 		 */
604 		if (sc >= 32 && sc < 132)
605 			continue;
606 
607 		if (sc == -1) {
608 			hw->hw_pa = (caddr_t) GRFIADDR;
609 			addr = (caddr_t) IIOV(hw->hw_pa);
610 			didmap = 0;
611 		} else if (sc == 7 && internalhpib) {
612 			hw->hw_pa = (caddr_t) 0x478000;
613 			addr = internalhpib = (caddr_t) IIOV(hw->hw_pa);
614 			didmap = 0;
615 		} else {
616 			hw->hw_pa = sctopa(sc);
617 			addr = iomap(hw->hw_pa, NBPG);
618 			if (addr == 0) {
619 				printf(notmappedmsg);
620 				continue;
621 			}
622 			didmap = 1;
623 		}
624 		if (badaddr(addr)) {
625 			if (didmap)
626 				iounmap(addr, NBPG);
627 			continue;
628 		}
629 		id_reg = (u_char *) addr;
630 		if (sc >= 132)
631 			hw->hw_size = (id_reg[0x101] + 1) * 0x100000;
632 		else
633 			hw->hw_size = DIOCSIZE;
634 		hw->hw_kva = addr;
635 		hw->hw_id = id_reg[1];
636 		hw->hw_sc = sc;
637 		/*
638 		 * Internal HP-IB on some machines (345/375) doesn't return
639 		 * consistant id info so we use the info gleaned from the
640 		 * boot ROMs SYSFLAG.
641 		 */
642 		if (sc == 7 && internalhpib) {
643 			hw->hw_type = C_HPIB;
644 			hw++;
645 			continue;
646 		}
647 		/*
648 		 * XXX: the following could be in a big static table
649 		 */
650 		switch (hw->hw_id) {
651 		/* Null device? */
652 		case 0:
653 			break;
654 		/* 98644A */
655 		case 2:
656 		case 2+128:
657 			hw->hw_type = D_COMMDCA;
658 			break;
659 		/* 98622A */
660 		case 3:
661 			hw->hw_type = D_MISC;
662 			break;
663 		/* 98623A */
664 		case 4:
665 			hw->hw_type = D_MISC;
666 			break;
667 		/* 98642A */
668 		case 5:
669 		case 5+128:
670 			hw->hw_type = D_COMMDCM;
671 			break;
672 		/* 345/375 builtin parallel port */
673 		case 6:
674 			hw->hw_type = D_PPORT;
675 			break;
676 		/* 98625A */
677 		case 7:
678 		case 7+32:
679 		case 7+64:
680 		case 7+96:
681 			hw->hw_type = C_SCSI;
682 			break;
683 		/* 98625B */
684 		case 8:
685 			hw->hw_type = C_HPIB;
686 			break;
687 		/* 98287A */
688 		case 9:
689 			hw->hw_type = D_KEYBOARD;
690 			break;
691 		/* 98635A */
692 		case 10:
693 			hw->hw_type = D_FPA;
694 			break;
695 		/* timer */
696 		case 11:
697 			hw->hw_type = D_MISC;
698 			break;
699 		/* 98640A */
700 		case 18:
701 			hw->hw_type = D_MISC;
702 			break;
703 		/* 98643A */
704 		case 21:
705 			hw->hw_type = D_LAN;
706 			break;
707 		/* 98659A */
708 		case 22:
709 			hw->hw_type = D_MISC;
710 			break;
711 		/* 237 display */
712 		case 25:
713 			hw->hw_type = D_BITMAP;
714 			break;
715 		/* quad-wide card */
716 		case 26:
717 			hw->hw_type = D_MISC;
718 			hw->hw_size *= 4;
719 			sc += 3;
720 			break;
721 		/* 98253A */
722 		case 27:
723 			hw->hw_type = D_MISC;
724 			break;
725 		/* 98627A */
726 		case 28:
727 			hw->hw_type = D_BITMAP;
728 			break;
729 		/* 98633A */
730 		case 29:
731 			hw->hw_type = D_BITMAP;
732 			break;
733 		/* 98259A */
734 		case 30:
735 			hw->hw_type = D_MISC;
736 			break;
737 		/* 8741 */
738 		case 31:
739 			hw->hw_type = D_MISC;
740 			break;
741 		/* 98577A */
742 		case 49:
743 			hw->hw_type = C_VME;
744 			if (sc < 132) {
745 				hw->hw_size *= 2;
746 				sc++;
747 			}
748 			break;
749 		/* 98628A */
750 		case 52:
751 		case 52+128:
752 			hw->hw_type = D_COMMDCL;
753 			break;
754 		/* bitmap display */
755 		case 57:
756 			hw->hw_type = D_BITMAP;
757 			hw->hw_secid = id_reg[0x15];
758 			switch (hw->hw_secid) {
759 			/* 98700/98710 */
760 			case 1:
761 				break;
762 			/* 98544-547 topcat */
763 			case 2:
764 				break;
765 			/* 98720/721 renassiance */
766 			case 4:
767 				if (sc < 132) {
768 					hw->hw_size *= 2;
769 					sc++;
770 				}
771 				break;
772 			/* 98548-98556 catseye */
773 			case 5:
774 			case 6:
775 			case 7:
776 			case 9:
777 				break;
778 			/* 98730/731 davinci */
779 			case 8:
780 				if (sc < 132) {
781 					hw->hw_size *= 2;
782 					sc++;
783 				}
784 				break;
785 			/* A1096A hyperion */
786 			case 14:
787 				break;
788 			/* 987xx */
789 			default:
790 				break;
791 			}
792 			break;
793 		/* 98644A */
794 		case 66:
795 		case 66+128:
796 			hw->hw_type = D_COMMDCA;
797 			break;
798 		/* 98624A */
799 		case 128:
800 			hw->hw_type = C_HPIB;
801 			break;
802 		default:
803 			hw->hw_type = D_MISC;
804 			break;
805 		}
806 		/*
807 		 * Re-map to proper size
808 		 */
809 		if (didmap) {
810 			iounmap(addr, NBPG);
811 			addr = iomap(hw->hw_pa, hw->hw_size);
812 			if (addr == 0) {
813 				printf(notmappedmsg);
814 				continue;
815 			}
816 			hw->hw_kva = addr;
817 		}
818 		/*
819 		 * Encode bus type
820 		 */
821 		if (sc >= 132)
822 			hw->hw_type |= B_DIOII;
823 		else
824 			hw->hw_type |= B_DIO;
825 		hw++;
826 	}
827 }
828 
829 /*
830  * Allocate/deallocate a cache-inhibited range of kernel virtual address
831  * space mapping the indicated physical address range [pa - pa+size)
832  */
833 caddr_t
834 iomap(pa, size)
835 	caddr_t pa;
836 	int size;
837 {
838 	int ix, npf;
839 	caddr_t kva;
840 
841 #ifdef DEBUG
842 	if (((int)pa & PGOFSET) || (size & PGOFSET))
843 		panic("iomap: unaligned");
844 #endif
845 	npf = btoc(size);
846 	ix = rmalloc(extiomap, npf);
847 	if (ix == 0)
848 		return(0);
849 	kva = extiobase + ctob(ix-1);
850 	physaccess(kva, pa, size, PG_RW|PG_CI);
851 	return(kva);
852 }
853 
854 iounmap(kva, size)
855 	caddr_t kva;
856 	int size;
857 {
858 	int ix;
859 
860 #ifdef DEBUG
861 	if (((int)kva & PGOFSET) || (size & PGOFSET))
862 		panic("iounmap: unaligned");
863 	if (kva < extiobase || kva >= extiobase + ctob(EIOMAPSIZE))
864 		panic("iounmap: bad address");
865 #endif
866 	physunaccess(kva, size);
867 	ix = btoc(kva - extiobase) + 1;
868 	rmfree(extiomap, btoc(size), ix);
869 }
870 
871 #if NCD > 0
872 #include <dev/cdvar.h>
873 
874 find_cdevices()
875 {
876 	register struct cddevice *cd;
877 
878 	for (cd = cddevice; cd->cd_unit >= 0; cd++) {
879 		/*
880 		 * XXX
881 		 * Assign disk index first so that init routine
882 		 * can use it (saves having the driver drag around
883 		 * the cddevice pointer just to set up the dk_*
884 		 * info in the open routine).
885 		 */
886 		if (dkn < DK_NDRIVE)
887 			cd->cd_dk = dkn++;
888 		else
889 			cd->cd_dk = -1;
890 		if (cdinit(cd))
891 			printf("cd%d configured\n", cd->cd_unit);
892 		else if (cd->cd_dk >= 0) {
893 			cd->cd_dk = -1;
894 			dkn--;
895 		}
896 	}
897 }
898 #endif
899 
900 isrinit()
901 {
902 	register int i;
903 
904 	for (i = 0; i < NISR; i++)
905 		isrqueue[i].isr_forw = isrqueue[i].isr_back = &isrqueue[i];
906 }
907 
908 void
909 isrlink(isr)
910 	register struct isr *isr;
911 {
912 	int i = ISRIPL(isr->isr_ipl);
913 
914 	if (i < 0 || i >= NISR) {
915 		printf("bad IPL %d\n", i);
916 		panic("configure");
917 	}
918 	insque(isr, isrqueue[i].isr_back);
919 }
920 
921 /*
922  * Configure swap space and related parameters.
923  */
924 swapconf()
925 {
926 	register struct swdevt *swp;
927 	register int nblks;
928 
929 	for (swp = swdevt; swp->sw_dev; swp++)
930 		if (bdevsw[major(swp->sw_dev)].d_psize) {
931 			nblks =
932 			  (*bdevsw[major(swp->sw_dev)].d_psize)(swp->sw_dev);
933 			if (nblks != -1 &&
934 			    (swp->sw_nblks == 0 || swp->sw_nblks > nblks))
935 				swp->sw_nblks = nblks;
936 		}
937 	dumpconf();
938 }
939 
940 #define	DOSWAP			/* Change swdevt and dumpdev too */
941 u_long	bootdev;		/* should be dev_t, but not until 32 bits */
942 
943 static	char devname[][2] = {
944 	0,0,		/* 0 = ct */
945 	0,0,		/* 1 = xx */
946 	'r','d',	/* 2 = rd */
947 	0,0,		/* 3 = sw */
948 	's','d',	/* 4 = rd */
949 };
950 
951 #define	PARTITIONMASK	0x7
952 #define	PARTITIONSHIFT	3
953 
954 /*
955  * Attempt to find the device from which we were booted.
956  * If we can do so, and not instructed not to do so,
957  * change rootdev to correspond to the load device.
958  */
959 setroot()
960 {
961 	register struct hp_ctlr *hc;
962 	register struct hp_device *hd;
963 	int  majdev, mindev, unit, part, controller, adaptor;
964 	dev_t temp, orootdev;
965 	struct swdevt *swp;
966 
967 	if (boothowto & RB_DFLTROOT ||
968 	    (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC)
969 		return;
970 	majdev = B_TYPE(bootdev);
971 	if (majdev >= sizeof(devname) / sizeof(devname[0]))
972 		return;
973 	adaptor = B_ADAPTOR(bootdev);
974 	controller = B_CONTROLLER(bootdev);
975 	part = B_PARTITION(bootdev);
976 	unit = B_UNIT(bootdev);
977 	/*
978 	 * First, find the controller type which supports this device.
979 	 */
980 	for (hd = hp_dinit; hd->hp_driver; hd++)
981 		if (hd->hp_driver->d_name[0] == devname[majdev][0] &&
982 		    hd->hp_driver->d_name[1] == devname[majdev][1])
983 			break;
984 	if (hd->hp_driver == 0)
985 		return;
986 	/*
987 	 * Next, find the "controller" (bus adaptor) of that type
988 	 * corresponding to the adaptor number.
989 	 */
990 	for (hc = hp_cinit; hc->hp_driver; hc++)
991 		if (hc->hp_alive && hc->hp_unit == adaptor &&
992 		    hc->hp_driver == hd->hp_cdriver)
993 			break;
994 	if (hc->hp_driver == 0)
995 		return;
996 	/*
997 	 * Finally, find the "device" (controller or slave) in question
998 	 * attached to that "controller".
999 	 */
1000 	for (hd = hp_dinit; hd->hp_driver; hd++)
1001 		if (hd->hp_alive && hd->hp_slave == controller &&
1002 		    hd->hp_cdriver == hc->hp_driver &&
1003 		    hd->hp_ctlr == hc->hp_unit)
1004 			break;
1005 	if (hd->hp_driver == 0)
1006 		return;
1007 	/*
1008 	 * XXX note that we are missing one level, the unit, here.
1009 	 * Most HP drives come with one controller per disk.  There
1010 	 * are some older drives (e.g. 7946) which have two units
1011 	 * on the same controller but those are typically a disk as
1012 	 * unit 0 and a tape as unit 1.  This would have to be
1013 	 * rethought if you ever wanted to boot from other than unit 0.
1014 	 */
1015 	if (unit != 0)
1016 		printf("WARNING: using device at unit 0 of controller\n");
1017 
1018 	mindev = hd->hp_unit;
1019 	/*
1020 	 * Form a new rootdev
1021 	 */
1022 	mindev = (mindev << PARTITIONSHIFT) + part;
1023 	orootdev = rootdev;
1024 	rootdev = makedev(majdev, mindev);
1025 	/*
1026 	 * If the original rootdev is the same as the one
1027 	 * just calculated, don't need to adjust the swap configuration.
1028 	 */
1029 	if (rootdev == orootdev)
1030 		return;
1031 
1032 	printf("Changing root device to %c%c%d%c\n",
1033 		devname[majdev][0], devname[majdev][1],
1034 		mindev >> PARTITIONSHIFT, part + 'a');
1035 
1036 #ifdef DOSWAP
1037 	mindev &= ~PARTITIONMASK;
1038 	for (swp = swdevt; swp->sw_dev; swp++) {
1039 		if (majdev == major(swp->sw_dev) &&
1040 		    mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) {
1041 			temp = swdevt[0].sw_dev;
1042 			swdevt[0].sw_dev = swp->sw_dev;
1043 			swp->sw_dev = temp;
1044 			break;
1045 		}
1046 	}
1047 	if (swp->sw_dev == 0)
1048 		return;
1049 
1050 	/*
1051 	 * If dumpdev was the same as the old primary swap
1052 	 * device, move it to the new primary swap device.
1053 	 */
1054 	if (temp == dumpdev)
1055 		dumpdev = swdevt[0].sw_dev;
1056 #endif
1057 }
1058