[BACK]Return to autoconf.c CVS log [TXT][DIR] Up to [local] / sys / arch / hp300 / hp300

Annotation of sys/arch/hp300/hp300/autoconf.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: autoconf.c,v 1.43 2007/06/01 19:25:09 deraadt Exp $   */
        !             2: /*     $NetBSD: autoconf.c,v 1.45 1999/04/10 17:31:02 kleink Exp $     */
        !             3:
        !             4: /*
        !             5:  * Copyright (c) 1996 Jason R. Thorpe.  All rights reserved.
        !             6:  * Copyright (c) 1988 University of Utah.
        !             7:  * Copyright (c) 1982, 1986, 1990, 1993
        !             8:  *     The Regents of the University of California.  All rights reserved.
        !             9:  *
        !            10:  * This code is derived from software contributed to Berkeley by
        !            11:  * the Systems Programming Group of the University of Utah Computer
        !            12:  * Science Department.
        !            13:  *
        !            14:  * Copyright (c) 1992, 1993
        !            15:  *     The Regents of the University of California.  All rights reserved.
        !            16:  *
        !            17:  * This software was developed by the Computer Systems Engineering group
        !            18:  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
        !            19:  * contributed to Berkeley.
        !            20:  *
        !            21:  * All advertising materials mentioning features or use of this software
        !            22:  * must display the following acknowledgement:
        !            23:  *     This product includes software developed by the University of
        !            24:  *     California, Lawrence Berkeley Laboratory.
        !            25:  *
        !            26:  * Redistribution and use in source and binary forms, with or without
        !            27:  * modification, are permitted provided that the following conditions
        !            28:  * are met:
        !            29:  * 1. Redistributions of source code must retain the above copyright
        !            30:  *    notice, this list of conditions and the following disclaimer.
        !            31:  * 2. Redistributions in binary form must reproduce the above copyright
        !            32:  *    notice, this list of conditions and the following disclaimer in the
        !            33:  *    documentation and/or other materials provided with the distribution.
        !            34:  * 3. Neither the name of the University nor the names of its contributors
        !            35:  *    may be used to endorse or promote products derived from this software
        !            36:  *    without specific prior written permission.
        !            37:  *
        !            38:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            39:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            40:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            41:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            42:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            43:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            44:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            45:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            46:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            47:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            48:  * SUCH DAMAGE.
        !            49:  *
        !            50:  * from: Utah $Hdr: autoconf.c 1.36 92/12/20$
        !            51:  *
        !            52:  *     @(#)autoconf.c  8.2 (Berkeley) 1/12/94
        !            53:  */
        !            54:
        !            55: /*
        !            56:  * Setup the system to run on the current machine.
        !            57:  *
        !            58:  * cpu_configure() is called at boot time.  Available
        !            59:  * devices are determined (from possibilities mentioned in ioconf.c),
        !            60:  * and the drivers are initialized.
        !            61:  */
        !            62:
        !            63: #include <sys/param.h>
        !            64: #include <sys/systm.h>
        !            65: #include <sys/buf.h>
        !            66: #include <sys/conf.h>
        !            67: #include <sys/device.h>
        !            68: #include <sys/disklabel.h>
        !            69: #include <sys/malloc.h>
        !            70: #include <sys/extent.h>
        !            71: #include <sys/mount.h>
        !            72: #include <sys/queue.h>
        !            73: #include <sys/reboot.h>
        !            74: #include <sys/tty.h>
        !            75:
        !            76: #include <dev/cons.h>
        !            77:
        !            78: #include <machine/autoconf.h>
        !            79: #include <machine/bus.h>
        !            80: #include <machine/vmparam.h>
        !            81: #include <machine/cpu.h>
        !            82: #include <machine/hp300spu.h>
        !            83: #include <machine/intr.h>
        !            84: #include <machine/pte.h>
        !            85:
        !            86: #include <hp300/dev/dioreg.h>
        !            87: #include <hp300/dev/diovar.h>
        !            88: #include <hp300/dev/diodevs.h>
        !            89:
        !            90: #include <hp300/dev/dmavar.h>
        !            91:
        !            92: #include <hp300/dev/hpibvar.h>
        !            93: #include <scsi/scsi_all.h>
        !            94: #include <scsi/scsiconf.h>
        !            95:
        !            96: #include <uvm/uvm_extern.h>
        !            97:
        !            98: /*
        !            99:  * The following several variables are related to
        !           100:  * the configuration process, and are used in initializing
        !           101:  * the machine.
        !           102:  */
        !           103:
        !           104: struct extent *extio;
        !           105:
        !           106: extern caddr_t internalhpib;
        !           107: extern char *extiobase;
        !           108:
        !           109: /* The boot device. */
        !           110: struct device *bootdv;
        !           111:
        !           112: /* The device we mount as root. */
        !           113: struct device *root_device;
        !           114:
        !           115: /* How we were booted. */
        !           116: u_int  bootdev;
        !           117:
        !           118: /*
        !           119:  * This information is built during the autoconfig process.
        !           120:  * A little explanation about the way this works is in order.
        !           121:  *
        !           122:  *     device_register() links all devices into dev_data_list.
        !           123:  *     If the device is an hpib controller, it is also linked
        !           124:  *     into dev_data_list_hpib.  If the device is a scsi controller,
        !           125:  *     it is also linked into dev_data_list_scsi.
        !           126:  *
        !           127:  *     dev_data_list_hpib and dev_data_list_scsi are sorted
        !           128:  *     by select code, from lowest to highest.
        !           129:  *
        !           130:  *     After autoconfiguration is complete, we need to determine
        !           131:  *     which device was the boot device.  The boot block assigns
        !           132:  *     controller unit numbers in order of select code.  Thus,
        !           133:  *     providing the controller is configured in the kernel, we
        !           134:  *     can determine our version of controller unit number from
        !           135:  *     the sorted hpib/scsi list.
        !           136:  *
        !           137:  *     At this point, we know the controller (device type
        !           138:  *     encoded in bootdev tells us "scsi disk", or "hpib tape",
        !           139:  *     etc.).  The next step is to find the device which
        !           140:  *     has the following properties:
        !           141:  *
        !           142:  *             - A child of the boot controller.
        !           143:  *             - Same slave as encoded in bootdev.
        !           144:  *             - Same physical unit as encoded in bootdev.
        !           145:  *
        !           146:  *     Later, after we've set the root device in stone, we
        !           147:  *     reverse the process to re-encode bootdev so it can be
        !           148:  *     passed back to the boot block.
        !           149:  */
        !           150: struct dev_data {
        !           151:        LIST_ENTRY(dev_data)    dd_list;  /* dev_data_list */
        !           152:        LIST_ENTRY(dev_data)    dd_clist; /* ctlr list */
        !           153:        struct device           *dd_dev;  /* device described by this entry */
        !           154:        int                     dd_scode; /* select code of device */
        !           155:        int                     dd_slave; /* ...or slave */
        !           156:        int                     dd_punit; /* and punit... */
        !           157: };
        !           158: typedef LIST_HEAD(, dev_data) ddlist_t;
        !           159: ddlist_t       dev_data_list;          /* all dev_datas */
        !           160: ddlist_t       dev_data_list_hpib;     /* hpib controller dev_datas */
        !           161: ddlist_t       dev_data_list_scsi;     /* scsi controller dev_datas */
        !           162:
        !           163: void   findbootdev(void);
        !           164: void   findbootdev_slave(ddlist_t *, int, int, int);
        !           165: void   setbootdev(void);
        !           166:
        !           167: static struct dev_data *dev_data_lookup(struct device *);
        !           168: static void dev_data_insert(struct dev_data *, ddlist_t *);
        !           169:
        !           170: static int device_match(const char *, const char *);
        !           171:
        !           172: int    mainbusmatch(struct device *, void *, void *);
        !           173: void   mainbusattach(struct device *, struct device *, void *);
        !           174: int    mainbussearch(struct device *, void *, void *);
        !           175:
        !           176: struct cfattach mainbus_ca = {
        !           177:        sizeof(struct device), mainbusmatch, mainbusattach
        !           178: };
        !           179:
        !           180: struct cfdriver mainbus_cd = {
        !           181:        NULL, "mainbus", DV_DULL
        !           182: };
        !           183:
        !           184: int
        !           185: mainbusmatch(parent, match, aux)
        !           186:        struct device *parent;
        !           187:        void *match, *aux;
        !           188: {
        !           189:        static int mainbus_matched = 0;
        !           190:
        !           191:        /* Allow only one instance. */
        !           192:        if (mainbus_matched)
        !           193:                return (0);
        !           194:
        !           195:        mainbus_matched = 1;
        !           196:        return (1);
        !           197: }
        !           198:
        !           199: void
        !           200: mainbusattach(parent, self, aux)
        !           201:        struct device *parent, *self;
        !           202:        void *aux;
        !           203: {
        !           204:
        !           205:        printf("\n");
        !           206:
        !           207:        /* Search for and attach children. */
        !           208:        config_search(mainbussearch, self, NULL);
        !           209: }
        !           210:
        !           211: int
        !           212: mainbussearch(parent, match, aux)
        !           213:        struct device *parent;
        !           214:        void *match, *aux;
        !           215: {
        !           216:        struct cfdata *cf = match;
        !           217:
        !           218:        if ((*cf->cf_attach->ca_match)(parent, cf, NULL) > 0)
        !           219:                config_attach(parent, cf, NULL, NULL);
        !           220:        return (0);
        !           221: }
        !           222:
        !           223: /*
        !           224:  * Determine the device configuration for the running system.
        !           225:  */
        !           226: void
        !           227: cpu_configure()
        !           228: {
        !           229:        /*
        !           230:         * Initialize the dev_data_lists.
        !           231:         */
        !           232:        LIST_INIT(&dev_data_list);
        !           233:        LIST_INIT(&dev_data_list_hpib);
        !           234:        LIST_INIT(&dev_data_list_scsi);
        !           235:
        !           236:        (void)splhigh();
        !           237:        if (config_rootfound("mainbus", "mainbus") == NULL)
        !           238:                panic("no mainbus found");
        !           239:        (void)spl0();
        !           240:
        !           241:        intr_printlevels();
        !           242:
        !           243:        /*
        !           244:         * Find boot device.
        !           245:         */
        !           246:        if ((bootdev & B_MAGICMASK) != B_DEVMAGIC) {
        !           247:                printf("WARNING: boot program didn't supply boot device.\n");
        !           248:                printf("Please update your boot program.\n");
        !           249:        } else {
        !           250:                findbootdev();
        !           251:                if (bootdv == NULL) {
        !           252:                        printf("WARNING: can't find match for bootdev:\n");
        !           253:                        printf(
        !           254:                    "type = %d, ctlr = %d, slave = %d, punit = %d, part = %d\n",
        !           255:                            B_TYPE(bootdev), B_ADAPTOR(bootdev),
        !           256:                            B_CONTROLLER(bootdev), B_UNIT(bootdev),
        !           257:                            B_PARTITION(bootdev));
        !           258:                        bootdev = 0;            /* invalidate bootdev */
        !           259:                } else {
        !           260:                        printf("boot device: %s\n", bootdv->dv_xname);
        !           261:                }
        !           262:        }
        !           263:        cold = 0;
        !           264: }
        !           265:
        !           266: void
        !           267: diskconf(void)
        !           268: {
        !           269:        int bootpartition = 0;
        !           270:
        !           271:        /*
        !           272:         * If bootdev is bogus, ask the user anyhow.
        !           273:         */
        !           274:        if (bootdev == 0)
        !           275:                boothowto |= RB_ASKNAME;
        !           276:        else
        !           277:                bootpartition = B_PARTITION(bootdev);
        !           278:
        !           279:        /*
        !           280:         * If we booted from tape, ask the user.
        !           281:         */
        !           282:        if (bootdv != NULL && bootdv->dv_class == DV_TAPE)
        !           283:                boothowto |= RB_ASKNAME;
        !           284:
        !           285:        setroot(bootdv, bootpartition, RB_USERREQ);
        !           286:        dumpconf();
        !           287:
        !           288:        /*
        !           289:         * Set bootdev based on the device we booted from.
        !           290:         * This is given to the boot program when we reboot.
        !           291:         */
        !           292:        setbootdev();
        !           293: }
        !           294:
        !           295: /**********************************************************************
        !           296:  * Code to find and set the boot device
        !           297:  **********************************************************************/
        !           298:
        !           299: static int
        !           300: device_match(const char *dvname, const char *template)
        !           301: {
        !           302:        size_t len = strlen(template);
        !           303:        char unit;
        !           304:
        !           305:        if (strncmp(dvname, template, len) != 0)
        !           306:                return (1);
        !           307:
        !           308:        /* Check that we are immediately followed by an unit number. */
        !           309:        unit = dvname[len];
        !           310:        if (unit < '0' || unit > '9')
        !           311:                return (1);
        !           312:
        !           313:        return (0);
        !           314: }
        !           315:
        !           316: /*
        !           317:  * Register a device.  We're passed the device and the arguments
        !           318:  * used to attach it.  This is used to find the boot device.
        !           319:  */
        !           320: void
        !           321: device_register(dev, aux)
        !           322:        struct device *dev;
        !           323:        void *aux;
        !           324: {
        !           325:        struct dev_data *dd;
        !           326:        static int seen_netdevice = 0;
        !           327:
        !           328:        /*
        !           329:         * Allocate a dev_data structure and fill it in.
        !           330:         * This means making some tests twice, but we don't
        !           331:         * care; this doesn't really have to be fast.
        !           332:         *
        !           333:         * Note that we only really care about devices that
        !           334:         * we can mount as root.
        !           335:         */
        !           336:        dd = (struct dev_data *)malloc(sizeof(struct dev_data),
        !           337:            M_DEVBUF, M_NOWAIT);
        !           338:        if (dd == NULL)
        !           339:                panic("device_register: can't allocate dev_data");
        !           340:        bzero(dd, sizeof(struct dev_data));
        !           341:
        !           342:        dd->dd_dev = dev;
        !           343:
        !           344:        /*
        !           345:         * BOOTROM and boot program can really only understand
        !           346:         * using the lowest select code network interface,
        !           347:         * so we ignore all but the first.
        !           348:         */
        !           349:        if (dev->dv_class == DV_IFNET && seen_netdevice == 0) {
        !           350:                struct dio_attach_args *da = aux;
        !           351:
        !           352:                seen_netdevice = 1;
        !           353:                dd->dd_scode = da->da_scode;
        !           354:                goto linkup;
        !           355:        }
        !           356:
        !           357:        if (device_match(dev->dv_xname, "fhpib") == 0 ||
        !           358:            device_match(dev->dv_xname, "nhpib") == 0 ||
        !           359:            device_match(dev->dv_xname, "spc") == 0) {
        !           360:                struct dio_attach_args *da = aux;
        !           361:
        !           362:                dd->dd_scode = da->da_scode;
        !           363:                goto linkup;
        !           364:        }
        !           365:
        !           366:        if (device_match(dev->dv_xname, "hd") == 0) {
        !           367:                struct hpibbus_attach_args *ha = aux;
        !           368:
        !           369:                dd->dd_slave = ha->ha_slave;
        !           370:                dd->dd_punit = ha->ha_punit;
        !           371:                goto linkup;
        !           372:        }
        !           373:
        !           374:        if (device_match(dev->dv_xname, "cd") == 0 ||
        !           375:            device_match(dev->dv_xname, "sd") == 0 ||
        !           376:            device_match(dev->dv_xname, "st") == 0) {
        !           377:                struct scsi_attach_args *sa = aux;
        !           378:
        !           379:                dd->dd_slave = sa->sa_sc_link->target;
        !           380:                dd->dd_punit = sa->sa_sc_link->lun;
        !           381:                goto linkup;
        !           382:        }
        !           383:
        !           384:        /*
        !           385:         * Didn't need the dev_data.
        !           386:         */
        !           387:        free(dd, M_DEVBUF);
        !           388:        return;
        !           389:
        !           390:  linkup:
        !           391:        LIST_INSERT_HEAD(&dev_data_list, dd, dd_list);
        !           392:
        !           393:        if (device_match(dev->dv_xname, "fhpib") == 0 ||
        !           394:            device_match(dev->dv_xname, "nhpib") == 0) {
        !           395:                dev_data_insert(dd, &dev_data_list_hpib);
        !           396:                return;
        !           397:        }
        !           398:
        !           399:        if (device_match(dev->dv_xname, "spc") == 0) {
        !           400:                dev_data_insert(dd, &dev_data_list_scsi);
        !           401:                return;
        !           402:        }
        !           403: }
        !           404:
        !           405: void
        !           406: findbootdev()
        !           407: {
        !           408:        int type, ctlr, slave, punit;
        !           409:        int scsiboot, hpibboot, netboot;
        !           410:        struct dev_data *dd;
        !           411:
        !           412:        bootdv = NULL;
        !           413:
        !           414:        if ((bootdev & B_MAGICMASK) != B_DEVMAGIC)
        !           415:                return;
        !           416:
        !           417:        type  = B_TYPE(bootdev);
        !           418:        ctlr  = B_ADAPTOR(bootdev);
        !           419:        slave = B_CONTROLLER(bootdev);
        !           420:        punit = B_UNIT(bootdev);
        !           421:
        !           422:        scsiboot = (type == 4);                 /* sd major */
        !           423:        hpibboot = (type == 0 || type == 2);    /* ct/hd major */
        !           424:        netboot  = (type == 6);                 /* le - special */
        !           425:
        !           426:        /*
        !           427:         * Check for network boot first, since it's a little
        !           428:         * different.  The BOOTROM/boot program can only boot
        !           429:         * off of the first (lowest select code) ethernet
        !           430:         * device.  device_register() knows this and only
        !           431:         * registers one DV_IFNET.  This is a safe assumption
        !           432:         * since the code that finds devices on the DIO bus
        !           433:         * always starts at scode 0 and works its way up.
        !           434:         */
        !           435:        if (netboot) {
        !           436:                LIST_FOREACH(dd, &dev_data_list, dd_list) {
        !           437:                        if (dd->dd_dev->dv_class == DV_IFNET) {
        !           438:                                /*
        !           439:                                 * Found it!
        !           440:                                 */
        !           441:                                bootdv = dd->dd_dev;
        !           442:                                break;
        !           443:                        }
        !           444:                }
        !           445:                return;
        !           446:        }
        !           447:
        !           448:        /*
        !           449:         * Check for HP-IB boots next.
        !           450:         */
        !           451:        if (hpibboot) {
        !           452:                findbootdev_slave(&dev_data_list_hpib, ctlr,
        !           453:                    slave, punit);
        !           454:                if (bootdv == NULL)
        !           455:                        return;
        !           456:
        !           457: #ifdef DIAGNOSTIC
        !           458:                /*
        !           459:                 * Sanity check.
        !           460:                 */
        !           461:                if ((type == 0 &&
        !           462:                     device_match(bootdv->dv_xname, "ct")) ||
        !           463:                    (type == 2 &&
        !           464:                     device_match(bootdv->dv_xname, "hd"))) {
        !           465:                        printf("WARNING: boot device/type mismatch!\n");
        !           466:                        printf("device = %s, type = %d\n",
        !           467:                            bootdv->dv_xname, type);
        !           468:                        bootdv = NULL;
        !           469:                }
        !           470: #endif
        !           471:                return;
        !           472:        }
        !           473:
        !           474:        /*
        !           475:         * Check for SCSI boots last.
        !           476:         */
        !           477:        if (scsiboot) {
        !           478:                findbootdev_slave(&dev_data_list_scsi, ctlr,
        !           479:                     slave, punit);
        !           480:                if (bootdv == NULL)
        !           481:                        return;
        !           482:
        !           483: #ifdef DIAGNOSTIC
        !           484:                /*
        !           485:                 * Sanity check.
        !           486:                 */
        !           487:                if (device_match(bootdv->dv_xname, "cd") != 0 &&
        !           488:                    device_match(bootdv->dv_xname, "sd") != 0 &&
        !           489:                    device_match(bootdv->dv_xname, "st") != 0) {
        !           490:                        printf("WARNING: boot device/type mismatch!\n");
        !           491:                        printf("device = %s, type = %d\n",
        !           492:                            bootdv->dv_xname, type);
        !           493:                        bootdv = NULL;
        !           494:                }
        !           495: #endif
        !           496:                return;
        !           497:        }
        !           498:
        !           499:        /* Oof! */
        !           500:        printf("WARNING: UNKNOWN BOOT DEVICE TYPE = %d\n", type);
        !           501: }
        !           502:
        !           503: void
        !           504: findbootdev_slave(ddlist, ctlr, slave, punit)
        !           505:        ddlist_t *ddlist;
        !           506:        int ctlr, slave, punit;
        !           507: {
        !           508:        struct dev_data *cdd, *dd;
        !           509:
        !           510:        /*
        !           511:         * Find the booted controller.
        !           512:         */
        !           513:        for (cdd = LIST_FIRST(ddlist); ctlr != 0 && cdd != LIST_END(ddlist);
        !           514:            cdd = LIST_NEXT(cdd, dd_clist))
        !           515:                ctlr--;
        !           516:        if (cdd == NULL) {
        !           517:                /*
        !           518:                 * Oof, couldn't find it...
        !           519:                 */
        !           520:                return;
        !           521:        }
        !           522:
        !           523:        /*
        !           524:         * Now find the device with the right slave/punit
        !           525:         * that's a child of the controller.
        !           526:         */
        !           527:        LIST_FOREACH(dd, &dev_data_list, dd_list) {
        !           528:                /*
        !           529:                 * "sd" / "st" / "cd" -> "scsibus" -> "spc"
        !           530:                 * "hd" -> "hpibbus" -> "fhpib"
        !           531:                 */
        !           532:                if (dd->dd_dev->dv_parent->dv_parent != cdd->dd_dev)
        !           533:                        continue;
        !           534:
        !           535:                if (dd->dd_slave == slave &&
        !           536:                    dd->dd_punit == punit) {
        !           537:                        /*
        !           538:                         * Found it!
        !           539:                         */
        !           540:                        bootdv = dd->dd_dev;
        !           541:                        break;
        !           542:                }
        !           543:        }
        !           544: }
        !           545:
        !           546: void
        !           547: setbootdev()
        !           548: {
        !           549:        struct dev_data *cdd, *dd;
        !           550:        int type, ctlr;
        !           551:
        !           552:        /*
        !           553:         * Note our magic numbers for type:
        !           554:         *
        !           555:         *      0 == ct
        !           556:         *      2 == hd
        !           557:         *      4 == scsi
        !           558:         *      6 == le
        !           559:         *
        !           560:         * All are bdevsw major numbers, except for le, which
        !           561:         * is just special. SCSI needs specific care since the
        !           562:         * ROM wants to see 4, but depending upon the real device
        !           563:         * we booted from, we might have a different major value.
        !           564:         */
        !           565:
        !           566:        /*
        !           567:         * Start with a clean slate.
        !           568:         */
        !           569:        bootdev = 0;
        !           570:
        !           571:        /*
        !           572:         * If we don't have a saveable root_device, just punt.
        !           573:         */
        !           574:        if (root_device == NULL)
        !           575:                goto out;
        !           576:
        !           577:        dd = dev_data_lookup(root_device);
        !           578:
        !           579:        /*
        !           580:         * If the root device is network, we're done
        !           581:         * early.
        !           582:         */
        !           583:        if (root_device->dv_class == DV_IFNET) {
        !           584:                bootdev = MAKEBOOTDEV(6, 0, 0, 0, 0);
        !           585:                goto out;
        !           586:        }
        !           587:
        !           588:        /*
        !           589:         * Determine device type.
        !           590:         */
        !           591:        if (device_match(root_device->dv_xname, "hd") == 0)
        !           592:                type = 2;
        !           593:        else if (device_match(root_device->dv_xname, "cd") == 0 ||
        !           594:            device_match(root_device->dv_xname, "sd") == 0 ||
        !           595:            device_match(root_device->dv_xname, "st") == 0)
        !           596:                /* force scsi disk regardless of the actual device */
        !           597:                type = 4;
        !           598:        else {
        !           599:                printf("WARNING: strange root device!\n");
        !           600:                goto out;
        !           601:        }
        !           602:
        !           603:        /*
        !           604:         * Get parent's info.
        !           605:         *
        !           606:         * "hd" -> "hpibbus" -> "fhpib"
        !           607:         * "sd" / "cd" / "st" -> "scsibus" -> "spc"
        !           608:         */
        !           609:        for (cdd = LIST_FIRST(&dev_data_list_hpib), ctlr = 0;
        !           610:            cdd != LIST_END(&dev_data_list_hpib);
        !           611:            cdd = LIST_NEXT(cdd, dd_clist), ctlr++) {
        !           612:                if (cdd->dd_dev == root_device->dv_parent->dv_parent) {
        !           613:                        /*
        !           614:                         * Found it!
        !           615:                         */
        !           616:                        bootdev = MAKEBOOTDEV(type, ctlr, dd->dd_slave,
        !           617:                            dd->dd_punit, DISKPART(rootdev));
        !           618:                        break;
        !           619:                }
        !           620:        }
        !           621:
        !           622:  out:
        !           623:        /* Don't need this anymore. */
        !           624:        for (dd = LIST_FIRST(&dev_data_list);
        !           625:            dd != LIST_END(&dev_data_list); ) {
        !           626:                cdd = dd;
        !           627:                dd = LIST_NEXT(dd, dd_list);
        !           628:                free(cdd, M_DEVBUF);
        !           629:        }
        !           630: }
        !           631:
        !           632: /*
        !           633:  * Return the dev_data corresponding to the given device.
        !           634:  */
        !           635: static struct dev_data *
        !           636: dev_data_lookup(dev)
        !           637:        struct device *dev;
        !           638: {
        !           639:        struct dev_data *dd;
        !           640:
        !           641:        LIST_FOREACH(dd, &dev_data_list, dd_list)
        !           642:                if (dd->dd_dev == dev)
        !           643:                        return (dd);
        !           644:
        !           645:        panic("dev_data_lookup");
        !           646: }
        !           647:
        !           648: /*
        !           649:  * Insert a dev_data into the provided list, sorted by select code.
        !           650:  */
        !           651: static void
        !           652: dev_data_insert(dd, ddlist)
        !           653:        struct dev_data *dd;
        !           654:        ddlist_t *ddlist;
        !           655: {
        !           656:        struct dev_data *de;
        !           657:
        !           658: #ifdef DIAGNOSTIC
        !           659:        if (dd->dd_scode < 0 || dd->dd_scode > 255) {
        !           660:                panic("bogus select code for %s", dd->dd_dev->dv_xname);
        !           661:        }
        !           662: #endif
        !           663:
        !           664:        /*
        !           665:         * Just insert at head if list is empty.
        !           666:         */
        !           667:        if (LIST_EMPTY(ddlist)) {
        !           668:                LIST_INSERT_HEAD(ddlist, dd, dd_clist);
        !           669:                return;
        !           670:        }
        !           671:
        !           672:        /*
        !           673:         * Traverse the list looking for a device who's select code
        !           674:         * is greater than ours.  When we find it, insert ourselves
        !           675:         * into the list before it.
        !           676:         */
        !           677:        for (de = LIST_FIRST(ddlist);
        !           678:            LIST_NEXT(de, dd_clist) != LIST_END(ddlist);
        !           679:            de = LIST_NEXT(de, dd_clist)) {
        !           680:                if (de->dd_scode > dd->dd_scode) {
        !           681:                        LIST_INSERT_BEFORE(de, dd, dd_clist);
        !           682:                        return;
        !           683:                }
        !           684:        }
        !           685:
        !           686:        /*
        !           687:         * Our select code is greater than everyone else's.  We go
        !           688:         * onto the end.
        !           689:         */
        !           690:        LIST_INSERT_AFTER(de, dd, dd_clist);
        !           691: }
        !           692:
        !           693: /**********************************************************************
        !           694:  * Code to find and initialize the console
        !           695:  **********************************************************************/
        !           696:
        !           697: /*
        !           698:  * Scan all select codes, passing the corresponding VA to (*func)().
        !           699:  * (*func)() is a driver-specific routine that looks for the console
        !           700:  * hardware.
        !           701:  */
        !           702: void
        !           703: console_scan(func, arg)
        !           704:        int (*func)(int, caddr_t, void *);
        !           705:        void *arg;
        !           706: {
        !           707:        int size, scode, sctop;
        !           708:        caddr_t pa, va;
        !           709:
        !           710:        /*
        !           711:         * Scan all select codes.  Check each location for some
        !           712:         * hardware.  If there's something there, call (*func)().
        !           713:         */
        !           714:        sctop = DIO_SCMAX(machineid);
        !           715:        for (scode = 0; scode < sctop; ++scode) {
        !           716:                /*
        !           717:                 * Skip over the select code hole and
        !           718:                 * the internal HP-IB controller.
        !           719:                 */
        !           720:                if (DIO_INHOLE(scode) ||
        !           721:                    ((scode == 7) && internalhpib))
        !           722:                        continue;
        !           723:
        !           724:                /* Map current PA. */
        !           725:                pa = dio_scodetopa(scode);
        !           726:                va = iomap(pa, PAGE_SIZE);
        !           727:                if (va == NULL)
        !           728:                        continue;
        !           729:
        !           730:                /* Check to see if hardware exists. */
        !           731:                if (badaddr(va)) {
        !           732:                        iounmap(va, PAGE_SIZE);
        !           733:                        continue;
        !           734:                }
        !           735:
        !           736:                /*
        !           737:                 * Hardware present, call callback.  Driver returns
        !           738:                 * size of region to map if console probe successful
        !           739:                 * and worthwhile.
        !           740:                 */
        !           741:                size = (*func)(scode, va, arg);
        !           742:                iounmap(va, PAGE_SIZE);
        !           743:                if (size != 0 && conscode == scode) {
        !           744:                        /* Free last mapping. */
        !           745:                        if (convasize)
        !           746:                                iounmap(conaddr, convasize);
        !           747:                        convasize = 0;
        !           748:
        !           749:                        /* Remap to correct size. */
        !           750:                        va = iomap(pa, size);
        !           751:                        if (va == NULL)
        !           752:                                continue;
        !           753:
        !           754:                        /* Save this state for next time. */
        !           755:                        conaddr = va;
        !           756:                        convasize = size;
        !           757:                }
        !           758:        }
        !           759: }
        !           760:
        !           761: int consolepass = -1;
        !           762:
        !           763: /*
        !           764:  * Special version of cninit().  Actually, crippled somewhat.
        !           765:  * This version lets the drivers assign cn_tab.
        !           766:  */
        !           767: void
        !           768: hp300_cninit(void)
        !           769: {
        !           770:        struct consdev *cp;
        !           771:        extern struct consdev constab[];
        !           772:
        !           773:        if (++consolepass == 0) {
        !           774:                cn_tab = NULL;
        !           775:
        !           776:                /*
        !           777:                 * Call all of the console probe functions.
        !           778:                 */
        !           779:                for (cp = constab; cp->cn_probe; cp++)
        !           780:                        (*cp->cn_probe)(cp);
        !           781:        }
        !           782:
        !           783:        /*
        !           784:         * No console, we can handle it.
        !           785:         */
        !           786:        if (cn_tab == NULL)
        !           787:                return;
        !           788:
        !           789:        /*
        !           790:         * Turn on the console.
        !           791:         *
        !           792:         * Note that we need to check for cn_init because DIO frame buffers
        !           793:         * will cause cn_tab to switch to wsdisplaycons, which does not
        !           794:         * have an cn_init function.
        !           795:         */
        !           796:        if (cn_tab->cn_init != NULL) {
        !           797:                (*cn_tab->cn_init)(cn_tab);
        !           798:        }
        !           799: }
        !           800:
        !           801: /**********************************************************************
        !           802:  * Mapping functions
        !           803:  **********************************************************************/
        !           804:
        !           805: /*
        !           806:  * Allocate/deallocate a cache-inhibited range of kernel virtual address
        !           807:  * space mapping the indicated physical address range [pa - pa+size)
        !           808:  */
        !           809: caddr_t
        !           810: iomap(pa, size)
        !           811:        caddr_t pa;
        !           812:        int size;
        !           813: {
        !           814:        vaddr_t iova, tva, off;
        !           815:        paddr_t ppa;
        !           816:        int error;
        !           817:
        !           818:        if (size <= 0)
        !           819:                return NULL;
        !           820:
        !           821:        ppa = trunc_page((paddr_t)pa);
        !           822:        off = (paddr_t)pa & PAGE_MASK;
        !           823:        size = round_page(off + size);
        !           824:
        !           825:        error = extent_alloc(extio, size, PAGE_SIZE, 0, EX_NOBOUNDARY,
        !           826:            EX_NOWAIT | EX_MALLOCOK, &iova);
        !           827:
        !           828:        if (error != 0)
        !           829:                return (NULL);
        !           830:
        !           831:        tva = iova;
        !           832:        while (size != 0) {
        !           833:                pmap_kenter_cache(tva, ppa, PG_RW | PG_CI);
        !           834:                size -= PAGE_SIZE;
        !           835:                tva += PAGE_SIZE;
        !           836:                ppa += PAGE_SIZE;
        !           837:        }
        !           838:        pmap_update(pmap_kernel());
        !           839:        return ((void *)(iova + off));
        !           840: }
        !           841:
        !           842: /*
        !           843:  * Unmap a previously mapped device.
        !           844:  */
        !           845: void
        !           846: iounmap(va, size)
        !           847:        caddr_t va;
        !           848:        int size;
        !           849: {
        !           850:        vaddr_t kva, off;
        !           851:        int error;
        !           852:
        !           853:        off = (vaddr_t)va & PAGE_MASK;
        !           854:        kva = trunc_page((vaddr_t)va);
        !           855:        size = round_page(off + size);
        !           856:
        !           857:        pmap_kremove(kva, size);
        !           858:        pmap_update(pmap_kernel());
        !           859:
        !           860:        error = extent_free(extio, kva, size, EX_NOWAIT);
        !           861: #ifdef DIAGNOSTIC
        !           862:        if (error != 0)
        !           863:                printf("iounmap: extent_free failed\n");
        !           864: #endif
        !           865: }
        !           866:
        !           867: struct nam2blk nam2blk[] = {
        !           868:        { "ct",         0 },
        !           869:        { "hd",         2 },
        !           870:        { "sd",         4 },
        !           871:        { "st",         7 },
        !           872:        { "rd",         8 },
        !           873:        { "cd",         9 },
        !           874:        { NULL,         -1 }
        !           875: };

CVSweb