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