autoconf.c revision 10653
1/*- 2 * Copyright (c) 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * William Jolitz. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. 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: @(#)autoconf.c 7.1 (Berkeley) 5/9/91 37 * $Id: autoconf.c,v 1.37 1995/09/03 05:43:00 julian Exp $ 38 */ 39 40/* 41 * Setup the system to run on the current machine. 42 * 43 * Configure() is called at boot time and initializes the vba 44 * device tables and the memory controller monitoring. Available 45 * devices are determined (from possibilities mentioned in ioconf.c), 46 * and the drivers are initialized. 47 */ 48#include <sys/param.h> 49#include <sys/systm.h> 50#include <sys/buf.h> 51#include <sys/dkstat.h> 52#include <sys/conf.h> 53#include <sys/dmap.h> 54#include <sys/reboot.h> 55#include <sys/kernel.h> 56#include <sys/mount.h> /* mountrootvfsops, struct vfsops*/ 57 58#include <machine/md_var.h> 59#include <machine/pte.h> 60 61static void setroot(void); 62 63/* 64 * The following several variables are related to 65 * the configuration process, and are used in initializing 66 * the machine. 67 */ 68int dkn; /* number of iostat dk numbers assigned so far */ 69 70#ifdef FFS 71extern struct vfsops ufs_vfsops; 72#endif 73#ifdef LFS 74extern struct vfsops lfs_vfsops; 75#endif 76#ifdef NFS 77int nfs_mountroot __P((void *)); 78#endif 79#ifdef CD9660 80int cd9660_mountroot __P((void *)); 81#endif 82#ifdef MSDOSFS 83int msdosfs_mountroot __P((void *)); 84#endif 85#ifdef MFS_ROOT 86int mfs_initminiroot __P((u_char *)); 87u_char mfs_root[MFS_ROOT*1024] = "MFS Filesystem goes here"; 88u_char end_mfs_root[] = "MFS Filesystem had better STOP here"; 89#endif 90 91#include "eisa.h" 92#include "isa.h" 93#if NISA > 0 94 #include <i386/isa/isa_device.h> 95#endif 96 97#include "pci.h" 98#if NPCI > 0 99 #include <pci/pcivar.h> 100#endif 101 102#include "crd.h" 103#if NCRD > 0 104void pccard_configure(); 105#endif 106 107#ifdef CD9660 108/* We need to try out all our potential CDROM drives, so we need a table. */ 109static struct { 110 char *name; 111 int major; 112} try_cdrom[] = { 113 { "cd", 6 }, 114 { "mcd", 7 }, 115 { "scd", 16 }, 116 { "matcd", 17 }, 117 { 0, 0} 118}; 119 120int 121find_cdrom_root(dummy) 122 void *dummy; 123{ 124 int i,j,k; 125 126 for (j = 0 ; j < 2; j++) 127 for (k = 0 ; try_cdrom[k].name ; k++) { 128 rootdev = makedev(try_cdrom[k].major,j*8); 129 printf("trying rootdev=0x%lx (%s%d)\n", 130 rootdev, try_cdrom[k].name,j); 131 i = (*cd9660_mountroot)(NULL); 132 if (!i) return i; 133 } 134 return EINVAL; 135} 136#endif /* CD9660 */ 137 138#include "scbus.h" 139#if NSCBUS > 0 140 #include <scsi/scsiconf.h> 141#endif 142 143void 144configure_start() 145{ 146#if NSCBUS > 0 147 scsi_configure_start(); 148#endif 149} 150 151void 152configure_finish() 153{ 154#if NSCBUS > 0 155 scsi_configure_finish(); 156#endif 157} 158 159/* 160 * Determine i/o configuration for a machine. 161 */ 162void 163configure(dummy) /* arg not used */ 164 void *dummy; 165{ 166 167 configure_start(); 168 169#if NEISA > 0 170 eisa_configure(); 171#endif 172 173 174#if NISA > 0 175 isa_configure(); 176#endif 177 178#if NPCI > 0 179 pci_configure(); 180#endif 181 182#if NCRD > 0 183 pccard_configure(); 184#endif 185 186 configure_finish(); 187 188#ifdef MFS_ROOT 189 mfs_initminiroot(mfs_root); /* XXX UGLY*/ 190#endif /* MFS_ROOT */ 191 192#ifdef CD9660 193 if ((boothowto & RB_CDROM) && !mountroot) 194 mountroot = find_cdrom_root; 195#endif 196 197#ifdef NFS 198 if (!mountroot && nfs_diskless_valid) 199 mountroot = nfs_mountroot; 200#endif /* NFS */ 201 202#ifdef FFS 203 if (!mountroot) { 204 mountroot = vfs_mountroot; /* XXX goes away*/ 205 mountrootvfsops = &ufs_vfsops; 206 /* 207 * Ignore the -a flag if this kernel isn't compiled 208 * with a generic root/swap configuration: if we skip 209 * setroot() and we aren't a generic kernel, chaos 210 * will ensue because setconf() will be a no-op. 211 * (rootdev is always initialized to NODEV in a 212 * generic configuration, so we test for that.) 213 */ 214 if ((boothowto & RB_ASKNAME) == 0 || rootdev != NODEV) 215 setroot(); 216 } 217#endif 218#ifdef LFS 219 if (!mountroot) { 220 mountroot = vfs_mountroot; /* XXX goes away*/ 221 mountrootvfsops = &lfs_vfsops; 222 /* 223 * Ignore the -a flag if this kernel isn't compiled 224 * with a generic root/swap configuration: if we skip 225 * setroot() and we aren't a generic kernel, chaos 226 * will ensue because setconf() will be a no-op. 227 * (rootdev is always initialized to NODEV in a 228 * generic configuration, so we test for that.) 229 */ 230 if ((boothowto & RB_ASKNAME) == 0 || rootdev != NODEV) 231 setroot(); 232 } 233#endif 234 if (!mountroot) { 235 panic("Nobody wants to mount my root for me"); 236 } 237 /* 238 * Configure swap area and related system 239 * parameter based on device(s) used. 240 */ 241 setconf(); 242 cold = 0; 243} 244/* 245 * Add a SYSINIT entry so that Configure gets called at the right time. 246 */ 247SYSINIT(configure, SI_SUB_CONFIGURE, SI_ORDER_FIRST, configure, NULL) 248 249 250int 251setdumpdev(dev) 252 dev_t dev; 253{ 254 int maj, psize; 255 long newdumplo; 256 257 if (dev == NODEV) { 258 dumpdev = dev; 259 dumplo = 0; 260 return (0); 261 } 262 maj = major(dev); 263 if (maj >= nblkdev) 264 return (ENXIO); 265 if (bdevsw[maj].d_psize == NULL) 266 return (ENXIO); /* XXX should sometimes be ENODEV */ 267 psize = bdevsw[maj].d_psize(dev); 268 if (psize == -1) 269 return (ENXIO); /* XXX should sometimes be ENODEV */ 270 newdumplo = psize - Maxmem * NBPG / DEV_BSIZE; 271 if (newdumplo < 0) 272 return (ENOSPC); 273 dumpdev = dev; 274 dumplo = newdumplo; 275 return (0); 276} 277 278u_long bootdev = 0; /* not a dev_t - encoding is different */ 279 280static char devname[][2] = { 281 {'w','d'}, /* 0 = wd */ 282 {'s','w'}, /* 1 = sw */ 283#define FDMAJOR 2 284 {'f','d'}, /* 2 = fd */ 285 {'w','t'}, /* 3 = wt */ 286 {'s','d'}, /* 4 = sd -- new SCSI system */ 287}; 288 289#define PARTITIONMASK 0x7 290#define PARTITIONSHIFT 3 291#define FDUNITSHIFT 6 292#define RAW_PART 2 293 294/* 295 * Attempt to find the device from which we were booted. 296 * If we can do so, and not instructed not to do so, 297 * change rootdev to correspond to the load device. 298 */ 299static void 300setroot() 301{ 302 int majdev, mindev, unit, part, adaptor; 303 dev_t temp = 0, orootdev; 304 struct swdevt *swp; 305 306/*printf("howto %x bootdev %x ", boothowto, bootdev);*/ 307 if (boothowto & RB_DFLTROOT || 308 (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC) 309 return; 310 majdev = (bootdev >> B_TYPESHIFT) & B_TYPEMASK; 311 if (majdev > sizeof(devname) / sizeof(devname[0])) 312 return; 313 adaptor = (bootdev >> B_ADAPTORSHIFT) & B_ADAPTORMASK; 314 unit = (bootdev >> B_UNITSHIFT) & B_UNITMASK; 315 if (majdev == FDMAJOR) { 316 part = RAW_PART; 317 mindev = unit << FDUNITSHIFT; 318 } 319 else { 320 part = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK; 321 mindev = (unit << PARTITIONSHIFT) + part; 322 } 323 orootdev = rootdev; 324 rootdev = makedev(majdev, mindev); 325 /* 326 * If the original rootdev is the same as the one 327 * just calculated, don't need to adjust the swap configuration. 328 */ 329 if (rootdev == orootdev) 330 return; 331 printf("changing root device to %c%c%d%c\n", 332 devname[majdev][0], devname[majdev][1], 333 mindev >> (majdev == FDMAJOR ? FDUNITSHIFT : PARTITIONSHIFT), 334 part + 'a'); 335} 336