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