xref: /netbsd-src/sys/arch/arc/arc/autoconf.c (revision 952c1ac435a694dec490ab331a2d13e47ad33c87)
1 /*	$NetBSD: autoconf.c,v 1.36 2023/08/30 17:10:17 tsutsui 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.36 2023/08/30 17:10:17 tsutsui 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
cpu_configure(void)131 cpu_configure(void)
132 {
133 
134 	(void)splhigh();	/* To be really sure.. */
135 	if (config_rootfound("mainbus", NULL) == NULL)
136 		panic("no mainbus found");
137 
138 	/* Configuration is finished, turn on interrupts. */
139 
140 	/* enable all source forcing SOFT_INTs cleared */
141 	spl0();
142 }
143 
144 #if defined(NFS_BOOT_BOOTP) || defined(NFS_BOOT_DHCP)
145 int nfs_boot_rfc951 = 1;
146 #endif
147 
148 void
cpu_rootconf(void)149 cpu_rootconf(void)
150 {
151 
152 	printf("boot device: %s\n",
153 	    booted_device ? device_xname(booted_device) : "<unknown>");
154 
155 	booted_partition = booted_device ? bootdev_data->partition : 0;
156 	rootconf();
157 }
158 
159 struct devmap {
160 	const char *attachment;
161 	const char *dev;
162 };
163 
164 /*
165  * Look at the string 'cp' and decode the boot device.
166  * Boot names look like: scsi()disk(n)rdisk()partition(1)\bsd
167  * (beware for empty scsi id's...)
168  */
169 void
makebootdev(const char * cp)170 makebootdev(const char *cp)
171 {
172 	int ok, junk;
173 	static struct devmap devmap[] = {
174 		{ "multi", "fd" },
175 		{ "eisa", "wd" },
176 		{ "scsi", "sd" },
177 		{ NULL, NULL }
178 	};
179 	struct devmap *dp = &devmap[0];
180 	static struct bootdev_data bd;
181 
182 	/* "scsi()" */
183 	while (dp->attachment) {
184 		if (strncmp(cp, dp->attachment, strlen(dp->attachment)) == 0)
185 			break;
186 		dp++;
187 	}
188 	if (!dp->attachment) {
189 		printf("Warning: boot device unrecognized: %s\n", cp);
190 		return;
191 	}
192 	bd.dev_type = dp->dev;
193 	ok = getpno(&cp, &bd.bus);
194 
195 	/* "multi(2)scsi(0)disk(0)rdisk(0)partition(1)" case */
196 	if (ok && strcmp(dp->attachment, "multi") == 0 &&
197 	    memcmp(cp, "scsi", 4) == 0) {
198 		bd.dev_type = "sd";
199 		ok = getpno(&cp, &bd.bus);
200 	}
201 
202 	/* "disk(N)" */
203 	if (ok)
204 		ok = getpno(&cp, &bd.unit);
205 	else
206 		bd.unit = 0;
207 
208 	/* "rdisk()" */
209 	if (*cp++ == ')')
210 		ok = getpno(&cp, &junk);
211 
212 	/* "partition(1)" */
213 #if 0 /* ignore partition number */
214 	if (ok && getpno(&cp, &bd.partition))
215 		--bd.partition;
216 	else
217 #endif
218 		bd.partition = 0;
219 
220 	bootdev_data = &bd;
221 }
222 
223 static int
getpno(const char ** cp,int * np)224 getpno(const char **cp, int *np)
225 {
226 	int val = 0;
227 	const char *s = *cp;
228 	int got = 0;
229 
230 	*np = 0;
231 
232 	while (*s && *s != '(')
233 		s++;
234 	if (*s == '(') {
235 		for (s++; *s; s++) {
236 			if (*s == ')') {
237 				s++;
238 				got = 1;
239 				*np = val;
240 				break;
241 			}
242 			val = val * 10 + *s - '0';
243 		}
244 	}
245 	*cp = s;
246 	return (got);
247 }
248 
249 /*
250  * Attempt to find the device from which we were booted.
251  */
252 void
device_register(device_t dev,void * aux)253 device_register(device_t dev, void *aux)
254 {
255 	struct bootdev_data *b = bootdev_data;
256 	device_t parent = device_parent(dev);
257 
258 	static int found = 0, initted = 0, scsiboot = 0;
259 	static device_t scsibusdev = NULL;
260 
261 	if (b == NULL)
262 		return;	/* There is no hope. */
263 	if (found)
264 		return;
265 
266 	if (!initted) {
267 		if (strcmp(b->dev_type, "sd") == 0)
268 			scsiboot = 1;
269 		initted = 1;
270 	}
271 
272 	if (scsiboot && device_is_a(dev, "scsibus")) {
273 		/* XXX device_unit() abuse */
274 		if (device_unit(dev) == b->bus) {
275 			scsibusdev = dev;
276 #if 0
277 			printf("\nscsibus = %s\n", device_xname(dev));
278 #endif
279 		}
280 		return;
281 	}
282 
283 	if (!device_is_a(dev, b->dev_type))
284 		return;
285 
286 	if (device_is_a(dev, "sd")) {
287 		struct scsipibus_attach_args *sa = aux;
288 
289 		if (scsiboot && scsibusdev && parent == scsibusdev &&
290 		    sa->sa_periph->periph_target == b->unit) {
291 			booted_device = dev;
292 #if 0
293 			printf("\nbooted_device = %s\n", device_xname(dev));
294 #endif
295 			found = 1;
296 		}
297 		return;
298 	}
299 	/* XXX device_unit() abuse */
300 	if (device_unit(dev) == b->unit) {
301 		booted_device = dev;
302 #if 0
303 		printf("\nbooted_device = %s\n", device_xname(dev));
304 #endif
305 		found = 1;
306 	}
307 }
308