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