[BACK]Return to x86_autoconf.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / x86 / x86

Annotation of src/sys/arch/x86/x86/x86_autoconf.c, Revision 1.36

1.36    ! jmcneill    1: /*     $NetBSD: x86_autoconf.c,v 1.35 2008/10/14 15:48:44 tsutsui Exp $        */
1.1       thorpej     2:
                      3: /*-
                      4:  * Copyright (c) 1990 The Regents of the University of California.
                      5:  * All rights reserved.
                      6:  *
                      7:  * This code is derived from software contributed to Berkeley by
                      8:  * William Jolitz.
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  * 3. Neither the name of the University nor the names of its contributors
                     19:  *    may be used to endorse or promote products derived from this software
                     20:  *    without specific prior written permission.
                     21:  *
                     22:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     23:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     24:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     25:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     26:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     27:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     28:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     29:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     30:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     31:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     32:  * SUCH DAMAGE.
                     33:  *
                     34:  *     @(#)autoconf.c  7.1 (Berkeley) 5/9/91
                     35:  */
                     36:
                     37: #include <sys/cdefs.h>
1.36    ! jmcneill   38: __KERNEL_RCSID(0, "$NetBSD: x86_autoconf.c,v 1.35 2008/10/14 15:48:44 tsutsui Exp $");
1.1       thorpej    39:
                     40: #include <sys/param.h>
                     41: #include <sys/systm.h>
                     42: #include <sys/device.h>
                     43: #include <sys/disklabel.h>
                     44: #include <sys/conf.h>
                     45: #include <sys/malloc.h>
                     46: #include <sys/vnode.h>
                     47: #include <sys/fcntl.h>
1.2       thorpej    48: #include <sys/disk.h>
1.1       thorpej    49: #include <sys/proc.h>
1.2       thorpej    50: #include <sys/md5.h>
1.16      elad       51: #include <sys/kauth.h>
1.1       thorpej    52:
                     53: #include <machine/bootinfo.h>
1.36    ! jmcneill   54: #include <machine/pio.h>
1.1       thorpej    55:
                     56: #include "pci.h"
                     57:
                     58: #include <dev/isa/isavar.h>
                     59: #if NPCI > 0
                     60: #include <dev/pci/pcivar.h>
                     61: #endif
1.36    ! jmcneill   62: #include <dev/wsfb/genfbvar.h>
        !            63: #include <dev/ic/vgareg.h>
        !            64:
        !            65: struct genfb_colormap_callback gfb_cb;
1.1       thorpej    66:
                     67: struct disklist *x86_alldisks;
                     68: int x86_ndisks;
                     69:
1.18      christos   70: static void
1.36    ! jmcneill   71: x86_genfb_set_mapreg(void *opaque, int index, int r, int g, int b)
        !            72: {
        !            73:        outb(0x3c0 + VGA_DAC_ADDRW, index);
        !            74:        outb(0x3c0 + VGA_DAC_PALETTE, (uint8_t)r >> 2);
        !            75:        outb(0x3c0 + VGA_DAC_PALETTE, (uint8_t)g >> 2);
        !            76:        outb(0x3c0 + VGA_DAC_PALETTE, (uint8_t)b >> 2);
        !            77: }
        !            78:
        !            79: static void
1.18      christos   80: handle_wedges(struct device *dv, int par)
                     81: {
1.26      dyoung     82:        if (config_handle_wedges(dv, par) == 0)
                     83:                return;
1.18      christos   84:        booted_device = dv;
                     85:        booted_partition = par;
                     86: }
                     87:
1.1       thorpej    88: static int
                     89: is_valid_disk(struct device *dv)
                     90: {
                     91:
1.9       thorpej    92:        if (device_class(dv) != DV_DISK)
1.1       thorpej    93:                return (0);
                     94:
1.17      christos   95:        return (device_is_a(dv, "dk") ||
                     96:                device_is_a(dv, "sd") ||
1.13      thorpej    97:                device_is_a(dv, "wd") ||
                     98:                device_is_a(dv, "ld") ||
                     99:                device_is_a(dv, "ed"));
1.1       thorpej   100: }
                    101:
                    102: /*
                    103:  * XXX Ugly bit of code.  But, this is the only safe time that the
                    104:  * match between BIOS disks and native disks can be done.
                    105:  */
1.8       jmmv      106: static void
                    107: matchbiosdisks(void)
1.1       thorpej   108: {
                    109:        struct btinfo_biosgeom *big;
                    110:        struct bi_biosgeom_entry *be;
                    111:        struct device *dv;
                    112:        int i, ck, error, m, n;
                    113:        struct vnode *tv;
                    114:        char mbr[DEV_BSIZE];
                    115:        int dklist_size;
1.18      christos  116:        int numbig;
1.1       thorpej   117:
                    118:        big = lookup_bootinfo(BTINFO_BIOSGEOM);
                    119:
                    120:        numbig = big ? big->num : 0;
                    121:
                    122:        /* First, count all native disks. */
1.27      dyoung    123:        TAILQ_FOREACH(dv, &alldevs, dv_list) {
1.1       thorpej   124:                if (is_valid_disk(dv))
                    125:                        x86_ndisks++;
                    126:        }
                    127:
                    128:        dklist_size = sizeof(struct disklist) + (x86_ndisks - 1) *
                    129:            sizeof(struct nativedisk_info);
                    130:
                    131:        /* XXX M_TEMP is wrong */
                    132:        x86_alldisks = malloc(dklist_size, M_TEMP, M_NOWAIT | M_ZERO);
                    133:        if (x86_alldisks == NULL)
                    134:                return;
                    135:
                    136:        x86_alldisks->dl_nnativedisks = x86_ndisks;
                    137:        x86_alldisks->dl_nbiosdisks = numbig;
                    138:        for (i = 0; i < numbig; i++) {
                    139:                x86_alldisks->dl_biosdisks[i].bi_dev = big->disk[i].dev;
                    140:                x86_alldisks->dl_biosdisks[i].bi_sec = big->disk[i].sec;
                    141:                x86_alldisks->dl_biosdisks[i].bi_head = big->disk[i].head;
                    142:                x86_alldisks->dl_biosdisks[i].bi_cyl = big->disk[i].cyl;
                    143:                x86_alldisks->dl_biosdisks[i].bi_lbasecs = big->disk[i].totsec;
                    144:                x86_alldisks->dl_biosdisks[i].bi_flags = big->disk[i].flags;
                    145: #ifdef GEOM_DEBUG
                    146: #ifdef notyet
                    147:                printf("disk %x: flags %x, interface %x, device %llx\n",
                    148:                       big->disk[i].dev, big->disk[i].flags,
                    149:                       big->disk[i].interface_path, big->disk[i].device_path);
                    150: #endif
                    151: #endif
                    152:        }
                    153:
                    154:        /* XXX Code duplication from findroot(). */
                    155:        n = -1;
1.29      xtraeme   156:        TAILQ_FOREACH(dv, &alldevs, dv_list) {
1.9       thorpej   157:                if (device_class(dv) != DV_DISK)
1.1       thorpej   158:                        continue;
                    159: #ifdef GEOM_DEBUG
                    160:                printf("matchbiosdisks: trying to match (%s) %s\n",
1.34      cegger    161:                    device_xname(dv), device_cfdata(dv)->cf_name);
1.1       thorpej   162: #endif
                    163:                if (is_valid_disk(dv)) {
                    164:                        n++;
                    165:                        /* XXXJRT why not just dv_xname?? */
                    166:                        snprintf(x86_alldisks->dl_nativedisks[n].ni_devname,
                    167:                            sizeof(x86_alldisks->dl_nativedisks[n].ni_devname),
1.34      cegger    168:                            "%s", device_xname(dv));
1.1       thorpej   169:
1.18      christos  170:                        if ((tv = opendisk(dv)) == NULL)
                    171:                                continue;
1.1       thorpej   172:
                    173:                        error = vn_rdwr(UIO_READ, tv, mbr, DEV_BSIZE, 0,
                    174:                            UIO_SYSSPACE, 0, NOCRED, NULL, NULL);
1.31      pooka     175:                        VOP_CLOSE(tv, FREAD, NOCRED);
1.1       thorpej   176:                        if (error) {
                    177: #ifdef GEOM_DEBUG
                    178:                                printf("matchbiosdisks: %s: MBR read failure\n",
1.34      cegger    179:                                    device_xname(dv));
1.1       thorpej   180: #endif
                    181:                                continue;
                    182:                        }
                    183:
                    184:                        for (ck = i = 0; i < DEV_BSIZE; i++)
                    185:                                ck += mbr[i];
                    186:                        for (m = i = 0; i < numbig; i++) {
                    187:                                be = &big->disk[i];
                    188: #ifdef GEOM_DEBUG
                    189:                                printf("match %s with %d "
1.34      cegger    190:                                    "dev ck %x bios ck %x\n", device_xname(dv), i,
1.1       thorpej   191:                                    ck, be->cksum);
                    192: #endif
                    193:                                if (be->flags & BI_GEOM_INVALID)
                    194:                                        continue;
                    195:                                if (be->cksum == ck &&
                    196:                                    memcmp(&mbr[MBR_PART_OFFSET], be->dosparts,
                    197:                                        MBR_PART_COUNT *
                    198:                                          sizeof(struct mbr_partition)) == 0) {
                    199: #ifdef GEOM_DEBUG
                    200:                                        printf("matched BIOS disk %x with %s\n",
1.34      cegger    201:                                            be->dev, device_xname(dv));
1.1       thorpej   202: #endif
                    203:                                        x86_alldisks->dl_nativedisks[n].
                    204:                                            ni_biosmatches[m++] = i;
                    205:                                }
                    206:                        }
                    207:                        x86_alldisks->dl_nativedisks[n].ni_nmatches = m;
                    208:                        vput(tv);
                    209:                }
                    210:        }
                    211: }
                    212:
                    213: /*
                    214:  * Helper function for findroot():
1.2       thorpej   215:  * Return non-zero if wedge device matches bootinfo.
                    216:  */
                    217: static int
                    218: match_bootwedge(struct device *dv, struct btinfo_bootwedge *biw)
                    219: {
                    220:        MD5_CTX ctx;
                    221:        struct vnode *tmpvn;
                    222:        int error;
1.4       christos  223:        uint8_t bf[DEV_BSIZE];
1.2       thorpej   224:        uint8_t hash[16];
                    225:        int found = 0;
                    226:        daddr_t blk;
                    227:        uint64_t nblks;
                    228:
                    229:        /*
                    230:         * If the boot loader didn't specify the sector, abort.
                    231:         */
                    232:        if (biw->matchblk == -1)
                    233:                return (0);
                    234:
1.19      christos  235:        if ((tmpvn = opendisk(dv)) == NULL)
                    236:                return 0;
                    237:
1.2       thorpej   238:        MD5Init(&ctx);
                    239:        for (blk = biw->matchblk, nblks = biw->matchnblks;
                    240:             nblks != 0; nblks--, blk++) {
1.25      christos  241:                error = vn_rdwr(UIO_READ, tmpvn, (void *) bf,
1.4       christos  242:                    sizeof(bf), blk * DEV_BSIZE, UIO_SYSSPACE,
1.2       thorpej   243:                    0, NOCRED, NULL, NULL);
                    244:                if (error) {
                    245:                        printf("findroot: unable to read block %" PRIu64 "\n",
                    246:                            blk);
                    247:                        goto closeout;
                    248:                }
1.4       christos  249:                MD5Update(&ctx, bf, sizeof(bf));
1.2       thorpej   250:        }
                    251:        MD5Final(hash, &ctx);
                    252:
                    253:        /* Compare with the provided hash. */
                    254:        found = memcmp(biw->matchhash, hash, sizeof(hash)) == 0;
                    255:
                    256:  closeout:
1.31      pooka     257:        VOP_CLOSE(tmpvn, FREAD, NOCRED);
1.2       thorpej   258:        vput(tmpvn);
                    259:        return (found);
                    260: }
                    261:
                    262: /*
                    263:  * Helper function for findroot():
1.1       thorpej   264:  * Return non-zero if disk device matches bootinfo.
                    265:  */
                    266: static int
                    267: match_bootdisk(struct device *dv, struct btinfo_bootdisk *bid)
                    268: {
                    269:        struct vnode *tmpvn;
                    270:        int error;
                    271:        struct disklabel label;
                    272:        int found = 0;
1.18      christos  273:
                    274:        if (device_is_a(dv, "dk"))
                    275:                return 0;
1.1       thorpej   276:
                    277:        /*
                    278:         * A disklabel is required here.  The boot loader doesn't refuse
                    279:         * to boot from a disk without a label, but this is normally not
                    280:         * wanted.
                    281:         */
                    282:        if (bid->labelsector == -1)
                    283:                return (0);
                    284:
1.18      christos  285:        if ((tmpvn = opendisk(dv)) == NULL)
                    286:                return 0;
1.2       thorpej   287:
1.31      pooka     288:        error = VOP_IOCTL(tmpvn, DIOCGDINFO, &label, FREAD, NOCRED);
1.1       thorpej   289:        if (error) {
                    290:                /*
                    291:                 * XXX Can't happen -- open() would have errored out
                    292:                 * or faked one up.
                    293:                 */
1.3       xtraeme   294:                printf("findroot: can't get label for dev %s (%d)\n",
1.34      cegger    295:                    device_xname(dv), error);
1.1       thorpej   296:                goto closeout;
                    297:        }
                    298:
                    299:        /* Compare with our data. */
                    300:        if (label.d_type == bid->label.type &&
                    301:            label.d_checksum == bid->label.checksum &&
                    302:            strncmp(label.d_packname, bid->label.packname, 16) == 0)
1.18      christos  303:                found = 1;
1.1       thorpej   304:
                    305:  closeout:
1.31      pooka     306:        VOP_CLOSE(tmpvn, FREAD, NOCRED);
1.1       thorpej   307:        vput(tmpvn);
                    308:        return (found);
                    309: }
                    310:
                    311: /*
                    312:  * Attempt to find the device from which we were booted.  If we can do so,
                    313:  * and not instructed not to do so, change rootdev to correspond to the
                    314:  * load device.
                    315:  */
                    316: static void
                    317: findroot(void)
                    318: {
1.6       jmmv      319:        struct btinfo_rootdevice *biv;
1.1       thorpej   320:        struct btinfo_bootdisk *bid;
1.2       thorpej   321:        struct btinfo_bootwedge *biw;
1.35      tsutsui   322:        struct btinfo_biosgeom *big;
1.32      joerg     323:        device_t dv;
1.1       thorpej   324:
                    325:        if (booted_device)
                    326:                return;
                    327:
                    328:        if (lookup_bootinfo(BTINFO_NETIF) != NULL) {
                    329:                /*
                    330:                 * We got netboot interface information, but device_register()
                    331:                 * failed to match it to a configured device.  Boot disk
                    332:                 * information cannot be present at the same time, so give
                    333:                 * up.
                    334:                 */
                    335:                printf("findroot: netboot interface not found.\n");
                    336:                return;
                    337:        }
                    338:
1.6       jmmv      339:        if ((biv = lookup_bootinfo(BTINFO_ROOTDEVICE)) != NULL) {
1.27      dyoung    340:                TAILQ_FOREACH(dv, &alldevs, dv_list) {
1.6       jmmv      341:                        struct cfdata *cd;
                    342:                        size_t len;
                    343:
1.9       thorpej   344:                        if (device_class(dv) != DV_DISK)
1.6       jmmv      345:                                continue;
                    346:
1.15      thorpej   347:                        cd = device_cfdata(dv);
1.6       jmmv      348:                        len = strlen(cd->cf_name);
                    349:
                    350:                        if (strncmp(cd->cf_name, biv->devname, len) == 0 &&
                    351:                            biv->devname[len] - '0' == cd->cf_unit) {
1.18      christos  352:                                handle_wedges(dv, biv->devname[len + 1] - 'a');
1.6       jmmv      353:                                return;
                    354:                        }
                    355:                }
                    356:        }
                    357:
1.2       thorpej   358:        if ((biw = lookup_bootinfo(BTINFO_BOOTWEDGE)) != NULL) {
                    359:                /*
                    360:                 * Scan all disk devices for ones that match the passed data.
                    361:                 * Don't break if one is found, to get possible multiple
                    362:                 * matches - for problem tracking.  Use the first match anyway
                    363:                 * because lower devices numbers are more likely to be the
                    364:                 * boot device.
                    365:                 */
1.27      dyoung    366:                TAILQ_FOREACH(dv, &alldevs, dv_list) {
1.9       thorpej   367:                        if (device_class(dv) != DV_DISK)
1.2       thorpej   368:                                continue;
                    369:
                    370:                        if (is_valid_disk(dv)) {
                    371:                                /*
                    372:                                 * Don't trust BIOS device numbers, try
                    373:                                 * to match the information passed by the
                    374:                                 * boot loader instead.
                    375:                                 */
                    376:                                if ((biw->biosdev & 0x80) == 0 ||
                    377:                                    match_bootwedge(dv, biw) == 0)
                    378:                                        continue;
                    379:                                goto bootwedge_found;
                    380:                        }
                    381:
                    382:                        continue;
                    383:  bootwedge_found:
                    384:                        if (booted_device) {
                    385:                                printf("WARNING: double match for boot "
                    386:                                    "device (%s, %s)\n",
1.34      cegger    387:                                    device_xname(booted_device),
                    388:                                    device_xname(dv));
1.2       thorpej   389:                                continue;
                    390:                        }
                    391:                        dkwedge_set_bootwedge(dv, biw->startblk, biw->nblks);
                    392:                }
                    393:
                    394:                if (booted_wedge)
                    395:                        return;
                    396:        }
                    397:
                    398:        if ((bid = lookup_bootinfo(BTINFO_BOOTDISK)) != NULL) {
1.1       thorpej   399:                /*
                    400:                 * Scan all disk devices for ones that match the passed data.
                    401:                 * Don't break if one is found, to get possible multiple
                    402:                 * matches - for problem tracking.  Use the first match anyway
                    403:                 * because lower device numbers are more likely to be the
                    404:                 * boot device.
                    405:                 */
1.27      dyoung    406:                TAILQ_FOREACH(dv, &alldevs, dv_list) {
1.9       thorpej   407:                        if (device_class(dv) != DV_DISK)
1.1       thorpej   408:                                continue;
                    409:
1.12      thorpej   410:                        if (device_is_a(dv, "fd")) {
1.1       thorpej   411:                                /*
                    412:                                 * Assume the configured unit number matches
                    413:                                 * the BIOS device number.  (This is the old
                    414:                                 * behavior.)  Needs some ideas how to handle
                    415:                                 * the BIOS's "swap floppy drive" options.
                    416:                                 */
1.14      thorpej   417:                                /* XXX device_unit() abuse */
1.1       thorpej   418:                                if ((bid->biosdev & 0x80) != 0 ||
1.14      thorpej   419:                                    device_unit(dv) != bid->biosdev)
1.1       thorpej   420:                                        continue;
1.2       thorpej   421:                                goto bootdisk_found;
1.1       thorpej   422:                        }
                    423:
                    424:                        if (is_valid_disk(dv)) {
                    425:                                /*
                    426:                                 * Don't trust BIOS device numbers, try
                    427:                                 * to match the information passed by the
                    428:                                 * boot loader instead.
                    429:                                 */
                    430:                                if ((bid->biosdev & 0x80) == 0 ||
                    431:                                    match_bootdisk(dv, bid) == 0)
                    432:                                        continue;
1.2       thorpej   433:                                goto bootdisk_found;
1.1       thorpej   434:                        }
                    435:
                    436:                        continue;
1.2       thorpej   437:  bootdisk_found:
1.1       thorpej   438:                        if (booted_device) {
                    439:                                printf("WARNING: double match for boot "
                    440:                                    "device (%s, %s)\n",
1.34      cegger    441:                                    device_xname(booted_device),
                    442:                                    device_xname(dv));
1.1       thorpej   443:                                continue;
                    444:                        }
1.18      christos  445:                        handle_wedges(dv, bid->partition);
1.1       thorpej   446:                }
                    447:
                    448:                if (booted_device)
                    449:                        return;
1.35      tsutsui   450:
                    451:                /*
                    452:                 * No booted device found; check CD-ROM boot at last.
                    453:                 *
                    454:                 * Our bootloader assumes CD-ROM boot if biosdev is larger
                    455:                 * than the number of hard drives recognized by the BIOS.
                    456:                 * The number of drives can be found in BTINFO_BIOSGEOM here.
                    457:                 *
                    458:                 * See src/sys/arch/i386/stand/boot/devopen.c and
                    459:                 * src/sys/arch/i386/stand/lib/bootinfo_biosgeom.c .
                    460:                 */
                    461:                if ((big = lookup_bootinfo(BTINFO_BIOSGEOM)) != NULL &&
                    462:                    bid->biosdev > 0x80 + big->num) {
                    463:                        /*
                    464:                         * XXX
                    465:                         * There is no proper way to detect which unit is
                    466:                         * recognized as a bootable CD-ROM drive by the BIOS.
                    467:                         * Assume the first unit is the one.
                    468:                         */
                    469:                        TAILQ_FOREACH(dv, &alldevs, dv_list) {
                    470:                                if (device_class(dv) == DV_DISK &&
                    471:                                    device_is_a(dv, "cd")) {
                    472:                                        booted_device = dv;
                    473:                                        booted_partition = 0;
                    474:                                        break;
                    475:                                }
                    476:                        }
                    477:                }
1.1       thorpej   478:        }
                    479: }
                    480:
                    481: void
1.8       jmmv      482: cpu_rootconf(void)
1.1       thorpej   483: {
                    484:
                    485:        findroot();
1.8       jmmv      486:        matchbiosdisks();
1.1       thorpej   487:
1.2       thorpej   488:        if (booted_wedge) {
                    489:                KASSERT(booted_device != NULL);
                    490:                printf("boot device: %s (%s)\n",
1.34      cegger    491:                    device_xname(booted_wedge), device_xname(booted_device));
1.2       thorpej   492:                setroot(booted_wedge, 0);
                    493:        } else {
                    494:                printf("boot device: %s\n",
1.34      cegger    495:                    booted_device ? device_xname(booted_device) : "<unknown>");
1.2       thorpej   496:                setroot(booted_device, booted_partition);
                    497:        }
1.1       thorpej   498: }
                    499:
                    500: void
                    501: device_register(struct device *dev, void *aux)
                    502: {
1.36    ! jmcneill  503:        static bool found_console = false;
1.1       thorpej   504:
                    505:        /*
                    506:         * Handle network interfaces here, the attachment information is
                    507:         * not available driver-independently later.
                    508:         *
                    509:         * For disks, there is nothing useful available at attach time.
                    510:         */
1.9       thorpej   511:        if (device_class(dev) == DV_IFNET) {
1.1       thorpej   512:                struct btinfo_netif *bin = lookup_bootinfo(BTINFO_NETIF);
                    513:                if (bin == NULL)
                    514:                        return;
                    515:
                    516:                /*
                    517:                 * We don't check the driver name against the device name
                    518:                 * passed by the boot ROM.  The ROM should stay usable if
                    519:                 * the driver becomes obsolete.  The physical attachment
                    520:                 * information (checked below) must be sufficient to
                    521:                 * idenfity the device.
                    522:                 */
                    523:                if (bin->bus == BI_BUS_ISA &&
1.11      thorpej   524:                    device_is_a(device_parent(dev), "isa")) {
1.1       thorpej   525:                        struct isa_attach_args *iaa = aux;
                    526:
                    527:                        /* Compare IO base address */
                    528:                        /* XXXJRT What about multiple IO addrs? */
                    529:                        if (iaa->ia_nio > 0 &&
                    530:                            bin->addr.iobase == iaa->ia_io[0].ir_addr)
                    531:                                goto found;
                    532:                }
                    533: #if NPCI > 0
                    534:                if (bin->bus == BI_BUS_PCI &&
1.11      thorpej   535:                    device_is_a(device_parent(dev), "pci")) {
1.1       thorpej   536:                        struct pci_attach_args *paa = aux;
                    537:                        int b, d, f;
                    538:
                    539:                        /*
                    540:                         * Calculate BIOS representation of:
                    541:                         *
                    542:                         *      <bus,device,function>
                    543:                         *
                    544:                         * and compare.
                    545:                         */
                    546:                        pci_decompose_tag(paa->pa_pc, paa->pa_tag, &b, &d, &f);
                    547:                        if (bin->addr.tag == ((b << 8) | (d << 3) | f))
                    548:                                goto found;
                    549:                }
                    550: #endif /* NPCI > 0 */
                    551:        }
1.36    ! jmcneill  552: #if NPCI > 0
        !           553:        if (device_parent(dev) && device_is_a(device_parent(dev), "pci") &&
        !           554:            found_console == false) {
        !           555:                struct btinfo_framebuffer *fbinfo;
        !           556:                struct pci_attach_args *pa = aux;
        !           557:                prop_dictionary_t dict;
        !           558:
        !           559:                if (PCI_CLASS(pa->pa_class) == PCI_CLASS_DISPLAY) {
        !           560:                        fbinfo = lookup_bootinfo(BTINFO_FRAMEBUFFER);
        !           561:                        if (fbinfo == NULL || fbinfo->physaddr == 0)
        !           562:                                return;
        !           563:                        dict = device_properties(dev);
        !           564:                        prop_dictionary_set_uint32(dict, "width",
        !           565:                            fbinfo->width);
        !           566:                        prop_dictionary_set_uint32(dict, "height",
        !           567:                            fbinfo->height);
        !           568:                        prop_dictionary_set_uint8(dict, "depth",
        !           569:                            fbinfo->depth);
        !           570:                        prop_dictionary_set_uint64(dict, "address",
        !           571:                            fbinfo->physaddr);
        !           572:                        prop_dictionary_set_uint16(dict, "linebytes",
        !           573:                            fbinfo->stride);
        !           574:                        prop_dictionary_set_bool(dict, "is_console", true);
        !           575: #if notyet
        !           576:                        prop_dictionary_set_bool(dict, "splash",
        !           577:                            fbinfo->flags & BI_FB_SPLASH ? true : false);
        !           578: #endif
        !           579:                        if (fbinfo->depth == 8) {
        !           580:                                gfb_cb.gcc_cookie = NULL;
        !           581:                                gfb_cb.gcc_set_mapreg = x86_genfb_set_mapreg;
        !           582:                                prop_dictionary_set_uint64(dict,
        !           583:                                    "cmap_callback", (uint64_t)&gfb_cb);
        !           584:                        }
        !           585:                        found_console = true;
        !           586:                        return;
        !           587:                }
        !           588:        }
        !           589: #endif
1.1       thorpej   590:        return;
                    591:
                    592:  found:
                    593:        if (booted_device) {
                    594:                /* XXX should be a panic() */
                    595:                printf("WARNING: double match for boot device (%s, %s)\n",
1.34      cegger    596:                    device_xname(booted_device), device_xname(dev));
1.1       thorpej   597:                return;
                    598:        }
                    599:        booted_device = dev;
                    600: }

CVSweb <webmaster@jp.NetBSD.org>