autoconf.c revision 25164
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 3725164Speter * $Id: autoconf.c,v 1.64 1997/02/22 09:32:08 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 */ 4825164Speter#include "opt_smp.h" 4925164Speter 502056Swollman#include <sys/param.h> 512056Swollman#include <sys/systm.h> 522056Swollman#include <sys/buf.h> 532056Swollman#include <sys/conf.h> 542056Swollman#include <sys/dmap.h> 552056Swollman#include <sys/reboot.h> 562056Swollman#include <sys/kernel.h> 5712604Sbde#include <sys/mount.h> 5822521Sdyson#include <sys/vnode.h> 5912649Speter#include <sys/sysctl.h> 604Srgrimes 6120641Sbde#include <machine/bootinfo.h> 6210665Sbde#include <machine/cons.h> 637090Sbde#include <machine/md_var.h> 6412791Sgibbs#include <i386/isa/icu.h> /* For interrupts */ 654Srgrimes 6625164Speter#if defined(APIC_IO) 6725164Speter#include <machine/smp.h> 6825164Speter#endif /* APIC_IO */ 6925164Speter 7012604Sbde#include "isa.h" 7112604Sbde#if NISA > 0 7212604Sbde#include <i386/isa/isa_device.h> 7312604Sbde#endif 7410665Sbde 7512604Sbde#include "eisa.h" 7612604Sbde#if NEISA > 0 7712604Sbde#include <i386/eisa/eisaconf.h> 7812604Sbde#endif 7910665Sbde 8012604Sbde#include "pci.h" 8112604Sbde#if NPCI > 0 8212604Sbde#include <pci/pcivar.h> 8312604Sbde#endif 84798Swollman 8512604Sbde#include "crd.h" 8612604Sbde#if NCRD > 0 8712604Sbde#include <pccard/driver.h> 8812604Sbde#endif 894Srgrimes 9012604Sbde#include "scbus.h" 9112604Sbde#if NSCBUS > 0 9212604Sbde#include <scsi/scsiconf.h> 9312604Sbde#endif 9412604Sbde 9512604Sbdestatic void configure __P((void *)); 9612604SbdeSYSINIT(configure, SI_SUB_CONFIGURE, SI_ORDER_FIRST, configure, NULL) 9712604Sbde 9812848Sbdestatic void configure_finish __P((void)); 9912848Sbdestatic void configure_start __P((void)); 10012848Sbdestatic int setdumpdev __P((dev_t dev)); 10112848Sbdestatic void setroot __P((void)); 10212848Sbde 1038007Sphk#ifdef CD9660 10422521Sdyson 10522521Sdyson#include <isofs/cd9660/iso.h> 10622521Sdyson 1077731Sphk/* We need to try out all our potential CDROM drives, so we need a table. */ 1087731Sphkstatic struct { 1097731Sphk char *name; 1107731Sphk int major; 1117731Sphk} try_cdrom[] = { 1127731Sphk { "cd", 6 }, 1137731Sphk { "mcd", 7 }, 1147731Sphk { "scd", 16 }, 1157731Sphk { "matcd", 17 }, 1167731Sphk { 0, 0} 1177731Sphk}; 1187731Sphk 11912604Sbdestatic int find_cdrom_root __P((void *)); 12012604Sbde 12112604Sbdestatic int 12210653Sdgfind_cdrom_root(dummy) 12310653Sdg void *dummy; 1247731Sphk{ 1257731Sphk int i,j,k; 1267731Sphk 1277731Sphk for (j = 0 ; j < 2; j++) 1287731Sphk for (k = 0 ; try_cdrom[k].name ; k++) { 1297731Sphk rootdev = makedev(try_cdrom[k].major,j*8); 1308456Srgrimes printf("trying rootdev=0x%lx (%s%d)\n", 1317731Sphk rootdev, try_cdrom[k].name,j); 13222521Sdyson i = (*cd9660_mountroot)(); 1337731Sphk if (!i) return i; 1347731Sphk } 1357731Sphk return EINVAL; 1367731Sphk} 1378007Sphk#endif /* CD9660 */ 1387731Sphk 13912604Sbdestatic void 1407818Sdufaultconfigure_start() 1417818Sdufault{ 1427818Sdufault#if NSCBUS > 0 1437818Sdufault scsi_configure_start(); 1447818Sdufault#endif 1457818Sdufault} 1467818Sdufault 14712604Sbdestatic void 1487818Sdufaultconfigure_finish() 1497818Sdufault{ 1507818Sdufault#if NSCBUS > 0 1517818Sdufault scsi_configure_finish(); 1527818Sdufault#endif 1537818Sdufault} 1547818Sdufault 1554Srgrimes/* 1564Srgrimes * Determine i/o configuration for a machine. 1574Srgrimes */ 15810665Sbdestatic void 15910665Sbdeconfigure(dummy) 16010653Sdg void *dummy; 1614Srgrimes{ 16220641Sbde int i; 1634Srgrimes 1648015Sjulian configure_start(); 1658015Sjulian 16612791Sgibbs /* Allow all routines to decide for themselves if they want intrs */ 16725164Speter#if defined(APIC_IO) 16825164Speter configure_local_apic(); 16912791Sgibbs enable_intr(); 17025164Speter#else 17125164Speter enable_intr(); 17212791Sgibbs INTREN(IRQ_SLAVE); 17325164Speter#endif /* APIC_IO */ 17412791Sgibbs 17525164Speter#if NCRD > 0 17625164Speter /* Before isa_configure to avoid ISA drivers finding our cards */ 17725164Speter pccard_configure(); 17825164Speter#endif 17925164Speter 18012091Sgibbs#if NEISA > 0 18112091Sgibbs eisa_configure(); 18212091Sgibbs#endif 18312091Sgibbs 1842430Sse#if NPCI > 0 1852430Sse pci_configure(); 1862430Sse#endif 1872430Sse 18812791Sgibbs#if NISA > 0 18912791Sgibbs isa_configure(); 19012791Sgibbs#endif 19112791Sgibbs 19222564Sbde#if NCRD > 0 19322564Sbde /* After everyone else has a chance at grabbing resources */ 19422564Sbde pccard_configure(); 19522564Sbde#endif 19622564Sbde 19717355Sbde if (setdumpdev(dumpdev) != 0) 19817355Sbde dumpdev = NODEV; 19917355Sbde 2007818Sdufault configure_finish(); 2017818Sdufault 20210665Sbde cninit_finish(); 20310665Sbde 20420641Sbde if (bootverbose) { 20520641Sbde /* 20620641Sbde * Print out the BIOS's idea of the disk geometries. 20720641Sbde */ 20820641Sbde printf("BIOS Geometries:\n"); 20920641Sbde for (i = 0; i < N_BIOS_GEOM; i++) { 21020641Sbde unsigned long bios_geom; 21120641Sbde int max_cylinder, max_head, max_sector; 21220641Sbde 21320641Sbde bios_geom = bootinfo.bi_bios_geom[i]; 21420641Sbde 21520641Sbde /* 21620641Sbde * XXX the bootstrap punts a 1200K floppy geometry 21720641Sbde * when the get-disk-geometry interrupt fails. Skip 21820641Sbde * drives that have this geometry. 21920641Sbde */ 22020641Sbde if (bios_geom == 0x4f010f) 22120641Sbde continue; 22220641Sbde 22320641Sbde printf(" %x:%08lx ", i, bios_geom); 22420641Sbde max_cylinder = bios_geom >> 16; 22520641Sbde max_head = (bios_geom >> 8) & 0xff; 22620641Sbde max_sector = bios_geom & 0xff; 22720641Sbde printf( 22820641Sbde "0..%d=%d cylinders, 0..%d=%d heads, 1..%d=%d sectors\n", 22920641Sbde max_cylinder, max_cylinder + 1, 23020641Sbde max_head, max_head + 1, 23120641Sbde max_sector, max_sector); 23220641Sbde } 23320641Sbde printf(" %d accounted for\n", bootinfo.bi_n_bios_used); 23420641Sbde 23516075Sjoerg printf("Device configuration finished.\n"); 23620641Sbde } 23716075Sjoerg 2387731Sphk#ifdef CD9660 23922521Sdyson if ((boothowto & RB_CDROM)) { 24016075Sjoerg if (bootverbose) 24116075Sjoerg printf("Considering CD-ROM root f/s.\n"); 24222521Sdyson mountrootfsname = "cd9660"; 24316075Sjoerg } 2447731Sphk#endif 2458007Sphk 24612499Speter#ifdef MFS_ROOT 24722521Sdyson if (!mountrootfsname) { 24816075Sjoerg if (bootverbose) 24916075Sjoerg printf("Considering MFS root f/s.\n"); 25022521Sdyson mountrootfsname = "mfs"; 25112499Speter /* 25212499Speter * Ignore the -a flag if this kernel isn't compiled 25312499Speter * with a generic root/swap configuration: if we skip 25412499Speter * setroot() and we aren't a generic kernel, chaos 25512499Speter * will ensue because setconf() will be a no-op. 25612499Speter * (rootdev is always initialized to NODEV in a 25712499Speter * generic configuration, so we test for that.) 25812499Speter */ 25912499Speter if ((boothowto & RB_ASKNAME) == 0 || rootdev != NODEV) 26012499Speter setroot(); 26112499Speter } 26212499Speter#endif 26322564Sbde 26422564Sbde#ifdef NFS 26522564Sbde if (!mountrootfsname && nfs_diskless_valid) { 26622564Sbde if (bootverbose) 26722564Sbde printf("Considering NFS root f/s.\n"); 26822564Sbde mountrootfsname = "nfs"; 26922564Sbde } 27022564Sbde#endif /* NFS */ 27122564Sbde 2724370Sphk#ifdef FFS 27322521Sdyson if (!mountrootfsname) { 27422521Sdyson mountrootfsname = "ufs"; 27516075Sjoerg if (bootverbose) 27616075Sjoerg printf("Considering FFS root f/s.\n"); 2776547Swpaul /* 2786547Swpaul * Ignore the -a flag if this kernel isn't compiled 2796547Swpaul * with a generic root/swap configuration: if we skip 2806547Swpaul * setroot() and we aren't a generic kernel, chaos 2816547Swpaul * will ensue because setconf() will be a no-op. 2826547Swpaul * (rootdev is always initialized to NODEV in a 2836547Swpaul * generic configuration, so we test for that.) 2846547Swpaul */ 2856547Swpaul if ((boothowto & RB_ASKNAME) == 0 || rootdev != NODEV) 2865321Sjkh setroot(); 2873795Sphk } 2884Srgrimes#endif 28922564Sbde 29010358Sjulian#ifdef LFS 29122521Sdyson if (!mountrootfsname) { 29216075Sjoerg if (bootverbose) 29316075Sjoerg printf("Considering LFS root f/s.\n"); 29422521Sdyson mountrootfsname = "lfs"; 29510358Sjulian /* 29610358Sjulian * Ignore the -a flag if this kernel isn't compiled 29710358Sjulian * with a generic root/swap configuration: if we skip 29810358Sjulian * setroot() and we aren't a generic kernel, chaos 29910358Sjulian * will ensue because setconf() will be a no-op. 30010358Sjulian * (rootdev is always initialized to NODEV in a 30110358Sjulian * generic configuration, so we test for that.) 30210358Sjulian */ 30310358Sjulian if ((boothowto & RB_ASKNAME) == 0 || rootdev != NODEV) 30410358Sjulian setroot(); 30510358Sjulian } 30610358Sjulian#endif 30722564Sbde 30822521Sdyson if (!mountrootfsname) { 3094370Sphk panic("Nobody wants to mount my root for me"); 3104370Sphk } 31117355Sbde 3128433Swpaul setconf(); 3134Srgrimes cold = 0; 31416075Sjoerg if (bootverbose) 31516075Sjoerg printf("configure() finished.\n"); 3164Srgrimes} 3174Srgrimes 31812722Sphkstatic int 3198833Sdgsetdumpdev(dev) 3208833Sdg dev_t dev; 3218481Swollman{ 3228833Sdg int maj, psize; 3238833Sdg long newdumplo; 3248833Sdg 3258833Sdg if (dev == NODEV) { 3268481Swollman dumpdev = dev; 3278833Sdg return (0); 3288481Swollman } 3298833Sdg maj = major(dev); 3308833Sdg if (maj >= nblkdev) 3318833Sdg return (ENXIO); 33212889Speter if (bdevsw[maj] == NULL) 33312889Speter return (ENXIO); /* XXX is this right? */ 33412813Sjulian if (bdevsw[maj]->d_psize == NULL) 33512889Speter return (ENXIO); /* XXX should be ENODEV ? */ 33612813Sjulian psize = bdevsw[maj]->d_psize(dev); 3378833Sdg if (psize == -1) 33812889Speter return (ENXIO); /* XXX should be ENODEV ? */ 33915538Sphk newdumplo = psize - Maxmem * PAGE_SIZE / DEV_BSIZE; 3408833Sdg if (newdumplo < 0) 3418833Sdg return (ENOSPC); 3428833Sdg dumpdev = dev; 3438833Sdg dumplo = newdumplo; 3448833Sdg return (0); 3458876Srgrimes} 3468481Swollman 3478833Sdgu_long bootdev = 0; /* not a dev_t - encoding is different */ 3484Srgrimes 3494Srgrimesstatic char devname[][2] = { 3506105Sse {'w','d'}, /* 0 = wd */ 3516105Sse {'s','w'}, /* 1 = sw */ 3521289Sache#define FDMAJOR 2 3536105Sse {'f','d'}, /* 2 = fd */ 3546105Sse {'w','t'}, /* 3 = wt */ 3556105Sse {'s','d'}, /* 4 = sd -- new SCSI system */ 3564Srgrimes}; 3574Srgrimes 3584Srgrimes#define PARTITIONMASK 0x7 3594Srgrimes#define PARTITIONSHIFT 3 3601290Sache#define FDUNITSHIFT 6 3612400Sache#define RAW_PART 2 3624Srgrimes 3634Srgrimes/* 3644Srgrimes * Attempt to find the device from which we were booted. 3654Srgrimes * If we can do so, and not instructed not to do so, 3664Srgrimes * change rootdev to correspond to the load device. 3674Srgrimes */ 368798Swollmanstatic void 3694Srgrimessetroot() 3704Srgrimes{ 3714Srgrimes int majdev, mindev, unit, part, adaptor; 37212417Sphk dev_t orootdev; 3734Srgrimes 3744Srgrimes/*printf("howto %x bootdev %x ", boothowto, bootdev);*/ 3754Srgrimes if (boothowto & RB_DFLTROOT || 3764Srgrimes (bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC) 3774Srgrimes return; 3784Srgrimes majdev = (bootdev >> B_TYPESHIFT) & B_TYPEMASK; 3794Srgrimes if (majdev > sizeof(devname) / sizeof(devname[0])) 3804Srgrimes return; 3814Srgrimes adaptor = (bootdev >> B_ADAPTORSHIFT) & B_ADAPTORMASK; 3824Srgrimes unit = (bootdev >> B_UNITSHIFT) & B_UNITMASK; 3831290Sache if (majdev == FDMAJOR) { 3842400Sache part = RAW_PART; 3851290Sache mindev = unit << FDUNITSHIFT; 3861290Sache } 3871290Sache else { 3881290Sache part = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK; 3891289Sache mindev = (unit << PARTITIONSHIFT) + part; 3901290Sache } 3914Srgrimes orootdev = rootdev; 3924Srgrimes rootdev = makedev(majdev, mindev); 3934Srgrimes /* 3944Srgrimes * If the original rootdev is the same as the one 3954Srgrimes * just calculated, don't need to adjust the swap configuration. 3964Srgrimes */ 3974Srgrimes if (rootdev == orootdev) 3984Srgrimes return; 3994Srgrimes printf("changing root device to %c%c%d%c\n", 4004Srgrimes devname[majdev][0], devname[majdev][1], 4011290Sache mindev >> (majdev == FDMAJOR ? FDUNITSHIFT : PARTITIONSHIFT), 4021290Sache part + 'a'); 4034Srgrimes} 40412649Speter 40512649Speterstatic int 40612649Spetersysctl_kern_dumpdev SYSCTL_HANDLER_ARGS 40712649Speter{ 40812649Speter int error; 40912649Speter dev_t ndumpdev; 41012649Speter 41112649Speter ndumpdev = dumpdev; 41212649Speter error = sysctl_handle_opaque(oidp, &ndumpdev, sizeof ndumpdev, req); 41317355Sbde if (error == 0 && req->newptr != NULL) 41412649Speter error = setdumpdev(ndumpdev); 41512649Speter return (error); 41612649Speter} 41712649Speter 41812649SpeterSYSCTL_PROC(_kern, KERN_DUMPDEV, dumpdev, CTLTYPE_OPAQUE|CTLFLAG_RW, 41922564Sbde 0, sizeof dumpdev, sysctl_kern_dumpdev, "T,dev_t", ""); 420