autoconf.c revision 8456
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * William Jolitz.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 *    must display the following acknowledgement:
18 *	This product includes software developed by the University of
19 *	California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 *    may be used to endorse or promote products derived from this software
22 *    without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 *	from: @(#)autoconf.c	7.1 (Berkeley) 5/9/91
37 *	$Id: autoconf.c,v 1.28 1995/05/11 02:50:11 wpaul Exp $
38 */
39
40/*
41 * Setup the system to run on the current machine.
42 *
43 * Configure() is called at boot time and initializes the vba
44 * device tables and the memory controller monitoring.  Available
45 * devices are determined (from possibilities mentioned in ioconf.c),
46 * and the drivers are initialized.
47 */
48#include <sys/param.h>
49#include <sys/systm.h>
50#include <sys/buf.h>
51#include <sys/dkstat.h>
52#include <sys/conf.h>
53#include <sys/dmap.h>
54#include <sys/reboot.h>
55#include <sys/kernel.h>
56
57#include <machine/md_var.h>
58#include <machine/pte.h>
59
60static void swapconf(void);
61static void setroot(void);
62
63/*
64 * The following several variables are related to
65 * the configuration process, and are used in initializing
66 * the machine.
67 */
68int	dkn;		/* number of iostat dk numbers assigned so far */
69
70extern int (*mountroot) __P((void));
71#ifdef FFS
72int ffs_mountroot __P((void));
73#endif
74#ifdef NFS
75int nfs_mountroot __P((void));
76#endif
77#ifdef CD9660
78int cd9660_mountroot __P((void));
79#endif
80#ifdef MSDOSFS
81int msdosfs_mountroot __P((void));
82#endif
83#ifdef MFS_ROOT
84int mfs_initminiroot __P((u_char *));
85u_char mfs_root[MFS_ROOT*1024] = "MFS Filesystem goes here";
86u_char end_mfs_root[] = "MFS Filesystem had better STOP here";
87#endif
88
89#include "eisa.h"
90#include "isa.h"
91#if NISA > 0
92      #include <i386/isa/isa_device.h>
93#endif
94
95#include "pci.h"
96#if NPCI > 0
97      #include <pci/pcivar.h>
98#endif
99
100#ifdef CD9660
101/* We need to try out all our potential CDROM drives, so we need a table. */
102static struct {
103	char *name;
104	int major;
105} try_cdrom[] = {
106	{ "cd", 6 },
107	{ "mcd", 7 },
108	{ "scd", 16 },
109	{ "matcd", 17 },
110	{ 0, 0}
111};
112
113int
114find_cdrom_root()
115{
116	int i,j,k;
117
118	for (j = 0 ; j < 2; j++)
119		for (k = 0 ; try_cdrom[k].name ; k++) {
120			rootdev = makedev(try_cdrom[k].major,j*8);
121			printf("trying rootdev=0x%lx (%s%d)\n",
122				rootdev, try_cdrom[k].name,j);
123			i = (*cd9660_mountroot)();
124			if (!i) return i;
125		}
126	return EINVAL;
127}
128#endif /* CD9660 */
129
130#include "scbus.h"
131#if NSCBUS > 0
132      #include <scsi/scsiconf.h>
133#endif
134
135void
136configure_start()
137{
138#if NSCBUS > 0
139	scsi_configure_start();
140#endif
141}
142
143void
144configure_finish()
145{
146#if NSCBUS > 0
147	scsi_configure_finish();
148#endif
149}
150
151/*
152 * Determine i/o configuration for a machine.
153 */
154void
155configure()
156{
157
158	configure_start();
159
160#if NEISA > 0
161	eisa_configure();
162#endif
163
164
165#if NISA > 0
166	isa_configure();
167#endif
168
169#if NPCI > 0
170	pci_configure();
171#endif
172
173	configure_finish();
174
175#ifdef MFS_ROOT
176	mfs_initminiroot(mfs_root);
177#endif /* MFS_ROOT */
178
179#ifdef CD9660
180	if ((boothowto & RB_CDROM) && !mountroot)
181		mountroot = find_cdrom_root;
182#endif
183
184#ifdef NFS
185	if (!mountroot && nfs_diskless_valid)
186		mountroot = nfs_mountroot;
187#endif /* NFS */
188
189#ifdef FFS
190	if (!mountroot) {
191		mountroot = ffs_mountroot;
192		/*
193		 * Ignore the -a flag if this kernel isn't compiled
194		 * with a generic root/swap configuration: if we skip
195		 * setroot() and we aren't a generic kernel, chaos
196		 * will ensue because setconf() will be a no-op.
197		 * (rootdev is always initialized to NODEV in a
198		 * generic configuration, so we test for that.)
199		 */
200		if ((boothowto & RB_ASKNAME) == 0 || rootdev != NODEV)
201			setroot();
202	}
203#endif
204	if (!mountroot) {
205		panic("Nobody wants to mount my root for me");
206	}
207	/*
208	 * Configure swap area and related system
209	 * parameter based on device(s) used.
210	 */
211	setconf();
212	swapconf();
213	cold = 0;
214}
215
216/*
217 * Configure swap space and related parameters.
218 */
219static void
220swapconf()
221{
222	register struct swdevt *swp;
223	register int nblks;
224
225	for (swp = swdevt; swp->sw_dev > 0; swp++)
226	{
227		unsigned d = major(swp->sw_dev);
228
229		if (d > nblkdev) break;
230		if (bdevsw[d].d_psize) {
231			nblks = (*bdevsw[d].d_psize)(swp->sw_dev);
232			if (nblks > 0 &&
233			    (swp->sw_nblks == 0 || swp->sw_nblks > nblks))
234				swp->sw_nblks = nblks;
235			else
236				swp->sw_nblks = 0;
237		}
238		swp->sw_nblks = ctod(dtoc(swp->sw_nblks));
239	}
240	if (dumplo == 0 && bdevsw[major(dumpdev)].d_psize)
241		dumplo = (*bdevsw[major(dumpdev)].d_psize)(dumpdev) -
242			Maxmem*NBPG/512;
243	if (dumplo < 0)
244		dumplo = 0;
245}
246
247#define	DOSWAP			/* change swdevt and dumpdev */
248u_long	bootdev = 0;		/* should be dev_t, but not until 32 bits */
249
250static	char devname[][2] = {
251      {'w','d'},      /* 0 = wd */
252      {'s','w'},      /* 1 = sw */
253#define FDMAJOR 2
254      {'f','d'},      /* 2 = fd */
255      {'w','t'},      /* 3 = wt */
256      {'s','d'},      /* 4 = sd -- new SCSI system */
257};
258
259#define	PARTITIONMASK	0x7
260#define	PARTITIONSHIFT	3
261#define FDUNITSHIFT     6
262#define RAW_PART        2
263
264/*
265 * Attempt to find the device from which we were booted.
266 * If we can do so, and not instructed not to do so,
267 * change rootdev to correspond to the load device.
268 */
269static void
270setroot()
271{
272	int  majdev, mindev, unit, part, adaptor;
273	dev_t temp = 0, orootdev;
274	struct swdevt *swp;
275
276/*printf("howto %x bootdev %x ", boothowto, bootdev);*/
277	if (boothowto & RB_DFLTROOT ||
278	    (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC)
279		return;
280	majdev = (bootdev >> B_TYPESHIFT) & B_TYPEMASK;
281	if (majdev > sizeof(devname) / sizeof(devname[0]))
282		return;
283	adaptor = (bootdev >> B_ADAPTORSHIFT) & B_ADAPTORMASK;
284	unit = (bootdev >> B_UNITSHIFT) & B_UNITMASK;
285	if (majdev == FDMAJOR) {
286		part = RAW_PART;
287		mindev = unit << FDUNITSHIFT;
288	}
289	else {
290		part = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK;
291		mindev = (unit << PARTITIONSHIFT) + part;
292	}
293	orootdev = rootdev;
294	rootdev = makedev(majdev, mindev);
295	/*
296	 * If the original rootdev is the same as the one
297	 * just calculated, don't need to adjust the swap configuration.
298	 */
299	if (rootdev == orootdev)
300		return;
301	printf("changing root device to %c%c%d%c\n",
302		devname[majdev][0], devname[majdev][1],
303		mindev >> (majdev == FDMAJOR ? FDUNITSHIFT : PARTITIONSHIFT),
304		part + 'a');
305#ifdef DOSWAP
306	mindev &= ~PARTITIONMASK;
307	for (swp = swdevt; swp->sw_dev; swp++) {
308		if (majdev == major(swp->sw_dev) &&
309		    mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) {
310
311			temp = swdevt[0].sw_dev;
312			swdevt[0].sw_dev = swp->sw_dev;
313			swp->sw_dev = temp;
314			break;
315		}
316	}
317	if (swp->sw_dev == 0)
318		return;
319	/*
320	 * If dumpdev was the same as the old primary swap
321	 * device, move it to the new primary swap device.
322	 */
323	if (temp == dumpdev)
324		dumpdev = swdevt[0].sw_dev;
325#endif
326}
327