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