autoconf.c revision 12091
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
3712091Sgibbs *	$Id: autoconf.c,v 1.40 1995/10/21 00:55:13 phk Exp $
384Srgrimes */
394Srgrimes
404Srgrimes/*
414Srgrimes * Setup the system to run on the current machine.
424Srgrimes *
438876Srgrimes * 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>
5610358Sjulian#include <sys/mount.h>	/* mountrootvfsops, struct vfsops*/
574Srgrimes
5810665Sbde#include <machine/cons.h>
597090Sbde#include <machine/md_var.h>
602056Swollman#include <machine/pte.h>
614Srgrimes
6210665Sbdestatic void configure __P((void *));
6310665SbdeSYSINIT(configure, SI_SUB_CONFIGURE, SI_ORDER_FIRST, configure, NULL)
6410665Sbde
6510665Sbdeint find_cdrom_root __P((void *));
6610665Sbdevoid configure_start __P((void));
6710665Sbdevoid configure_finish __P((void));
6810665Sbde
69798Swollmanstatic void setroot(void);
70798Swollman
714Srgrimes/*
724Srgrimes * The following several variables are related to
734Srgrimes * the configuration process, and are used in initializing
744Srgrimes * the machine.
754Srgrimes */
764Srgrimesint	dkn;		/* number of iostat dk numbers assigned so far */
774Srgrimes
784370Sphk#ifdef FFS
7910358Sjulianextern struct vfsops	ufs_vfsops;
804370Sphk#endif
8110358Sjulian#ifdef LFS
8210358Sjulianextern struct vfsops	lfs_vfsops;
8310358Sjulian#endif
844370Sphk#ifdef NFS
8510653Sdgint nfs_mountroot __P((void *));
864370Sphk#endif
877731Sphk#ifdef CD9660
8810653Sdgint cd9660_mountroot __P((void *));
897731Sphk#endif
908055Sphk#ifdef MSDOSFS
9110653Sdgint msdosfs_mountroot __P((void *));
928055Sphk#endif
938055Sphk#ifdef MFS_ROOT
948055Sphkint mfs_initminiroot __P((u_char *));
958055Sphku_char mfs_root[MFS_ROOT*1024] = "MFS Filesystem goes here";
968055Sphku_char end_mfs_root[] = "MFS Filesystem had better STOP here";
978055Sphk#endif
984370Sphk
998014Sjulian#include "eisa.h"
1006105Sse#include "isa.h"
1016105Sse#if NISA > 0
1026105Sse      #include <i386/isa/isa_device.h>
1036105Sse#endif
1046105Sse
10512091Sgibbs#if NEISA > 0
10612091Sgibbsvoid	eisa_configure();
10712091Sgibbs#endif
10812091Sgibbs
1096105Sse#include "pci.h"
1106105Sse#if NPCI > 0
1116105Sse      #include <pci/pcivar.h>
1126105Sse#endif
1136105Sse
1149547Sphk#include "crd.h"
1159547Sphk#if NCRD > 0
1169547Sphkvoid	pccard_configure();
1179547Sphk#endif
1189547Sphk
1198007Sphk#ifdef CD9660
1207731Sphk/* We need to try out all our potential CDROM drives, so we need a table. */
1217731Sphkstatic struct {
1227731Sphk	char *name;
1237731Sphk	int major;
1247731Sphk} try_cdrom[] = {
1257731Sphk	{ "cd", 6 },
1267731Sphk	{ "mcd", 7 },
1277731Sphk	{ "scd", 16 },
1287731Sphk	{ "matcd", 17 },
1297731Sphk	{ 0, 0}
1307731Sphk};
1317731Sphk
1327731Sphkint
13310653Sdgfind_cdrom_root(dummy)
13410653Sdg	void *dummy;
1357731Sphk{
1367731Sphk	int i,j,k;
1377731Sphk
1387731Sphk	for (j = 0 ; j < 2; j++)
1397731Sphk		for (k = 0 ; try_cdrom[k].name ; k++) {
1407731Sphk			rootdev = makedev(try_cdrom[k].major,j*8);
1418456Srgrimes			printf("trying rootdev=0x%lx (%s%d)\n",
1427731Sphk				rootdev, try_cdrom[k].name,j);
14310665Sbde			i = (*cd9660_mountroot)((void *)NULL);
1447731Sphk			if (!i) return i;
1457731Sphk		}
1467731Sphk	return EINVAL;
1477731Sphk}
1488007Sphk#endif /* CD9660 */
1497731Sphk
1507818Sdufault#include "scbus.h"
1517818Sdufault#if NSCBUS > 0
1527818Sdufault      #include <scsi/scsiconf.h>
1537818Sdufault#endif
1547818Sdufault
1557818Sdufaultvoid
1567818Sdufaultconfigure_start()
1577818Sdufault{
1587818Sdufault#if NSCBUS > 0
1597818Sdufault	scsi_configure_start();
1607818Sdufault#endif
1617818Sdufault}
1627818Sdufault
1637818Sdufaultvoid
1647818Sdufaultconfigure_finish()
1657818Sdufault{
1667818Sdufault#if NSCBUS > 0
1677818Sdufault	scsi_configure_finish();
1687818Sdufault#endif
1697818Sdufault}
1707818Sdufault
1714Srgrimes/*
1724Srgrimes * Determine i/o configuration for a machine.
1734Srgrimes */
17410665Sbdestatic void
17510665Sbdeconfigure(dummy)
17610653Sdg	void *dummy;
1774Srgrimes{
1784Srgrimes
1798015Sjulian	configure_start();
1808015Sjulian
18111602Sphk#if NCRD > 0
18211602Sphk	/* Before isa_configure to avoid ISA drivers finding our cards */
18311602Sphk	pccard_configure();
18411602Sphk#endif
1857818Sdufault
1864Srgrimes#if NISA > 0
1874Srgrimes	isa_configure();
1884Srgrimes#endif
1894Srgrimes
19012091Sgibbs#if NEISA > 0
19112091Sgibbs	eisa_configure();
19212091Sgibbs#endif
19312091Sgibbs
1942430Sse#if NPCI > 0
1952430Sse	pci_configure();
1962430Sse#endif
1972430Sse
1987818Sdufault	configure_finish();
1997818Sdufault
20010665Sbde	cninit_finish();
20110665Sbde
2028055Sphk#ifdef MFS_ROOT
20310358Sjulian	mfs_initminiroot(mfs_root);		/* XXX UGLY*/
2048055Sphk#endif /* MFS_ROOT */
2058055Sphk
2067731Sphk#ifdef CD9660
2078007Sphk	if ((boothowto & RB_CDROM) && !mountroot)
2087731Sphk		mountroot = find_cdrom_root;
2097731Sphk#endif
2108007Sphk
2114370Sphk#ifdef NFS
2127731Sphk	if (!mountroot && nfs_diskless_valid)
2133795Sphk		mountroot = nfs_mountroot;
2144370Sphk#endif /* NFS */
2158007Sphk
2164370Sphk#ifdef FFS
2174370Sphk	if (!mountroot) {
21810358Sjulian		mountroot = vfs_mountroot;	/* XXX goes away*/
21910358Sjulian		mountrootvfsops = &ufs_vfsops;
2206547Swpaul		/*
2216547Swpaul		 * Ignore the -a flag if this kernel isn't compiled
2226547Swpaul		 * with a generic root/swap configuration: if we skip
2236547Swpaul		 * setroot() and we aren't a generic kernel, chaos
2246547Swpaul		 * will ensue because setconf() will be a no-op.
2256547Swpaul		 * (rootdev is always initialized to NODEV in a
2266547Swpaul		 * generic configuration, so we test for that.)
2276547Swpaul		 */
2286547Swpaul		if ((boothowto & RB_ASKNAME) == 0 || rootdev != NODEV)
2295321Sjkh			setroot();
2303795Sphk	}
2314Srgrimes#endif
23210358Sjulian#ifdef LFS
2334370Sphk	if (!mountroot) {
23410358Sjulian		mountroot = vfs_mountroot;	/* XXX goes away*/
23510358Sjulian		mountrootvfsops = &lfs_vfsops;
23610358Sjulian		/*
23710358Sjulian		 * Ignore the -a flag if this kernel isn't compiled
23810358Sjulian		 * with a generic root/swap configuration: if we skip
23910358Sjulian		 * setroot() and we aren't a generic kernel, chaos
24010358Sjulian		 * will ensue because setconf() will be a no-op.
24110358Sjulian		 * (rootdev is always initialized to NODEV in a
24210358Sjulian		 * generic configuration, so we test for that.)
24310358Sjulian		 */
24410358Sjulian		if ((boothowto & RB_ASKNAME) == 0 || rootdev != NODEV)
24510358Sjulian			setroot();
24610358Sjulian	}
24710358Sjulian#endif
24810358Sjulian	if (!mountroot) {
2494370Sphk		panic("Nobody wants to mount my root for me");
2504370Sphk	}
2514Srgrimes	/*
2524Srgrimes	 * Configure swap area and related system
2534Srgrimes	 * parameter based on device(s) used.
2544Srgrimes	 */
2558433Swpaul	setconf();
2564Srgrimes	cold = 0;
2574Srgrimes}
2584Srgrimes
2598481Swollmanint
2608833Sdgsetdumpdev(dev)
2618833Sdg	dev_t dev;
2628481Swollman{
2638833Sdg	int maj, psize;
2648833Sdg	long newdumplo;
2658833Sdg
2668833Sdg	if (dev == NODEV) {
2678481Swollman		dumpdev = dev;
2688481Swollman		dumplo = 0;
2698833Sdg		return (0);
2708481Swollman	}
2718833Sdg	maj = major(dev);
2728833Sdg	if (maj >= nblkdev)
2738833Sdg		return (ENXIO);
2748833Sdg	if (bdevsw[maj].d_psize == NULL)
2758833Sdg		return (ENXIO);		/* XXX should sometimes be ENODEV */
2768833Sdg	psize = bdevsw[maj].d_psize(dev);
2778833Sdg	if (psize == -1)
2788833Sdg		return (ENXIO);		/* XXX should sometimes be ENODEV */
2798833Sdg	newdumplo = psize - Maxmem * NBPG / DEV_BSIZE;
2808833Sdg	if (newdumplo < 0)
2818833Sdg		return (ENOSPC);
2828833Sdg	dumpdev = dev;
2838833Sdg	dumplo = newdumplo;
2848833Sdg	return (0);
2858876Srgrimes}
2868481Swollman
2878833Sdgu_long	bootdev = 0;		/* not a dev_t - encoding is different */
2884Srgrimes
2894Srgrimesstatic	char devname[][2] = {
2906105Sse      {'w','d'},      /* 0 = wd */
2916105Sse      {'s','w'},      /* 1 = sw */
2921289Sache#define FDMAJOR 2
2936105Sse      {'f','d'},      /* 2 = fd */
2946105Sse      {'w','t'},      /* 3 = wt */
2956105Sse      {'s','d'},      /* 4 = sd -- new SCSI system */
2964Srgrimes};
2974Srgrimes
2984Srgrimes#define	PARTITIONMASK	0x7
2994Srgrimes#define	PARTITIONSHIFT	3
3001290Sache#define FDUNITSHIFT     6
3012400Sache#define RAW_PART        2
3024Srgrimes
3034Srgrimes/*
3044Srgrimes * Attempt to find the device from which we were booted.
3054Srgrimes * If we can do so, and not instructed not to do so,
3064Srgrimes * change rootdev to correspond to the load device.
3074Srgrimes */
308798Swollmanstatic void
3094Srgrimessetroot()
3104Srgrimes{
3114Srgrimes	int  majdev, mindev, unit, part, adaptor;
312798Swollman	dev_t temp = 0, orootdev;
3134Srgrimes	struct swdevt *swp;
3144Srgrimes
3154Srgrimes/*printf("howto %x bootdev %x ", boothowto, bootdev);*/
3164Srgrimes	if (boothowto & RB_DFLTROOT ||
3174Srgrimes	    (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC)
3184Srgrimes		return;
3194Srgrimes	majdev = (bootdev >> B_TYPESHIFT) & B_TYPEMASK;
3204Srgrimes	if (majdev > sizeof(devname) / sizeof(devname[0]))
3214Srgrimes		return;
3224Srgrimes	adaptor = (bootdev >> B_ADAPTORSHIFT) & B_ADAPTORMASK;
3234Srgrimes	unit = (bootdev >> B_UNITSHIFT) & B_UNITMASK;
3241290Sache	if (majdev == FDMAJOR) {
3252400Sache		part = RAW_PART;
3261290Sache		mindev = unit << FDUNITSHIFT;
3271290Sache	}
3281290Sache	else {
3291290Sache		part = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK;
3301289Sache		mindev = (unit << PARTITIONSHIFT) + part;
3311290Sache	}
3324Srgrimes	orootdev = rootdev;
3334Srgrimes	rootdev = makedev(majdev, mindev);
3344Srgrimes	/*
3354Srgrimes	 * If the original rootdev is the same as the one
3364Srgrimes	 * just calculated, don't need to adjust the swap configuration.
3374Srgrimes	 */
3384Srgrimes	if (rootdev == orootdev)
3394Srgrimes		return;
3404Srgrimes	printf("changing root device to %c%c%d%c\n",
3414Srgrimes		devname[majdev][0], devname[majdev][1],
3421290Sache		mindev >> (majdev == FDMAJOR ? FDUNITSHIFT : PARTITIONSHIFT),
3431290Sache		part + 'a');
3444Srgrimes}
345