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