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