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 */
configure()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
find_controller(hw)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
find_device(hw)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 */
find_busslaves(hc,startslave,endslave)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
sctopa(sc)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
patosc(addr)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
sctova(sc)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
vatosc(addr)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 */
find_devs()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
iomap(pa,size)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
iounmap(kva,size)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
isrinit()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
isrlink(isr)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 */
swapconf()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 */
setroot()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