autoconf.c revision 1.7
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 "configdev.h" 65#include "custom.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/* set up in amiga_init.c */ 78extern caddr_t ZORRO2ADDR; 79 80/* maps a zorro2 and/or A3000 builtin address into the mapped kva address */ 81#define zorro2map(pa) ((caddr_t) ((u_int)ZORRO2ADDR - ZORRO2BASE + (u_int)pa)) 82/* tests whether the address lies in our zorro2 space */ 83#define iszorro2kva(kva) ((u_int)kva >= (u_int)ZORRO2ADDR && (u_int)kva < ((u_int)ZORRO2ADDR+(u_int)ZORRO2TOP-(u_int)ZORRO2BASE)) 84#define iszorro2pa(pa) ((u_int)pa >= ZORRO2BASE && (u_int)pa <= ZORRO2TOP) 85 86#ifdef DEBUG 87int acdebug = 0; 88#endif 89 90/* 91 * Determine mass storage and memory configuration for a machine. 92 */ 93configure() 94{ 95 register struct amiga_hw *hw; 96 int found; 97 98 /* XXXX I HATE IT XXXX */ 99 custom.intena = INTF_INTEN; 100 101 /* 102 * Look over each hardware device actually found and attempt 103 * to match it with an ioconf.c table entry. 104 */ 105 for (hw = sc_table; hw->hw_type; hw++) { 106 if (HW_ISCTLR(hw)) 107 found = find_controller(hw); 108 else 109 found = find_device(hw); 110#ifdef DEBUG 111 if (!found && acdebug) { 112 printf("unconfigured device %d/%d\n", 113 hw->hw_manufacturer, hw->hw_product); 114 } 115#endif 116 } 117 118#if 0 119#include "cd.h" 120#if NCD > 0 121 /* 122 * Now deal with concatenated disks 123 */ 124 find_cdevices(); 125#endif 126#endif 127 128#if GENERIC 129 if ((boothowto & RB_ASKNAME) == 0) 130 setroot(); 131 setconf(); 132#else 133 setroot(); 134#endif 135 swapconf(); 136 cold = 0; 137 138 custom.intena = INTF_SETCLR | INTF_INTEN; 139} 140 141#define dr_type(d, s) \ 142 (strcmp((d)->d_name, (s)) == 0) 143 144#define same_hw_ctlr(hw, ac) \ 145 (HW_ISFLOPPY(hw) && dr_type((ac)->amiga_driver, "floppy") || \ 146 HW_ISSCSI(hw) && (dr_type((ac)->amiga_driver, "a3000scsi") \ 147 || dr_type((ac)->amiga_driver, "a2091scsi") \ 148 || dr_type((ac)->amiga_driver, "GVPIIscsi") \ 149 || dr_type((ac)->amiga_driver, "Zeusscsi") \ 150 || dr_type((ac)->amiga_driver, "Magnumscsi"))) 151 152find_controller(hw) 153 register struct amiga_hw *hw; 154{ 155 register struct amiga_ctlr *ac; 156 struct amiga_ctlr *match_c; 157 caddr_t oaddr; 158 int sc; 159 160#ifdef DEBUG 161 if (acdebug) 162 printf("find_controller: hw: [%d/%d] (%x), type %x...", 163 hw->hw_manufacturer, hw->hw_product, 164 hw->hw_kva, hw->hw_type); 165#endif 166 sc = (hw->hw_manufacturer << 16) | hw->hw_product; 167 match_c = NULL; 168 for (ac = amiga_cinit; ac->amiga_driver; ac++) { 169 if (ac->amiga_alive) 170 continue; 171 /* 172 * Make sure we are looking at the right 173 * controller type. 174 */ 175 if (!same_hw_ctlr(hw, ac)) 176 continue; 177 /* 178 * Exact match; all done 179 */ 180 if ((int)ac->amiga_addr == sc) { 181 match_c = ac; 182 break; 183 } 184 /* 185 * Wildcard; possible match so remember first instance 186 * but continue looking for exact match. 187 */ 188 if (ac->amiga_addr == NULL && match_c == NULL) 189 match_c = ac; 190 } 191#ifdef DEBUG 192 if (acdebug) { 193 if (match_c) 194 printf("found %s%d\n", 195 match_c->amiga_driver->d_name, 196 match_c->amiga_unit); 197 else 198 printf("not found\n"); 199 } 200#endif 201 /* 202 * Didn't find an ioconf entry for this piece of hardware, 203 * just ignore it. 204 */ 205 if (match_c == NULL) 206 return(0); 207 /* 208 * Found a match, attempt to initialize and configure all attached 209 * slaves. Note, we can still fail if HW won't initialize. 210 */ 211 ac = match_c; 212 oaddr = ac->amiga_addr; 213 ac->amiga_addr = hw->hw_kva; 214 if ((*ac->amiga_driver->d_init)(ac)) { 215 ac->amiga_alive = 1; 216 printf ("%s%d", ac->amiga_driver->d_name, ac->amiga_unit); 217 printf (" [%d/%d]", hw->hw_manufacturer, hw->hw_product); 218 if (ac->amiga_flags) 219 printf(", flags 0x%x", ac->amiga_flags); 220 printf("\n"); 221 find_slaves(ac); 222 } else 223 ac->amiga_addr = oaddr; 224 return(1); 225} 226 227find_device(hw) 228 register struct amiga_hw *hw; 229{ 230 register struct amiga_device *ad; 231 struct amiga_device *match_d; 232 caddr_t oaddr; 233 int sc; 234 235#ifdef DEBUG 236 if (acdebug) 237 printf("find_device: hw: [%d/%d] (%x), type %x...", 238 hw->hw_manufacturer, hw->hw_product, 239 hw->hw_kva, hw->hw_type); 240#endif 241 match_d = NULL; 242 for (ad = amiga_dinit; ad->amiga_driver; ad++) { 243 if (ad->amiga_alive) 244 continue; 245 /* Must not be a slave */ 246 if (ad->amiga_cdriver) 247 continue; 248 249 /* 250 * XXX: A graphics device that was found as part of the 251 * console init will have the amiga_addr field already set 252 * (i.e. no longer the select code). Gotta perform a 253 * slightly different check for an exact match. 254 */ 255 if (HW_ISDEV(hw, D_BITMAP) && iszorro2kva(ad->amiga_addr)) 256 { 257 if (ad->amiga_addr == hw->hw_kva) 258 { 259 match_d = ad; 260 break; 261 } 262 continue; 263 } 264 sc = (int) ad->amiga_addr; 265 /* 266 * Exact match; all done. 267 */ 268 if (sc > 0 && sc == ((hw->hw_manufacturer << 16) | hw->hw_product)) { 269 match_d = ad; 270 break; 271 } 272 /* 273 * Wildcard; possible match so remember first instance 274 * but continue looking for exact match. 275 */ 276 if (sc == 0 && same_hw_device(hw, ad) && match_d == NULL) 277 match_d = ad; 278 } 279#ifdef DEBUG 280 if (acdebug) { 281 if (match_d) 282 printf("found %s%d\n", 283 match_d->amiga_driver->d_name, 284 match_d->amiga_unit); 285 else 286 printf("not found\n"); 287 } 288#endif 289 /* 290 * Didn't find an ioconf entry for this piece 291 * of hardware, just ignore it. 292 */ 293 if (match_d == NULL) 294 return(0); 295 /* 296 * Found a match, attempt to initialize. 297 * Note, we can still fail if HW won't initialize. 298 */ 299 ad = match_d; 300 oaddr = ad->amiga_addr; 301 ad->amiga_addr = hw->hw_kva; 302 ad->amiga_serno = hw->hw_serno; 303 ad->amiga_size = hw->hw_size; 304 if ((*ad->amiga_driver->d_init)(ad)) { 305 ad->amiga_alive = 1; 306 printf("%s%d", ad->amiga_driver->d_name, ad->amiga_unit); 307 printf (" [%d/%d]", hw->hw_manufacturer, hw->hw_product); 308 if (ad->amiga_flags) 309 printf(", flags 0x%x", ad->amiga_flags); 310 printf("\n"); 311 } else 312 ad->amiga_addr = oaddr; 313 return(1); 314} 315 316find_slaves(ac) 317 struct amiga_ctlr *ac; 318{ 319 if (dr_type(ac->amiga_driver, "floppy")) 320 find_busslaves(ac, 4); 321 else if (dr_type(ac->amiga_driver, "a3000scsi") 322 || dr_type(ac->amiga_driver, "a2091scsi") 323 || dr_type(ac->amiga_driver, "GVPIIscsi") 324 || dr_type(ac->amiga_driver, "Zeusscsi") 325 || dr_type(ac->amiga_driver, "Magnumscsi")) 326 find_busslaves(ac, 7); 327} 328 329/* 330 */ 331find_busslaves(ac, maxslaves) 332 register struct amiga_ctlr *ac; 333 int maxslaves; 334{ 335 register int s; 336 register struct amiga_device *ad; 337 struct amiga_device *match_s; 338 int new_s, new_c, old_s, old_c; 339 int rescan; 340 341#ifdef DEBUG 342 if (acdebug) 343 printf("find_busslaves: for %s%d\n", 344 ac->amiga_driver->d_name, ac->amiga_unit); 345#endif 346 for (s = 0; s < maxslaves; s++) { 347 rescan = 1; 348 match_s = NULL; 349 for (ad = amiga_dinit; ad->amiga_driver; ad++) { 350 /* 351 * Rule out the easy ones: 352 * 1. slave already assigned or not a slave 353 * 2. not of the proper type 354 * 3. controller specified but not this one 355 * 4. slave specified but not this one 356 */ 357 if (ad->amiga_alive || ad->amiga_cdriver == NULL) 358 continue; 359 if (!dr_type(ac->amiga_driver, ad->amiga_cdriver->d_name)) 360 continue; 361 if (ad->amiga_ctlr >= 0 && ad->amiga_ctlr != ac->amiga_unit) 362 continue; 363 if (ad->amiga_slave >= 0 && ad->amiga_slave != s) 364 continue; 365 /* 366 * Case 0: first possible match. 367 * Remember it and keep looking for better. 368 */ 369 if (match_s == NULL) { 370 match_s = ad; 371 new_c = ac->amiga_unit; 372 new_s = s; 373 continue; 374 } 375 /* 376 * Case 1: exact match. 377 * All done. Note that we do not attempt any other 378 * matches if this one fails. This allows us to 379 * "reserve" locations for dynamic addition of 380 * disk/tape drives by fully qualifing the location. 381 */ 382 if (ad->amiga_slave == s && ad->amiga_ctlr == ac->amiga_unit) { 383 match_s = ad; 384 rescan = 0; 385 break; 386 } 387 /* 388 * Case 2: right controller, wildcarded slave. 389 * Remember first and keep looking for an exact match. 390 */ 391 if (ad->amiga_ctlr == ac->amiga_unit && 392 match_s->amiga_ctlr < 0) { 393 match_s = ad; 394 new_s = s; 395 continue; 396 } 397 /* 398 * Case 3: right slave, wildcarded controller. 399 * Remember and keep looking for a better match. 400 */ 401 if (ad->amiga_slave == s && 402 match_s->amiga_ctlr < 0 && match_s->amiga_slave < 0) { 403 match_s = ad; 404 new_c = ac->amiga_unit; 405 continue; 406 } 407 /* 408 * OW: we had a totally wildcarded spec. 409 * If we got this far, we have found a possible 410 * match already (match_s != NULL) so there is no 411 * reason to remember this one. 412 */ 413 continue; 414 } 415 /* 416 * Found a match. We need to set amiga_ctlr/amiga_slave properly 417 * for the init routines but we also need to remember all 418 * the old values in case this doesn't pan out. 419 */ 420 if (match_s) { 421 ad = match_s; 422 old_c = ad->amiga_ctlr; 423 old_s = ad->amiga_slave; 424 if (ad->amiga_ctlr < 0) 425 ad->amiga_ctlr = new_c; 426 if (ad->amiga_slave < 0) 427 ad->amiga_slave = new_s; 428#ifdef DEBUG 429 if (acdebug) 430 printf("looking for %s%d at slave %d...", 431 ad->amiga_driver->d_name, 432 ad->amiga_unit, ad->amiga_slave); 433#endif 434 435 if ((*ad->amiga_driver->d_init)(ad)) { 436#ifdef DEBUG 437 if (acdebug) 438 printf("found\n"); 439#endif 440 printf("%s%d at %s%d, slave %d", 441 ad->amiga_driver->d_name, ad->amiga_unit, 442 ac->amiga_driver->d_name, ad->amiga_ctlr, 443 ad->amiga_slave); 444 if (ad->amiga_flags) 445 printf(" flags 0x%x", ad->amiga_flags); 446 printf("\n"); 447 ad->amiga_alive = 1; 448 if (ad->amiga_dk && dkn < DK_NDRIVE) 449 ad->amiga_dk = dkn++; 450 else 451 ad->amiga_dk = -1; 452 rescan = 1; 453 /* 454 * The init on this unit suceeded, so we need to 455 * mark the same device/unit on other hardware 456 * controllers as "alive" since we can't reuse 457 * the same unit for that device driver. mlh 458 */ 459 for (ad = amiga_dinit; ad->amiga_driver; ad++) { 460 if (ad->amiga_driver == match_s->amiga_driver && 461 ad->amiga_unit == match_s->amiga_unit) 462 ad->amiga_alive = 2; 463 } 464 } else { 465#ifdef DEBUG 466 if (acdebug) 467 printf("not found\n"); 468#endif 469 ad->amiga_ctlr = old_c; 470 ad->amiga_slave = old_s; 471 } 472 /* 473 * XXX: This should be handled better. 474 * Re-scan a slave. There are two reasons to do this. 475 * 1. It is possible to have both a tape and disk 476 * (e.g. 7946) or two disks (e.g. 9122) at the 477 * same slave address. Here we need to rescan 478 * looking only at entries with a different 479 * physical unit number (amiga_flags). 480 * 2. It is possible that an init failed because the 481 * slave was there but of the wrong type. In this 482 * case it may still be possible to match the slave 483 * to another ioconf entry of a different type. 484 * Here we need to rescan looking only at entries 485 * of different types. 486 * In both cases we avoid looking at undesirable 487 * ioconf entries of the same type by setting their 488 * alive fields to -1. 489 */ 490 if (rescan) { 491 for (ad = amiga_dinit; ad->amiga_driver; ad++) { 492 if (ad->amiga_alive) 493 continue; 494 if (match_s->amiga_alive == 1) { /* 1 */ 495 if (ad->amiga_flags == match_s->amiga_flags) 496 ad->amiga_alive = -1; 497 } else { /* 2 */ 498 if (ad->amiga_driver == match_s->amiga_driver) 499 ad->amiga_alive = -1; 500 } 501 } 502 s--; 503 continue; 504 } 505 } 506 /* 507 * Reset bogon alive fields prior to attempting next slave 508 */ 509 for (ad = amiga_dinit; ad->amiga_driver; ad++) 510 if (ad->amiga_alive == -1) 511 ad->amiga_alive = 0; 512 } 513} 514 515same_hw_device(hw, ad) 516 struct amiga_hw *hw; 517 struct amiga_device *ad; 518{ 519 int found = 0; 520 521 switch (hw->hw_type & ~B_MASK) { 522 case C_FLOPPY: 523 found = dr_type(ad->amiga_driver, "floppy"); 524 break; 525 case C_SCSI: 526 found = (dr_type(ad->amiga_driver, "a3000scsi") 527 || dr_type(ad->amiga_driver, "a2091scsi") 528 || dr_type(ad->amiga_driver, "GVPIIscsi") 529 || dr_type(ad->amiga_driver, "Zeusscsi") 530 || dr_type(ad->amiga_driver, "Magnumscsi")); 531 break; 532 case D_BITMAP: 533 found = dr_type(ad->amiga_driver, "grf"); 534 break; 535 case D_LAN: 536 found = dr_type(ad->amiga_driver, "le"); 537 break; 538 case D_COMMSER: 539 found = dr_type(ad->amiga_driver, "ser"); 540 break; 541 case D_CLOCK: 542 found = dr_type(ad->amiga_driver, "rtclock"); 543 break; 544 case D_PPORT: 545 found = dr_type(ad->amiga_driver, "par"); 546 break; 547 default: 548 break; 549 } 550 return(found); 551} 552 553char notmappedmsg[] = "WARNING: no space to map IO card, ignored\n"; 554 555/* 556 * Scan the IO space looking for devices. 557 */ 558find_devs() 559{ 560 short sc; 561 u_char *id_reg; 562 register caddr_t addr; 563 register struct amiga_hw *hw; 564 int didmap, sctop; 565 extern int num_ConfigDev; 566 extern struct ConfigDev *ConfigDev; 567 struct ConfigDev *cd; 568 569#if 0 570 /* 571 * Initialize IO resource map for iomap(). 572 */ 573 rminit(extiomap, (long)EIOMAPSIZE, (long)1, "extio", EIOMAPSIZE/16); 574#endif 575 hw = sc_table; 576 577 /* first enter builtin devices */ 578 579 if (is_a4000 ()) 580 { 581 /* The A4000 appears to use the same realtime clock as the A3000. 582 Add the IDE controller when that information becomes available. 583 */ 584 585 hw->hw_pa = (caddr_t) 0xdc0000; 586 hw->hw_size = NBPG; 587 hw->hw_kva = zorro2map (0xdc0000); 588 hw->hw_manufacturer = MANUF_BUILTIN; 589 hw->hw_product = PROD_BUILTIN_CLOCK; 590 hw->hw_type = B_BUILTIN | D_CLOCK; 591 hw->hw_serno = 0; 592 hw++; 593 } 594 else if (is_a3000 ()) 595 { 596 /* hm, this doesn't belong here... */ 597 volatile u_char *magic_reset_reg = zorro2map (0xde0002); 598 /* this bit makes the next reset look like a powerup reset, Amiga 599 Unix sets this bit, and perhaps it will enable 16M machines to 600 boot again... */ 601 *magic_reset_reg |= 0x80; 602 603 hw->hw_pa = (caddr_t) 0xdd0000; 604 hw->hw_size = NBPG; 605 hw->hw_kva = zorro2map (0xdd0000); 606 hw->hw_manufacturer = MANUF_BUILTIN; 607 hw->hw_product = PROD_BUILTIN_SCSI; 608 hw->hw_type = B_BUILTIN | C_SCSI; 609 hw->hw_serno = 0; 610 hw++; 611 612 hw->hw_pa = (caddr_t) 0xdc0000; 613 hw->hw_size = NBPG; 614 hw->hw_kva = zorro2map (0xdc0000); 615 hw->hw_manufacturer = MANUF_BUILTIN; 616 hw->hw_product = PROD_BUILTIN_CLOCK; 617 hw->hw_type = B_BUILTIN | D_CLOCK; 618 hw->hw_serno = 0; 619 hw++; 620 } 621 else 622 { 623 /* what about other Amigas? Oh well.. */ 624 hw->hw_pa = (caddr_t) 0xdc0000; 625 hw->hw_size = NBPG; 626 hw->hw_kva = zorro2map (0xdc0000); 627 hw->hw_manufacturer = MANUF_BUILTIN; 628 hw->hw_product = PROD_BUILTIN_CLOCK2; 629 hw->hw_type = B_BUILTIN | D_CLOCK; 630 hw->hw_serno = 0; 631 hw++; 632 } 633 634 hw->hw_pa = 0; 635 hw->hw_size = 0; 636 hw->hw_kva = (caddr_t) CUSTOMbase; 637 hw->hw_manufacturer = MANUF_BUILTIN; 638 hw->hw_product = PROD_BUILTIN_FLOPPY; 639 hw->hw_type = B_BUILTIN | C_FLOPPY; 640 hw->hw_serno = 0; 641 hw++; 642 643 hw->hw_pa = 0; 644 hw->hw_size = 0; 645 hw->hw_kva = (caddr_t) CUSTOMbase; 646 hw->hw_manufacturer = MANUF_BUILTIN; 647 hw->hw_product = PROD_BUILTIN_KEYBOARD; 648 hw->hw_type = B_BUILTIN | D_KEYBOARD; 649 hw->hw_serno = 0; 650 hw++; 651 652 hw->hw_pa = 0; 653 hw->hw_size = 0; 654 hw->hw_kva = (caddr_t) CUSTOMbase; 655 hw->hw_manufacturer = MANUF_BUILTIN; 656 hw->hw_product = PROD_BUILTIN_PPORT; 657 hw->hw_type = B_BUILTIN | D_PPORT; 658 hw->hw_serno = 0; 659 hw++; 660 661 hw->hw_pa = 0; 662 hw->hw_size = 0; 663 hw->hw_kva = (caddr_t) CUSTOMbase; 664 hw->hw_manufacturer = MANUF_BUILTIN; 665 hw->hw_product = PROD_BUILTIN_DISPLAY; 666 hw->hw_type = B_BUILTIN | D_BITMAP; 667 hw->hw_serno = 0; 668 hw++; 669 670 hw->hw_pa = 0; 671 hw->hw_size = 0; 672 hw->hw_kva = (caddr_t) CUSTOMbase; 673 hw->hw_manufacturer = MANUF_BUILTIN; 674 hw->hw_product = PROD_BUILTIN_RS232; 675 hw->hw_type = B_BUILTIN | D_COMMSER; 676 hw->hw_serno = 0; 677 hw++; 678 679 /* and afterwards add Zorro II/III devices passed by the loader */ 680 681 for (sc = 0, cd = ConfigDev; sc < num_ConfigDev; sc++, cd++) 682 { 683 hw->hw_pa = cd->cd_BoardAddr; 684 hw->hw_size = cd->cd_BoardSize; 685 /* ADD ZORRO3 SUPPORT HERE !! */ 686 hw->hw_kva = iszorro2pa(cd->cd_BoardAddr) ? zorro2map (cd->cd_BoardAddr) : 0; 687 hw->hw_manufacturer = cd->cd_Rom.er_Manufacturer; 688 hw->hw_product = cd->cd_Rom.er_Product; 689 hw->hw_serno = cd->cd_Rom.er_SerialNumber; 690 691 switch (hw->hw_manufacturer) 692 { 693 case MANUF_CBM_1: 694 switch (hw->hw_product) 695 { 696 case PROD_CBM_1_A2088: 697 hw->hw_type = B_ZORROII | D_MISC; 698 break; 699 700 default: 701 continue; 702 } 703 break; 704 705 case MANUF_CBM_2: 706 switch (hw->hw_product) 707 { 708 case PROD_CBM_2_A2091: 709 hw->hw_type = B_ZORROII | C_SCSI; 710 break; 711 712 case PROD_CBM_2_A2065: 713 hw->hw_type = B_ZORROII | D_LAN; 714 /* the ethernet board uses bytes 1 to 3 for ID, set byte 0 to indicate 715 whether Commodore or Ameristar board. */ 716 hw->hw_serno = (hw->hw_serno & 0x00ffffff) | 0x01000000; 717 break; 718 719 default: 720 continue; 721 } 722 break; 723 724 case MANUF_AMERISTAR: 725 switch (hw->hw_product) 726 { 727 case PROD_AMERISTAR_ETHER: 728 hw->hw_type = B_ZORROII | D_LAN; 729 /* the ethernet board uses bytes 1 to 3 for ID, set byte 0 to indicate 730 whether Commodore or Ameristar board. */ 731 hw->hw_serno = (hw->hw_serno & 0x00ffffff) | 0x02000000; 732 break; 733 734 default: 735 continue; 736 } 737 break; 738 739 case MANUF_UNILOWELL: 740 switch (hw->hw_product) 741 { 742 case PROD_UNILOWELL_A2410: 743 hw->hw_type = B_ZORROII | D_BITMAP; 744 break; 745 746 default: 747 continue; 748 } 749 break; 750 751 case MANUF_MACROSYSTEM: 752 switch (hw->hw_product) 753 { 754 case PROD_MACROSYSTEM_RETINA: 755 hw->hw_type = B_ZORROII | D_BITMAP; 756 break; 757 758 default: 759 continue; 760 } 761 break; 762 763 case MANUF_GVP: 764 switch (hw->hw_product) 765 { 766 case PROD_GVP_SERIES_II: 767 /* Kludge for I/O extender: 768 if er_notused != 0, it's a SCSI controller 769 if er_notused == 0, it's either an I/O extender or might 770 possibly be a SCSI controller with autoboot disabled */ 771 if (cd->cd_Rom.er_notused) 772 hw->hw_type = B_ZORROII | C_SCSI; 773 else 774 hw->hw_type = B_ZORROII | D_COMMSER; 775 break; 776 777 case PROD_GVP_IV24: 778 hw->hw_type = B_ZORROII | D_BITMAP; 779 break; 780 781 default: 782 continue; 783 } 784 break; 785 786 case MANUF_PPI: 787 switch (hw->hw_product) 788 { 789 case PROD_PPI_ZEUS: 790 hw->hw_type = B_ZORROII | C_SCSI; 791 break; 792 793 default: 794 continue; 795 } 796 break; 797 798 case MANUF_CSA: 799 switch (hw->hw_product) 800 { 801 case PROD_CSA_MAGNUM: 802 hw->hw_type = B_ZORROII | C_SCSI; 803 break; 804 805 default: 806 continue; 807 } 808 break; 809 810 default: 811 continue; 812 } 813 814 hw++; 815 } 816} 817 818#if 0 819/* 820 * Allocate/deallocate a cache-inhibited range of kernel virtual address 821 * space mapping the indicated physical address range [pa - pa+size) 822 */ 823caddr_t 824iomap(pa, size) 825 caddr_t pa; 826 int size; 827{ 828 int ix, npf; 829 caddr_t kva; 830 831#ifdef DEBUG 832 if (((int)pa & PGOFSET) || (size & PGOFSET)) 833 panic("iomap: unaligned"); 834#endif 835 npf = btoc(size); 836 ix = rmalloc(extiomap, npf); 837 if (ix == 0) 838 return(0); 839 kva = extiobase + ctob(ix-1); 840 physaccess(kva, pa, size, PG_RW|PG_CI); 841 return(kva); 842} 843 844iounmap(kva, size) 845 caddr_t kva; 846 int size; 847{ 848 int ix; 849 850#ifdef DEBUG 851 if (((int)kva & PGOFSET) || (size & PGOFSET)) 852 panic("iounmap: unaligned"); 853 if (kva < extiobase || kva >= extiobase + ctob(EIOMAPSIZE)) 854 panic("iounmap: bad address"); 855#endif 856 physunaccess(kva, size); 857 ix = btoc(kva - extiobase) + 1; 858 rmfree(extiomap, btoc(size), ix); 859} 860#endif 861 862#if NCD > 0 863#include "../dev/cdvar.h" 864 865find_cdevices() 866{ 867 register struct cddevice *cd; 868 869 for (cd = cddevice; cd->cd_unit >= 0; cd++) { 870 /* 871 * XXX 872 * Assign disk index first so that init routine 873 * can use it (saves having the driver drag around 874 * the cddevice pointer just to set up the dk_* 875 * info in the open routine). 876 */ 877 if (dkn < DK_NDRIVE) 878 cd->cd_dk = dkn++; 879 else 880 cd->cd_dk = -1; 881 if (cdinit(cd)) 882 printf("cd%d configured\n", cd->cd_unit); 883 else if (cd->cd_dk >= 0) { 884 cd->cd_dk = -1; 885 dkn--; 886 } 887 } 888} 889#endif 890 891#if 0 892isrinit() 893{ 894 register int i; 895 896 for (i = 0; i < NISR; i++) 897 isrqueue[i].isr_forw = isrqueue[i].isr_back = &isrqueue[i]; 898} 899 900void 901isrlink(isr) 902 register struct isr *isr; 903{ 904 int i = ISRIPL(isr->isr_ipl); 905 906 if (i < 0 || i >= NISR) { 907 printf("bad IPL %d\n", i); 908 panic("configure"); 909 } 910 insque(isr, isrqueue[i].isr_back); 911} 912#endif 913 914/* 915 * Configure swap space and related parameters. 916 */ 917swapconf() 918{ 919 register struct swdevt *swp; 920 register int nblks; 921 922 for (swp = swdevt; swp->sw_dev; swp++) 923 { 924 if (bdevsw[major(swp->sw_dev)].d_psize) { 925 nblks = 926 (*bdevsw[major(swp->sw_dev)].d_psize)(swp->sw_dev); 927 if (nblks != -1 && 928 (swp->sw_nblks == 0 || swp->sw_nblks > nblks)) 929 { 930 swp->sw_nblks = nblks; 931/* printf ("swap: dev %x = %d\n", swp->sw_dev, nblks);*/ 932 } 933 } 934 } 935 dumpconf(); 936 937 printf ("\n"); 938} 939 940#define DOSWAP /* Change swdevt and dumpdev too */ 941u_long bootdev; /* should be dev_t, but not until 32 bits */ 942 943static 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 = sd */ 949 'r','z', /* 5 = sz */ 950}; 951 952#define PARTITIONMASK 0x7 953#define PARTITIONSHIFT 3 954 955/* 956 * Attempt to find the device from which we were booted. 957 * If we can do so, and not instructed not to do so, 958 * change rootdev to correspond to the load device. 959 */ 960setroot() 961{ 962 register struct amiga_ctlr *ac; 963 register struct amiga_device *ad; 964 int majdev, mindev, unit, part, adaptor; 965 dev_t temp, orootdev; 966 struct swdevt *swp; 967 968#ifdef DEBUG 969 if (acdebug > 1) 970 printf ("setroot: boothowto = 0x%x, bootdev = 0x%x\n", boothowto, bootdev); 971#endif 972 973 if (boothowto & RB_DFLTROOT || 974 (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC) 975 { 976#ifdef DEBUG 977 if (acdebug > 1) 978 printf ("returning due to: bad boothowto\n"); 979#endif 980 return; 981 } 982 majdev = (bootdev >> B_TYPESHIFT) & B_TYPEMASK; 983 if (majdev > sizeof(devname) / sizeof(devname[0])) 984 { 985#ifdef DEBUG 986 if (acdebug > 1) 987 printf ("returning due to: majdev (%d) > maxdevs (%d)\n", 988 majdev, sizeof(devname) / sizeof(devname[0])); 989#endif 990 return; 991 } 992 adaptor = (bootdev >> B_ADAPTORSHIFT) & B_ADAPTORMASK; 993 part = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK; 994 unit = (bootdev >> B_UNITSHIFT) & B_UNITMASK; 995 996 /* First, find the controller type which support this device. 997 998 Can have more than one controller for the same device, with 999 just one of them configured, so test for ad->amiga_cdriver != 0 1000 too. */ 1001 1002 for (ad = amiga_dinit; ad->amiga_driver; ad++) 1003 { 1004 if (ad->amiga_driver->d_name[0] != devname[majdev][0] 1005 || ad->amiga_driver->d_name[1] != devname[majdev][1]) 1006 continue; 1007 1008 /* 1009 * Next, find the controller of that type corresponding to 1010 * the adaptor number. 1011 */ 1012 for (ac = amiga_cinit; ac->amiga_driver; ac++) 1013 if (ac->amiga_alive && ac->amiga_unit == adaptor && 1014 ac->amiga_driver == ad->amiga_cdriver) 1015 goto found_it; 1016 } 1017 1018/* could also place after test, but I'd like to be on the safe side */ 1019found_it: 1020 if (ad->amiga_driver == 0) 1021 { 1022#ifdef DEBUG 1023 if (acdebug > 1) 1024 printf ("returning due to: amiga_driver == 0\n"); 1025#endif 1026 return; 1027 } 1028 1029 /* 1030 * Finally, find the device in question attached to that controller. 1031 */ 1032 for (ad = amiga_dinit; ad->amiga_driver; ad++) 1033 if (ad->amiga_alive && ad->amiga_slave == unit && 1034 ad->amiga_cdriver == ac->amiga_driver && 1035 ad->amiga_ctlr == ac->amiga_unit) 1036 break; 1037 if (ad->amiga_driver == 0) 1038 { 1039#ifdef DEBUG 1040 if (acdebug > 1) 1041 printf ("returning due to: no device\n"); 1042#endif 1043 return; 1044 } 1045 mindev = ad->amiga_unit; 1046 /* 1047 * Form a new rootdev 1048 */ 1049 mindev = (mindev << PARTITIONSHIFT) + part; 1050 orootdev = rootdev; 1051 rootdev = makedev(majdev, mindev); 1052 /* 1053 * If the original rootdev is the same as the one 1054 * just calculated, don't need to adjust the swap configuration. 1055 */ 1056 if (rootdev == orootdev) 1057 { 1058#ifdef DEBUG 1059 if (acdebug > 1) 1060 printf ("returning due to: new root == old root\n"); 1061#endif 1062 return; 1063 } 1064 1065 1066 1067 printf("Changing root device to %c%c%d%c\n", 1068 devname[majdev][0], devname[majdev][1], 1069 mindev >> PARTITIONSHIFT, part + 'a'); 1070 1071#ifdef DOSWAP 1072 mindev &= ~PARTITIONMASK; 1073 for (swp = swdevt; swp->sw_dev; swp++) { 1074 if (majdev == major(swp->sw_dev) && 1075 mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) { 1076 temp = swdevt[0].sw_dev; 1077 swdevt[0].sw_dev = swp->sw_dev; 1078 swp->sw_dev = temp; 1079 break; 1080 } 1081 } 1082 if (swp->sw_dev == 0) 1083 return; 1084 1085 /* 1086 * If dumpdev was the same as the old primary swap 1087 * device, move it to the new primary swap device. 1088 */ 1089 if (temp == dumpdev) 1090 dumpdev = swdevt[0].sw_dev; 1091#endif 1092} 1093 1094/* try to determine, of this machine is an A3000, which has a builtin 1095 realtime clock and scsi controller, so that this hardware is only 1096 included as "configured" if this IS an A3000 */ 1097 1098int a3000_flag = 1; /* patchable */ 1099#ifdef A4000 1100int a4000_flag = 1; /* patchable - default to A4000 */ 1101#else 1102int a4000_flag = 0; /* patchable */ 1103#endif 1104 1105int 1106is_a3000 () 1107{ 1108 /* this is a dirty kludge.. but how do you do this RIGHT ? :-) */ 1109 extern long orig_fastram_start; 1110 short sc; 1111 extern int num_ConfigDev; 1112 extern struct ConfigDev *ConfigDev; 1113 struct ConfigDev *cd; 1114 1115 /* where is fastram on the A4000 ?? */ 1116 /* if fastram is below 0x07000000, assume it's not an A3000 */ 1117 if (orig_fastram_start < 0x07000000) 1118 return (0); 1119 1120 /* OK, fastram starts at or above 0x07000000, check specific machines */ 1121 for (sc = 0, cd = ConfigDev; sc < num_ConfigDev; sc++, cd++) { 1122 switch (cd->cd_Rom.er_Manufacturer) { 1123 case MANUF_PPI: /* Progressive Peripherals, Inc */ 1124 switch (cd->cd_Rom.er_Product) { 1125#if 0 1126 case PROD_PPI_MECURY: /* PPI Mecury - it's an A3000 */ 1127 return (1); 1128 case PROD_PPI_2000: 1129 case PROD_PPI_500: 1130#endif 1131 case PROD_PPI_ZEUS: 1132 return (0); 1133 } 1134 } 1135 } 1136 /* assume it's an A3000 */ 1137 return (a3000_flag); 1138} 1139 1140int 1141is_a4000 () 1142{ 1143 /* This is a real dirty kludge.. */ 1144 return (a4000_flag); 1145} 1146