xref: /netbsd/sys/arch/pmax/pmax/autoconf.c (revision c4a72b64)
1 /*	$NetBSD: autoconf.c,v 1.63 2002/09/27 02:24:21 thorpej Exp $	*/
2 
3 /*
4  * Copyright (c) 1988 University of Utah.
5  * Copyright (c) 1992, 1993
6  *	The Regents of the University of California.  All rights reserved.
7  *
8  * This code is derived from software contributed to Berkeley by
9  * the Systems Programming Group of the University of Utah Computer
10  * Science Department and Ralph Campbell.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  * 3. All advertising materials mentioning features or use of this software
21  *    must display the following acknowledgement:
22  *	This product includes software developed by the University of
23  *	California, Berkeley and its contributors.
24  * 4. Neither the name of the University nor the names of its contributors
25  *    may be used to endorse or promote products derived from this software
26  *    without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38  * SUCH DAMAGE.
39  *
40  * from: Utah Hdr: autoconf.c 1.31 91/01/21
41  *
42  *	@(#)autoconf.c	8.1 (Berkeley) 6/10/93
43  */
44 
45 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
46 __KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.63 2002/09/27 02:24:21 thorpej Exp $");
47 
48 #include <sys/param.h>
49 #include <sys/systm.h>
50 #include <sys/conf.h>
51 #include <sys/reboot.h>
52 #include <sys/device.h>
53 
54 #include <machine/autoconf.h>
55 #include <machine/intr.h>
56 #include <machine/sysconf.h>
57 
58 #include <pmax/pmax/pmaxtype.h>
59 
60 #include <dev/tc/tcvar.h>
61 
62 #include <dev/scsipi/scsi_all.h>
63 #include <dev/scsipi/scsipi_all.h>
64 #include <dev/scsipi/scsiconf.h>
65 
66 #include "opt_dec_3100.h"
67 #include "opt_dec_5100.h"
68 
69 struct intrhand		 intrtab[MAX_DEV_NCOOKIES];
70 struct device		*booted_device;
71 static struct device	*booted_controller;
72 static int		 booted_slot, booted_unit, booted_partition;
73 static char		*booted_protocol;
74 
75 /*
76  * Configure all devices on system
77  */
78 void
79 cpu_configure()
80 {
81 	/* Kick off autoconfiguration. */
82 	(void)splhigh();
83 
84 	softintr_init();
85 	evcnt_attach_static(&pmax_clock_evcnt);
86 	evcnt_attach_static(&pmax_fpu_evcnt);
87 	evcnt_attach_static(&pmax_memerr_evcnt);
88 
89 	if (config_rootfound("mainbus", "mainbus") == NULL)
90 		panic("no mainbus found");
91 
92 	/* Reset any bus errors due to probing nonexistent devices. */
93 	(*platform.bus_reset)();
94 
95 	/* Configuration is finished, turn on interrupts. */
96 	_splnone();	/* enable all source forcing SOFT_INTs cleared */
97 }
98 
99 /*
100  * Look at the string 'cp' and decode the boot device.  Boot names
101  * can be something like 'rz(0,0,0)vmunix' or '5/rz0/vmunix'.
102  *
103  * 2100/3100/5100 allows abbrivation;
104  *	dev(controller[,uni-number[,partition-number]]])[filename]
105  */
106 void
107 makebootdev(cp)
108 	char *cp;
109 {
110 	booted_device = NULL;
111 	booted_slot = booted_unit = booted_partition = 0;
112 	booted_protocol = NULL;
113 
114 #if defined(DEC_3100) || defined(DEC_5100)
115 	if (cp[0] == 'r' && cp[1] == 'z' && cp[2] == '(') {
116 		cp += 3;
117 		if (*cp >= '0' && *cp <= '9')
118 			booted_slot = *cp++ - '0';
119 		if (*cp == ',')
120 			cp += 1;
121 		if (*cp >= '0' && *cp <= '9')
122 			booted_unit = *cp++ - '0';
123 		if (*cp == ',')
124 			cp += 1;
125 		if (*cp >= '0' && *cp <= '9')
126 			booted_partition = *cp - '0';
127 		booted_protocol = "SCSI";
128 		return;
129 	}
130 	if (strncmp(cp, "tftp(", 5) == 0) {
131 		booted_protocol = "BOOTP";
132 		return;
133 	}
134 	if (strncmp(cp, "mop(", 4) == 0) {
135 		booted_protocol = "MOP";
136 		return;
137 	}
138 #endif
139 
140 	if (cp[0] >= '0' && cp[0] <= '9' && cp[1] == '/') {
141 		booted_slot = cp[0] - '0';
142 		if (cp[2] == 'r' && cp[3] == 'z'
143 		    && cp[4] >= '0' && cp[4] <= '9') {
144 			booted_protocol = "SCSI";
145 			booted_unit = cp[4] - '0';
146 		}
147 		else if (strncmp(cp+2, "tftp", 4) == 0)
148 			booted_protocol = "BOOTP";
149 		else if (strncmp(cp+2, "mop", 3) == 0)
150 			booted_protocol = "MOP";
151 	}
152 }
153 
154 void
155 cpu_rootconf()
156 {
157 	printf("boot device: %s\n",
158 	    booted_device ? booted_device->dv_xname : "<unknown>");
159 
160 	setroot(booted_device, booted_partition);
161 }
162 
163 /*
164  * Try to determine the boot device.
165  */
166 void
167 device_register(dev, aux)
168 	struct device *dev;
169 	void *aux;
170 {
171 	static int found, initted, scsiboot, netboot;
172 	static struct device *ioasicdev;
173 	struct device *parent = dev->dv_parent;
174 	struct cfdata *cf = dev->dv_cfdata;
175 	const char *name = cf->cf_name;
176 
177 	if (found)
178 		return;
179 
180 	if (!initted) {
181 		scsiboot = strcmp(booted_protocol, "SCSI") == 0;
182 		netboot = (strcmp(booted_protocol, "BOOTP") == 0) ||
183 		    (strcmp(booted_protocol, "MOP") == 0);
184 		initted = 1;
185 	}
186 
187 	/*
188 	 * Check if IOASIC was the boot slot.
189 	 */
190 	if (strcmp(name, "ioasic") == 0) {
191 		struct tc_attach_args *ta = aux;
192 
193 		if (ta->ta_slot == booted_slot)
194 			ioasicdev = dev;
195 		return;
196 	}
197 
198 	/*
199 	 * Check for ASC controller on either IOASIC or TC option card.
200 	 */
201 	if (scsiboot && strcmp(name, "asc") == 0) {
202 		struct tc_attach_args *ta = aux;
203 
204 		/*
205 		 * If boot was from IOASIC controller, ioasicdev will
206 		 * be the ASC parent.
207 		 * If boot was from a TC option card, the TC slot number
208 		 * of the ASC will match the boot slot.
209 		 */
210 		if (parent == ioasicdev ||
211 		    ta->ta_slot == booted_slot) {
212 			booted_controller = dev;
213 			return;
214 		}
215 	}
216 
217 	/*
218 	 * If an SII device is configured, it's currently the only
219 	 * possible SCSI boot device.
220 	 */
221 	if (scsiboot && strcmp(name, "sii") == 0) {
222 		booted_controller = dev;
223 		return;
224 	}
225 
226 	/*
227 	 * If we found the boot controller, if check disk/tape/cdrom device
228 	 * on that controller matches.
229 	 */
230 	if (booted_controller && (strcmp(name, "sd") == 0 ||
231 	    strcmp(name, "st") == 0 ||
232 	    strcmp(name, "cd") == 0)) {
233 		struct scsipibus_attach_args *sa = aux;
234 
235 		if (parent->dv_parent != booted_controller)
236 			return;
237 		if (booted_unit != sa->sa_periph->periph_target)
238 			return;
239 		booted_device = dev;
240 		found = 1;
241 		return;
242 	}
243 
244 	/*
245 	 * Check if netboot device.
246 	 */
247 	if (netboot && strcmp(name, "le") == 0) {
248 		struct tc_attach_args *ta = aux;
249 
250 #if defined(DEC_3100) || defined(DEC_5100)
251 		/* Only one Ethernet interface on 2100/3100/5100. */
252 		if (systype == DS_PMAX || systype == DS_MIPSMATE) {
253 			booted_device = dev;
254 			found = 1;
255 			return;
256 		}
257 #endif
258 		if (parent == ioasicdev ||
259 		    ta->ta_slot == booted_slot) {
260 			booted_device = dev;
261 			found = 1;
262 			return;
263 		}
264 	}
265 }
266