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