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