xref: /netbsd/sys/arch/arc/arc/autoconf.c (revision 6550d01e)
1 /*	$NetBSD: autoconf.c,v 1.32 2007/12/03 15:33:12 ad Exp $	*/
2 /*	$OpenBSD: autoconf.c,v 1.9 1997/05/18 13:45:20 pefo Exp $	*/
3 
4 /*
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. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  *
36  * from: Utah Hdr: autoconf.c 1.31 91/01/21
37  *
38  *	from: @(#)autoconf.c	8.1 (Berkeley) 6/10/93
39  */
40 
41 /*
42  * Copyright (c) 1996 Per Fogelstrom
43  * Copyright (c) 1988 University of Utah.
44  *
45  * This code is derived from software contributed to Berkeley by
46  * the Systems Programming Group of the University of Utah Computer
47  * Science Department and Ralph Campbell.
48  *
49  * Redistribution and use in source and binary forms, with or without
50  * modification, are permitted provided that the following conditions
51  * are met:
52  * 1. Redistributions of source code must retain the above copyright
53  *    notice, this list of conditions and the following disclaimer.
54  * 2. Redistributions in binary form must reproduce the above copyright
55  *    notice, this list of conditions and the following disclaimer in the
56  *    documentation and/or other materials provided with the distribution.
57  * 3. All advertising materials mentioning features or use of this software
58  *    must display the following acknowledgement:
59  *	This product includes software developed by the University of
60  *	California, Berkeley and its contributors.
61  * 4. Neither the name of the University nor the names of its contributors
62  *    may be used to endorse or promote products derived from this software
63  *    without specific prior written permission.
64  *
65  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
66  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
67  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
68  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
69  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
70  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
71  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
72  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
73  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
74  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
75  * SUCH DAMAGE.
76  *
77  * from: Utah Hdr: autoconf.c 1.31 91/01/21
78  *
79  *	from: @(#)autoconf.c	8.1 (Berkeley) 6/10/93
80  */
81 
82 /*
83  * Setup the system to run on the current machine.
84  *
85  * Configure() is called at boot time.  Available
86  * devices are determined (from possibilities mentioned in ioconf.c),
87  * and the drivers are initialized.
88  */
89 
90 #include <sys/cdefs.h>
91 __KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.32 2007/12/03 15:33:12 ad Exp $");
92 
93 #include <sys/param.h>
94 #include <sys/systm.h>
95 #include <sys/buf.h>
96 #include <sys/disklabel.h>
97 #include <sys/conf.h>
98 #include <sys/reboot.h>
99 #include <sys/device.h>
100 
101 #include <machine/cpu.h>
102 #include <machine/autoconf.h>
103 
104 #include <dev/scsipi/scsi_all.h>
105 #include <dev/scsipi/scsipi_all.h>
106 #include <dev/scsipi/scsiconf.h>
107 
108 #include <arc/arc/timervar.h>
109 
110 struct bootdev_data {
111 	const char *dev_type;
112 	int	bus;
113 	int	unit;
114 	int	partition;
115 };
116 
117 static int getpno(const char **, int *);
118 
119 /*
120  * The following several variables are related to
121  * the configuration process, and are used in initializing
122  * the machine.
123  */
124 struct bootdev_data *bootdev_data;
125 
126 /*
127  *  Configure all devices found that we know about.
128  *  This is done at boot time.
129  */
130 void
131 cpu_configure(void)
132 {
133 
134 #ifdef ENABLE_INT5_STATCLOCK
135 	evcnt_attach_static(&statclock_ev);
136 #endif
137 
138 	(void)splhigh();	/* To be really sure.. */
139 	if (config_rootfound("mainbus", NULL) == NULL)
140 		panic("no mainbus found");
141 
142 	/* Configuration is finished, turn on interrupts. */
143 #ifdef ENABLE_INT5_STATCLOCK
144 	/*
145 	 * Enable interrupt sources.
146 	 * We can't enable CPU INT5 which is used by statclock(9) here
147 	 * until cpu_initclocks(9) is called because there is no way
148 	 * to disable it other than setting status register by spl(9).
149 	 */
150 	_spllower(MIPS_INT_MASK_5);
151 #else
152 	/* enable all source forcing SOFT_INTs cleared */
153 	_splnone();
154 #endif
155 }
156 
157 #if defined(NFS_BOOT_BOOTP) || defined(NFS_BOOT_DHCP)
158 int nfs_boot_rfc951 = 1;
159 #endif
160 
161 void
162 cpu_rootconf(void)
163 {
164 
165 	printf("boot device: %s\n",
166 	    booted_device ? booted_device->dv_xname : "<unknown>");
167 
168 	setroot(booted_device, booted_device ? bootdev_data->partition : 0);
169 }
170 
171 struct devmap {
172 	const char *attachment;
173 	const char *dev;
174 };
175 
176 /*
177  * Look at the string 'cp' and decode the boot device.
178  * Boot names look like: scsi()disk(n)rdisk()partition(1)\bsd
179  * (beware for empty scsi id's...)
180  */
181 void
182 makebootdev(const char *cp)
183 {
184 	int ok, junk;
185 	static struct devmap devmap[] = {
186 		{ "multi", "fd" },
187 		{ "eisa", "wd" },
188 		{ "scsi", "sd" },
189 		{ NULL, NULL }
190 	};
191 	struct devmap *dp = &devmap[0];
192 	static struct bootdev_data bd;
193 
194 	/* "scsi()" */
195 	while (dp->attachment) {
196 		if (strncmp(cp, dp->attachment, strlen(dp->attachment)) == 0)
197 			break;
198 		dp++;
199 	}
200 	if (!dp->attachment) {
201 		printf("Warning: boot device unrecognized: %s\n", cp);
202 		return;
203 	}
204 	bd.dev_type = dp->dev;
205 	ok = getpno(&cp, &bd.bus);
206 
207 	/* "multi(2)scsi(0)disk(0)rdisk(0)partition(1)" case */
208 	if (ok && strcmp(dp->attachment, "multi") == 0 &&
209 	    memcmp(cp, "scsi", 4) == 0) {
210 		bd.dev_type = "sd";
211 		ok = getpno(&cp, &bd.bus);
212 	}
213 
214 	/* "disk(N)" */
215 	if (ok)
216 		ok = getpno(&cp, &bd.unit);
217 	else
218 		bd.unit = 0;
219 
220 	/* "rdisk()" */
221 	if (*cp++ == ')')
222 		ok = getpno(&cp, &junk);
223 
224 	/* "partition(1)" */
225 #if 0 /* ignore partition number */
226 	if (ok && getpno(&cp, &bd.partition))
227 		--bd.partition;
228 	else
229 #endif
230 		bd.partition = 0;
231 
232 	bootdev_data = &bd;
233 }
234 
235 static int
236 getpno(const char **cp, int *np)
237 {
238 	int val = 0;
239 	const char *s = *cp;
240 	int got = 0;
241 
242 	*np = 0;
243 
244 	while (*s && *s != '(')
245 		s++;
246 	if (*s == '(') {
247 		for (s++; *s; s++) {
248 			if (*s == ')') {
249 				s++;
250 				got = 1;
251 				*np = val;
252 				break;
253 			}
254 			val = val * 10 + *s - '0';
255 		}
256 	}
257 	*cp = s;
258 	return (got);
259 }
260 
261 /*
262  * Attempt to find the device from which we were booted.
263  */
264 void
265 device_register(struct device *dev, void *aux)
266 {
267 	struct bootdev_data *b = bootdev_data;
268 	struct device *parent = device_parent(dev);
269 
270 	static int found = 0, initted = 0, scsiboot = 0;
271 	static struct device *scsibusdev = NULL;
272 
273 	if (b == NULL)
274 		return;	/* There is no hope. */
275 	if (found)
276 		return;
277 
278 	if (!initted) {
279 		if (strcmp(b->dev_type, "sd") == 0)
280 			scsiboot = 1;
281 		initted = 1;
282 	}
283 
284 	if (scsiboot && device_is_a(dev, "scsibus")) {
285 		/* XXX device_unit() abuse */
286 		if (device_unit(dev) == b->bus) {
287 			scsibusdev = dev;
288 #if 0
289 			printf("\nscsibus = %s\n", dev->dv_xname);
290 #endif
291 		}
292 		return;
293 	}
294 
295 	if (!device_is_a(dev, b->dev_type))
296 		return;
297 
298 	if (device_is_a(dev, "sd")) {
299 		struct scsipibus_attach_args *sa = aux;
300 
301 		if (scsiboot && scsibusdev && parent == scsibusdev &&
302 		    sa->sa_periph->periph_target == b->unit) {
303 			booted_device = dev;
304 #if 0
305 			printf("\nbooted_device = %s\n", dev->dv_xname);
306 #endif
307 			found = 1;
308 		}
309 		return;
310 	}
311 	/* XXX device_unit() abuse */
312 	if (device_unit(dev) == b->unit) {
313 		booted_device = dev;
314 #if 0
315 		printf("\nbooted_device = %s\n", dev->dv_xname);
316 #endif
317 		found = 1;
318 	}
319 }
320