autoconf.c revision 55117
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 55117 1999-12-26 16:21:19Z bde $ 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 5655117Sbde#include "isa.h" 5755117Sbde 582056Swollman#include <sys/param.h> 592056Swollman#include <sys/systm.h> 6045720Speter#include <sys/bus.h> 612056Swollman#include <sys/conf.h> 6231328Speter#include <sys/disklabel.h> 6336809Sbde#include <sys/diskslice.h> 642056Swollman#include <sys/reboot.h> 652056Swollman#include <sys/kernel.h> 6636809Sbde#include <sys/malloc.h> 6712604Sbde#include <sys/mount.h> 6849558Sphk#include <sys/cons.h> 694Srgrimes 7020641Sbde#include <machine/bootinfo.h> 7131337Sbde#include <machine/ipl.h> 727090Sbde#include <machine/md_var.h> 7327288Sfsmp#ifdef APIC_IO 7425164Speter#include <machine/smp.h> 7550197Speter#else 7650197Speter#include <i386/isa/icu.h> 7725164Speter#endif /* APIC_IO */ 7827288Sfsmp 7955117Sbde#if NISA > 0 8050769Sdfr#include <isa/isavar.h> 8155117Sbde 8246915Speterdevice_t isa_bus_device = 0; 8355117Sbde#endif 8446915Speter 8542817Speterstatic void configure_first __P((void *)); 8612604Sbdestatic void configure __P((void *)); 8742817Speterstatic void configure_final __P((void *)); 8812604Sbde 8952778Smsmith#if defined(FFS) && defined(FFS_ROOT) 9012848Sbdestatic void setroot __P((void)); 9147444Sjb#endif 9212848Sbde 9342817SpeterSYSINIT(configure1, SI_SUB_CONFIGURE, SI_ORDER_FIRST, configure_first, NULL); 9442817Speter/* SI_ORDER_SECOND is hookable */ 9542817SpeterSYSINIT(configure2, SI_SUB_CONFIGURE, SI_ORDER_THIRD, configure, NULL); 9642817Speter/* SI_ORDER_MIDDLE is hookable */ 9742817SpeterSYSINIT(configure3, SI_SUB_CONFIGURE, SI_ORDER_ANY, configure_final, NULL); 9842817Speter 9946806Sphkdev_t rootdev = NODEV; 10046806Sphkdev_t dumpdev = NODEV; 10142817Speter 10245720Speterdevice_t nexus_dev; 10345720Speter 1044Srgrimes/* 1054Srgrimes * Determine i/o configuration for a machine. 1064Srgrimes */ 10710665Sbdestatic void 10842817Speterconfigure_first(dummy) 10942817Speter void *dummy; 11042817Speter{ 11142817Speter} 11242817Speter 11342817Speterstatic void 11410665Sbdeconfigure(dummy) 11510653Sdg void *dummy; 1164Srgrimes{ 1174Srgrimes 11829675Sgibbs /* 11950184Speter * Activate the ICU's. Note that we are explicitly at splhigh() 12050184Speter * at present as we have no way to disable stray PCI level triggered 12150184Speter * interrupts until the devices have had a driver attached. This 12250184Speter * is particularly a problem when the interrupts are shared. For 12350184Speter * example, if IRQ 10 is shared between a disk and network device 12450184Speter * and the disk device generates an interrupt, if we "activate" 12550184Speter * IRQ 10 when the network driver is set up, then we will get 12650184Speter * recursive interrupt 10's as nothing will know how to turn off 12750184Speter * the disk device's interrupt. 12850184Speter * 12950184Speter * Having the ICU's active means we can probe interrupt routing to 13050184Speter * see if a device causes the corresponding pending bit to be set. 13150184Speter * 13250184Speter * This is all rather inconvenient. 13329675Sgibbs */ 13427288Sfsmp#ifdef APIC_IO 13527288Sfsmp bsp_apic_configure(); 13625172Speter enable_intr(); 13727288Sfsmp#else 13827288Sfsmp enable_intr(); 13925172Speter INTREN(IRQ_SLAVE); 14027288Sfsmp#endif /* APIC_IO */ 14112791Sgibbs 14245720Speter /* nexus0 is the top of the i386 device tree */ 14354073Smdodd device_add_child(root_bus, "nexus", 0); 14412791Sgibbs 14538779Snsouch /* initialize new bus architecture */ 14638779Snsouch root_bus_configure(); 14738779Snsouch 14850769Sdfr#if NISA > 0 14950184Speter /* 15050184Speter * Explicitly probe and attach ISA last. The isa bus saves 15150184Speter * it's device node at attach time for us here. 15250184Speter */ 15345720Speter if (isa_bus_device) 15450769Sdfr isa_probe_children(isa_bus_device); 15550769Sdfr#endif 15645720Speter 15731336Sbde /* 15831336Sbde * Now we're ready to handle (pending) interrupts. 15931336Sbde * XXX this is slightly misplaced. 16031336Sbde */ 16131336Sbde spl0(); 16231336Sbde 16331337Sbde /* 16431337Sbde * Allow lowering of the ipl to the lowest kernel level if we 16531337Sbde * panic (or call tsleep() before clearing `cold'). No level is 16631337Sbde * completely safe (since a panic may occur in a critical region 16731337Sbde * at splhigh()), but we want at least bio interrupts to work. 16831337Sbde */ 16931337Sbde safepri = cpl; 17042817Speter} 17131337Sbde 17242817Speterstatic void 17342817Speterconfigure_final(dummy) 17442817Speter void *dummy; 17542817Speter{ 17642817Speter int i; 17722564Sbde 17810665Sbde cninit_finish(); 17910665Sbde 18020641Sbde if (bootverbose) { 18127561Sfsmp 18227561Sfsmp#ifdef APIC_IO 18327615Sfsmp imen_dump(); 18427561Sfsmp#endif /* APIC_IO */ 18527561Sfsmp 18620641Sbde /* 18720641Sbde * Print out the BIOS's idea of the disk geometries. 18820641Sbde */ 18920641Sbde printf("BIOS Geometries:\n"); 19020641Sbde for (i = 0; i < N_BIOS_GEOM; i++) { 19120641Sbde unsigned long bios_geom; 19220641Sbde int max_cylinder, max_head, max_sector; 19320641Sbde 19420641Sbde bios_geom = bootinfo.bi_bios_geom[i]; 19520641Sbde 19620641Sbde /* 19720641Sbde * XXX the bootstrap punts a 1200K floppy geometry 19820641Sbde * when the get-disk-geometry interrupt fails. Skip 19920641Sbde * drives that have this geometry. 20020641Sbde */ 20120641Sbde if (bios_geom == 0x4f010f) 20220641Sbde continue; 20320641Sbde 20420641Sbde printf(" %x:%08lx ", i, bios_geom); 20520641Sbde max_cylinder = bios_geom >> 16; 20620641Sbde max_head = (bios_geom >> 8) & 0xff; 20720641Sbde max_sector = bios_geom & 0xff; 20820641Sbde printf( 20920641Sbde "0..%d=%d cylinders, 0..%d=%d heads, 1..%d=%d sectors\n", 21020641Sbde max_cylinder, max_cylinder + 1, 21120641Sbde max_head, max_head + 1, 21220641Sbde max_sector, max_sector); 21320641Sbde } 21420641Sbde printf(" %d accounted for\n", bootinfo.bi_n_bios_used); 21520641Sbde 21616075Sjoerg printf("Device configuration finished.\n"); 21720641Sbde } 21829675Sgibbs cold = 0; 21929675Sgibbs} 22016075Sjoerg 22153888Sdillon#ifdef BOOTP 22253888Sdillonextern void bootpc_init(void); 22353888Sdillon#endif 22452778Smsmith/* 22552778Smsmith * Do legacy root filesystem discovery. 22652778Smsmith */ 22729675Sgibbsvoid 22829675Sgibbscpu_rootconf() 22929675Sgibbs{ 23053888Sdillon#ifdef BOOTP 23153888Sdillon bootpc_init(); 23253888Sdillon#endif 23352778Smsmith#if defined(NFS) && defined(NFS_ROOT) 23452778Smsmith#if !defined(BOOTP_NFSROOT) 23552778Smsmith if (nfs_diskless_valid) 2367731Sphk#endif 23752778Smsmith rootdevnames[0] = "nfs:"; 2384Srgrimes#endif 23952778Smsmith#if defined(FFS) && defined(FFS_ROOT) 24053888Sdillon if (!rootdevnames[0]) 24153888Sdillon setroot(); 24252778Smsmith#endif 24329675Sgibbs} 24452778SmsmithSYSINIT(cpu_rootconf, SI_SUB_ROOT_CONF, SI_ORDER_FIRST, cpu_rootconf, NULL) 24517355Sbde 2468833Sdgu_long bootdev = 0; /* not a dev_t - encoding is different */ 2474Srgrimes 24852778Smsmith#if defined(FFS) && defined(FFS_ROOT) 24952778Smsmith#define FDMAJOR 2 2501290Sache#define FDUNITSHIFT 6 2514Srgrimes 2524Srgrimes/* 2534Srgrimes * Attempt to find the device from which we were booted. 2544Srgrimes * If we can do so, and not instructed not to do so, 25536809Sbde * set rootdevs[] and rootdevnames[] to correspond to the 25636809Sbde * boot device(s). 25752778Smsmith * 25852778Smsmith * This code survives in order to allow the system to be 25952778Smsmith * booted from legacy environments that do not correctly 26052778Smsmith * populate the kernel environment. There are significant 26152778Smsmith * restrictions on the bootability of the system in this 26252778Smsmith * situation; it can only be mounting root from a 'da' 26352778Smsmith * 'wd' or 'fd' device, and the root filesystem must be ufs. 2644Srgrimes */ 265798Swollmanstatic void 2664Srgrimessetroot() 2674Srgrimes{ 26836809Sbde int majdev, mindev, unit, slice, part; 26946773Sphk dev_t newrootdev, dev; 27036809Sbde char partname[2]; 27136809Sbde char *sname; 2724Srgrimes 27348512Sphk if ((bootdev & B_MAGICMASK) != B_DEVMAGIC) { 27450268Sbde printf("no B_DEVMAGIC (bootdev=%#lx)\n", bootdev); 27546806Sphk return; 27648512Sphk } 27736809Sbde majdev = B_TYPE(bootdev); 27847680Sphk dev = makebdev(majdev, 0); 27949679Sphk if (devsw(dev) == NULL) { 28050268Sbde printf("no devsw (majdev=%d bootdev=%#lx)\n", majdev, bootdev); 28136809Sbde return; 28248512Sphk } 28336809Sbde unit = B_UNIT(bootdev); 28436809Sbde slice = B_SLICE(bootdev); 28536809Sbde if (slice == WHOLE_DISK_SLICE) 28634624Smsmith slice = COMPATIBILITY_SLICE; 28748512Sphk if (slice < 0 || slice >= MAX_SLICES) { 28848512Sphk printf("bad slice\n"); 2894Srgrimes return; 29048512Sphk } 29136809Sbde 29236809Sbde /* 29336809Sbde * XXX kludge for inconsistent unit numbering and lack of slice 29436809Sbde * support for floppies. 29536809Sbde */ 2961290Sache if (majdev == FDMAJOR) { 29736809Sbde slice = COMPATIBILITY_SLICE; 2982400Sache part = RAW_PART; 2991290Sache mindev = unit << FDUNITSHIFT; 30036809Sbde } else { 30136809Sbde part = B_PARTITION(bootdev); 30234622Smsmith mindev = dkmakeminor(unit, slice, part); 3031290Sache } 30436809Sbde 30547680Sphk newrootdev = makebdev(majdev, mindev); 30650511Sphk sname = dsname(newrootdev, unit, slice, part, partname); 30752778Smsmith rootdevnames[0] = malloc(strlen(sname) + 6, M_DEVBUF, M_NOWAIT); 30852778Smsmith sprintf(rootdevnames[0], "ufs:%s%s", sname, partname); 30936809Sbde 3104Srgrimes /* 31136809Sbde * For properly dangerously dedicated disks (ones with a historical 31236809Sbde * bogus partition table), the boot blocks will give slice = 4, but 31336809Sbde * the kernel will only provide the compatibility slice since it 31436809Sbde * knows that slice 4 is not a real slice. Arrange to try mounting 31536809Sbde * the compatibility slice as root if mounting the slice passed by 31636809Sbde * the boot blocks fails. This handles the dangerously dedicated 31736809Sbde * case and perhaps others. 3184Srgrimes */ 31936809Sbde if (slice == COMPATIBILITY_SLICE) 3204Srgrimes return; 32136809Sbde slice = COMPATIBILITY_SLICE; 32250511Sphk sname = dsname(newrootdev, unit, slice, part, partname); 32352778Smsmith rootdevnames[1] = malloc(strlen(sname) + 6, M_DEVBUF, M_NOWAIT); 32452778Smsmith sprintf(rootdevnames[1], "ufs:%s%s", sname, partname); 3254Srgrimes} 32647444Sjb#endif 327