autoconf.c revision 53888
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 3750477Speter * $FreeBSD: head/sys/i386/i386/autoconf.c 53888 1999-11-29 18:51:04Z dillon $ 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 */ 4832358Seivind#include "opt_bootp.h" 4932726Seivind#include "opt_ffs.h" 5025460Sjoerg#include "opt_cd9660.h" 5153888Sdillon#include "opt_nfs.h" 5237272Sjmg#include "opt_nfsroot.h" 5345720Speter#include "opt_bus.h" 5446806Sphk#include "opt_rootdevname.h" 5525164Speter 562056Swollman#include <sys/param.h> 572056Swollman#include <sys/systm.h> 5845720Speter#include <sys/bus.h> 592056Swollman#include <sys/conf.h> 6031328Speter#include <sys/disklabel.h> 6136809Sbde#include <sys/diskslice.h> 622056Swollman#include <sys/reboot.h> 632056Swollman#include <sys/kernel.h> 6436809Sbde#include <sys/malloc.h> 6512604Sbde#include <sys/mount.h> 6649558Sphk#include <sys/cons.h> 674Srgrimes 6820641Sbde#include <machine/bootinfo.h> 6931337Sbde#include <machine/ipl.h> 707090Sbde#include <machine/md_var.h> 7127288Sfsmp#ifdef APIC_IO 7225164Speter#include <machine/smp.h> 7350197Speter#else 7450197Speter#include <i386/isa/icu.h> 7525164Speter#endif /* APIC_IO */ 7627288Sfsmp 7750769Sdfr#include "isa.h" 7850769Sdfr#include <isa/isavar.h> 7946915Speterdevice_t isa_bus_device = 0; 8046915Speter 8142817Speterstatic void configure_first __P((void *)); 8212604Sbdestatic void configure __P((void *)); 8342817Speterstatic void configure_final __P((void *)); 8412604Sbde 8552778Smsmith#if defined(FFS) && defined(FFS_ROOT) 8612848Sbdestatic void setroot __P((void)); 8747444Sjb#endif 8812848Sbde 8942817SpeterSYSINIT(configure1, SI_SUB_CONFIGURE, SI_ORDER_FIRST, configure_first, NULL); 9042817Speter/* SI_ORDER_SECOND is hookable */ 9142817SpeterSYSINIT(configure2, SI_SUB_CONFIGURE, SI_ORDER_THIRD, configure, NULL); 9242817Speter/* SI_ORDER_MIDDLE is hookable */ 9342817SpeterSYSINIT(configure3, SI_SUB_CONFIGURE, SI_ORDER_ANY, configure_final, NULL); 9442817Speter 9546806Sphkdev_t rootdev = NODEV; 9646806Sphkdev_t dumpdev = NODEV; 9742817Speter 9845720Speterdevice_t nexus_dev; 9945720Speter 1004Srgrimes/* 1014Srgrimes * Determine i/o configuration for a machine. 1024Srgrimes */ 10310665Sbdestatic void 10442817Speterconfigure_first(dummy) 10542817Speter void *dummy; 10642817Speter{ 10742817Speter} 10842817Speter 10942817Speterstatic void 11010665Sbdeconfigure(dummy) 11110653Sdg void *dummy; 1124Srgrimes{ 1134Srgrimes 11429675Sgibbs /* 11550184Speter * Activate the ICU's. Note that we are explicitly at splhigh() 11650184Speter * at present as we have no way to disable stray PCI level triggered 11750184Speter * interrupts until the devices have had a driver attached. This 11850184Speter * is particularly a problem when the interrupts are shared. For 11950184Speter * example, if IRQ 10 is shared between a disk and network device 12050184Speter * and the disk device generates an interrupt, if we "activate" 12150184Speter * IRQ 10 when the network driver is set up, then we will get 12250184Speter * recursive interrupt 10's as nothing will know how to turn off 12350184Speter * the disk device's interrupt. 12450184Speter * 12550184Speter * Having the ICU's active means we can probe interrupt routing to 12650184Speter * see if a device causes the corresponding pending bit to be set. 12750184Speter * 12850184Speter * This is all rather inconvenient. 12929675Sgibbs */ 13027288Sfsmp#ifdef APIC_IO 13127288Sfsmp bsp_apic_configure(); 13225172Speter enable_intr(); 13327288Sfsmp#else 13427288Sfsmp enable_intr(); 13525172Speter INTREN(IRQ_SLAVE); 13627288Sfsmp#endif /* APIC_IO */ 13712791Sgibbs 13845720Speter /* nexus0 is the top of the i386 device tree */ 13945720Speter device_add_child(root_bus, "nexus", 0, 0); 14012791Sgibbs 14138779Snsouch /* initialize new bus architecture */ 14238779Snsouch root_bus_configure(); 14338779Snsouch 14450769Sdfr#if NISA > 0 14550184Speter /* 14650184Speter * Explicitly probe and attach ISA last. The isa bus saves 14750184Speter * it's device node at attach time for us here. 14850184Speter */ 14945720Speter if (isa_bus_device) 15050769Sdfr isa_probe_children(isa_bus_device); 15150769Sdfr#endif 15245720Speter 15331336Sbde /* 15431336Sbde * Now we're ready to handle (pending) interrupts. 15531336Sbde * XXX this is slightly misplaced. 15631336Sbde */ 15731336Sbde spl0(); 15831336Sbde 15931337Sbde /* 16031337Sbde * Allow lowering of the ipl to the lowest kernel level if we 16131337Sbde * panic (or call tsleep() before clearing `cold'). No level is 16231337Sbde * completely safe (since a panic may occur in a critical region 16331337Sbde * at splhigh()), but we want at least bio interrupts to work. 16431337Sbde */ 16531337Sbde safepri = cpl; 16642817Speter} 16731337Sbde 16842817Speterstatic void 16942817Speterconfigure_final(dummy) 17042817Speter void *dummy; 17142817Speter{ 17242817Speter int i; 17322564Sbde 17410665Sbde cninit_finish(); 17510665Sbde 17620641Sbde if (bootverbose) { 17727561Sfsmp 17827561Sfsmp#ifdef APIC_IO 17927615Sfsmp imen_dump(); 18027561Sfsmp#endif /* APIC_IO */ 18127561Sfsmp 18220641Sbde /* 18320641Sbde * Print out the BIOS's idea of the disk geometries. 18420641Sbde */ 18520641Sbde printf("BIOS Geometries:\n"); 18620641Sbde for (i = 0; i < N_BIOS_GEOM; i++) { 18720641Sbde unsigned long bios_geom; 18820641Sbde int max_cylinder, max_head, max_sector; 18920641Sbde 19020641Sbde bios_geom = bootinfo.bi_bios_geom[i]; 19120641Sbde 19220641Sbde /* 19320641Sbde * XXX the bootstrap punts a 1200K floppy geometry 19420641Sbde * when the get-disk-geometry interrupt fails. Skip 19520641Sbde * drives that have this geometry. 19620641Sbde */ 19720641Sbde if (bios_geom == 0x4f010f) 19820641Sbde continue; 19920641Sbde 20020641Sbde printf(" %x:%08lx ", i, bios_geom); 20120641Sbde max_cylinder = bios_geom >> 16; 20220641Sbde max_head = (bios_geom >> 8) & 0xff; 20320641Sbde max_sector = bios_geom & 0xff; 20420641Sbde printf( 20520641Sbde "0..%d=%d cylinders, 0..%d=%d heads, 1..%d=%d sectors\n", 20620641Sbde max_cylinder, max_cylinder + 1, 20720641Sbde max_head, max_head + 1, 20820641Sbde max_sector, max_sector); 20920641Sbde } 21020641Sbde printf(" %d accounted for\n", bootinfo.bi_n_bios_used); 21120641Sbde 21216075Sjoerg printf("Device configuration finished.\n"); 21320641Sbde } 21429675Sgibbs cold = 0; 21529675Sgibbs} 21616075Sjoerg 21753888Sdillon#ifdef BOOTP 21853888Sdillonextern void bootpc_init(void); 21953888Sdillon#endif 22052778Smsmith/* 22152778Smsmith * Do legacy root filesystem discovery. 22252778Smsmith */ 22329675Sgibbsvoid 22429675Sgibbscpu_rootconf() 22529675Sgibbs{ 22653888Sdillon#ifdef BOOTP 22753888Sdillon bootpc_init(); 22853888Sdillon#endif 22952778Smsmith#if defined(NFS) && defined(NFS_ROOT) 23052778Smsmith#if !defined(BOOTP_NFSROOT) 23152778Smsmith if (nfs_diskless_valid) 2327731Sphk#endif 23352778Smsmith rootdevnames[0] = "nfs:"; 2344Srgrimes#endif 23552778Smsmith#if defined(FFS) && defined(FFS_ROOT) 23653888Sdillon if (!rootdevnames[0]) 23753888Sdillon setroot(); 23852778Smsmith#endif 23929675Sgibbs} 24052778SmsmithSYSINIT(cpu_rootconf, SI_SUB_ROOT_CONF, SI_ORDER_FIRST, cpu_rootconf, NULL) 24117355Sbde 2428833Sdgu_long bootdev = 0; /* not a dev_t - encoding is different */ 2434Srgrimes 24452778Smsmith#if defined(FFS) && defined(FFS_ROOT) 24552778Smsmith#define FDMAJOR 2 2461290Sache#define FDUNITSHIFT 6 2474Srgrimes 2484Srgrimes/* 2494Srgrimes * Attempt to find the device from which we were booted. 2504Srgrimes * If we can do so, and not instructed not to do so, 25136809Sbde * set rootdevs[] and rootdevnames[] to correspond to the 25236809Sbde * boot device(s). 25352778Smsmith * 25452778Smsmith * This code survives in order to allow the system to be 25552778Smsmith * booted from legacy environments that do not correctly 25652778Smsmith * populate the kernel environment. There are significant 25752778Smsmith * restrictions on the bootability of the system in this 25852778Smsmith * situation; it can only be mounting root from a 'da' 25952778Smsmith * 'wd' or 'fd' device, and the root filesystem must be ufs. 2604Srgrimes */ 261798Swollmanstatic void 2624Srgrimessetroot() 2634Srgrimes{ 26436809Sbde int majdev, mindev, unit, slice, part; 26546773Sphk dev_t newrootdev, dev; 26636809Sbde char partname[2]; 26736809Sbde char *sname; 2684Srgrimes 26948512Sphk if ((bootdev & B_MAGICMASK) != B_DEVMAGIC) { 27050268Sbde printf("no B_DEVMAGIC (bootdev=%#lx)\n", bootdev); 27146806Sphk return; 27248512Sphk } 27336809Sbde majdev = B_TYPE(bootdev); 27447680Sphk dev = makebdev(majdev, 0); 27549679Sphk if (devsw(dev) == NULL) { 27650268Sbde printf("no devsw (majdev=%d bootdev=%#lx)\n", majdev, bootdev); 27736809Sbde return; 27848512Sphk } 27936809Sbde unit = B_UNIT(bootdev); 28036809Sbde slice = B_SLICE(bootdev); 28136809Sbde if (slice == WHOLE_DISK_SLICE) 28234624Smsmith slice = COMPATIBILITY_SLICE; 28348512Sphk if (slice < 0 || slice >= MAX_SLICES) { 28448512Sphk printf("bad slice\n"); 2854Srgrimes return; 28648512Sphk } 28736809Sbde 28836809Sbde /* 28936809Sbde * XXX kludge for inconsistent unit numbering and lack of slice 29036809Sbde * support for floppies. 29136809Sbde */ 2921290Sache if (majdev == FDMAJOR) { 29336809Sbde slice = COMPATIBILITY_SLICE; 2942400Sache part = RAW_PART; 2951290Sache mindev = unit << FDUNITSHIFT; 29636809Sbde } else { 29736809Sbde part = B_PARTITION(bootdev); 29834622Smsmith mindev = dkmakeminor(unit, slice, part); 2991290Sache } 30036809Sbde 30147680Sphk newrootdev = makebdev(majdev, mindev); 30250511Sphk sname = dsname(newrootdev, unit, slice, part, partname); 30352778Smsmith rootdevnames[0] = malloc(strlen(sname) + 6, M_DEVBUF, M_NOWAIT); 30452778Smsmith sprintf(rootdevnames[0], "ufs:%s%s", sname, partname); 30536809Sbde 3064Srgrimes /* 30736809Sbde * For properly dangerously dedicated disks (ones with a historical 30836809Sbde * bogus partition table), the boot blocks will give slice = 4, but 30936809Sbde * the kernel will only provide the compatibility slice since it 31036809Sbde * knows that slice 4 is not a real slice. Arrange to try mounting 31136809Sbde * the compatibility slice as root if mounting the slice passed by 31236809Sbde * the boot blocks fails. This handles the dangerously dedicated 31336809Sbde * case and perhaps others. 3144Srgrimes */ 31536809Sbde if (slice == COMPATIBILITY_SLICE) 3164Srgrimes return; 31736809Sbde slice = COMPATIBILITY_SLICE; 31850511Sphk sname = dsname(newrootdev, unit, slice, part, partname); 31952778Smsmith rootdevnames[1] = malloc(strlen(sname) + 6, M_DEVBUF, M_NOWAIT); 32052778Smsmith sprintf(rootdevnames[1], "ufs:%s%s", sname, partname); 3214Srgrimes} 32247444Sjb#endif 323