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