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