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