autoconf.c revision 8433
14Srgrimes/*-
24Srgrimes * Copyright (c) 1990 The Regents of the University of California.
34Srgrimes * All rights reserved.
44Srgrimes *
54Srgrimes * This code is derived from software contributed to Berkeley by
64Srgrimes * William Jolitz.
74Srgrimes *
84Srgrimes * Redistribution and use in source and binary forms, with or without
94Srgrimes * modification, are permitted provided that the following conditions
104Srgrimes * are met:
114Srgrimes * 1. Redistributions of source code must retain the above copyright
124Srgrimes *    notice, this list of conditions and the following disclaimer.
134Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
144Srgrimes *    notice, this list of conditions and the following disclaimer in the
154Srgrimes *    documentation and/or other materials provided with the distribution.
164Srgrimes * 3. All advertising materials mentioning features or use of this software
174Srgrimes *    must display the following acknowledgement:
184Srgrimes *	This product includes software developed by the University of
194Srgrimes *	California, Berkeley and its contributors.
204Srgrimes * 4. Neither the name of the University nor the names of its contributors
214Srgrimes *    may be used to endorse or promote products derived from this software
224Srgrimes *    without specific prior written permission.
234Srgrimes *
244Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
254Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
264Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
274Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
284Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
294Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
304Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
314Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
324Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
334Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
344Srgrimes * SUCH DAMAGE.
354Srgrimes *
36620Srgrimes *	from: @(#)autoconf.c	7.1 (Berkeley) 5/9/91
378433Swpaul *	$Id: autoconf.c,v 1.27 1995/04/25 03:41:12 phk Exp $
384Srgrimes */
394Srgrimes
404Srgrimes/*
414Srgrimes * Setup the system to run on the current machine.
424Srgrimes *
434Srgrimes * Configure() is called at boot time and initializes the vba
444Srgrimes * device tables and the memory controller monitoring.  Available
454Srgrimes * devices are determined (from possibilities mentioned in ioconf.c),
464Srgrimes * and the drivers are initialized.
474Srgrimes */
482056Swollman#include <sys/param.h>
492056Swollman#include <sys/systm.h>
502056Swollman#include <sys/buf.h>
512056Swollman#include <sys/dkstat.h>
522056Swollman#include <sys/conf.h>
532056Swollman#include <sys/dmap.h>
542056Swollman#include <sys/reboot.h>
552056Swollman#include <sys/kernel.h>
564Srgrimes
577090Sbde#include <machine/md_var.h>
582056Swollman#include <machine/pte.h>
594Srgrimes
60798Swollmanstatic void swapconf(void);
61798Swollmanstatic void setroot(void);
62798Swollman
634Srgrimes/*
644Srgrimes * The following several variables are related to
654Srgrimes * the configuration process, and are used in initializing
664Srgrimes * the machine.
674Srgrimes */
684Srgrimesint	dkn;		/* number of iostat dk numbers assigned so far */
694Srgrimes
704370Sphkextern int (*mountroot) __P((void));
714370Sphk#ifdef FFS
724370Sphkint ffs_mountroot __P((void));
734370Sphk#endif
744370Sphk#ifdef NFS
754370Sphkint nfs_mountroot __P((void));
764370Sphk#endif
777731Sphk#ifdef CD9660
787731Sphkint cd9660_mountroot __P((void));
797731Sphk#endif
808055Sphk#ifdef MSDOSFS
818055Sphkint msdosfs_mountroot __P((void));
828055Sphk#endif
838055Sphk#ifdef MFS_ROOT
848055Sphkint mfs_initminiroot __P((u_char *));
858055Sphku_char mfs_root[MFS_ROOT*1024] = "MFS Filesystem goes here";
868055Sphku_char end_mfs_root[] = "MFS Filesystem had better STOP here";
878055Sphk#endif
884370Sphk
898014Sjulian#include "eisa.h"
906105Sse#include "isa.h"
916105Sse#if NISA > 0
926105Sse      #include <i386/isa/isa_device.h>
936105Sse#endif
946105Sse
956105Sse#include "pci.h"
966105Sse#if NPCI > 0
976105Sse      #include <pci/pcivar.h>
986105Sse#endif
996105Sse
1008007Sphk#ifdef CD9660
1017731Sphk/* We need to try out all our potential CDROM drives, so we need a table. */
1027731Sphkstatic struct {
1037731Sphk	char *name;
1047731Sphk	int major;
1057731Sphk} try_cdrom[] = {
1067731Sphk	{ "cd", 6 },
1077731Sphk	{ "mcd", 7 },
1087731Sphk	{ "scd", 16 },
1097731Sphk	{ "matcd", 17 },
1107731Sphk	{ 0, 0}
1117731Sphk};
1127731Sphk
1137731Sphkint
1147731Sphkfind_cdrom_root()
1157731Sphk{
1167731Sphk	int i,j,k;
1177731Sphk
1187731Sphk	for (j = 0 ; j < 2; j++)
1197731Sphk		for (k = 0 ; try_cdrom[k].name ; k++) {
1207731Sphk			rootdev = makedev(try_cdrom[k].major,j*8);
1217731Sphk			printf("trying rootdev=%x (%s%d)\n",
1227731Sphk				rootdev, try_cdrom[k].name,j);
1237731Sphk			i = (*cd9660_mountroot)();
1247731Sphk			if (!i) return i;
1257731Sphk		}
1267731Sphk	return EINVAL;
1277731Sphk}
1288007Sphk#endif /* CD9660 */
1297731Sphk
1307818Sdufault#include "scbus.h"
1317818Sdufault#if NSCBUS > 0
1327818Sdufault      #include <scsi/scsiconf.h>
1337818Sdufault#endif
1347818Sdufault
1357818Sdufaultvoid
1367818Sdufaultconfigure_start()
1377818Sdufault{
1387818Sdufault#if NSCBUS > 0
1397818Sdufault	scsi_configure_start();
1407818Sdufault#endif
1417818Sdufault}
1427818Sdufault
1437818Sdufaultvoid
1447818Sdufaultconfigure_finish()
1457818Sdufault{
1467818Sdufault#if NSCBUS > 0
1477818Sdufault	scsi_configure_finish();
1487818Sdufault#endif
1497818Sdufault}
1507818Sdufault
1514Srgrimes/*
1524Srgrimes * Determine i/o configuration for a machine.
1534Srgrimes */
154798Swollmanvoid
1554Srgrimesconfigure()
1564Srgrimes{
1574Srgrimes
1588015Sjulian	configure_start();
1598015Sjulian
1608014Sjulian#if NEISA > 0
1618014Sjulian	eisa_configure();
1628014Sjulian#endif
1638014Sjulian
1647818Sdufault
1654Srgrimes#if NISA > 0
1664Srgrimes	isa_configure();
1674Srgrimes#endif
1684Srgrimes
1692430Sse#if NPCI > 0
1702430Sse	pci_configure();
1712430Sse#endif
1722430Sse
1737818Sdufault	configure_finish();
1747818Sdufault
1758055Sphk#ifdef MFS_ROOT
1768055Sphk	mfs_initminiroot(mfs_root);
1778055Sphk#endif /* MFS_ROOT */
1788055Sphk
1797731Sphk#ifdef CD9660
1808007Sphk	if ((boothowto & RB_CDROM) && !mountroot)
1817731Sphk		mountroot = find_cdrom_root;
1827731Sphk#endif
1838007Sphk
1844370Sphk#ifdef NFS
1857731Sphk	if (!mountroot && nfs_diskless_valid)
1863795Sphk		mountroot = nfs_mountroot;
1874370Sphk#endif /* NFS */
1888007Sphk
1894370Sphk#ifdef FFS
1904370Sphk	if (!mountroot) {
1914370Sphk		mountroot = ffs_mountroot;
1926547Swpaul		/*
1936547Swpaul		 * Ignore the -a flag if this kernel isn't compiled
1946547Swpaul		 * with a generic root/swap configuration: if we skip
1956547Swpaul		 * setroot() and we aren't a generic kernel, chaos
1966547Swpaul		 * will ensue because setconf() will be a no-op.
1976547Swpaul		 * (rootdev is always initialized to NODEV in a
1986547Swpaul		 * generic configuration, so we test for that.)
1996547Swpaul		 */
2006547Swpaul		if ((boothowto & RB_ASKNAME) == 0 || rootdev != NODEV)
2015321Sjkh			setroot();
2023795Sphk	}
2034Srgrimes#endif
2044370Sphk	if (!mountroot) {
2054370Sphk		panic("Nobody wants to mount my root for me");
2064370Sphk	}
2074Srgrimes	/*
2084Srgrimes	 * Configure swap area and related system
2094Srgrimes	 * parameter based on device(s) used.
2104Srgrimes	 */
2118433Swpaul	setconf();
2124Srgrimes	swapconf();
2134Srgrimes	cold = 0;
2144Srgrimes}
2154Srgrimes
2164Srgrimes/*
2174Srgrimes * Configure swap space and related parameters.
2184Srgrimes */
219798Swollmanstatic void
2204Srgrimesswapconf()
2214Srgrimes{
2224Srgrimes	register struct swdevt *swp;
2234Srgrimes	register int nblks;
2244Srgrimes
2254Srgrimes	for (swp = swdevt; swp->sw_dev > 0; swp++)
2264Srgrimes	{
2274Srgrimes		unsigned d = major(swp->sw_dev);
2284Srgrimes
2294Srgrimes		if (d > nblkdev) break;
2304Srgrimes		if (bdevsw[d].d_psize) {
2314Srgrimes			nblks = (*bdevsw[d].d_psize)(swp->sw_dev);
2324Srgrimes			if (nblks > 0 &&
2334Srgrimes			    (swp->sw_nblks == 0 || swp->sw_nblks > nblks))
2344Srgrimes				swp->sw_nblks = nblks;
2354Srgrimes			else
2364Srgrimes				swp->sw_nblks = 0;
2374Srgrimes		}
2384Srgrimes		swp->sw_nblks = ctod(dtoc(swp->sw_nblks));
2394Srgrimes	}
2404Srgrimes	if (dumplo == 0 && bdevsw[major(dumpdev)].d_psize)
2414Srgrimes		dumplo = (*bdevsw[major(dumpdev)].d_psize)(dumpdev) -
2424Srgrimes			Maxmem*NBPG/512;
2434Srgrimes	if (dumplo < 0)
2444Srgrimes		dumplo = 0;
2454Srgrimes}
2464Srgrimes
2474Srgrimes#define	DOSWAP			/* change swdevt and dumpdev */
2484Srgrimesu_long	bootdev = 0;		/* should be dev_t, but not until 32 bits */
2494Srgrimes
2504Srgrimesstatic	char devname[][2] = {
2516105Sse      {'w','d'},      /* 0 = wd */
2526105Sse      {'s','w'},      /* 1 = sw */
2531289Sache#define FDMAJOR 2
2546105Sse      {'f','d'},      /* 2 = fd */
2556105Sse      {'w','t'},      /* 3 = wt */
2566105Sse      {'s','d'},      /* 4 = sd -- new SCSI system */
2574Srgrimes};
2584Srgrimes
2594Srgrimes#define	PARTITIONMASK	0x7
2604Srgrimes#define	PARTITIONSHIFT	3
2611290Sache#define FDUNITSHIFT     6
2622400Sache#define RAW_PART        2
2634Srgrimes
2644Srgrimes/*
2654Srgrimes * Attempt to find the device from which we were booted.
2664Srgrimes * If we can do so, and not instructed not to do so,
2674Srgrimes * change rootdev to correspond to the load device.
2684Srgrimes */
269798Swollmanstatic void
2704Srgrimessetroot()
2714Srgrimes{
2724Srgrimes	int  majdev, mindev, unit, part, adaptor;
273798Swollman	dev_t temp = 0, orootdev;
2744Srgrimes	struct swdevt *swp;
2754Srgrimes
2764Srgrimes/*printf("howto %x bootdev %x ", boothowto, bootdev);*/
2774Srgrimes	if (boothowto & RB_DFLTROOT ||
2784Srgrimes	    (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC)
2794Srgrimes		return;
2804Srgrimes	majdev = (bootdev >> B_TYPESHIFT) & B_TYPEMASK;
2814Srgrimes	if (majdev > sizeof(devname) / sizeof(devname[0]))
2824Srgrimes		return;
2834Srgrimes	adaptor = (bootdev >> B_ADAPTORSHIFT) & B_ADAPTORMASK;
2844Srgrimes	unit = (bootdev >> B_UNITSHIFT) & B_UNITMASK;
2851290Sache	if (majdev == FDMAJOR) {
2862400Sache		part = RAW_PART;
2871290Sache		mindev = unit << FDUNITSHIFT;
2881290Sache	}
2891290Sache	else {
2901290Sache		part = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK;
2911289Sache		mindev = (unit << PARTITIONSHIFT) + part;
2921290Sache	}
2934Srgrimes	orootdev = rootdev;
2944Srgrimes	rootdev = makedev(majdev, mindev);
2954Srgrimes	/*
2964Srgrimes	 * If the original rootdev is the same as the one
2974Srgrimes	 * just calculated, don't need to adjust the swap configuration.
2984Srgrimes	 */
2994Srgrimes	if (rootdev == orootdev)
3004Srgrimes		return;
3014Srgrimes	printf("changing root device to %c%c%d%c\n",
3024Srgrimes		devname[majdev][0], devname[majdev][1],
3031290Sache		mindev >> (majdev == FDMAJOR ? FDUNITSHIFT : PARTITIONSHIFT),
3041290Sache		part + 'a');
3054Srgrimes#ifdef DOSWAP
3064Srgrimes	mindev &= ~PARTITIONMASK;
3074Srgrimes	for (swp = swdevt; swp->sw_dev; swp++) {
3084Srgrimes		if (majdev == major(swp->sw_dev) &&
3094Srgrimes		    mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) {
3104Srgrimes
3114Srgrimes			temp = swdevt[0].sw_dev;
3124Srgrimes			swdevt[0].sw_dev = swp->sw_dev;
3134Srgrimes			swp->sw_dev = temp;
3144Srgrimes			break;
3154Srgrimes		}
3164Srgrimes	}
3174Srgrimes	if (swp->sw_dev == 0)
3184Srgrimes		return;
3194Srgrimes	/*
3204Srgrimes	 * If dumpdev was the same as the old primary swap
3214Srgrimes	 * device, move it to the new primary swap device.
3224Srgrimes	 */
3234Srgrimes	if (temp == dumpdev)
3244Srgrimes		dumpdev = swdevt[0].sw_dev;
3254Srgrimes#endif
3264Srgrimes}
327