[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.55

1.55    ! jmcneill    1: /*     $NetBSD: x86_autoconf.c,v 1.54 2011/02/08 10:52:56 jmcneill 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.55    ! jmcneill   38: __KERNEL_RCSID(0, "$NetBSD: x86_autoconf.c,v 1.54 2011/02/08 10:52:56 jmcneill 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:
1.43      jmcneill   56: #include "acpica.h"
1.1       thorpej    57: #include "pci.h"
1.51      jmcneill   58: #include "isa.h"
1.38      jmcneill   59: #include "genfb.h"
                     60: #include "wsdisplay.h"
1.43      jmcneill   61: #include "opt_vga.h"
1.55    ! jmcneill   62: #include "opt_ddb.h"
        !            63:
        !            64: #ifdef DDB
        !            65: #include <machine/db_machdep.h>
        !            66: #include <ddb/db_sym.h>
        !            67: #include <ddb/db_extern.h>
        !            68: #endif
1.1       thorpej    69:
1.51      jmcneill   70: #if NACPICA > 0
                     71: #include <dev/acpi/acpivar.h>
                     72: #endif
                     73:
1.43      jmcneill   74: #ifdef VGA_POST
                     75: #include <x86/vga_post.h>
                     76: #endif
1.1       thorpej    77: #include <dev/isa/isavar.h>
                     78: #if NPCI > 0
                     79: #include <dev/pci/pcivar.h>
                     80: #endif
1.36      jmcneill   81: #include <dev/wsfb/genfbvar.h>
1.54      jmcneill   82: #include <arch/x86/include/genfb_machdep.h>
1.47      tron       83: #if NPCI > 0
1.43      jmcneill   84: #include <dev/pci/genfb_pcivar.h>
1.47      tron       85: #endif
1.36      jmcneill   86: #include <dev/ic/vgareg.h>
                     87:
1.47      tron       88: #if NPCI > 0
1.42      jmcneill   89: static struct genfb_colormap_callback gfb_cb;
                     90: static struct genfb_pmf_callback pmf_cb;
1.54      jmcneill   91: static struct genfb_mode_callback mode_cb;
1.47      tron       92: #endif
1.43      jmcneill   93: #ifdef VGA_POST
                     94: static struct vga_post *vga_posth = NULL;
                     95: #endif
1.1       thorpej    96:
                     97: struct disklist *x86_alldisks;
                     98: int x86_ndisks;
                     99:
1.41      dsl       100: #if NPCI > 0
1.18      christos  101: static void
1.36      jmcneill  102: x86_genfb_set_mapreg(void *opaque, int index, int r, int g, int b)
                    103: {
                    104:        outb(0x3c0 + VGA_DAC_ADDRW, index);
                    105:        outb(0x3c0 + VGA_DAC_PALETTE, (uint8_t)r >> 2);
                    106:        outb(0x3c0 + VGA_DAC_PALETTE, (uint8_t)g >> 2);
                    107:        outb(0x3c0 + VGA_DAC_PALETTE, (uint8_t)b >> 2);
                    108: }
1.42      jmcneill  109:
                    110: static bool
1.54      jmcneill  111: x86_genfb_setmode(struct genfb_softc *sc, int newmode)
                    112: {
                    113:        if (newmode == WSDISPLAYIO_MODE_EMUL)
                    114:                x86_genfb_mtrr_init(sc->sc_fboffset,
                    115:                    sc->sc_height * sc->sc_stride);
                    116:        return true;
                    117: }
                    118:
                    119: static bool
1.50      dyoung    120: x86_genfb_suspend(device_t dev, const pmf_qual_t *qual)
1.42      jmcneill  121: {
                    122:        return true;
                    123: }
                    124:
                    125: static bool
1.50      dyoung    126: x86_genfb_resume(device_t dev, const pmf_qual_t *qual)
1.42      jmcneill  127: {
1.44      jmcneill  128: #if NGENFB > 0
1.43      jmcneill  129:        struct pci_genfb_softc *psc = device_private(dev);
                    130: #if NACPICA > 0 && defined(VGA_POST)
                    131:        extern int acpi_md_vbios_reset;
                    132:        extern int acpi_md_vesa_modenum;
                    133: #endif
1.42      jmcneill  134:
1.43      jmcneill  135: #if NACPICA > 0 && defined(VGA_POST)
                    136:        if (vga_posth != NULL && acpi_md_vbios_reset == 2) {
                    137:                vga_post_call(vga_posth);
                    138:                if (acpi_md_vesa_modenum != 0)
                    139:                        vga_post_set_vbe(vga_posth, acpi_md_vesa_modenum);
                    140:        }
                    141: #endif
                    142:        genfb_restore_palette(&psc->sc_gen);
1.44      jmcneill  143: #endif
1.42      jmcneill  144:
                    145:        return true;
                    146: }
1.41      dsl       147: #endif
1.36      jmcneill  148:
                    149: static void
1.39      cegger    150: handle_wedges(device_t dv, int par)
1.18      christos  151: {
1.26      dyoung    152:        if (config_handle_wedges(dv, par) == 0)
                    153:                return;
1.18      christos  154:        booted_device = dv;
                    155:        booted_partition = par;
                    156: }
                    157:
1.1       thorpej   158: static int
1.39      cegger    159: is_valid_disk(device_t dv)
1.1       thorpej   160: {
                    161:
1.9       thorpej   162:        if (device_class(dv) != DV_DISK)
1.1       thorpej   163:                return (0);
                    164:
1.17      christos  165:        return (device_is_a(dv, "dk") ||
                    166:                device_is_a(dv, "sd") ||
1.13      thorpej   167:                device_is_a(dv, "wd") ||
                    168:                device_is_a(dv, "ld") ||
                    169:                device_is_a(dv, "ed"));
1.1       thorpej   170: }
                    171:
                    172: /*
                    173:  * XXX Ugly bit of code.  But, this is the only safe time that the
                    174:  * match between BIOS disks and native disks can be done.
                    175:  */
1.8       jmmv      176: static void
                    177: matchbiosdisks(void)
1.1       thorpej   178: {
                    179:        struct btinfo_biosgeom *big;
                    180:        struct bi_biosgeom_entry *be;
1.39      cegger    181:        device_t dv;
1.46      dyoung    182:        deviter_t di;
1.1       thorpej   183:        int i, ck, error, m, n;
                    184:        struct vnode *tv;
                    185:        char mbr[DEV_BSIZE];
                    186:        int dklist_size;
1.18      christos  187:        int numbig;
1.1       thorpej   188:
                    189:        big = lookup_bootinfo(BTINFO_BIOSGEOM);
                    190:
                    191:        numbig = big ? big->num : 0;
                    192:
                    193:        /* First, count all native disks. */
1.46      dyoung    194:        for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST); dv != NULL;
                    195:             dv = deviter_next(&di)) {
1.1       thorpej   196:                if (is_valid_disk(dv))
                    197:                        x86_ndisks++;
                    198:        }
1.46      dyoung    199:        deviter_release(&di);
1.1       thorpej   200:
                    201:        dklist_size = sizeof(struct disklist) + (x86_ndisks - 1) *
                    202:            sizeof(struct nativedisk_info);
                    203:
                    204:        /* XXX M_TEMP is wrong */
                    205:        x86_alldisks = malloc(dklist_size, M_TEMP, M_NOWAIT | M_ZERO);
                    206:        if (x86_alldisks == NULL)
                    207:                return;
                    208:
                    209:        x86_alldisks->dl_nnativedisks = x86_ndisks;
                    210:        x86_alldisks->dl_nbiosdisks = numbig;
                    211:        for (i = 0; i < numbig; i++) {
                    212:                x86_alldisks->dl_biosdisks[i].bi_dev = big->disk[i].dev;
                    213:                x86_alldisks->dl_biosdisks[i].bi_sec = big->disk[i].sec;
                    214:                x86_alldisks->dl_biosdisks[i].bi_head = big->disk[i].head;
                    215:                x86_alldisks->dl_biosdisks[i].bi_cyl = big->disk[i].cyl;
                    216:                x86_alldisks->dl_biosdisks[i].bi_lbasecs = big->disk[i].totsec;
                    217:                x86_alldisks->dl_biosdisks[i].bi_flags = big->disk[i].flags;
                    218: #ifdef GEOM_DEBUG
                    219: #ifdef notyet
                    220:                printf("disk %x: flags %x, interface %x, device %llx\n",
                    221:                       big->disk[i].dev, big->disk[i].flags,
                    222:                       big->disk[i].interface_path, big->disk[i].device_path);
                    223: #endif
                    224: #endif
                    225:        }
                    226:
                    227:        /* XXX Code duplication from findroot(). */
                    228:        n = -1;
1.46      dyoung    229:        for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST); dv != NULL;
                    230:             dv = deviter_next(&di)) {
1.9       thorpej   231:                if (device_class(dv) != DV_DISK)
1.1       thorpej   232:                        continue;
                    233: #ifdef GEOM_DEBUG
                    234:                printf("matchbiosdisks: trying to match (%s) %s\n",
1.34      cegger    235:                    device_xname(dv), device_cfdata(dv)->cf_name);
1.1       thorpej   236: #endif
                    237:                if (is_valid_disk(dv)) {
                    238:                        n++;
                    239:                        snprintf(x86_alldisks->dl_nativedisks[n].ni_devname,
                    240:                            sizeof(x86_alldisks->dl_nativedisks[n].ni_devname),
1.34      cegger    241:                            "%s", device_xname(dv));
1.1       thorpej   242:
1.18      christos  243:                        if ((tv = opendisk(dv)) == NULL)
                    244:                                continue;
1.1       thorpej   245:
                    246:                        error = vn_rdwr(UIO_READ, tv, mbr, DEV_BSIZE, 0,
                    247:                            UIO_SYSSPACE, 0, NOCRED, NULL, NULL);
1.31      pooka     248:                        VOP_CLOSE(tv, FREAD, NOCRED);
1.1       thorpej   249:                        if (error) {
                    250: #ifdef GEOM_DEBUG
                    251:                                printf("matchbiosdisks: %s: MBR read failure\n",
1.34      cegger    252:                                    device_xname(dv));
1.1       thorpej   253: #endif
                    254:                                continue;
                    255:                        }
                    256:
                    257:                        for (ck = i = 0; i < DEV_BSIZE; i++)
                    258:                                ck += mbr[i];
                    259:                        for (m = i = 0; i < numbig; i++) {
                    260:                                be = &big->disk[i];
                    261: #ifdef GEOM_DEBUG
                    262:                                printf("match %s with %d "
1.34      cegger    263:                                    "dev ck %x bios ck %x\n", device_xname(dv), i,
1.1       thorpej   264:                                    ck, be->cksum);
                    265: #endif
                    266:                                if (be->flags & BI_GEOM_INVALID)
                    267:                                        continue;
                    268:                                if (be->cksum == ck &&
                    269:                                    memcmp(&mbr[MBR_PART_OFFSET], be->dosparts,
                    270:                                        MBR_PART_COUNT *
                    271:                                          sizeof(struct mbr_partition)) == 0) {
                    272: #ifdef GEOM_DEBUG
                    273:                                        printf("matched BIOS disk %x with %s\n",
1.34      cegger    274:                                            be->dev, device_xname(dv));
1.1       thorpej   275: #endif
                    276:                                        x86_alldisks->dl_nativedisks[n].
                    277:                                            ni_biosmatches[m++] = i;
                    278:                                }
                    279:                        }
                    280:                        x86_alldisks->dl_nativedisks[n].ni_nmatches = m;
                    281:                        vput(tv);
                    282:                }
                    283:        }
1.46      dyoung    284:        deviter_release(&di);
1.1       thorpej   285: }
                    286:
                    287: /*
                    288:  * Helper function for findroot():
1.2       thorpej   289:  * Return non-zero if wedge device matches bootinfo.
                    290:  */
                    291: static int
1.39      cegger    292: match_bootwedge(device_t dv, struct btinfo_bootwedge *biw)
1.2       thorpej   293: {
                    294:        MD5_CTX ctx;
                    295:        struct vnode *tmpvn;
                    296:        int error;
1.4       christos  297:        uint8_t bf[DEV_BSIZE];
1.2       thorpej   298:        uint8_t hash[16];
                    299:        int found = 0;
                    300:        daddr_t blk;
                    301:        uint64_t nblks;
                    302:
                    303:        /*
                    304:         * If the boot loader didn't specify the sector, abort.
                    305:         */
                    306:        if (biw->matchblk == -1)
                    307:                return (0);
                    308:
1.19      christos  309:        if ((tmpvn = opendisk(dv)) == NULL)
                    310:                return 0;
                    311:
1.2       thorpej   312:        MD5Init(&ctx);
                    313:        for (blk = biw->matchblk, nblks = biw->matchnblks;
                    314:             nblks != 0; nblks--, blk++) {
1.25      christos  315:                error = vn_rdwr(UIO_READ, tmpvn, (void *) bf,
1.4       christos  316:                    sizeof(bf), blk * DEV_BSIZE, UIO_SYSSPACE,
1.2       thorpej   317:                    0, NOCRED, NULL, NULL);
                    318:                if (error) {
1.53      jakllsch  319:                        printf("findroot: unable to read block %" PRId64 " "
                    320:                            "of dev %s (%d)\n", blk, device_xname(dv), error);
1.2       thorpej   321:                        goto closeout;
                    322:                }
1.4       christos  323:                MD5Update(&ctx, bf, sizeof(bf));
1.2       thorpej   324:        }
                    325:        MD5Final(hash, &ctx);
                    326:
                    327:        /* Compare with the provided hash. */
                    328:        found = memcmp(biw->matchhash, hash, sizeof(hash)) == 0;
                    329:
                    330:  closeout:
1.31      pooka     331:        VOP_CLOSE(tmpvn, FREAD, NOCRED);
1.2       thorpej   332:        vput(tmpvn);
                    333:        return (found);
                    334: }
                    335:
                    336: /*
                    337:  * Helper function for findroot():
1.1       thorpej   338:  * Return non-zero if disk device matches bootinfo.
                    339:  */
                    340: static int
1.39      cegger    341: match_bootdisk(device_t dv, struct btinfo_bootdisk *bid)
1.1       thorpej   342: {
                    343:        struct vnode *tmpvn;
                    344:        int error;
                    345:        struct disklabel label;
                    346:        int found = 0;
1.18      christos  347:
                    348:        if (device_is_a(dv, "dk"))
                    349:                return 0;
1.1       thorpej   350:
                    351:        /*
                    352:         * A disklabel is required here.  The boot loader doesn't refuse
                    353:         * to boot from a disk without a label, but this is normally not
                    354:         * wanted.
                    355:         */
                    356:        if (bid->labelsector == -1)
                    357:                return (0);
                    358:
1.18      christos  359:        if ((tmpvn = opendisk(dv)) == NULL)
                    360:                return 0;
1.2       thorpej   361:
1.31      pooka     362:        error = VOP_IOCTL(tmpvn, DIOCGDINFO, &label, FREAD, NOCRED);
1.1       thorpej   363:        if (error) {
                    364:                /*
                    365:                 * XXX Can't happen -- open() would have errored out
                    366:                 * or faked one up.
                    367:                 */
1.3       xtraeme   368:                printf("findroot: can't get label for dev %s (%d)\n",
1.34      cegger    369:                    device_xname(dv), error);
1.1       thorpej   370:                goto closeout;
                    371:        }
                    372:
                    373:        /* Compare with our data. */
                    374:        if (label.d_type == bid->label.type &&
                    375:            label.d_checksum == bid->label.checksum &&
                    376:            strncmp(label.d_packname, bid->label.packname, 16) == 0)
1.18      christos  377:                found = 1;
1.1       thorpej   378:
                    379:  closeout:
1.31      pooka     380:        VOP_CLOSE(tmpvn, FREAD, NOCRED);
1.1       thorpej   381:        vput(tmpvn);
                    382:        return (found);
                    383: }
                    384:
                    385: /*
                    386:  * Attempt to find the device from which we were booted.  If we can do so,
                    387:  * and not instructed not to do so, change rootdev to correspond to the
                    388:  * load device.
                    389:  */
                    390: static void
                    391: findroot(void)
                    392: {
1.6       jmmv      393:        struct btinfo_rootdevice *biv;
1.1       thorpej   394:        struct btinfo_bootdisk *bid;
1.2       thorpej   395:        struct btinfo_bootwedge *biw;
1.35      tsutsui   396:        struct btinfo_biosgeom *big;
1.32      joerg     397:        device_t dv;
1.46      dyoung    398:        deviter_t di;
1.1       thorpej   399:
                    400:        if (booted_device)
                    401:                return;
                    402:
                    403:        if (lookup_bootinfo(BTINFO_NETIF) != NULL) {
                    404:                /*
                    405:                 * We got netboot interface information, but device_register()
                    406:                 * failed to match it to a configured device.  Boot disk
                    407:                 * information cannot be present at the same time, so give
                    408:                 * up.
                    409:                 */
                    410:                printf("findroot: netboot interface not found.\n");
                    411:                return;
                    412:        }
                    413:
1.6       jmmv      414:        if ((biv = lookup_bootinfo(BTINFO_ROOTDEVICE)) != NULL) {
1.46      dyoung    415:                for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST);
                    416:                     dv != NULL;
                    417:                     dv = deviter_next(&di)) {
1.40      cegger    418:                        cfdata_t cd;
1.6       jmmv      419:                        size_t len;
                    420:
1.9       thorpej   421:                        if (device_class(dv) != DV_DISK)
1.6       jmmv      422:                                continue;
                    423:
1.15      thorpej   424:                        cd = device_cfdata(dv);
1.6       jmmv      425:                        len = strlen(cd->cf_name);
                    426:
                    427:                        if (strncmp(cd->cf_name, biv->devname, len) == 0 &&
                    428:                            biv->devname[len] - '0' == cd->cf_unit) {
1.18      christos  429:                                handle_wedges(dv, biv->devname[len + 1] - 'a');
1.46      dyoung    430:                                break;
1.6       jmmv      431:                        }
                    432:                }
1.46      dyoung    433:                deviter_release(&di);
                    434:                if (dv != NULL)
                    435:                        return;
1.6       jmmv      436:        }
                    437:
1.2       thorpej   438:        if ((biw = lookup_bootinfo(BTINFO_BOOTWEDGE)) != NULL) {
                    439:                /*
                    440:                 * Scan all disk devices for ones that match the passed data.
                    441:                 * Don't break if one is found, to get possible multiple
                    442:                 * matches - for problem tracking.  Use the first match anyway
                    443:                 * because lower devices numbers are more likely to be the
                    444:                 * boot device.
                    445:                 */
1.46      dyoung    446:                for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST);
                    447:                     dv != NULL;
                    448:                     dv = deviter_next(&di)) {
1.9       thorpej   449:                        if (device_class(dv) != DV_DISK)
1.2       thorpej   450:                                continue;
                    451:
                    452:                        if (is_valid_disk(dv)) {
                    453:                                /*
                    454:                                 * Don't trust BIOS device numbers, try
                    455:                                 * to match the information passed by the
                    456:                                 * boot loader instead.
                    457:                                 */
                    458:                                if ((biw->biosdev & 0x80) == 0 ||
                    459:                                    match_bootwedge(dv, biw) == 0)
                    460:                                        continue;
                    461:                                goto bootwedge_found;
                    462:                        }
                    463:
                    464:                        continue;
                    465:  bootwedge_found:
                    466:                        if (booted_device) {
                    467:                                printf("WARNING: double match for boot "
                    468:                                    "device (%s, %s)\n",
1.34      cegger    469:                                    device_xname(booted_device),
                    470:                                    device_xname(dv));
1.2       thorpej   471:                                continue;
                    472:                        }
                    473:                        dkwedge_set_bootwedge(dv, biw->startblk, biw->nblks);
                    474:                }
1.46      dyoung    475:                deviter_release(&di);
1.2       thorpej   476:
                    477:                if (booted_wedge)
                    478:                        return;
                    479:        }
                    480:
                    481:        if ((bid = lookup_bootinfo(BTINFO_BOOTDISK)) != NULL) {
1.1       thorpej   482:                /*
                    483:                 * Scan all disk devices for ones that match the passed data.
                    484:                 * Don't break if one is found, to get possible multiple
                    485:                 * matches - for problem tracking.  Use the first match anyway
                    486:                 * because lower device numbers are more likely to be the
                    487:                 * boot device.
                    488:                 */
1.46      dyoung    489:                for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST);
                    490:                     dv != NULL;
                    491:                     dv = deviter_next(&di)) {
1.9       thorpej   492:                        if (device_class(dv) != DV_DISK)
1.1       thorpej   493:                                continue;
                    494:
1.12      thorpej   495:                        if (device_is_a(dv, "fd")) {
1.1       thorpej   496:                                /*
                    497:                                 * Assume the configured unit number matches
                    498:                                 * the BIOS device number.  (This is the old
                    499:                                 * behavior.)  Needs some ideas how to handle
                    500:                                 * the BIOS's "swap floppy drive" options.
                    501:                                 */
1.14      thorpej   502:                                /* XXX device_unit() abuse */
1.1       thorpej   503:                                if ((bid->biosdev & 0x80) != 0 ||
1.14      thorpej   504:                                    device_unit(dv) != bid->biosdev)
1.1       thorpej   505:                                        continue;
1.2       thorpej   506:                                goto bootdisk_found;
1.1       thorpej   507:                        }
                    508:
                    509:                        if (is_valid_disk(dv)) {
                    510:                                /*
                    511:                                 * Don't trust BIOS device numbers, try
                    512:                                 * to match the information passed by the
                    513:                                 * boot loader instead.
                    514:                                 */
                    515:                                if ((bid->biosdev & 0x80) == 0 ||
                    516:                                    match_bootdisk(dv, bid) == 0)
                    517:                                        continue;
1.2       thorpej   518:                                goto bootdisk_found;
1.1       thorpej   519:                        }
                    520:
                    521:                        continue;
1.2       thorpej   522:  bootdisk_found:
1.1       thorpej   523:                        if (booted_device) {
                    524:                                printf("WARNING: double match for boot "
                    525:                                    "device (%s, %s)\n",
1.34      cegger    526:                                    device_xname(booted_device),
                    527:                                    device_xname(dv));
1.1       thorpej   528:                                continue;
                    529:                        }
1.18      christos  530:                        handle_wedges(dv, bid->partition);
1.1       thorpej   531:                }
1.46      dyoung    532:                deviter_release(&di);
1.1       thorpej   533:
                    534:                if (booted_device)
                    535:                        return;
1.35      tsutsui   536:
                    537:                /*
                    538:                 * No booted device found; check CD-ROM boot at last.
                    539:                 *
                    540:                 * Our bootloader assumes CD-ROM boot if biosdev is larger
                    541:                 * than the number of hard drives recognized by the BIOS.
                    542:                 * The number of drives can be found in BTINFO_BIOSGEOM here.
                    543:                 *
                    544:                 * See src/sys/arch/i386/stand/boot/devopen.c and
                    545:                 * src/sys/arch/i386/stand/lib/bootinfo_biosgeom.c .
                    546:                 */
                    547:                if ((big = lookup_bootinfo(BTINFO_BIOSGEOM)) != NULL &&
                    548:                    bid->biosdev > 0x80 + big->num) {
                    549:                        /*
                    550:                         * XXX
                    551:                         * There is no proper way to detect which unit is
                    552:                         * recognized as a bootable CD-ROM drive by the BIOS.
                    553:                         * Assume the first unit is the one.
                    554:                         */
1.46      dyoung    555:                        for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST);
                    556:                             dv != NULL;
                    557:                             dv = deviter_next(&di)) {
1.35      tsutsui   558:                                if (device_class(dv) == DV_DISK &&
                    559:                                    device_is_a(dv, "cd")) {
                    560:                                        booted_device = dv;
                    561:                                        booted_partition = 0;
                    562:                                        break;
                    563:                                }
                    564:                        }
1.46      dyoung    565:                        deviter_release(&di);
1.35      tsutsui   566:                }
1.1       thorpej   567:        }
                    568: }
                    569:
                    570: void
1.8       jmmv      571: cpu_rootconf(void)
1.1       thorpej   572: {
                    573:
                    574:        findroot();
1.8       jmmv      575:        matchbiosdisks();
1.1       thorpej   576:
1.2       thorpej   577:        if (booted_wedge) {
                    578:                KASSERT(booted_device != NULL);
1.49      hubertf   579:                aprint_normal("boot device: %s (%s)\n",
1.34      cegger    580:                    device_xname(booted_wedge), device_xname(booted_device));
1.2       thorpej   581:                setroot(booted_wedge, 0);
                    582:        } else {
1.49      hubertf   583:                aprint_normal("boot device: %s\n",
1.34      cegger    584:                    booted_device ? device_xname(booted_device) : "<unknown>");
1.2       thorpej   585:                setroot(booted_device, booted_partition);
                    586:        }
1.1       thorpej   587: }
                    588:
                    589: void
1.39      cegger    590: device_register(device_t dev, void *aux)
1.1       thorpej   591: {
1.41      dsl       592: #if NPCI > 0
1.36      jmcneill  593:        static bool found_console = false;
1.41      dsl       594: #endif
1.1       thorpej   595:
                    596:        /*
                    597:         * Handle network interfaces here, the attachment information is
                    598:         * not available driver-independently later.
                    599:         *
                    600:         * For disks, there is nothing useful available at attach time.
                    601:         */
1.9       thorpej   602:        if (device_class(dev) == DV_IFNET) {
1.1       thorpej   603:                struct btinfo_netif *bin = lookup_bootinfo(BTINFO_NETIF);
                    604:                if (bin == NULL)
                    605:                        return;
                    606:
                    607:                /*
                    608:                 * We don't check the driver name against the device name
                    609:                 * passed by the boot ROM.  The ROM should stay usable if
                    610:                 * the driver becomes obsolete.  The physical attachment
                    611:                 * information (checked below) must be sufficient to
                    612:                 * idenfity the device.
                    613:                 */
                    614:                if (bin->bus == BI_BUS_ISA &&
1.11      thorpej   615:                    device_is_a(device_parent(dev), "isa")) {
1.1       thorpej   616:                        struct isa_attach_args *iaa = aux;
                    617:
                    618:                        /* Compare IO base address */
                    619:                        /* XXXJRT What about multiple IO addrs? */
                    620:                        if (iaa->ia_nio > 0 &&
                    621:                            bin->addr.iobase == iaa->ia_io[0].ir_addr)
                    622:                                goto found;
                    623:                }
                    624: #if NPCI > 0
                    625:                if (bin->bus == BI_BUS_PCI &&
1.11      thorpej   626:                    device_is_a(device_parent(dev), "pci")) {
1.1       thorpej   627:                        struct pci_attach_args *paa = aux;
                    628:                        int b, d, f;
                    629:
                    630:                        /*
                    631:                         * Calculate BIOS representation of:
                    632:                         *
                    633:                         *      <bus,device,function>
                    634:                         *
                    635:                         * and compare.
                    636:                         */
                    637:                        pci_decompose_tag(paa->pa_pc, paa->pa_tag, &b, &d, &f);
                    638:                        if (bin->addr.tag == ((b << 8) | (d << 3) | f))
                    639:                                goto found;
                    640:                }
                    641: #endif /* NPCI > 0 */
                    642:        }
1.51      jmcneill  643: #if NISA > 0 && NACPICA > 0
1.52      jmcneill  644: #if notyet
1.51      jmcneill  645:        if (device_is_a(dev, "isa") && acpi_active) {
                    646:                if (!(AcpiGbl_FADT.BootFlags & ACPI_FADT_LEGACY_DEVICES))
                    647:                        prop_dictionary_set_bool(device_properties(dev),
                    648:                            "no-legacy-devices", true);
                    649:        }
1.52      jmcneill  650: #endif
1.51      jmcneill  651: #endif /* NISA > 0 && NACPICA > 0 */
1.36      jmcneill  652: #if NPCI > 0
                    653:        if (device_parent(dev) && device_is_a(device_parent(dev), "pci") &&
                    654:            found_console == false) {
                    655:                struct btinfo_framebuffer *fbinfo;
                    656:                struct pci_attach_args *pa = aux;
                    657:                prop_dictionary_t dict;
                    658:
                    659:                if (PCI_CLASS(pa->pa_class) == PCI_CLASS_DISPLAY) {
1.38      jmcneill  660: #if NWSDISPLAY > 0 && NGENFB > 0
1.37      jmcneill  661:                        extern struct vcons_screen x86_genfb_console_screen;
1.38      jmcneill  662: #endif
1.37      jmcneill  663:
1.36      jmcneill  664:                        fbinfo = lookup_bootinfo(BTINFO_FRAMEBUFFER);
                    665:                        dict = device_properties(dev);
1.45      macallan  666:                        /*
                    667:                         * framebuffer drivers other than genfb can work
                    668:                         * without the address property
                    669:                         */
                    670:                        if (fbinfo != NULL) {
                    671:                                if (fbinfo->physaddr != 0) {
                    672:                                prop_dictionary_set_uint32(dict, "width",
                    673:                                    fbinfo->width);
                    674:                                prop_dictionary_set_uint32(dict, "height",
                    675:                                    fbinfo->height);
                    676:                                prop_dictionary_set_uint8(dict, "depth",
                    677:                                    fbinfo->depth);
                    678:                                prop_dictionary_set_uint16(dict, "linebytes",
                    679:                                    fbinfo->stride);
                    680:
                    681:                                        prop_dictionary_set_uint64(dict,
                    682:                                            "address", fbinfo->physaddr);
                    683:                                }
                    684: #if notyet
                    685:                                prop_dictionary_set_bool(dict, "splash",
                    686:                                    fbinfo->flags & BI_FB_SPLASH ?
                    687:                                     true : false);
                    688: #endif
                    689:                                if (fbinfo->depth == 8) {
                    690:                                        gfb_cb.gcc_cookie = NULL;
                    691:                                        gfb_cb.gcc_set_mapreg =
                    692:                                            x86_genfb_set_mapreg;
                    693:                                        prop_dictionary_set_uint64(dict,
                    694:                                            "cmap_callback", (uint64_t)&gfb_cb);
                    695:                                }
1.54      jmcneill  696:                                if (fbinfo->physaddr != 0) {
                    697:                                        mode_cb.gmc_setmode = x86_genfb_setmode;
                    698:                                        prop_dictionary_set_uint64(dict,
                    699:                                            "mode_callback",
                    700:                                            (uint64_t)&mode_cb);
                    701:                                }
1.55    ! jmcneill  702:
        !           703: #if NWSDISPLAY > 0 && NGENFB > 0
        !           704:                                if (device_is_a(dev, "genfb")) {
        !           705:                                        x86_genfb_set_console_dev(dev);
        !           706: #ifdef DDB
        !           707:                                        db_trap_callback =
        !           708:                                            x86_genfb_ddb_trap_callback;
        !           709: #endif
        !           710:                                }
        !           711: #endif
1.45      macallan  712:                        }
1.36      jmcneill  713:                        prop_dictionary_set_bool(dict, "is_console", true);
1.37      jmcneill  714:                        prop_dictionary_set_bool(dict, "clear-screen", false);
1.38      jmcneill  715: #if NWSDISPLAY > 0 && NGENFB > 0
1.37      jmcneill  716:                        prop_dictionary_set_uint16(dict, "cursor-row",
                    717:                            x86_genfb_console_screen.scr_ri.ri_crow);
1.38      jmcneill  718: #endif
1.36      jmcneill  719: #if notyet
                    720:                        prop_dictionary_set_bool(dict, "splash",
                    721:                            fbinfo->flags & BI_FB_SPLASH ? true : false);
                    722: #endif
1.42      jmcneill  723:                        pmf_cb.gpc_suspend = x86_genfb_suspend;
                    724:                        pmf_cb.gpc_resume = x86_genfb_resume;
                    725:                        prop_dictionary_set_uint64(dict,
                    726:                            "pmf_callback", (uint64_t)&pmf_cb);
1.43      jmcneill  727: #ifdef VGA_POST
                    728:                        vga_posth = vga_post_init(pa->pa_bus, pa->pa_device,
                    729:                            pa->pa_function);
                    730: #endif
1.36      jmcneill  731:                        found_console = true;
                    732:                        return;
                    733:                }
                    734:        }
                    735: #endif
1.1       thorpej   736:        return;
                    737:
                    738:  found:
                    739:        if (booted_device) {
                    740:                /* XXX should be a panic() */
                    741:                printf("WARNING: double match for boot device (%s, %s)\n",
1.34      cegger    742:                    device_xname(booted_device), device_xname(dev));
1.1       thorpej   743:                return;
                    744:        }
                    745:        booted_device = dev;
                    746: }

CVSweb <webmaster@jp.NetBSD.org>