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