autoconf.c revision 1.1
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 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the University of 21 * California, Berkeley and its contributors. 22 * 4. Neither the name of the University nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * from: Utah $Hdr: autoconf.c 1.31 91/01/21$ 39 * 40 * @(#)autoconf.c 7.5 (Berkeley) 5/7/91 41 */ 42 43/* 44 * Setup the system to run on the current machine. 45 * 46 * Configure() is called at boot time. Available 47 * devices are determined (from possibilities mentioned in ioconf.c), 48 * and the drivers are initialized. 49 */ 50 51#include "sys/param.h" 52#include "sys/systm.h" 53#include "sys/buf.h" 54#include "sys/dkstat.h" 55#include "sys/conf.h" 56#include "sys/dmap.h" 57#include "sys/reboot.h" 58 59#include "machine/vmparam.h" 60#include "machine/cpu.h" 61#include "pte.h" 62#include "../dev/device.h" 63 64#include <libraries/configregs.h> 65#include <libraries/configvars.h> 66 67/* 68 * The following several variables are related to 69 * the configuration process, and are used in initializing 70 * the machine. 71 */ 72int cold; /* if 1, still working on cold-start */ 73int dkn; /* number of iostat dk numbers assigned so far */ 74int cpuspeed = MHZ_8; /* relative cpu speed */ 75struct amiga_hw sc_table[MAXCTLRS]; 76 77#ifdef DEBUG 78int acdebug = 0; 79#endif 80 81/* 82 * Determine mass storage and memory configuration for a machine. 83 */ 84configure() 85{ 86 register struct amiga_hw *hw; 87 int found; 88 89 /* 90 * XXX: these should be consolidated into some kind of table 91 */ 92 dmainit(); 93 94 /* 95 * Look over each hardware device actually found and attempt 96 * to match it with an ioconf.c table entry. 97 */ 98 for (hw = sc_table; hw->hw_type; hw++) { 99 if (HW_ISCTLR(hw)) 100 found = find_controller(hw); 101 else 102 found = find_device(hw); 103#ifdef DEBUG 104 if (!found && acdebug) { 105 printf("unconfigured device %d/%d\n", 106 hw->hw_manufacturer, hw->hw_product); 107 } 108#endif 109 } 110 111#if 0 112#include "cd.h" 113#if NCD > 0 114 /* 115 * Now deal with concatenated disks 116 */ 117 find_cdevices(); 118#endif 119#endif 120 121#if GENERIC 122 if ((boothowto & RB_ASKNAME) == 0) 123 setroot(); 124 setconf(); 125#else 126 setroot(); 127#endif 128 swapconf(); 129 cold = 0; 130} 131 132#define dr_type(d, s) \ 133 (strcmp((d)->d_name, (s)) == 0) 134 135#define same_hw_ctlr(hw, ac) \ 136 (HW_ISFLOPPY(hw) && dr_type((ac)->amiga_driver, "floppy") || \ 137 HW_ISSCSI(hw) && dr_type((ac)->amiga_driver, "scsi")) 138 139find_controller(hw) 140 register struct amiga_hw *hw; 141{ 142 register struct amiga_ctlr *ac; 143 struct amiga_ctlr *match_c; 144 caddr_t oaddr; 145 int sc; 146 147#ifdef DEBUG 148 if (acdebug) 149 printf("find_controller: hw: [%d/%d] (%x), type %x...", 150 hw->hw_manufacturer, hw->hw_product, 151 hw->hw_kva, hw->hw_type); 152#endif 153 sc = (hw->hw_manufacturer << 16) | hw->hw_product; 154 match_c = NULL; 155 for (ac = amiga_cinit; ac->amiga_driver; ac++) { 156 if (ac->amiga_alive) 157 continue; 158 /* 159 * Make sure we are looking at the right 160 * controller type. 161 */ 162 if (!same_hw_ctlr(hw, ac)) 163 continue; 164 /* 165 * Exact match; all done 166 */ 167 if ((int)ac->amiga_addr == sc) { 168 match_c = ac; 169 break; 170 } 171 /* 172 * Wildcard; possible match so remember first instance 173 * but continue looking for exact match. 174 */ 175 if (ac->amiga_addr == NULL && match_c == NULL) 176 match_c = ac; 177 } 178#ifdef DEBUG 179 if (acdebug) { 180 if (match_c) 181 printf("found %s%d\n", 182 match_c->amiga_driver->d_name, 183 match_c->amiga_unit); 184 else 185 printf("not found\n"); 186 } 187#endif 188 /* 189 * Didn't find an ioconf entry for this piece of hardware, 190 * just ignore it. 191 */ 192 if (match_c == NULL) 193 return(0); 194 /* 195 * Found a match, attempt to initialize and configure all attached 196 * slaves. Note, we can still fail if HW won't initialize. 197 */ 198 ac = match_c; 199 oaddr = ac->amiga_addr; 200 ac->amiga_addr = hw->hw_kva; 201 if ((*ac->amiga_driver->d_init)(ac)) { 202 ac->amiga_alive = 1; 203 printf ("%s%d", ac->amiga_driver->d_name, ac->amiga_unit); 204 printf (" [%d/%d]", hw->hw_manufacturer, hw->hw_product); 205 if (ac->amiga_flags) 206 printf(", flags 0x%x", ac->amiga_flags); 207 printf("\n"); 208 find_slaves(ac); 209 } else 210 ac->amiga_addr = oaddr; 211 return(1); 212} 213 214find_device(hw) 215 register struct amiga_hw *hw; 216{ 217 register struct amiga_device *ad; 218 struct amiga_device *match_d; 219 caddr_t oaddr; 220 int sc; 221 222#ifdef DEBUG 223 if (acdebug) 224 printf("find_device: hw: [%d/%d] (%x), type %x...", 225 hw->hw_manufacturer, hw->hw_product, 226 hw->hw_kva, hw->hw_type); 227#endif 228 match_d = NULL; 229 for (ad = amiga_dinit; ad->amiga_driver; ad++) { 230 if (ad->amiga_alive) 231 continue; 232 /* Must not be a slave */ 233 if (ad->amiga_cdriver) 234 continue; 235 236 sc = (int) ad->amiga_addr; 237 /* 238 * Exact match; all done. 239 */ 240 if (sc > 0 && sc == ((hw->hw_manufacturer << 16) | hw->hw_product)) { 241 match_d = ad; 242 break; 243 } 244 /* 245 * Wildcard; possible match so remember first instance 246 * but continue looking for exact match. 247 */ 248 if (sc == 0 && same_hw_device(hw, ad) && match_d == NULL) 249 match_d = ad; 250 } 251#ifdef DEBUG 252 if (acdebug) { 253 if (match_d) 254 printf("found %s%d\n", 255 match_d->amiga_driver->d_name, 256 match_d->amiga_unit); 257 else 258 printf("not found\n"); 259 } 260#endif 261 /* 262 * Didn't find an ioconf entry for this piece 263 * of hardware, just ignore it. 264 */ 265 if (match_d == NULL) 266 return(0); 267 /* 268 * Found a match, attempt to initialize. 269 * Note, we can still fail if HW won't initialize. 270 */ 271 ad = match_d; 272 oaddr = ad->amiga_addr; 273 ad->amiga_addr = hw->hw_kva; 274 if ((*ad->amiga_driver->d_init)(ad)) { 275 ad->amiga_alive = 1; 276 printf("%s%d", ad->amiga_driver->d_name, ad->amiga_unit); 277 printf (" [%d/%d]", hw->hw_manufacturer, hw->hw_product); 278 if (ad->amiga_flags) 279 printf(", flags 0x%x", ad->amiga_flags); 280 printf("\n"); 281 } else 282 ad->amiga_addr = oaddr; 283 return(1); 284} 285 286find_slaves(ac) 287 struct amiga_ctlr *ac; 288{ 289 if (dr_type(ac->amiga_driver, "floppy")) 290 find_busslaves(ac, 4); 291 else if (dr_type(ac->amiga_driver, "scsi")) 292 find_busslaves(ac, 7); 293} 294 295/* 296 */ 297find_busslaves(ac, maxslaves) 298 register struct amiga_ctlr *ac; 299 int maxslaves; 300{ 301 register int s; 302 register struct amiga_device *ad; 303 struct amiga_device *match_s; 304 int new_s, new_c, old_s, old_c; 305 int rescan; 306 307#ifdef DEBUG 308 if (acdebug) 309 printf("find_busslaves: for %s%d\n", 310 ac->amiga_driver->d_name, ac->amiga_unit); 311#endif 312 for (s = 0; s < maxslaves; s++) { 313 rescan = 1; 314 match_s = NULL; 315 for (ad = amiga_dinit; ad->amiga_driver; ad++) { 316 /* 317 * Rule out the easy ones: 318 * 1. slave already assigned or not a slave 319 * 2. not of the proper type 320 * 3. controller specified but not this one 321 * 4. slave specified but not this one 322 */ 323 if (ad->amiga_alive || ad->amiga_cdriver == NULL) 324 continue; 325 if (!dr_type(ac->amiga_driver, ad->amiga_cdriver->d_name)) 326 continue; 327 if (ad->amiga_ctlr >= 0 && ad->amiga_ctlr != ac->amiga_unit) 328 continue; 329 if (ad->amiga_slave >= 0 && ad->amiga_slave != s) 330 continue; 331 /* 332 * Case 0: first possible match. 333 * Remember it and keep looking for better. 334 */ 335 if (match_s == NULL) { 336 match_s = ad; 337 new_c = ac->amiga_unit; 338 new_s = s; 339 continue; 340 } 341 /* 342 * Case 1: exact match. 343 * All done. Note that we do not attempt any other 344 * matches if this one fails. This allows us to 345 * "reserve" locations for dynamic addition of 346 * disk/tape drives by fully qualifing the location. 347 */ 348 if (ad->amiga_slave == s && ad->amiga_ctlr == ac->amiga_unit) { 349 match_s = ad; 350 rescan = 0; 351 break; 352 } 353 /* 354 * Case 2: right controller, wildcarded slave. 355 * Remember first and keep looking for an exact match. 356 */ 357 if (ad->amiga_ctlr == ac->amiga_unit && 358 match_s->amiga_ctlr < 0) { 359 match_s = ad; 360 new_s = s; 361 continue; 362 } 363 /* 364 * Case 3: right slave, wildcarded controller. 365 * Remember and keep looking for a better match. 366 */ 367 if (ad->amiga_slave == s && 368 match_s->amiga_ctlr < 0 && match_s->amiga_slave < 0) { 369 match_s = ad; 370 new_c = ac->amiga_unit; 371 continue; 372 } 373 /* 374 * OW: we had a totally wildcarded spec. 375 * If we got this far, we have found a possible 376 * match already (match_s != NULL) so there is no 377 * reason to remember this one. 378 */ 379 continue; 380 } 381 /* 382 * Found a match. We need to set amiga_ctlr/amiga_slave properly 383 * for the init routines but we also need to remember all 384 * the old values in case this doesn't pan out. 385 */ 386 if (match_s) { 387 ad = match_s; 388 old_c = ad->amiga_ctlr; 389 old_s = ad->amiga_slave; 390 if (ad->amiga_ctlr < 0) 391 ad->amiga_ctlr = new_c; 392 if (ad->amiga_slave < 0) 393 ad->amiga_slave = new_s; 394#ifdef DEBUG 395 if (acdebug) 396 printf("looking for %s%d at slave %d...", 397 ad->amiga_driver->d_name, 398 ad->amiga_unit, ad->amiga_slave); 399#endif 400 401 if ((*ad->amiga_driver->d_init)(ad)) { 402#ifdef DEBUG 403 if (acdebug) 404 printf("found\n"); 405#endif 406 printf("%s%d at %s%d, slave %d", 407 ad->amiga_driver->d_name, ad->amiga_unit, 408 ac->amiga_driver->d_name, ad->amiga_ctlr, 409 ad->amiga_slave); 410 if (ad->amiga_flags) 411 printf(" flags 0x%x", ad->amiga_flags); 412 printf("\n"); 413 ad->amiga_alive = 1; 414 if (ad->amiga_dk && dkn < DK_NDRIVE) 415 ad->amiga_dk = dkn++; 416 else 417 ad->amiga_dk = -1; 418 rescan = 1; 419 } else { 420#ifdef DEBUG 421 if (acdebug) 422 printf("not found\n"); 423#endif 424 ad->amiga_ctlr = old_c; 425 ad->amiga_slave = old_s; 426 } 427 /* 428 * XXX: This should be handled better. 429 * Re-scan a slave. There are two reasons to do this. 430 * 1. It is possible to have both a tape and disk 431 * (e.g. 7946) or two disks (e.g. 9122) at the 432 * same slave address. Here we need to rescan 433 * looking only at entries with a different 434 * physical unit number (amiga_flags). 435 * 2. It is possible that an init failed because the 436 * slave was there but of the wrong type. In this 437 * case it may still be possible to match the slave 438 * to another ioconf entry of a different type. 439 * Here we need to rescan looking only at entries 440 * of different types. 441 * In both cases we avoid looking at undesirable 442 * ioconf entries of the same type by setting their 443 * alive fields to -1. 444 */ 445 if (rescan) { 446 for (ad = amiga_dinit; ad->amiga_driver; ad++) { 447 if (ad->amiga_alive) 448 continue; 449 if (match_s->amiga_alive == 1) { /* 1 */ 450 if (ad->amiga_flags == match_s->amiga_flags) 451 ad->amiga_alive = -1; 452 } else { /* 2 */ 453 if (ad->amiga_driver == match_s->amiga_driver) 454 ad->amiga_alive = -1; 455 } 456 } 457 s--; 458 continue; 459 } 460 } 461 /* 462 * Reset bogon alive fields prior to attempting next slave 463 */ 464 for (ad = amiga_dinit; ad->amiga_driver; ad++) 465 if (ad->amiga_alive == -1) 466 ad->amiga_alive = 0; 467 } 468} 469 470same_hw_device(hw, ad) 471 struct amiga_hw *hw; 472 struct amiga_device *ad; 473{ 474 int found = 0; 475 476 switch (hw->hw_type & ~B_MASK) { 477 case C_FLOPPY: 478 found = dr_type(ad->amiga_driver, "floppy"); 479 break; 480 case C_SCSI: 481 found = dr_type(ad->amiga_driver, "scsi"); 482 break; 483 case D_BITMAP: 484 found = dr_type(ad->amiga_driver, "grf"); 485 break; 486 case D_LAN: 487 found = dr_type(ad->amiga_driver, "le"); 488 break; 489 case D_COMMSER: 490 found = dr_type(ad->amiga_driver, "ser"); 491 break; 492 default: 493 break; 494 } 495 return(found); 496} 497 498char notmappedmsg[] = "WARNING: no space to map IO card, ignored\n"; 499 500/* 501 * Scan the IO space looking for devices. 502 */ 503find_devs() 504{ 505 short sc; 506 u_char *id_reg; 507 register caddr_t addr; 508 register struct amiga_hw *hw; 509 int didmap, sctop; 510 extern int num_ConfigDev; 511 extern struct ConfigDev *ConfigDev; 512 struct ConfigDev *cd; 513 514#if 0 515 /* 516 * Initialize IO resource map for iomap(). 517 */ 518 rminit(extiomap, (long)EIOMAPSIZE, (long)1, "extio", EIOMAPSIZE/16); 519#endif 520 hw = sc_table; 521 522 /* first enter builtin devices */ 523 524 /* this is only for the A3000, but... */ 525 hw->hw_pa = 0xdd0000; 526 hw->hw_size = NBPG; 527 hw->hw_kva = 0; /* filled out in scsiinit */ 528 hw->hw_manufacturer = MANUF_BUILTIN; 529 hw->hw_product = PROD_BUILTIN_SCSI; 530 hw->hw_type = B_BUILTIN | C_SCSI; 531 hw++; 532 533 hw->hw_pa = 0xdc0000; 534 hw->hw_size = NBPG; 535 hw->hw_kva = 0; /* should be mapped here! */ 536 hw->hw_manufacturer = MANUF_BUILTIN; 537 hw->hw_product = PROD_BUILTIN_CLOCK; 538 hw->hw_type = B_BUILTIN | D_CLOCK; 539 hw++; 540 541 hw->hw_pa = 0; 542 hw->hw_size = 0; 543 hw->hw_kva = 0; /* already mapped, uses CUSTOMbase */ 544 hw->hw_manufacturer = MANUF_BUILTIN; 545 hw->hw_product = PROD_BUILTIN_FLOPPY; 546 hw->hw_type = B_BUILTIN | C_FLOPPY; 547 hw++; 548 549 hw->hw_pa = 0; 550 hw->hw_size = 0; 551 hw->hw_kva = 0; /* already mapped, uses CUSTOMbase */ 552 hw->hw_manufacturer = MANUF_BUILTIN; 553 hw->hw_product = PROD_BUILTIN_RS232; 554 hw->hw_type = B_BUILTIN | D_COMMSER; 555 hw++; 556 557 hw->hw_pa = 0; 558 hw->hw_size = 0; 559 hw->hw_kva = 0; /* already mapped, uses CUSTOMbase */ 560 hw->hw_manufacturer = MANUF_BUILTIN; 561 hw->hw_product = PROD_BUILTIN_KEYBOARD; 562 hw->hw_type = B_BUILTIN | D_KEYBOARD; 563 hw++; 564 565 hw->hw_pa = 0; 566 hw->hw_size = 0; 567 hw->hw_kva = 0; /* already mapped, uses CUSTOMbase */ 568 hw->hw_manufacturer = MANUF_BUILTIN; 569 hw->hw_product = PROD_BUILTIN_PPORT; 570 hw->hw_type = B_BUILTIN | D_PPORT; 571 hw++; 572 573 hw->hw_pa = 0; 574 hw->hw_size = 0; 575 hw->hw_kva = 0; /* already mapped, uses CUSTOMbase */ 576 hw->hw_manufacturer = MANUF_BUILTIN; 577 hw->hw_product = PROD_BUILTIN_DISPLAY; 578 hw->hw_type = B_BUILTIN | D_BITMAP; 579 hw++; 580 581 /* and afterwards add Zorro II/III devices passed by the loader */ 582 583 for (sc = 0, cd = ConfigDev; sc < num_ConfigDev; sc++, cd++) 584 { 585 hw->hw_pa = cd->cd_BoardAddr; 586 hw->hw_size = cd->cd_BoardSize; 587 hw->hw_kva = 0; /* XXX */ 588 hw->hw_manufacturer = cd->cd_Rom.er_Manufacturer; 589 hw->hw_product = cd->cd_Rom.er_Product; 590 591 switch (hw->hw_manufacturer) 592 { 593 case MANUF_CBM_1: 594 switch (hw->hw_product) 595 { 596 case PROD_CBM_1_A2088: 597 hw->hw_type = B_ZORROII | D_MISC; 598 break; 599 600 default: 601 continue; 602 } 603 604 case MANUF_UNILOWELL: 605 switch (hw->hw_product) 606 { 607 case PROD_UNILOWELL_A2410: 608 hw->hw_type = B_ZORROII | D_BITMAP; 609 break; 610 611 default: 612 continue; 613 } 614 615 default: 616 continue; 617 } 618 619 hw++; 620 } 621} 622 623#if 0 624/* 625 * Allocate/deallocate a cache-inhibited range of kernel virtual address 626 * space mapping the indicated physical address range [pa - pa+size) 627 */ 628caddr_t 629iomap(pa, size) 630 caddr_t pa; 631 int size; 632{ 633 int ix, npf; 634 caddr_t kva; 635 636#ifdef DEBUG 637 if (((int)pa & PGOFSET) || (size & PGOFSET)) 638 panic("iomap: unaligned"); 639#endif 640 npf = btoc(size); 641 ix = rmalloc(extiomap, npf); 642 if (ix == 0) 643 return(0); 644 kva = extiobase + ctob(ix-1); 645 physaccess(kva, pa, size, PG_RW|PG_CI); 646 return(kva); 647} 648 649iounmap(kva, size) 650 caddr_t kva; 651 int size; 652{ 653 int ix; 654 655#ifdef DEBUG 656 if (((int)kva & PGOFSET) || (size & PGOFSET)) 657 panic("iounmap: unaligned"); 658 if (kva < extiobase || kva >= extiobase + ctob(EIOMAPSIZE)) 659 panic("iounmap: bad address"); 660#endif 661 physunaccess(kva, size); 662 ix = btoc(kva - extiobase) + 1; 663 rmfree(extiomap, btoc(size), ix); 664} 665#endif 666 667#if NCD > 0 668#include "../dev/cdvar.h" 669 670find_cdevices() 671{ 672 register struct cddevice *cd; 673 674 for (cd = cddevice; cd->cd_unit >= 0; cd++) { 675 /* 676 * XXX 677 * Assign disk index first so that init routine 678 * can use it (saves having the driver drag around 679 * the cddevice pointer just to set up the dk_* 680 * info in the open routine). 681 */ 682 if (dkn < DK_NDRIVE) 683 cd->cd_dk = dkn++; 684 else 685 cd->cd_dk = -1; 686 if (cdinit(cd)) 687 printf("cd%d configured\n", cd->cd_unit); 688 else if (cd->cd_dk >= 0) { 689 cd->cd_dk = -1; 690 dkn--; 691 } 692 } 693} 694#endif 695 696#if 0 697isrinit() 698{ 699 register int i; 700 701 for (i = 0; i < NISR; i++) 702 isrqueue[i].isr_forw = isrqueue[i].isr_back = &isrqueue[i]; 703} 704 705void 706isrlink(isr) 707 register struct isr *isr; 708{ 709 int i = ISRIPL(isr->isr_ipl); 710 711 if (i < 0 || i >= NISR) { 712 printf("bad IPL %d\n", i); 713 panic("configure"); 714 } 715 insque(isr, isrqueue[i].isr_back); 716} 717#endif 718 719/* 720 * Configure swap space and related parameters. 721 */ 722swapconf() 723{ 724 register struct swdevt *swp; 725 register int nblks; 726 727 for (swp = swdevt; swp->sw_dev; swp++) 728 { 729 if (bdevsw[major(swp->sw_dev)].d_psize) { 730 nblks = 731 (*bdevsw[major(swp->sw_dev)].d_psize)(swp->sw_dev); 732 if (nblks != -1 && 733 (swp->sw_nblks == 0 || swp->sw_nblks > nblks)) 734 { 735 swp->sw_nblks = nblks; 736/* printf ("swap: dev %x = %d\n", swp->sw_dev, nblks);*/ 737 } 738 } 739 } 740 dumpconf(); 741 742 printf ("\n"); 743} 744 745#define DOSWAP /* Change swdevt and dumpdev too */ 746u_long bootdev; /* should be dev_t, but not until 32 bits */ 747 748static char devname[][2] = { 749 0,0, /* 0 = ct */ 750 0,0, /* 1 = xx */ 751 'r','d', /* 2 = rd */ 752 0,0, /* 3 = sw */ 753 's','d', /* 4 = sd */ 754}; 755 756#define PARTITIONMASK 0x7 757#define PARTITIONSHIFT 3 758 759/* 760 * Attempt to find the device from which we were booted. 761 * If we can do so, and not instructed not to do so, 762 * change rootdev to correspond to the load device. 763 */ 764setroot() 765{ 766 register struct amiga_ctlr *ac; 767 register struct amiga_device *ad; 768 int majdev, mindev, unit, part, adaptor; 769 dev_t temp, orootdev; 770 struct swdevt *swp; 771 772/* printf ("setroot: boothowto = 0x%x, bootdev = 0x%x\n", boothowto, bootdev);*/ 773 774 if (boothowto & RB_DFLTROOT || 775 (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC) 776 return; 777 majdev = (bootdev >> B_TYPESHIFT) & B_TYPEMASK; 778 if (majdev > sizeof(devname) / sizeof(devname[0])) 779 return; 780 adaptor = (bootdev >> B_ADAPTORSHIFT) & B_ADAPTORMASK; 781 part = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK; 782 unit = (bootdev >> B_UNITSHIFT) & B_UNITMASK; 783 /* 784 * First, find the controller type which support this device. 785 */ 786 for (ad = amiga_dinit; ad->amiga_driver; ad++) 787 if (ad->amiga_driver->d_name[0] == devname[majdev][0] && 788 ad->amiga_driver->d_name[1] == devname[majdev][1]) 789 break; 790 if (ad->amiga_driver == 0) 791 return; 792 /* 793 * Next, find the controller of that type corresponding to 794 * the adaptor number. 795 */ 796 for (ac = amiga_cinit; ac->amiga_driver; ac++) 797 if (ac->amiga_alive && ac->amiga_unit == adaptor && 798 ac->amiga_driver == ad->amiga_cdriver) 799 break; 800 if (ac->amiga_driver == 0) 801 return; 802 /* 803 * Finally, find the device in question attached to that controller. 804 */ 805 for (ad = amiga_dinit; ad->amiga_driver; ad++) 806 if (ad->amiga_alive && ad->amiga_slave == unit && 807 ad->amiga_cdriver == ac->amiga_driver && 808 ad->amiga_ctlr == ac->amiga_unit) 809 break; 810 if (ad->amiga_driver == 0) 811 return; 812 mindev = ad->amiga_unit; 813 /* 814 * Form a new rootdev 815 */ 816 mindev = (mindev << PARTITIONSHIFT) + part; 817 orootdev = rootdev; 818 rootdev = makedev(majdev, mindev); 819 /* 820 * If the original rootdev is the same as the one 821 * just calculated, don't need to adjust the swap configuration. 822 */ 823 if (rootdev == orootdev) 824 return; 825 826 printf("Changing root device to %c%c%d%c\n", 827 devname[majdev][0], devname[majdev][1], 828 mindev >> PARTITIONSHIFT, part + 'a'); 829 830#ifdef DOSWAP 831 mindev &= ~PARTITIONMASK; 832 for (swp = swdevt; swp->sw_dev; swp++) { 833 if (majdev == major(swp->sw_dev) && 834 mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) { 835 temp = swdevt[0].sw_dev; 836 swdevt[0].sw_dev = swp->sw_dev; 837 swp->sw_dev = temp; 838 break; 839 } 840 } 841 if (swp->sw_dev == 0) 842 return; 843 844 /* 845 * If dumpdev was the same as the old primary swap 846 * device, move it to the new primary swap device. 847 */ 848 if (temp == dumpdev) 849 dumpdev = swdevt[0].sw_dev; 850#endif 851} 852