autoconf.c revision 6105
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.18 1995/01/11 17:51:26 jkh 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/pte.h>
58
59static void swapconf(void);
60static void setroot(void);
61
62/*
63 * The following several variables are related to
64 * the configuration process, and are used in initializing
65 * the machine.
66 */
67int	dkn;		/* number of iostat dk numbers assigned so far */
68extern int	cold;		/* cold start flag initialized in locore.s */
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
78#include "isa.h"
79#if NISA > 0
80      #include <i386/isa/isa_device.h>
81#endif
82
83#include "pci.h"
84#if NPCI > 0
85      #include <pci/pcivar.h>
86#endif
87
88/*
89 * Determine i/o configuration for a machine.
90 */
91void
92configure()
93{
94
95#if NISA > 0
96	isa_configure();
97#endif
98
99#if NPCI > 0
100	pci_configure();
101#endif
102
103#ifdef NFS
104	{
105	extern int nfs_diskless_valid;
106
107	if (nfs_diskless_valid)
108		mountroot = nfs_mountroot;
109	}
110#endif /* NFS */
111#ifdef FFS
112	if (!mountroot) {
113		mountroot = ffs_mountroot;
114#ifdef SWAP_GENERIC
115		if ((boothowto & RB_ASKNAME) == 0)
116			setroot();
117		setconf();
118#else
119		setroot();
120#endif
121	}
122#endif
123	if (!mountroot) {
124		panic("Nobody wants to mount my root for me");
125	}
126	/*
127	 * Configure swap area and related system
128	 * parameter based on device(s) used.
129	 */
130	swapconf();
131	cold = 0;
132}
133
134/*
135 * Configure swap space and related parameters.
136 */
137static void
138swapconf()
139{
140	register struct swdevt *swp;
141	register int nblks;
142	extern int Maxmem;
143
144	for (swp = swdevt; swp->sw_dev > 0; swp++)
145	{
146		unsigned d = major(swp->sw_dev);
147
148		if (d > nblkdev) break;
149		if (bdevsw[d].d_psize) {
150			nblks = (*bdevsw[d].d_psize)(swp->sw_dev);
151			if (nblks > 0 &&
152			    (swp->sw_nblks == 0 || swp->sw_nblks > nblks))
153				swp->sw_nblks = nblks;
154			else
155				swp->sw_nblks = 0;
156		}
157		swp->sw_nblks = ctod(dtoc(swp->sw_nblks));
158	}
159	if (dumplo == 0 && bdevsw[major(dumpdev)].d_psize)
160		dumplo = (*bdevsw[major(dumpdev)].d_psize)(dumpdev) -
161			Maxmem*NBPG/512;
162	if (dumplo < 0)
163		dumplo = 0;
164}
165
166#define	DOSWAP			/* change swdevt and dumpdev */
167u_long	bootdev = 0;		/* should be dev_t, but not until 32 bits */
168
169static	char devname[][2] = {
170      {'w','d'},      /* 0 = wd */
171      {'s','w'},      /* 1 = sw */
172#define FDMAJOR 2
173      {'f','d'},      /* 2 = fd */
174      {'w','t'},      /* 3 = wt */
175      {'s','d'},      /* 4 = sd -- new SCSI system */
176};
177
178#define	PARTITIONMASK	0x7
179#define	PARTITIONSHIFT	3
180#define FDUNITSHIFT     6
181#define RAW_PART        2
182
183/*
184 * Attempt to find the device from which we were booted.
185 * If we can do so, and not instructed not to do so,
186 * change rootdev to correspond to the load device.
187 */
188static void
189setroot()
190{
191	int  majdev, mindev, unit, part, adaptor;
192	dev_t temp = 0, orootdev;
193	struct swdevt *swp;
194
195/*printf("howto %x bootdev %x ", boothowto, bootdev);*/
196	if (boothowto & RB_DFLTROOT ||
197	    (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC)
198		return;
199	majdev = (bootdev >> B_TYPESHIFT) & B_TYPEMASK;
200	if (majdev > sizeof(devname) / sizeof(devname[0]))
201		return;
202	adaptor = (bootdev >> B_ADAPTORSHIFT) & B_ADAPTORMASK;
203	unit = (bootdev >> B_UNITSHIFT) & B_UNITMASK;
204	if (majdev == FDMAJOR) {
205		part = RAW_PART;
206		mindev = unit << FDUNITSHIFT;
207	}
208	else {
209		part = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK;
210		mindev = (unit << PARTITIONSHIFT) + part;
211	}
212	orootdev = rootdev;
213	rootdev = makedev(majdev, mindev);
214	/*
215	 * If the original rootdev is the same as the one
216	 * just calculated, don't need to adjust the swap configuration.
217	 */
218	if (rootdev == orootdev)
219		return;
220	printf("changing root device to %c%c%d%c\n",
221		devname[majdev][0], devname[majdev][1],
222		mindev >> (majdev == FDMAJOR ? FDUNITSHIFT : PARTITIONSHIFT),
223		part + 'a');
224#ifdef DOSWAP
225	mindev &= ~PARTITIONMASK;
226	for (swp = swdevt; swp->sw_dev; swp++) {
227		if (majdev == major(swp->sw_dev) &&
228		    mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) {
229
230			temp = swdevt[0].sw_dev;
231			swdevt[0].sw_dev = swp->sw_dev;
232			swp->sw_dev = temp;
233			break;
234		}
235	}
236	if (swp->sw_dev == 0)
237		return;
238	/*
239	 * If dumpdev was the same as the old primary swap
240	 * device, move it to the new primary swap device.
241	 */
242	if (temp == dumpdev)
243		dumpdev = swdevt[0].sw_dev;
244#endif
245}
246