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