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