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