1 /* $OpenBSD: autoconf.c,v 1.47 2022/09/02 20:06:56 miod Exp $ */
2 /*
3 * Copyright (c) 1996, 1997 Per Fogelstrom
4 * Copyright (c) 1995 Theo de Raadt
5 * Copyright (c) 1988 University of Utah.
6 * Copyright (c) 1992, 1993
7 * The Regents of the University of California. All rights reserved.
8 *
9 * This code is derived from software contributed to Berkeley by
10 * the Systems Programming Group of the University of Utah Computer
11 * Science Department and Ralph Campbell.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 * 3. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 *
37 * from: Utah Hdr: autoconf.c 1.31 91/01/21
38 *
39 * from: @(#)autoconf.c 8.1 (Berkeley) 6/10/93
40 * $Id: autoconf.c,v 1.47 2022/09/02 20:06:56 miod Exp $
41 */
42
43 /*
44 * Setup the system to run on the current machine.
45 *
46 * cpu_configure() is called at boot time. Available
47 * devices are determined (from possibilities mentioned in ioconf.c),
48 * and the drivers are initialized.
49 */
50
51 #include "sd.h"
52 #include "mpath.h"
53
54 #include <sys/param.h>
55 #include <sys/systm.h>
56 #include <sys/buf.h>
57 #include <sys/disklabel.h>
58 #include <sys/conf.h>
59 #include <sys/reboot.h>
60 #include <sys/device.h>
61 #include <dev/cons.h>
62 #include <uvm/uvm_extern.h>
63 #include <machine/autoconf.h>
64
65 #include <sys/disk.h>
66 #include <scsi/scsi_all.h>
67 #include <scsi/scsiconf.h>
68 #include <dev/ata/atavar.h>
69
70 #if NMPATH > 0
71 #include <scsi/mpathvar.h>
72 #endif
73
74 void dumpconf(void);
75 static struct devmap *findtype(char **);
76 void parseofwbp(char *);
77 int getpno(char **);
78
79 /*
80 * The following several variables are related to
81 * the configuration process, and are used in initializing
82 * the machine.
83 */
84 int cold = 1; /* if 1, still working on cold-start */
85 char bootdev[16]; /* to hold boot dev name */
86 struct device *bootdv = NULL;
87 enum devclass bootdev_class = DV_DULL;
88 int bootdev_type = 0;
89 int bootdev_unit = 0;
90
91 /*
92 * Configure all devices found that we know about.
93 * This is done at boot time.
94 */
95 void
cpu_configure(void)96 cpu_configure(void)
97 {
98 (void)splhigh(); /* To be really sure.. */
99
100 softintr_init();
101
102 if (config_rootfound("mainbus", "mainbus") == 0)
103 panic("no mainbus found");
104 (void)spl0();
105 cold = 0;
106 }
107
108 struct devmap {
109 char *att;
110 char *dev;
111 int type;
112 };
113 #define T_IFACE 0x10
114
115 #define T_BUS 0x00
116 #define T_SCSI 0x11
117 #define T_IDE 0x12
118 #define T_DISK 0x21
119
120 static struct devmap *
findtype(char ** s)121 findtype(char **s)
122 {
123 static struct devmap devmap[] = {
124 { "/ht", NULL, T_BUS },
125 { "/ht@", NULL, T_BUS },
126 { "/pci@", NULL, T_BUS },
127 { "/pci", NULL, T_BUS },
128 { "/AppleKiwi@", NULL, T_BUS },
129 { "/AppleKiwi", NULL, T_BUS },
130 { "/mac-io@", NULL, T_BUS },
131 { "/mac-io", NULL, T_BUS },
132 { "/@", NULL, T_BUS },
133 { "/LSILogic,sas@", "sd", T_SCSI },
134 { "/scsi@", "sd", T_SCSI },
135 { "/ide", "wd", T_IDE },
136 { "/ata", "wd", T_IDE },
137 { "/k2-sata-root", NULL, T_BUS },
138 { "/k2-sata", "wd", T_IDE },
139 { "/disk@", "sd", T_DISK },
140 { "/disk", "wd", T_DISK },
141 { "/usb@", "sd", T_SCSI },
142 { "/ADPT,2940U2B@", "sd", T_SCSI },
143 { "/bcom5704@4", "bge0", T_IFACE },
144 { "/bcom5704@4,1", "bge1", T_IFACE },
145 { "/ethernet", "gem0", T_IFACE },
146 { "/enet", "mc0", T_IFACE },
147 { NULL, NULL }
148 };
149 struct devmap *dp = &devmap[0];
150
151 while (dp->att) {
152 if (strncmp(*s, dp->att, strlen(dp->att)) == 0) {
153 *s += strlen(dp->att);
154 break;
155 }
156 dp++;
157 }
158 if (dp->att == NULL)
159 printf("string [%s] not found\n", *s);
160
161 return(dp);
162 }
163
164 /*
165 * Look at the string 'bp' and decode the boot device.
166 * Boot names look like: '/pci/scsi@c/disk@0,0/bsd'
167 * '/pci/mac-io/ide@20000/disk@0,0/bsd
168 * '/pci/mac-io/ide/disk/bsd
169 * '/ht@0,f2000000/pci@2/bcom5704@4/bsd'
170 */
171 void
parseofwbp(char * bp)172 parseofwbp(char *bp)
173 {
174 int ptype;
175 char *dev, *cp;
176 struct devmap *dp;
177
178 cp = bp;
179 do {
180 while(*cp && *cp != '/')
181 cp++;
182
183 dp = findtype(&cp);
184 if (!dp->att) {
185 printf("Warning: bootpath unrecognized: %s\n", bp);
186 return;
187 }
188 } while((dp->type & T_IFACE) == 0);
189
190 if (dp->att && dp->type == T_IFACE) {
191 bootdev_class = DV_IFNET;
192 bootdev_type = dp->type;
193 strlcpy(bootdev, dp->dev, sizeof bootdev);
194 return;
195 }
196 dev = dp->dev;
197 while(*cp && *cp != '/')
198 cp++;
199 ptype = dp->type;
200 dp = findtype(&cp);
201 if (dp->att && dp->type == T_DISK) {
202 bootdev_class = DV_DISK;
203 bootdev_type = ptype;
204 bootdev_unit = getpno(&cp);
205 return;
206 }
207 printf("Warning: boot device unrecognized: %s\n", bp);
208 }
209
210 int
getpno(char ** cp)211 getpno(char **cp)
212 {
213 int val = 0, digit;
214 char *cx = *cp;
215
216 while (*cx) {
217 if (*cx >= '0' && *cx <= '9')
218 digit = *cx - '0';
219 else if (*cx >= 'a' && *cx <= 'f')
220 digit = *cx - 'a' + 0x0a;
221 else
222 break;
223 val = val * 16 + digit;
224 cx++;
225 }
226 *cp = cx;
227 return (val);
228 }
229
230 void
device_register(struct device * dev,void * aux)231 device_register(struct device *dev, void *aux)
232 {
233 #if NSD > 0
234 extern struct cfdriver scsibus_cd;
235 #endif
236 const char *drvrname = dev->dv_cfdata->cf_driver->cd_name;
237 const char *name = dev->dv_xname;
238
239 if (bootdv != NULL || dev->dv_class != bootdev_class)
240 return;
241
242 switch (bootdev_type) {
243 #if NSD > 0
244 case T_SCSI:
245 if (dev->dv_parent->dv_cfdata->cf_driver == &scsibus_cd) {
246 struct scsi_attach_args *sa = aux;
247
248 if (sa->sa_sc_link->target == bootdev_unit)
249 bootdv = dev;
250 }
251 #endif
252 case T_IDE:
253 if (strcmp(drvrname, "wd") == 0) {
254 struct ata_atapi_attach *aa = aux;
255
256 if (aa->aa_drv_data->drive == bootdev_unit)
257 bootdv = dev;
258 }
259 break;
260 case T_IFACE:
261 if (strcmp(name, bootdev) == 0)
262 bootdv = dev;
263 break;
264 default:
265 break;
266 }
267 }
268
269 void
diskconf(void)270 diskconf(void)
271 {
272 printf("bootpath: %s\n", bootpath);
273
274 #if NMPATH > 0
275 if (bootdv != NULL)
276 bootdv = mpath_bootdv(bootdv);
277 #endif
278
279 setroot(bootdv, 0, RB_USERREQ);
280 dumpconf();
281 }
282
283 const struct nam2blk nam2blk[] = {
284 { "wd", 0 },
285 { "sd", 2 },
286 { "cd", 3 },
287 { "vnd", 14 },
288 { "rd", 17 },
289 { NULL, -1 }
290 };
291