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, Ralph Campbell, Sony Corp. and Kazumasa
9  * Utashiro of Software Research Associates, Inc.
10  *
11  * %sccs.include.redist.c%
12  *
13  * from: Utah $Hdr: autoconf.c 1.31 91/01/21$
14  *
15  *	@(#)autoconf.c	7.2 (Berkeley) 06/26/92
16  */
17 
18 /*
19  * Setup the system to run on the current machine.
20  *
21  * Configure() is called at boot time.  Available
22  * devices are determined (from possibilities mentioned in ioconf.c),
23  * and the drivers are initialized.
24  */
25 
26 #include "hb.h"
27 
28 #include "param.h"
29 #include "systm.h"
30 #include "map.h"
31 #include "buf.h"
32 #include "dkstat.h"
33 #include "conf.h"
34 #include "dmap.h"
35 #include "reboot.h"
36 
37 #include "machid.h"
38 #include "../include/adrsmap.h"
39 #include "../include/cpu.h"
40 
41 #if NHB > 0
42 #include "../hbdev/hbvar.h"
43 #endif
44 
45 /*
46  * The following several variables are related to
47  * the configuration process, and are used in initializing
48  * the machine.
49  */
50 int	cold = 1;	/* if 1, still working on cold-start */
51 int	dkn;		/* number of iostat dk numbers assigned so far */
52 int	cpuspeed = 6;	/* approx # instr per usec. */
53 
54 struct idrom	idrom;
55 
56 /*
57  * Determine mass storage and memory configuration for a machine.
58  * Get cpu type, and then switch out to machine specific procedures
59  * which will probe adaptors to see what is out there.
60  */
61 configure()
62 {
63 	register struct scsi_device *dp;
64 	register struct driver *drp;
65 
66 	readidrom((u_char *)&idrom);
67 	printf("SONY NET WORK STATION, Model %s, ", idrom.id_model);
68 	printf("Machine ID #%d\n", idrom.id_serial);
69 
70 	/* print what type of CPU and FPU we have */
71 	switch (cpu.cpu.cp_imp) {
72 	    case MIPS_R2000:
73 		printf("cpu0 (MIPS R2000 revision %d.%d)\n",
74 			cpu.cpu.cp_majrev, cpu.cpu.cp_minrev);
75 		break;
76 
77 	    case MIPS_R3000:
78 		printf("cpu0 (MIPS R3000 revision %d.%d)\n",
79 			cpu.cpu.cp_majrev, cpu.cpu.cp_minrev);
80 		break;
81 
82 	    case MIPS_R4000:
83 		printf("cpu0 (MIPS R4000 revision %d.%d)\n",
84 			cpu.cpu.cp_majrev, cpu.cpu.cp_minrev);
85 		break;
86 
87 	    default:
88 		printf("cpu0 (implementation %d revision %d.%d)\n",
89 			cpu.cpu.cp_imp, cpu.cpu.cp_majrev, cpu.cpu.cp_minrev);
90 	}
91 
92 	switch (fpu.cpu.cp_imp) {
93 	    case MIPS_R2010_FPU:
94 		printf("fpu0 (MIPS R2010 revision %d.%d)\n",
95 			fpu.cpu.cp_majrev, fpu.cpu.cp_minrev);
96 		break;
97 
98 	    case MIPS_R3010_FPU:
99 		printf("fpu0 (MIPS R3010 revision %d.%d)\n",
100 			fpu.cpu.cp_majrev, fpu.cpu.cp_minrev);
101 		break;
102 
103 	    case MIPS_R4000_FPU:
104 		printf("fpu0 (MIPS R4000 revision %d.%d)\n",
105 			fpu.cpu.cp_majrev, fpu.cpu.cp_minrev);
106 		break;
107 
108 	    default:
109 		printf("fpu0 (implementation %d revision %d.%d)\n",
110 			fpu.cpu.cp_imp, fpu.cpu.cp_majrev, fpu.cpu.cp_minrev);
111 	}
112 
113 	printf("data cache size %dK inst cache size %dK\n",
114 		machDataCacheSize >> 10, machInstCacheSize >> 10);
115 
116 	init_hb_intr();
117 
118 	probeio();
119 
120 #if GENERIC
121 	if ((boothowto & RB_ASKNAME) == 0)
122 		setroot();
123 	setconf();
124 #else
125 	setroot();
126 #endif
127 	swapconf();
128 	cold = 0;
129 }
130 
131 /*
132  * Probe the main IO bus(es).
133  * The percpu structure gives us a handle on the addresses and/or types.
134  */
135 probeio()
136 {
137 #if NHB > 0
138 	hbfind();
139 #endif
140 }
141 
142 #if NHB > 0
143 int	scsidev_setup_time = 10;
144 
145 /*
146  * Find devices on a Hyper-bus.
147  * Fills in the tables, with help from a per-driver
148  * slave initialization routine.
149  */
150 hbfind()
151 {
152 	register struct hb_device *hi;
153 	register struct hb_ctlr *hm;
154 	register int intr, i;
155 	register caddr_t reg;
156 	register struct hb_hd *hhp;
157 	register struct hb_driver *hdp;
158 	int scsi_inq_done = 0;
159 	int scsi_skip = 0;
160 	caddr_t calloc();
161 
162 	/*
163 	 * Initialize the SCSI.
164 	 */
165 #if defined(RB_NOINITSCSI)
166 	if ((boothowto & RB_NOINITSCSI) == 0) {
167 #else
168 	if (1) {
169 #endif
170 		printf("Initializing SCSI");
171 		scop_init(0);
172 		for (i = 0; i < scsidev_setup_time; i++) {
173 			printf(".");
174 #ifndef notdef
175 			DELAY( 200000);	/* 0.2 sec? */
176 #else
177 			DELAY(1000000);	/* 1 sec. */
178 #endif
179 		}
180 		printf(" done\n");
181 	}
182 
183 	hhp = &hb_hd;
184 
185 	/*
186 	 * Check each Hyper_bus mass storage controller.
187 	 * For each one which is potentially on Hyper_bus,
188 	 * see if it is really there, and if it is record it and
189 	 * then go looking for slaves.
190 	 */
191 	for (hm = hminit; hdp = hm->hm_driver; hm++) {
192 		intr = (int)hm->hm_intr;
193 		reg = hm->hm_addr;
194 		if (intr < 17) {
195 			if ((scsi_inq_done & (1 << intr)) == 0) {
196 				scsi_inq_done |= (1 << intr);
197 				if (psdprobe(hm) < 0) {
198 					scsi_skip |= (1 << intr);
199 					continue;
200 				}
201 			} else if (scsi_skip & (1 << intr)) {
202 				continue;
203 			}
204 		}
205 		i = (*hdp->hd_probe)(hm);
206 		if (i == 0)
207 			continue;
208 		scsi_skip |= (1 << intr);
209 		if (intr >= 0 && intr <= 13) {
210 			/*
211 			 * SCSI device !!
212 			 */
213 			/* hm->hm_driver is re-writed by driver probe routine */
214 			hm->hm_scnum = intr / 7;
215 			hm->hm_intr = intr % 7;
216 		}
217 		else {
218 			hm->hm_scnum = -1;
219 		}
220 		printf("%s%d at hb addr %x intr %d\n",
221 			hdp->hd_mname, hm->hm_ctlr, hm->hm_addr, intr);
222 		hm->hm_alive = 1;
223 		hm->hm_hd = &hb_hd;
224 		hdp->hd_minfo[hm->hm_ctlr] = hm;
225 		for (hi = hdinit; hi->hi_driver; hi++) {
226 			if (hi->hi_driver != hdp || hi->hi_alive ||
227 			    hi->hi_ctlr != hm->hm_ctlr && hi->hi_ctlr != '?')
228 				continue;
229 			if (intr >= 0 && intr <= 13) {
230 				hi->hi_ctlr = hm->hm_ctlr;
231 			}
232 			if ((*hdp->hd_slave)(hi, reg, intr)) {
233 				hi->hi_alive = 1;
234 				hi->hi_ctlr = hm->hm_ctlr;
235 				hi->hi_hd = &hb_hd;
236 				hi->hi_addr = (caddr_t)0;
237 				if (hi->hi_dk && dkn < DK_NDRIVE)
238 					hi->hi_dk = dkn++;
239 				else
240 					hi->hi_dk = -1;
241 				hi->hi_mi = hm;
242 				/* hi_type comes from driver */
243 				hdp->hd_dinfo[hi->hi_unit] = hi;
244 				printf("%s%d at %s%d slave %d",
245 				    hdp->hd_dname, hi->hi_unit,
246 				    hdp->hd_mname, hm->hm_ctlr, hi->hi_slave);
247 				if (hi->hi_intr < 16 && (hi->hi_intr & 7) != 7)
248 					printf(" (bus=%d, chan=%d, lun=%d)",
249 						hi->hi_intr / 8,
250 						hi->hi_intr & 7,
251 						hi->hi_slave);
252 				printf("\n");
253 				(*hdp->hd_attach)(hi);
254 			}
255 		}
256 	}
257 
258 	/*
259 	 * Now look for non-mass storage peripherals.
260 	 */
261 	for (hi = hdinit; hdp = hi->hi_driver; hi++) {
262 		if (hi->hi_alive || hi->hi_slave != -1)
263 			continue;
264 		intr = (int)hi->hi_intr;
265 		i = (*hdp->hd_probe)(hi);
266 		if (i == 0)
267 			continue;
268 		printf("%s%d at hb addr %x intr %d",
269 		    hi->hi_driver->hd_dname, hi->hi_unit, hi->hi_addr, hi->hi_intr);
270 		if (hi->hi_intr < 16 && (hi->hi_intr & 7) != 7)
271 			printf(" (bus=%d, chan=%d, lun=%d)",
272 				hi->hi_intr / 8,
273 				hi->hi_intr & 7,
274 				hi->hi_slave);
275 		printf("\n");
276 		hi->hi_hd = &hb_hd;
277 		hi->hi_alive = 1;
278 
279 		if(hm->hm_intr >= 0 && hm->hm_intr <= 13) {
280 			/* This is SCSI device !! */
281 			hm->hm_scnum = (int)hm->hm_intr / 7;
282 			hm->hm_intr = hm->hm_intr % 7;
283 		}
284 		else {
285 			hm->hm_scnum = -1 ;
286 		}
287 
288 		hi->hi_addr = (caddr_t)0;
289 		hi->hi_dk = -1;
290 		/* hi_type comes from driver */
291 		hdp->hd_dinfo[hi->hi_unit] = hi;
292 		(*hdp->hd_attach)(hi);
293 	}
294 }
295 #endif /* NHB > 0 */
296 
297 /*
298  * Configure swap space and related parameters.
299  */
300 swapconf()
301 {
302 	register struct swdevt *swp;
303 	register int nblks;
304 
305 	for (swp = swdevt; swp->sw_dev; swp++)
306 		if (bdevsw[major(swp->sw_dev)].d_psize) {
307 			nblks =
308 			  (*bdevsw[major(swp->sw_dev)].d_psize)(swp->sw_dev);
309 			if (nblks != -1 &&
310 			    (swp->sw_nblks == 0 || swp->sw_nblks > nblks))
311 				swp->sw_nblks = nblks;
312 		}
313 	dumpconf();
314 }
315 
316 #define	DOSWAP			/* Change swdevt and dumpdev too */
317 u_long	bootdev;		/* should be dev_t, but not until 32 bits */
318 
319 static	char devname[][2] = {
320 	's', 'd',	/*  0 = sd */
321 	'f', 'd',	/*  1 = fd */
322 	'f', 'h',	/*  2 = fh */
323 	0, 0,		/*  3 = not use */
324 	0, 0,		/*  4 = not use */
325 	'r', 'd',	/*  5 = rd */
326 	0, 0,		/*  6 = not use */
327 	0, 0,		/*  7 = not use */
328 	0, 0,		/*  8 = not use */
329 	0, 0,		/*  9 = not use */
330 	'o', 'd',	/* 10 = od */
331 };
332 
333 #define	PARTITIONMASK	0x7
334 #define	PARTITIONSHIFT	3
335 
336 /*
337  * Attempt to find the device from which we were booted.
338  * If we can do so, and not instructed not to do so,
339  * change rootdev to correspond to the load device.
340  */
341 setroot()
342 {
343 	register struct hb_device *ip;
344 	int  majdev, mindev, unit, part, controller;
345 	dev_t temp, orootdev;
346 	struct swdevt *swp;
347 
348 	if (boothowto & RB_DFLTROOT ||
349 	    (bootdev & B_MAGICMASK) != B_DEVMAGIC)
350 		return;
351 	majdev = B_TYPE(bootdev);
352 	if (majdev >= sizeof(devname) / sizeof(devname[0]))
353 		return;
354 	controller = B_CONTROLLER(bootdev);
355 	part = B_PARTITION(bootdev);
356 	unit = B_UNIT(bootdev);
357 
358 	for (ip = hdinit; ip->hi_driver; ip++) {
359 		if (ip->hi_alive && ip->hi_slave == unit &&
360 		   ip->hi_ctlr == controller &&
361 		   ip->hi_driver->hd_dname[0] == devname[majdev][0] &&
362 		   ip->hi_driver->hd_dname[1] == devname[majdev][1])
363 			break;
364 	}
365 
366 	if (ip->hi_driver == 0)
367 		return;
368 	mindev = ip->hi_unit;
369 
370 	/*
371 	 * Form a new rootdev
372 	 */
373 	mindev = (mindev << PARTITIONSHIFT) + part;
374 	orootdev = rootdev;
375 	rootdev = makedev(majdev, mindev);
376 
377 	/*
378 	 * If the original rootdev is the same as the one
379 	 * just calculated, don't need to adjust the swap configuration.
380 	 */
381 	if (rootdev == orootdev)
382 		return;
383 
384 	printf("Changing root device to %c%c%d%c\n",
385 		devname[majdev][0], devname[majdev][1],
386 		mindev >> PARTITIONSHIFT, part + 'a');
387 
388 #ifdef DOSWAP
389 	mindev &= ~PARTITIONMASK;
390 	for (swp = swdevt; swp->sw_dev; swp++) {
391 		if (majdev == major(swp->sw_dev) &&
392 		    mindev == (minor(swp->sw_dev) & ~PARTITIONMASK)) {
393 			temp = swdevt[0].sw_dev;
394 			swdevt[0].sw_dev = swp->sw_dev;
395 			swp->sw_dev = temp;
396 			break;
397 		}
398 	}
399 	if (swp->sw_dev == 0)
400 		return;
401 
402 	/*
403 	 * If dumpdev was the same as the old primary swap
404 	 * device, move it to the new primary swap device.
405 	 */
406 	if (temp == dumpdev)
407 		dumpdev = swdevt[0].sw_dev;
408 #endif
409 }
410 
411 readidrom(rom)
412 	register u_char *rom;
413 {
414 	register u_char *p = (u_char *)IDROM;
415 	register int i;
416 
417 	for (i = 0; i < sizeof (struct idrom); i++, p += 2)
418 		*rom++ = ((*p & 0x0f) << 4) + (*(p + 1) & 0x0f);
419 	return (0);
420 }
421