autoconf.c revision 15538
14Srgrimes/*- 24Srgrimes * Copyright (c) 1990 The Regents of the University of California. 34Srgrimes * All rights reserved. 44Srgrimes * 54Srgrimes * This code is derived from software contributed to Berkeley by 64Srgrimes * William Jolitz. 74Srgrimes * 84Srgrimes * Redistribution and use in source and binary forms, with or without 94Srgrimes * modification, are permitted provided that the following conditions 104Srgrimes * are met: 114Srgrimes * 1. Redistributions of source code must retain the above copyright 124Srgrimes * notice, this list of conditions and the following disclaimer. 134Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 144Srgrimes * notice, this list of conditions and the following disclaimer in the 154Srgrimes * documentation and/or other materials provided with the distribution. 164Srgrimes * 3. All advertising materials mentioning features or use of this software 174Srgrimes * must display the following acknowledgement: 184Srgrimes * This product includes software developed by the University of 194Srgrimes * California, Berkeley and its contributors. 204Srgrimes * 4. Neither the name of the University nor the names of its contributors 214Srgrimes * may be used to endorse or promote products derived from this software 224Srgrimes * without specific prior written permission. 234Srgrimes * 244Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 254Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 264Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 274Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 284Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 294Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 304Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 314Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 324Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 334Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 344Srgrimes * SUCH DAMAGE. 354Srgrimes * 36620Srgrimes * from: @(#)autoconf.c 7.1 (Berkeley) 5/9/91 3715538Sphk * $Id: autoconf.c,v 1.51 1995/12/16 18:52:05 peter Exp $ 384Srgrimes */ 394Srgrimes 404Srgrimes/* 414Srgrimes * Setup the system to run on the current machine. 424Srgrimes * 438876Srgrimes * Configure() is called at boot time and initializes the vba 444Srgrimes * device tables and the memory controller monitoring. Available 454Srgrimes * devices are determined (from possibilities mentioned in ioconf.c), 464Srgrimes * and the drivers are initialized. 474Srgrimes */ 482056Swollman#include <sys/param.h> 492056Swollman#include <sys/systm.h> 502056Swollman#include <sys/buf.h> 512056Swollman#include <sys/dkstat.h> 522056Swollman#include <sys/conf.h> 532056Swollman#include <sys/dmap.h> 542056Swollman#include <sys/reboot.h> 552056Swollman#include <sys/kernel.h> 5612604Sbde#include <sys/mount.h> 5712649Speter#include <sys/sysctl.h> 584Srgrimes 5910665Sbde#include <machine/cons.h> 607090Sbde#include <machine/md_var.h> 612056Swollman#include <machine/pte.h> 6212791Sgibbs#include <i386/isa/icu.h> /* For interrupts */ 634Srgrimes 6412604Sbde#include "isa.h" 6512604Sbde#if NISA > 0 6612604Sbde#include <i386/isa/isa_device.h> 6712604Sbde#endif 6810665Sbde 6912604Sbde#include "eisa.h" 7012604Sbde#if NEISA > 0 7112604Sbde#include <i386/eisa/eisaconf.h> 7212604Sbde#endif 7310665Sbde 7412604Sbde#include "pci.h" 7512604Sbde#if NPCI > 0 7612604Sbde#include <pci/pcivar.h> 7712604Sbde#endif 78798Swollman 7912604Sbde#include "crd.h" 8012604Sbde#if NCRD > 0 8112604Sbde#include <pccard/driver.h> 8212604Sbde#endif 834Srgrimes 8412604Sbde#include "scbus.h" 8512604Sbde#if NSCBUS > 0 8612604Sbde#include <scsi/scsiconf.h> 8712604Sbde#endif 8812604Sbde 8912604Sbdestatic void configure __P((void *)); 9012604SbdeSYSINIT(configure, SI_SUB_CONFIGURE, SI_ORDER_FIRST, configure, NULL) 9112604Sbde 9212499Speter#ifdef MFS_ROOT 9312499Speterextern struct vfsops mfs_vfsops; 9412499Speter#endif 954370Sphk#ifdef FFS 9610358Sjulianextern struct vfsops ufs_vfsops; 974370Sphk#endif 9810358Sjulian#ifdef LFS 9910358Sjulianextern struct vfsops lfs_vfsops; 10010358Sjulian#endif 1014370Sphk#ifdef NFS 10212604Sbdeextern int nfs_mountroot __P((void *)); 1034370Sphk#endif 1047731Sphk#ifdef CD9660 10512604Sbdeextern int cd9660_mountroot __P((void *)); 1067731Sphk#endif 1078055Sphk#ifdef MSDOSFS 10812604Sbdeextern int msdosfs_mountroot __P((void *)); 1098055Sphk#endif 1104370Sphk 11112848Sbdestatic void configure_finish __P((void)); 11212848Sbdestatic void configure_start __P((void)); 11312848Sbdestatic int setdumpdev __P((dev_t dev)); 11412848Sbdestatic void setroot __P((void)); 11512848Sbde 1168007Sphk#ifdef CD9660 1177731Sphk/* We need to try out all our potential CDROM drives, so we need a table. */ 1187731Sphkstatic struct { 1197731Sphk char *name; 1207731Sphk int major; 1217731Sphk} try_cdrom[] = { 1227731Sphk { "cd", 6 }, 1237731Sphk { "mcd", 7 }, 1247731Sphk { "scd", 16 }, 1257731Sphk { "matcd", 17 }, 1267731Sphk { 0, 0} 1277731Sphk}; 1287731Sphk 12912604Sbdestatic int find_cdrom_root __P((void *)); 13012604Sbde 13112604Sbdestatic int 13210653Sdgfind_cdrom_root(dummy) 13310653Sdg void *dummy; 1347731Sphk{ 1357731Sphk int i,j,k; 1367731Sphk 1377731Sphk for (j = 0 ; j < 2; j++) 1387731Sphk for (k = 0 ; try_cdrom[k].name ; k++) { 1397731Sphk rootdev = makedev(try_cdrom[k].major,j*8); 1408456Srgrimes printf("trying rootdev=0x%lx (%s%d)\n", 1417731Sphk rootdev, try_cdrom[k].name,j); 14210665Sbde i = (*cd9660_mountroot)((void *)NULL); 1437731Sphk if (!i) return i; 1447731Sphk } 1457731Sphk return EINVAL; 1467731Sphk} 1478007Sphk#endif /* CD9660 */ 1487731Sphk 14912604Sbdestatic void 1507818Sdufaultconfigure_start() 1517818Sdufault{ 1527818Sdufault#if NSCBUS > 0 1537818Sdufault scsi_configure_start(); 1547818Sdufault#endif 1557818Sdufault} 1567818Sdufault 15712604Sbdestatic void 1587818Sdufaultconfigure_finish() 1597818Sdufault{ 1607818Sdufault#if NSCBUS > 0 1617818Sdufault scsi_configure_finish(); 1627818Sdufault#endif 1637818Sdufault} 1647818Sdufault 1654Srgrimes/* 1664Srgrimes * Determine i/o configuration for a machine. 1674Srgrimes */ 16810665Sbdestatic void 16910665Sbdeconfigure(dummy) 17010653Sdg void *dummy; 1714Srgrimes{ 1724Srgrimes 1738015Sjulian configure_start(); 1748015Sjulian 17512791Sgibbs /* Allow all routines to decide for themselves if they want intrs */ 17612791Sgibbs enable_intr(); 17712791Sgibbs INTREN(IRQ_SLAVE); 17812791Sgibbs 17911602Sphk#if NCRD > 0 18011602Sphk /* Before isa_configure to avoid ISA drivers finding our cards */ 18111602Sphk pccard_configure(); 18211602Sphk#endif 1837818Sdufault 18412091Sgibbs#if NEISA > 0 18512091Sgibbs eisa_configure(); 18612091Sgibbs#endif 18712091Sgibbs 1882430Sse#if NPCI > 0 1892430Sse pci_configure(); 1902430Sse#endif 1912430Sse 19212791Sgibbs#if NISA > 0 19312791Sgibbs isa_configure(); 19412791Sgibbs#endif 19512791Sgibbs 1967818Sdufault configure_finish(); 1977818Sdufault 19810665Sbde cninit_finish(); 19910665Sbde 2007731Sphk#ifdef CD9660 2018007Sphk if ((boothowto & RB_CDROM) && !mountroot) 2027731Sphk mountroot = find_cdrom_root; 2037731Sphk#endif 2048007Sphk 2054370Sphk#ifdef NFS 2067731Sphk if (!mountroot && nfs_diskless_valid) 2073795Sphk mountroot = nfs_mountroot; 2084370Sphk#endif /* NFS */ 2098007Sphk 21012499Speter#ifdef MFS_ROOT 21112499Speter if (!mountroot) { 21212499Speter mountroot = vfs_mountroot; /* XXX goes away*/ 21312499Speter mountrootvfsops = &mfs_vfsops; 21412499Speter /* 21512499Speter * Ignore the -a flag if this kernel isn't compiled 21612499Speter * with a generic root/swap configuration: if we skip 21712499Speter * setroot() and we aren't a generic kernel, chaos 21812499Speter * will ensue because setconf() will be a no-op. 21912499Speter * (rootdev is always initialized to NODEV in a 22012499Speter * generic configuration, so we test for that.) 22112499Speter */ 22212499Speter if ((boothowto & RB_ASKNAME) == 0 || rootdev != NODEV) 22312499Speter setroot(); 22412499Speter } 22512499Speter#endif 2264370Sphk#ifdef FFS 2274370Sphk if (!mountroot) { 22810358Sjulian mountroot = vfs_mountroot; /* XXX goes away*/ 22910358Sjulian mountrootvfsops = &ufs_vfsops; 2306547Swpaul /* 2316547Swpaul * Ignore the -a flag if this kernel isn't compiled 2326547Swpaul * with a generic root/swap configuration: if we skip 2336547Swpaul * setroot() and we aren't a generic kernel, chaos 2346547Swpaul * will ensue because setconf() will be a no-op. 2356547Swpaul * (rootdev is always initialized to NODEV in a 2366547Swpaul * generic configuration, so we test for that.) 2376547Swpaul */ 2386547Swpaul if ((boothowto & RB_ASKNAME) == 0 || rootdev != NODEV) 2395321Sjkh setroot(); 2403795Sphk } 2414Srgrimes#endif 24210358Sjulian#ifdef LFS 2434370Sphk if (!mountroot) { 24410358Sjulian mountroot = vfs_mountroot; /* XXX goes away*/ 24510358Sjulian mountrootvfsops = &lfs_vfsops; 24610358Sjulian /* 24710358Sjulian * Ignore the -a flag if this kernel isn't compiled 24810358Sjulian * with a generic root/swap configuration: if we skip 24910358Sjulian * setroot() and we aren't a generic kernel, chaos 25010358Sjulian * will ensue because setconf() will be a no-op. 25110358Sjulian * (rootdev is always initialized to NODEV in a 25210358Sjulian * generic configuration, so we test for that.) 25310358Sjulian */ 25410358Sjulian if ((boothowto & RB_ASKNAME) == 0 || rootdev != NODEV) 25510358Sjulian setroot(); 25610358Sjulian } 25710358Sjulian#endif 25810358Sjulian if (!mountroot) { 2594370Sphk panic("Nobody wants to mount my root for me"); 2604370Sphk } 2614Srgrimes /* 2624Srgrimes * Configure swap area and related system 2634Srgrimes * parameter based on device(s) used. 2644Srgrimes */ 2658433Swpaul setconf(); 2664Srgrimes cold = 0; 2674Srgrimes} 2684Srgrimes 26912722Sphkstatic int 2708833Sdgsetdumpdev(dev) 2718833Sdg dev_t dev; 2728481Swollman{ 2738833Sdg int maj, psize; 2748833Sdg long newdumplo; 2758833Sdg 2768833Sdg if (dev == NODEV) { 2778481Swollman dumpdev = dev; 2788481Swollman dumplo = 0; 2798833Sdg return (0); 2808481Swollman } 2818833Sdg maj = major(dev); 2828833Sdg if (maj >= nblkdev) 2838833Sdg return (ENXIO); 28412889Speter if (bdevsw[maj] == NULL) 28512889Speter return (ENXIO); /* XXX is this right? */ 28612813Sjulian if (bdevsw[maj]->d_psize == NULL) 28712889Speter return (ENXIO); /* XXX should be ENODEV ? */ 28812813Sjulian psize = bdevsw[maj]->d_psize(dev); 2898833Sdg if (psize == -1) 29012889Speter return (ENXIO); /* XXX should be ENODEV ? */ 29115538Sphk newdumplo = psize - Maxmem * PAGE_SIZE / DEV_BSIZE; 2928833Sdg if (newdumplo < 0) 2938833Sdg return (ENOSPC); 2948833Sdg dumpdev = dev; 2958833Sdg dumplo = newdumplo; 2968833Sdg return (0); 2978876Srgrimes} 2988481Swollman 2998833Sdgu_long bootdev = 0; /* not a dev_t - encoding is different */ 3004Srgrimes 3014Srgrimesstatic char devname[][2] = { 3026105Sse {'w','d'}, /* 0 = wd */ 3036105Sse {'s','w'}, /* 1 = sw */ 3041289Sache#define FDMAJOR 2 3056105Sse {'f','d'}, /* 2 = fd */ 3066105Sse {'w','t'}, /* 3 = wt */ 3076105Sse {'s','d'}, /* 4 = sd -- new SCSI system */ 3084Srgrimes}; 3094Srgrimes 3104Srgrimes#define PARTITIONMASK 0x7 3114Srgrimes#define PARTITIONSHIFT 3 3121290Sache#define FDUNITSHIFT 6 3132400Sache#define RAW_PART 2 3144Srgrimes 3154Srgrimes/* 3164Srgrimes * Attempt to find the device from which we were booted. 3174Srgrimes * If we can do so, and not instructed not to do so, 3184Srgrimes * change rootdev to correspond to the load device. 3194Srgrimes */ 320798Swollmanstatic void 3214Srgrimessetroot() 3224Srgrimes{ 3234Srgrimes int majdev, mindev, unit, part, adaptor; 32412417Sphk dev_t orootdev; 3254Srgrimes 3264Srgrimes/*printf("howto %x bootdev %x ", boothowto, bootdev);*/ 3274Srgrimes if (boothowto & RB_DFLTROOT || 3284Srgrimes (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC) 3294Srgrimes return; 3304Srgrimes majdev = (bootdev >> B_TYPESHIFT) & B_TYPEMASK; 3314Srgrimes if (majdev > sizeof(devname) / sizeof(devname[0])) 3324Srgrimes return; 3334Srgrimes adaptor = (bootdev >> B_ADAPTORSHIFT) & B_ADAPTORMASK; 3344Srgrimes unit = (bootdev >> B_UNITSHIFT) & B_UNITMASK; 3351290Sache if (majdev == FDMAJOR) { 3362400Sache part = RAW_PART; 3371290Sache mindev = unit << FDUNITSHIFT; 3381290Sache } 3391290Sache else { 3401290Sache part = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK; 3411289Sache mindev = (unit << PARTITIONSHIFT) + part; 3421290Sache } 3434Srgrimes orootdev = rootdev; 3444Srgrimes rootdev = makedev(majdev, mindev); 3454Srgrimes /* 3464Srgrimes * If the original rootdev is the same as the one 3474Srgrimes * just calculated, don't need to adjust the swap configuration. 3484Srgrimes */ 3494Srgrimes if (rootdev == orootdev) 3504Srgrimes return; 3514Srgrimes printf("changing root device to %c%c%d%c\n", 3524Srgrimes devname[majdev][0], devname[majdev][1], 3531290Sache mindev >> (majdev == FDMAJOR ? FDUNITSHIFT : PARTITIONSHIFT), 3541290Sache part + 'a'); 3554Srgrimes} 35612649Speter 35712649Speterstatic int 35812649Spetersysctl_kern_dumpdev SYSCTL_HANDLER_ARGS 35912649Speter{ 36012649Speter int error; 36112649Speter dev_t ndumpdev; 36212649Speter 36312649Speter ndumpdev = dumpdev; 36412649Speter error = sysctl_handle_opaque(oidp, &ndumpdev, sizeof ndumpdev, req); 36512649Speter if (!error && ndumpdev != dumpdev) { 36612649Speter error = setdumpdev(ndumpdev); 36712649Speter } 36812649Speter return (error); 36912649Speter} 37012649Speter 37112649SpeterSYSCTL_PROC(_kern, KERN_DUMPDEV, dumpdev, CTLTYPE_OPAQUE|CTLFLAG_RW, 37212649Speter 0, sizeof dumpdev, sysctl_kern_dumpdev, "I", ""); 373