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