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