xref: /original-bsd/sys/pmax/pmax/autoconf.c (revision e59fb703)
1 /*
2  * Copyright (c) 1988 University of Utah.
3  * Copyright (c) 1992 The Regents of the University of California.
4  * All rights reserved.
5  *
6  * This code is derived from software contributed to Berkeley by
7  * the Systems Programming Group of the University of Utah Computer
8  * Science Department and Ralph Campbell.
9  *
10  * %sccs.include.redist.c%
11  *
12  * from: Utah $Hdr: autoconf.c 1.31 91/01/21$
13  *
14  *	@(#)autoconf.c	7.1 (Berkeley) 01/07/92
15  */
16 
17 /*
18  * Setup the system to run on the current machine.
19  *
20  * Configure() is called at boot time.  Available
21  * devices are determined (from possibilities mentioned in ioconf.c),
22  * and the drivers are initialized.
23  */
24 
25 #include "param.h"
26 #include "systm.h"
27 #include "map.h"
28 #include "buf.h"
29 #include "dkstat.h"
30 #include "conf.h"
31 #include "dmap.h"
32 #include "reboot.h"
33 
34 #include "../include/cpu.h"
35 #include "../dev/device.h"
36 
37 /*
38  * The following several variables are related to
39  * the configuration process, and are used in initializing
40  * the machine.
41  */
42 int	cold = 1;	/* if 1, still working on cold-start */
43 int	dkn;		/* number of iostat dk numbers assigned so far */
44 int	cpuspeed = 30;	/* approx # instr per usec. */
45 
46 /*
47  * Determine mass storage and memory configuration for a machine.
48  * Get cpu type, and then switch out to machine specific procedures
49  * which will probe adaptors to see what is out there.
50  */
51 configure()
52 {
53 	register struct pmax_ctlr *cp;
54 	register struct scsi_device *dp;
55 	register struct driver *drp;
56 
57 	/* print what type of CPU and FPU we have */
58 	switch (cpu.cpu.cp_imp) {
59 	case MIPS_R2000:
60 		printf("cpu0 (MIPS R2000 revision %d.%d)\n",
61 			cpu.cpu.cp_majrev, cpu.cpu.cp_minrev);
62 		break;
63 
64 	default:
65 		printf("cpu0 (implementation %d revision %d.%d)\n",
66 			cpu.cpu.cp_imp, cpu.cpu.cp_majrev, cpu.cpu.cp_minrev);
67 	}
68 	switch (fpu.cpu.cp_imp) {
69 	case MIPS_R2010:
70 		printf("fpu0 (MIPS R2010 revision %d.%d)\n",
71 			fpu.cpu.cp_majrev, fpu.cpu.cp_minrev);
72 		break;
73 
74 	default:
75 		printf("fpu0 (implementation %d revision %d.%d)\n",
76 			fpu.cpu.cp_imp, fpu.cpu.cp_majrev, fpu.cpu.cp_minrev);
77 	}
78 	printf("data cache size %dK inst cache size %dK\n",
79 		machDataCacheSize >> 10, machInstCacheSize >> 10);
80 
81 	/* probe and initialize controllers */
82 	for (cp = pmax_cinit; drp = cp->pmax_driver; cp++) {
83 		if (!(*drp->d_init)(cp))
84 			continue;
85 
86 		cp->pmax_alive = 1;
87 
88 		/* probe and initialize devices connected to controller */
89 		for (dp = scsi_dinit; drp = dp->sd_driver; dp++) {
90 			/* might want to get fancier later */
91 			if (dp->sd_cdriver != cp->pmax_driver ||
92 			    dp->sd_ctlr != cp->pmax_unit)
93 				continue;	/* not connected */
94 			if (!(*drp->d_init)(dp))
95 				continue;
96 			dp->sd_alive = 1;
97 			/* if device is a disk, assign number for statistics */
98 			if (dp->sd_dk && dkn < DK_NDRIVE)
99 				dp->sd_dk = dkn++;
100 			else
101 				dp->sd_dk = -1;
102 		}
103 	}
104 
105 #if GENERIC
106 	if ((boothowto & RB_ASKNAME) == 0)
107 		setroot();
108 	setconf();
109 #else
110 	setroot();
111 #endif
112 	swapconf();
113 	cold = 0;
114 }
115 
116 /*
117  * Configure swap space and related parameters.
118  */
119 swapconf()
120 {
121 	register struct swdevt *swp;
122 	register int nblks;
123 
124 	for (swp = swdevt; swp->sw_dev; swp++)
125 		if (bdevsw[major(swp->sw_dev)].d_psize) {
126 			nblks =
127 			  (*bdevsw[major(swp->sw_dev)].d_psize)(swp->sw_dev);
128 			if (nblks != -1 &&
129 			    (swp->sw_nblks == 0 || swp->sw_nblks > nblks))
130 				swp->sw_nblks = nblks;
131 		}
132 	dumpconf();
133 }
134 
135 #define	DOSWAP			/* Change swdevt and dumpdev too */
136 u_long	bootdev;		/* should be dev_t, but not until 32 bits */
137 
138 static	char devname[][2] = {
139 	'r','z',	/* 0 = rz */
140 };
141 
142 #define	PARTITIONMASK	0x7
143 #define	PARTITIONSHIFT	3
144 
145 /*
146  * Attempt to find the device from which we were booted.
147  * If we can do so, and not instructed not to do so,
148  * change rootdev to correspond to the load device.
149  */
150 setroot()
151 {
152 	register struct scsi_device *dp;
153 	int  majdev, mindev, unit, part, controller;
154 	dev_t temp, orootdev;
155 	struct swdevt *swp;
156 
157 	if (boothowto & RB_DFLTROOT ||
158 	    (bootdev & B_MAGICMASK) != B_DEVMAGIC)
159 		return;
160 	majdev = B_TYPE(bootdev);
161 	if (majdev >= sizeof(devname) / sizeof(devname[0]))
162 		return;
163 	controller = B_CONTROLLER(bootdev);
164 	part = B_PARTITION(bootdev);
165 	unit = B_UNIT(bootdev);
166 
167 	for (dp = scsi_dinit; ; dp++) {
168 		if (dp->sd_driver == 0)
169 			return;
170 		if (dp->sd_alive && dp->sd_drive == unit &&
171 		    dp->sd_ctlr == controller &&
172 		    dp->sd_driver->d_name[0] == devname[majdev][0] &&
173 		    dp->sd_driver->d_name[1] == devname[majdev][1]) {
174 			mindev = dp->sd_unit;
175 		    	break;
176 		}
177 	}
178 	/*
179 	 * Form a new rootdev
180 	 */
181 	mindev = (mindev << PARTITIONSHIFT) + part;
182 	orootdev = rootdev;
183 	rootdev = makedev(majdev, mindev);
184 	/*
185 	 * If the original rootdev is the same as the one
186 	 * just calculated, don't need to adjust the swap configuration.
187 	 */
188 	if (rootdev == orootdev)
189 		return;
190 
191 	printf("Changing root device to %c%c%d%c\n",
192 		devname[majdev][0], devname[majdev][1],
193 		mindev >> PARTITIONSHIFT, part + 'a');
194 
195 #ifdef DOSWAP
196 	mindev &= ~PARTITIONMASK;
197 	for (swp = swdevt; swp->sw_dev; swp++) {
198 		if (majdev == major(swp->sw_dev) &&
199 		    mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) {
200 			temp = swdevt[0].sw_dev;
201 			swdevt[0].sw_dev = swp->sw_dev;
202 			swp->sw_dev = temp;
203 			break;
204 		}
205 	}
206 	if (swp->sw_dev == 0)
207 		return;
208 
209 	/*
210 	 * If dumpdev was the same as the old primary swap
211 	 * device, move it to the new primary swap device.
212 	 */
213 	if (temp == dumpdev)
214 		dumpdev = swdevt[0].sw_dev;
215 #endif
216 }
217 
218 /*
219  * Look at the string 'cp' and decode the boot device.
220  */
221 void
222 makebootdev(cp)
223 	register char *cp;
224 {
225 	int  majdev, unit, part, ctrl;
226 
227 	for (majdev = 0; majdev < sizeof(devname)/sizeof(devname[0]); majdev++)
228 		if (cp[0] == devname[majdev][0] &&
229 		    cp[1] == devname[majdev][1] &&
230 		    cp[2] == '(')
231 			goto fndmaj;
232 defdev:
233 	bootdev = B_DEVMAGIC;
234 	return;
235 
236 fndmaj:
237 	for (ctrl = 0, cp += 3; *cp >= '0' && *cp <= '9'; )
238 		ctrl = ctrl * 10 + *cp++ - '0';
239 	if (*cp == ',')
240 		cp++;
241 	for (unit = 0; *cp >= '0' && *cp <= '9'; )
242 		unit = unit * 10 + *cp++ - '0';
243 	if (*cp == ',')
244 		cp++;
245 	for (part = 0; *cp >= '0' && *cp <= '9'; )
246 		part = part * 10 + *cp++ - '0';
247 	if (*cp != ')')
248 		goto defdev;
249 	bootdev = (majdev << B_TYPESHIFT) |
250 		(ctrl << B_CONTROLLERSHIFT) |
251 		(unit << B_UNITSHIFT) |
252 		(part << B_PARTITIONSHIFT);
253 }
254