autoconf.c revision 1.1
11.1Smw/* 21.1Smw * Copyright (c) 1988 University of Utah. 31.1Smw * Copyright (c) 1982, 1986, 1990 The Regents of the University of California. 41.1Smw * All rights reserved. 51.1Smw * 61.1Smw * This code is derived from software contributed to Berkeley by 71.1Smw * the Systems Programming Group of the University of Utah Computer 81.1Smw * Science Department. 91.1Smw * 101.1Smw * Redistribution and use in source and binary forms, with or without 111.1Smw * modification, are permitted provided that the following conditions 121.1Smw * are met: 131.1Smw * 1. Redistributions of source code must retain the above copyright 141.1Smw * notice, this list of conditions and the following disclaimer. 151.1Smw * 2. Redistributions in binary form must reproduce the above copyright 161.1Smw * notice, this list of conditions and the following disclaimer in the 171.1Smw * documentation and/or other materials provided with the distribution. 181.1Smw * 3. All advertising materials mentioning features or use of this software 191.1Smw * must display the following acknowledgement: 201.1Smw * This product includes software developed by the University of 211.1Smw * California, Berkeley and its contributors. 221.1Smw * 4. Neither the name of the University nor the names of its contributors 231.1Smw * may be used to endorse or promote products derived from this software 241.1Smw * without specific prior written permission. 251.1Smw * 261.1Smw * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 271.1Smw * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 281.1Smw * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 291.1Smw * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 301.1Smw * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 311.1Smw * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 321.1Smw * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 331.1Smw * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 341.1Smw * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 351.1Smw * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 361.1Smw * SUCH DAMAGE. 371.1Smw * 381.1Smw * from: Utah $Hdr: autoconf.c 1.31 91/01/21$ 391.1Smw * 401.1Smw * @(#)autoconf.c 7.5 (Berkeley) 5/7/91 411.1Smw */ 421.1Smw 431.1Smw/* 441.1Smw * Setup the system to run on the current machine. 451.1Smw * 461.1Smw * Configure() is called at boot time. Available 471.1Smw * devices are determined (from possibilities mentioned in ioconf.c), 481.1Smw * and the drivers are initialized. 491.1Smw */ 501.1Smw 511.1Smw#include "sys/param.h" 521.1Smw#include "sys/systm.h" 531.1Smw#include "sys/buf.h" 541.1Smw#include "sys/dkstat.h" 551.1Smw#include "sys/conf.h" 561.1Smw#include "sys/dmap.h" 571.1Smw#include "sys/reboot.h" 581.1Smw 591.1Smw#include "machine/vmparam.h" 601.1Smw#include "machine/cpu.h" 611.1Smw#include "pte.h" 621.1Smw#include "../dev/device.h" 631.1Smw 641.1Smw#include <libraries/configregs.h> 651.1Smw#include <libraries/configvars.h> 661.1Smw 671.1Smw/* 681.1Smw * The following several variables are related to 691.1Smw * the configuration process, and are used in initializing 701.1Smw * the machine. 711.1Smw */ 721.1Smwint cold; /* if 1, still working on cold-start */ 731.1Smwint dkn; /* number of iostat dk numbers assigned so far */ 741.1Smwint cpuspeed = MHZ_8; /* relative cpu speed */ 751.1Smwstruct amiga_hw sc_table[MAXCTLRS]; 761.1Smw 771.1Smw#ifdef DEBUG 781.1Smwint acdebug = 0; 791.1Smw#endif 801.1Smw 811.1Smw/* 821.1Smw * Determine mass storage and memory configuration for a machine. 831.1Smw */ 841.1Smwconfigure() 851.1Smw{ 861.1Smw register struct amiga_hw *hw; 871.1Smw int found; 881.1Smw 891.1Smw /* 901.1Smw * XXX: these should be consolidated into some kind of table 911.1Smw */ 921.1Smw dmainit(); 931.1Smw 941.1Smw /* 951.1Smw * Look over each hardware device actually found and attempt 961.1Smw * to match it with an ioconf.c table entry. 971.1Smw */ 981.1Smw for (hw = sc_table; hw->hw_type; hw++) { 991.1Smw if (HW_ISCTLR(hw)) 1001.1Smw found = find_controller(hw); 1011.1Smw else 1021.1Smw found = find_device(hw); 1031.1Smw#ifdef DEBUG 1041.1Smw if (!found && acdebug) { 1051.1Smw printf("unconfigured device %d/%d\n", 1061.1Smw hw->hw_manufacturer, hw->hw_product); 1071.1Smw } 1081.1Smw#endif 1091.1Smw } 1101.1Smw 1111.1Smw#if 0 1121.1Smw#include "cd.h" 1131.1Smw#if NCD > 0 1141.1Smw /* 1151.1Smw * Now deal with concatenated disks 1161.1Smw */ 1171.1Smw find_cdevices(); 1181.1Smw#endif 1191.1Smw#endif 1201.1Smw 1211.1Smw#if GENERIC 1221.1Smw if ((boothowto & RB_ASKNAME) == 0) 1231.1Smw setroot(); 1241.1Smw setconf(); 1251.1Smw#else 1261.1Smw setroot(); 1271.1Smw#endif 1281.1Smw swapconf(); 1291.1Smw cold = 0; 1301.1Smw} 1311.1Smw 1321.1Smw#define dr_type(d, s) \ 1331.1Smw (strcmp((d)->d_name, (s)) == 0) 1341.1Smw 1351.1Smw#define same_hw_ctlr(hw, ac) \ 1361.1Smw (HW_ISFLOPPY(hw) && dr_type((ac)->amiga_driver, "floppy") || \ 1371.1Smw HW_ISSCSI(hw) && dr_type((ac)->amiga_driver, "scsi")) 1381.1Smw 1391.1Smwfind_controller(hw) 1401.1Smw register struct amiga_hw *hw; 1411.1Smw{ 1421.1Smw register struct amiga_ctlr *ac; 1431.1Smw struct amiga_ctlr *match_c; 1441.1Smw caddr_t oaddr; 1451.1Smw int sc; 1461.1Smw 1471.1Smw#ifdef DEBUG 1481.1Smw if (acdebug) 1491.1Smw printf("find_controller: hw: [%d/%d] (%x), type %x...", 1501.1Smw hw->hw_manufacturer, hw->hw_product, 1511.1Smw hw->hw_kva, hw->hw_type); 1521.1Smw#endif 1531.1Smw sc = (hw->hw_manufacturer << 16) | hw->hw_product; 1541.1Smw match_c = NULL; 1551.1Smw for (ac = amiga_cinit; ac->amiga_driver; ac++) { 1561.1Smw if (ac->amiga_alive) 1571.1Smw continue; 1581.1Smw /* 1591.1Smw * Make sure we are looking at the right 1601.1Smw * controller type. 1611.1Smw */ 1621.1Smw if (!same_hw_ctlr(hw, ac)) 1631.1Smw continue; 1641.1Smw /* 1651.1Smw * Exact match; all done 1661.1Smw */ 1671.1Smw if ((int)ac->amiga_addr == sc) { 1681.1Smw match_c = ac; 1691.1Smw break; 1701.1Smw } 1711.1Smw /* 1721.1Smw * Wildcard; possible match so remember first instance 1731.1Smw * but continue looking for exact match. 1741.1Smw */ 1751.1Smw if (ac->amiga_addr == NULL && match_c == NULL) 1761.1Smw match_c = ac; 1771.1Smw } 1781.1Smw#ifdef DEBUG 1791.1Smw if (acdebug) { 1801.1Smw if (match_c) 1811.1Smw printf("found %s%d\n", 1821.1Smw match_c->amiga_driver->d_name, 1831.1Smw match_c->amiga_unit); 1841.1Smw else 1851.1Smw printf("not found\n"); 1861.1Smw } 1871.1Smw#endif 1881.1Smw /* 1891.1Smw * Didn't find an ioconf entry for this piece of hardware, 1901.1Smw * just ignore it. 1911.1Smw */ 1921.1Smw if (match_c == NULL) 1931.1Smw return(0); 1941.1Smw /* 1951.1Smw * Found a match, attempt to initialize and configure all attached 1961.1Smw * slaves. Note, we can still fail if HW won't initialize. 1971.1Smw */ 1981.1Smw ac = match_c; 1991.1Smw oaddr = ac->amiga_addr; 2001.1Smw ac->amiga_addr = hw->hw_kva; 2011.1Smw if ((*ac->amiga_driver->d_init)(ac)) { 2021.1Smw ac->amiga_alive = 1; 2031.1Smw printf ("%s%d", ac->amiga_driver->d_name, ac->amiga_unit); 2041.1Smw printf (" [%d/%d]", hw->hw_manufacturer, hw->hw_product); 2051.1Smw if (ac->amiga_flags) 2061.1Smw printf(", flags 0x%x", ac->amiga_flags); 2071.1Smw printf("\n"); 2081.1Smw find_slaves(ac); 2091.1Smw } else 2101.1Smw ac->amiga_addr = oaddr; 2111.1Smw return(1); 2121.1Smw} 2131.1Smw 2141.1Smwfind_device(hw) 2151.1Smw register struct amiga_hw *hw; 2161.1Smw{ 2171.1Smw register struct amiga_device *ad; 2181.1Smw struct amiga_device *match_d; 2191.1Smw caddr_t oaddr; 2201.1Smw int sc; 2211.1Smw 2221.1Smw#ifdef DEBUG 2231.1Smw if (acdebug) 2241.1Smw printf("find_device: hw: [%d/%d] (%x), type %x...", 2251.1Smw hw->hw_manufacturer, hw->hw_product, 2261.1Smw hw->hw_kva, hw->hw_type); 2271.1Smw#endif 2281.1Smw match_d = NULL; 2291.1Smw for (ad = amiga_dinit; ad->amiga_driver; ad++) { 2301.1Smw if (ad->amiga_alive) 2311.1Smw continue; 2321.1Smw /* Must not be a slave */ 2331.1Smw if (ad->amiga_cdriver) 2341.1Smw continue; 2351.1Smw 2361.1Smw sc = (int) ad->amiga_addr; 2371.1Smw /* 2381.1Smw * Exact match; all done. 2391.1Smw */ 2401.1Smw if (sc > 0 && sc == ((hw->hw_manufacturer << 16) | hw->hw_product)) { 2411.1Smw match_d = ad; 2421.1Smw break; 2431.1Smw } 2441.1Smw /* 2451.1Smw * Wildcard; possible match so remember first instance 2461.1Smw * but continue looking for exact match. 2471.1Smw */ 2481.1Smw if (sc == 0 && same_hw_device(hw, ad) && match_d == NULL) 2491.1Smw match_d = ad; 2501.1Smw } 2511.1Smw#ifdef DEBUG 2521.1Smw if (acdebug) { 2531.1Smw if (match_d) 2541.1Smw printf("found %s%d\n", 2551.1Smw match_d->amiga_driver->d_name, 2561.1Smw match_d->amiga_unit); 2571.1Smw else 2581.1Smw printf("not found\n"); 2591.1Smw } 2601.1Smw#endif 2611.1Smw /* 2621.1Smw * Didn't find an ioconf entry for this piece 2631.1Smw * of hardware, just ignore it. 2641.1Smw */ 2651.1Smw if (match_d == NULL) 2661.1Smw return(0); 2671.1Smw /* 2681.1Smw * Found a match, attempt to initialize. 2691.1Smw * Note, we can still fail if HW won't initialize. 2701.1Smw */ 2711.1Smw ad = match_d; 2721.1Smw oaddr = ad->amiga_addr; 2731.1Smw ad->amiga_addr = hw->hw_kva; 2741.1Smw if ((*ad->amiga_driver->d_init)(ad)) { 2751.1Smw ad->amiga_alive = 1; 2761.1Smw printf("%s%d", ad->amiga_driver->d_name, ad->amiga_unit); 2771.1Smw printf (" [%d/%d]", hw->hw_manufacturer, hw->hw_product); 2781.1Smw if (ad->amiga_flags) 2791.1Smw printf(", flags 0x%x", ad->amiga_flags); 2801.1Smw printf("\n"); 2811.1Smw } else 2821.1Smw ad->amiga_addr = oaddr; 2831.1Smw return(1); 2841.1Smw} 2851.1Smw 2861.1Smwfind_slaves(ac) 2871.1Smw struct amiga_ctlr *ac; 2881.1Smw{ 2891.1Smw if (dr_type(ac->amiga_driver, "floppy")) 2901.1Smw find_busslaves(ac, 4); 2911.1Smw else if (dr_type(ac->amiga_driver, "scsi")) 2921.1Smw find_busslaves(ac, 7); 2931.1Smw} 2941.1Smw 2951.1Smw/* 2961.1Smw */ 2971.1Smwfind_busslaves(ac, maxslaves) 2981.1Smw register struct amiga_ctlr *ac; 2991.1Smw int maxslaves; 3001.1Smw{ 3011.1Smw register int s; 3021.1Smw register struct amiga_device *ad; 3031.1Smw struct amiga_device *match_s; 3041.1Smw int new_s, new_c, old_s, old_c; 3051.1Smw int rescan; 3061.1Smw 3071.1Smw#ifdef DEBUG 3081.1Smw if (acdebug) 3091.1Smw printf("find_busslaves: for %s%d\n", 3101.1Smw ac->amiga_driver->d_name, ac->amiga_unit); 3111.1Smw#endif 3121.1Smw for (s = 0; s < maxslaves; s++) { 3131.1Smw rescan = 1; 3141.1Smw match_s = NULL; 3151.1Smw for (ad = amiga_dinit; ad->amiga_driver; ad++) { 3161.1Smw /* 3171.1Smw * Rule out the easy ones: 3181.1Smw * 1. slave already assigned or not a slave 3191.1Smw * 2. not of the proper type 3201.1Smw * 3. controller specified but not this one 3211.1Smw * 4. slave specified but not this one 3221.1Smw */ 3231.1Smw if (ad->amiga_alive || ad->amiga_cdriver == NULL) 3241.1Smw continue; 3251.1Smw if (!dr_type(ac->amiga_driver, ad->amiga_cdriver->d_name)) 3261.1Smw continue; 3271.1Smw if (ad->amiga_ctlr >= 0 && ad->amiga_ctlr != ac->amiga_unit) 3281.1Smw continue; 3291.1Smw if (ad->amiga_slave >= 0 && ad->amiga_slave != s) 3301.1Smw continue; 3311.1Smw /* 3321.1Smw * Case 0: first possible match. 3331.1Smw * Remember it and keep looking for better. 3341.1Smw */ 3351.1Smw if (match_s == NULL) { 3361.1Smw match_s = ad; 3371.1Smw new_c = ac->amiga_unit; 3381.1Smw new_s = s; 3391.1Smw continue; 3401.1Smw } 3411.1Smw /* 3421.1Smw * Case 1: exact match. 3431.1Smw * All done. Note that we do not attempt any other 3441.1Smw * matches if this one fails. This allows us to 3451.1Smw * "reserve" locations for dynamic addition of 3461.1Smw * disk/tape drives by fully qualifing the location. 3471.1Smw */ 3481.1Smw if (ad->amiga_slave == s && ad->amiga_ctlr == ac->amiga_unit) { 3491.1Smw match_s = ad; 3501.1Smw rescan = 0; 3511.1Smw break; 3521.1Smw } 3531.1Smw /* 3541.1Smw * Case 2: right controller, wildcarded slave. 3551.1Smw * Remember first and keep looking for an exact match. 3561.1Smw */ 3571.1Smw if (ad->amiga_ctlr == ac->amiga_unit && 3581.1Smw match_s->amiga_ctlr < 0) { 3591.1Smw match_s = ad; 3601.1Smw new_s = s; 3611.1Smw continue; 3621.1Smw } 3631.1Smw /* 3641.1Smw * Case 3: right slave, wildcarded controller. 3651.1Smw * Remember and keep looking for a better match. 3661.1Smw */ 3671.1Smw if (ad->amiga_slave == s && 3681.1Smw match_s->amiga_ctlr < 0 && match_s->amiga_slave < 0) { 3691.1Smw match_s = ad; 3701.1Smw new_c = ac->amiga_unit; 3711.1Smw continue; 3721.1Smw } 3731.1Smw /* 3741.1Smw * OW: we had a totally wildcarded spec. 3751.1Smw * If we got this far, we have found a possible 3761.1Smw * match already (match_s != NULL) so there is no 3771.1Smw * reason to remember this one. 3781.1Smw */ 3791.1Smw continue; 3801.1Smw } 3811.1Smw /* 3821.1Smw * Found a match. We need to set amiga_ctlr/amiga_slave properly 3831.1Smw * for the init routines but we also need to remember all 3841.1Smw * the old values in case this doesn't pan out. 3851.1Smw */ 3861.1Smw if (match_s) { 3871.1Smw ad = match_s; 3881.1Smw old_c = ad->amiga_ctlr; 3891.1Smw old_s = ad->amiga_slave; 3901.1Smw if (ad->amiga_ctlr < 0) 3911.1Smw ad->amiga_ctlr = new_c; 3921.1Smw if (ad->amiga_slave < 0) 3931.1Smw ad->amiga_slave = new_s; 3941.1Smw#ifdef DEBUG 3951.1Smw if (acdebug) 3961.1Smw printf("looking for %s%d at slave %d...", 3971.1Smw ad->amiga_driver->d_name, 3981.1Smw ad->amiga_unit, ad->amiga_slave); 3991.1Smw#endif 4001.1Smw 4011.1Smw if ((*ad->amiga_driver->d_init)(ad)) { 4021.1Smw#ifdef DEBUG 4031.1Smw if (acdebug) 4041.1Smw printf("found\n"); 4051.1Smw#endif 4061.1Smw printf("%s%d at %s%d, slave %d", 4071.1Smw ad->amiga_driver->d_name, ad->amiga_unit, 4081.1Smw ac->amiga_driver->d_name, ad->amiga_ctlr, 4091.1Smw ad->amiga_slave); 4101.1Smw if (ad->amiga_flags) 4111.1Smw printf(" flags 0x%x", ad->amiga_flags); 4121.1Smw printf("\n"); 4131.1Smw ad->amiga_alive = 1; 4141.1Smw if (ad->amiga_dk && dkn < DK_NDRIVE) 4151.1Smw ad->amiga_dk = dkn++; 4161.1Smw else 4171.1Smw ad->amiga_dk = -1; 4181.1Smw rescan = 1; 4191.1Smw } else { 4201.1Smw#ifdef DEBUG 4211.1Smw if (acdebug) 4221.1Smw printf("not found\n"); 4231.1Smw#endif 4241.1Smw ad->amiga_ctlr = old_c; 4251.1Smw ad->amiga_slave = old_s; 4261.1Smw } 4271.1Smw /* 4281.1Smw * XXX: This should be handled better. 4291.1Smw * Re-scan a slave. There are two reasons to do this. 4301.1Smw * 1. It is possible to have both a tape and disk 4311.1Smw * (e.g. 7946) or two disks (e.g. 9122) at the 4321.1Smw * same slave address. Here we need to rescan 4331.1Smw * looking only at entries with a different 4341.1Smw * physical unit number (amiga_flags). 4351.1Smw * 2. It is possible that an init failed because the 4361.1Smw * slave was there but of the wrong type. In this 4371.1Smw * case it may still be possible to match the slave 4381.1Smw * to another ioconf entry of a different type. 4391.1Smw * Here we need to rescan looking only at entries 4401.1Smw * of different types. 4411.1Smw * In both cases we avoid looking at undesirable 4421.1Smw * ioconf entries of the same type by setting their 4431.1Smw * alive fields to -1. 4441.1Smw */ 4451.1Smw if (rescan) { 4461.1Smw for (ad = amiga_dinit; ad->amiga_driver; ad++) { 4471.1Smw if (ad->amiga_alive) 4481.1Smw continue; 4491.1Smw if (match_s->amiga_alive == 1) { /* 1 */ 4501.1Smw if (ad->amiga_flags == match_s->amiga_flags) 4511.1Smw ad->amiga_alive = -1; 4521.1Smw } else { /* 2 */ 4531.1Smw if (ad->amiga_driver == match_s->amiga_driver) 4541.1Smw ad->amiga_alive = -1; 4551.1Smw } 4561.1Smw } 4571.1Smw s--; 4581.1Smw continue; 4591.1Smw } 4601.1Smw } 4611.1Smw /* 4621.1Smw * Reset bogon alive fields prior to attempting next slave 4631.1Smw */ 4641.1Smw for (ad = amiga_dinit; ad->amiga_driver; ad++) 4651.1Smw if (ad->amiga_alive == -1) 4661.1Smw ad->amiga_alive = 0; 4671.1Smw } 4681.1Smw} 4691.1Smw 4701.1Smwsame_hw_device(hw, ad) 4711.1Smw struct amiga_hw *hw; 4721.1Smw struct amiga_device *ad; 4731.1Smw{ 4741.1Smw int found = 0; 4751.1Smw 4761.1Smw switch (hw->hw_type & ~B_MASK) { 4771.1Smw case C_FLOPPY: 4781.1Smw found = dr_type(ad->amiga_driver, "floppy"); 4791.1Smw break; 4801.1Smw case C_SCSI: 4811.1Smw found = dr_type(ad->amiga_driver, "scsi"); 4821.1Smw break; 4831.1Smw case D_BITMAP: 4841.1Smw found = dr_type(ad->amiga_driver, "grf"); 4851.1Smw break; 4861.1Smw case D_LAN: 4871.1Smw found = dr_type(ad->amiga_driver, "le"); 4881.1Smw break; 4891.1Smw case D_COMMSER: 4901.1Smw found = dr_type(ad->amiga_driver, "ser"); 4911.1Smw break; 4921.1Smw default: 4931.1Smw break; 4941.1Smw } 4951.1Smw return(found); 4961.1Smw} 4971.1Smw 4981.1Smwchar notmappedmsg[] = "WARNING: no space to map IO card, ignored\n"; 4991.1Smw 5001.1Smw/* 5011.1Smw * Scan the IO space looking for devices. 5021.1Smw */ 5031.1Smwfind_devs() 5041.1Smw{ 5051.1Smw short sc; 5061.1Smw u_char *id_reg; 5071.1Smw register caddr_t addr; 5081.1Smw register struct amiga_hw *hw; 5091.1Smw int didmap, sctop; 5101.1Smw extern int num_ConfigDev; 5111.1Smw extern struct ConfigDev *ConfigDev; 5121.1Smw struct ConfigDev *cd; 5131.1Smw 5141.1Smw#if 0 5151.1Smw /* 5161.1Smw * Initialize IO resource map for iomap(). 5171.1Smw */ 5181.1Smw rminit(extiomap, (long)EIOMAPSIZE, (long)1, "extio", EIOMAPSIZE/16); 5191.1Smw#endif 5201.1Smw hw = sc_table; 5211.1Smw 5221.1Smw /* first enter builtin devices */ 5231.1Smw 5241.1Smw /* this is only for the A3000, but... */ 5251.1Smw hw->hw_pa = 0xdd0000; 5261.1Smw hw->hw_size = NBPG; 5271.1Smw hw->hw_kva = 0; /* filled out in scsiinit */ 5281.1Smw hw->hw_manufacturer = MANUF_BUILTIN; 5291.1Smw hw->hw_product = PROD_BUILTIN_SCSI; 5301.1Smw hw->hw_type = B_BUILTIN | C_SCSI; 5311.1Smw hw++; 5321.1Smw 5331.1Smw hw->hw_pa = 0xdc0000; 5341.1Smw hw->hw_size = NBPG; 5351.1Smw hw->hw_kva = 0; /* should be mapped here! */ 5361.1Smw hw->hw_manufacturer = MANUF_BUILTIN; 5371.1Smw hw->hw_product = PROD_BUILTIN_CLOCK; 5381.1Smw hw->hw_type = B_BUILTIN | D_CLOCK; 5391.1Smw hw++; 5401.1Smw 5411.1Smw hw->hw_pa = 0; 5421.1Smw hw->hw_size = 0; 5431.1Smw hw->hw_kva = 0; /* already mapped, uses CUSTOMbase */ 5441.1Smw hw->hw_manufacturer = MANUF_BUILTIN; 5451.1Smw hw->hw_product = PROD_BUILTIN_FLOPPY; 5461.1Smw hw->hw_type = B_BUILTIN | C_FLOPPY; 5471.1Smw hw++; 5481.1Smw 5491.1Smw hw->hw_pa = 0; 5501.1Smw hw->hw_size = 0; 5511.1Smw hw->hw_kva = 0; /* already mapped, uses CUSTOMbase */ 5521.1Smw hw->hw_manufacturer = MANUF_BUILTIN; 5531.1Smw hw->hw_product = PROD_BUILTIN_RS232; 5541.1Smw hw->hw_type = B_BUILTIN | D_COMMSER; 5551.1Smw hw++; 5561.1Smw 5571.1Smw hw->hw_pa = 0; 5581.1Smw hw->hw_size = 0; 5591.1Smw hw->hw_kva = 0; /* already mapped, uses CUSTOMbase */ 5601.1Smw hw->hw_manufacturer = MANUF_BUILTIN; 5611.1Smw hw->hw_product = PROD_BUILTIN_KEYBOARD; 5621.1Smw hw->hw_type = B_BUILTIN | D_KEYBOARD; 5631.1Smw hw++; 5641.1Smw 5651.1Smw hw->hw_pa = 0; 5661.1Smw hw->hw_size = 0; 5671.1Smw hw->hw_kva = 0; /* already mapped, uses CUSTOMbase */ 5681.1Smw hw->hw_manufacturer = MANUF_BUILTIN; 5691.1Smw hw->hw_product = PROD_BUILTIN_PPORT; 5701.1Smw hw->hw_type = B_BUILTIN | D_PPORT; 5711.1Smw hw++; 5721.1Smw 5731.1Smw hw->hw_pa = 0; 5741.1Smw hw->hw_size = 0; 5751.1Smw hw->hw_kva = 0; /* already mapped, uses CUSTOMbase */ 5761.1Smw hw->hw_manufacturer = MANUF_BUILTIN; 5771.1Smw hw->hw_product = PROD_BUILTIN_DISPLAY; 5781.1Smw hw->hw_type = B_BUILTIN | D_BITMAP; 5791.1Smw hw++; 5801.1Smw 5811.1Smw /* and afterwards add Zorro II/III devices passed by the loader */ 5821.1Smw 5831.1Smw for (sc = 0, cd = ConfigDev; sc < num_ConfigDev; sc++, cd++) 5841.1Smw { 5851.1Smw hw->hw_pa = cd->cd_BoardAddr; 5861.1Smw hw->hw_size = cd->cd_BoardSize; 5871.1Smw hw->hw_kva = 0; /* XXX */ 5881.1Smw hw->hw_manufacturer = cd->cd_Rom.er_Manufacturer; 5891.1Smw hw->hw_product = cd->cd_Rom.er_Product; 5901.1Smw 5911.1Smw switch (hw->hw_manufacturer) 5921.1Smw { 5931.1Smw case MANUF_CBM_1: 5941.1Smw switch (hw->hw_product) 5951.1Smw { 5961.1Smw case PROD_CBM_1_A2088: 5971.1Smw hw->hw_type = B_ZORROII | D_MISC; 5981.1Smw break; 5991.1Smw 6001.1Smw default: 6011.1Smw continue; 6021.1Smw } 6031.1Smw 6041.1Smw case MANUF_UNILOWELL: 6051.1Smw switch (hw->hw_product) 6061.1Smw { 6071.1Smw case PROD_UNILOWELL_A2410: 6081.1Smw hw->hw_type = B_ZORROII | D_BITMAP; 6091.1Smw break; 6101.1Smw 6111.1Smw default: 6121.1Smw continue; 6131.1Smw } 6141.1Smw 6151.1Smw default: 6161.1Smw continue; 6171.1Smw } 6181.1Smw 6191.1Smw hw++; 6201.1Smw } 6211.1Smw} 6221.1Smw 6231.1Smw#if 0 6241.1Smw/* 6251.1Smw * Allocate/deallocate a cache-inhibited range of kernel virtual address 6261.1Smw * space mapping the indicated physical address range [pa - pa+size) 6271.1Smw */ 6281.1Smwcaddr_t 6291.1Smwiomap(pa, size) 6301.1Smw caddr_t pa; 6311.1Smw int size; 6321.1Smw{ 6331.1Smw int ix, npf; 6341.1Smw caddr_t kva; 6351.1Smw 6361.1Smw#ifdef DEBUG 6371.1Smw if (((int)pa & PGOFSET) || (size & PGOFSET)) 6381.1Smw panic("iomap: unaligned"); 6391.1Smw#endif 6401.1Smw npf = btoc(size); 6411.1Smw ix = rmalloc(extiomap, npf); 6421.1Smw if (ix == 0) 6431.1Smw return(0); 6441.1Smw kva = extiobase + ctob(ix-1); 6451.1Smw physaccess(kva, pa, size, PG_RW|PG_CI); 6461.1Smw return(kva); 6471.1Smw} 6481.1Smw 6491.1Smwiounmap(kva, size) 6501.1Smw caddr_t kva; 6511.1Smw int size; 6521.1Smw{ 6531.1Smw int ix; 6541.1Smw 6551.1Smw#ifdef DEBUG 6561.1Smw if (((int)kva & PGOFSET) || (size & PGOFSET)) 6571.1Smw panic("iounmap: unaligned"); 6581.1Smw if (kva < extiobase || kva >= extiobase + ctob(EIOMAPSIZE)) 6591.1Smw panic("iounmap: bad address"); 6601.1Smw#endif 6611.1Smw physunaccess(kva, size); 6621.1Smw ix = btoc(kva - extiobase) + 1; 6631.1Smw rmfree(extiomap, btoc(size), ix); 6641.1Smw} 6651.1Smw#endif 6661.1Smw 6671.1Smw#if NCD > 0 6681.1Smw#include "../dev/cdvar.h" 6691.1Smw 6701.1Smwfind_cdevices() 6711.1Smw{ 6721.1Smw register struct cddevice *cd; 6731.1Smw 6741.1Smw for (cd = cddevice; cd->cd_unit >= 0; cd++) { 6751.1Smw /* 6761.1Smw * XXX 6771.1Smw * Assign disk index first so that init routine 6781.1Smw * can use it (saves having the driver drag around 6791.1Smw * the cddevice pointer just to set up the dk_* 6801.1Smw * info in the open routine). 6811.1Smw */ 6821.1Smw if (dkn < DK_NDRIVE) 6831.1Smw cd->cd_dk = dkn++; 6841.1Smw else 6851.1Smw cd->cd_dk = -1; 6861.1Smw if (cdinit(cd)) 6871.1Smw printf("cd%d configured\n", cd->cd_unit); 6881.1Smw else if (cd->cd_dk >= 0) { 6891.1Smw cd->cd_dk = -1; 6901.1Smw dkn--; 6911.1Smw } 6921.1Smw } 6931.1Smw} 6941.1Smw#endif 6951.1Smw 6961.1Smw#if 0 6971.1Smwisrinit() 6981.1Smw{ 6991.1Smw register int i; 7001.1Smw 7011.1Smw for (i = 0; i < NISR; i++) 7021.1Smw isrqueue[i].isr_forw = isrqueue[i].isr_back = &isrqueue[i]; 7031.1Smw} 7041.1Smw 7051.1Smwvoid 7061.1Smwisrlink(isr) 7071.1Smw register struct isr *isr; 7081.1Smw{ 7091.1Smw int i = ISRIPL(isr->isr_ipl); 7101.1Smw 7111.1Smw if (i < 0 || i >= NISR) { 7121.1Smw printf("bad IPL %d\n", i); 7131.1Smw panic("configure"); 7141.1Smw } 7151.1Smw insque(isr, isrqueue[i].isr_back); 7161.1Smw} 7171.1Smw#endif 7181.1Smw 7191.1Smw/* 7201.1Smw * Configure swap space and related parameters. 7211.1Smw */ 7221.1Smwswapconf() 7231.1Smw{ 7241.1Smw register struct swdevt *swp; 7251.1Smw register int nblks; 7261.1Smw 7271.1Smw for (swp = swdevt; swp->sw_dev; swp++) 7281.1Smw { 7291.1Smw if (bdevsw[major(swp->sw_dev)].d_psize) { 7301.1Smw nblks = 7311.1Smw (*bdevsw[major(swp->sw_dev)].d_psize)(swp->sw_dev); 7321.1Smw if (nblks != -1 && 7331.1Smw (swp->sw_nblks == 0 || swp->sw_nblks > nblks)) 7341.1Smw { 7351.1Smw swp->sw_nblks = nblks; 7361.1Smw/* printf ("swap: dev %x = %d\n", swp->sw_dev, nblks);*/ 7371.1Smw } 7381.1Smw } 7391.1Smw } 7401.1Smw dumpconf(); 7411.1Smw 7421.1Smw printf ("\n"); 7431.1Smw} 7441.1Smw 7451.1Smw#define DOSWAP /* Change swdevt and dumpdev too */ 7461.1Smwu_long bootdev; /* should be dev_t, but not until 32 bits */ 7471.1Smw 7481.1Smwstatic char devname[][2] = { 7491.1Smw 0,0, /* 0 = ct */ 7501.1Smw 0,0, /* 1 = xx */ 7511.1Smw 'r','d', /* 2 = rd */ 7521.1Smw 0,0, /* 3 = sw */ 7531.1Smw 's','d', /* 4 = sd */ 7541.1Smw}; 7551.1Smw 7561.1Smw#define PARTITIONMASK 0x7 7571.1Smw#define PARTITIONSHIFT 3 7581.1Smw 7591.1Smw/* 7601.1Smw * Attempt to find the device from which we were booted. 7611.1Smw * If we can do so, and not instructed not to do so, 7621.1Smw * change rootdev to correspond to the load device. 7631.1Smw */ 7641.1Smwsetroot() 7651.1Smw{ 7661.1Smw register struct amiga_ctlr *ac; 7671.1Smw register struct amiga_device *ad; 7681.1Smw int majdev, mindev, unit, part, adaptor; 7691.1Smw dev_t temp, orootdev; 7701.1Smw struct swdevt *swp; 7711.1Smw 7721.1Smw/* printf ("setroot: boothowto = 0x%x, bootdev = 0x%x\n", boothowto, bootdev);*/ 7731.1Smw 7741.1Smw if (boothowto & RB_DFLTROOT || 7751.1Smw (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC) 7761.1Smw return; 7771.1Smw majdev = (bootdev >> B_TYPESHIFT) & B_TYPEMASK; 7781.1Smw if (majdev > sizeof(devname) / sizeof(devname[0])) 7791.1Smw return; 7801.1Smw adaptor = (bootdev >> B_ADAPTORSHIFT) & B_ADAPTORMASK; 7811.1Smw part = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK; 7821.1Smw unit = (bootdev >> B_UNITSHIFT) & B_UNITMASK; 7831.1Smw /* 7841.1Smw * First, find the controller type which support this device. 7851.1Smw */ 7861.1Smw for (ad = amiga_dinit; ad->amiga_driver; ad++) 7871.1Smw if (ad->amiga_driver->d_name[0] == devname[majdev][0] && 7881.1Smw ad->amiga_driver->d_name[1] == devname[majdev][1]) 7891.1Smw break; 7901.1Smw if (ad->amiga_driver == 0) 7911.1Smw return; 7921.1Smw /* 7931.1Smw * Next, find the controller of that type corresponding to 7941.1Smw * the adaptor number. 7951.1Smw */ 7961.1Smw for (ac = amiga_cinit; ac->amiga_driver; ac++) 7971.1Smw if (ac->amiga_alive && ac->amiga_unit == adaptor && 7981.1Smw ac->amiga_driver == ad->amiga_cdriver) 7991.1Smw break; 8001.1Smw if (ac->amiga_driver == 0) 8011.1Smw return; 8021.1Smw /* 8031.1Smw * Finally, find the device in question attached to that controller. 8041.1Smw */ 8051.1Smw for (ad = amiga_dinit; ad->amiga_driver; ad++) 8061.1Smw if (ad->amiga_alive && ad->amiga_slave == unit && 8071.1Smw ad->amiga_cdriver == ac->amiga_driver && 8081.1Smw ad->amiga_ctlr == ac->amiga_unit) 8091.1Smw break; 8101.1Smw if (ad->amiga_driver == 0) 8111.1Smw return; 8121.1Smw mindev = ad->amiga_unit; 8131.1Smw /* 8141.1Smw * Form a new rootdev 8151.1Smw */ 8161.1Smw mindev = (mindev << PARTITIONSHIFT) + part; 8171.1Smw orootdev = rootdev; 8181.1Smw rootdev = makedev(majdev, mindev); 8191.1Smw /* 8201.1Smw * If the original rootdev is the same as the one 8211.1Smw * just calculated, don't need to adjust the swap configuration. 8221.1Smw */ 8231.1Smw if (rootdev == orootdev) 8241.1Smw return; 8251.1Smw 8261.1Smw printf("Changing root device to %c%c%d%c\n", 8271.1Smw devname[majdev][0], devname[majdev][1], 8281.1Smw mindev >> PARTITIONSHIFT, part + 'a'); 8291.1Smw 8301.1Smw#ifdef DOSWAP 8311.1Smw mindev &= ~PARTITIONMASK; 8321.1Smw for (swp = swdevt; swp->sw_dev; swp++) { 8331.1Smw if (majdev == major(swp->sw_dev) && 8341.1Smw mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) { 8351.1Smw temp = swdevt[0].sw_dev; 8361.1Smw swdevt[0].sw_dev = swp->sw_dev; 8371.1Smw swp->sw_dev = temp; 8381.1Smw break; 8391.1Smw } 8401.1Smw } 8411.1Smw if (swp->sw_dev == 0) 8421.1Smw return; 8431.1Smw 8441.1Smw /* 8451.1Smw * If dumpdev was the same as the old primary swap 8461.1Smw * device, move it to the new primary swap device. 8471.1Smw */ 8481.1Smw if (temp == dumpdev) 8491.1Smw dumpdev = swdevt[0].sw_dev; 8501.1Smw#endif 8511.1Smw} 852