[BACK]Return to vesabios.c CVS log [TXT][DIR] Up to [local] / sys / dev / vesa

Annotation of sys/dev/vesa/vesabios.c, Revision 1.1.1.1

1.1       nbrk        1: /* $OpenBSD: vesabios.c,v 1.4 2007/02/18 19:19:02 gwk Exp $ */
                      2:
                      3: /*
                      4:  * Copyright (c) 2002, 2004
                      5:  *     Matthias Drochner.  All rights reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions, and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
                     15:  *
                     16:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
                     17:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     18:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     19:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
                     20:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     21:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     22:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     23:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     24:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     25:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     26:  * SUCH DAMAGE.
                     27:  */
                     28:
                     29: #include <sys/cdefs.h>
                     30:
                     31: #include <sys/param.h>
                     32: #include <sys/systm.h>
                     33: #include <sys/device.h>
                     34: #include <sys/malloc.h>
                     35: #include <machine/frame.h>
                     36: #include <machine/kvm86.h>
                     37:
                     38: #include <dev/vesa/vesabiosvar.h>
                     39: #include <dev/vesa/vesabiosreg.h>
                     40: #include <dev/vesa/vbe.h>
                     41:
                     42: struct vbeinfoblock
                     43: {
                     44:        char VbeSignature[4];
                     45:        uint16_t VbeVersion;
                     46:        uint32_t OemStringPtr;
                     47:        uint32_t Capabilities;
                     48:        uint32_t VideoModePtr;
                     49:        uint16_t TotalMemory;
                     50:        uint16_t OemSoftwareRev;
                     51:        uint32_t OemVendorNamePtr, OemProductNamePtr, OemProductRevPtr;
                     52:        /* data area, in total max 512 bytes for VBE 2.0 */
                     53: } __packed;
                     54:
                     55: #define FAR2FLATPTR(p) ((p & 0xffff) + ((p >> 12) & 0xffff0))
                     56:
                     57: int vesabios_match(struct device *, void *, void *);
                     58: void vesabios_attach(struct device *, struct device *, void *);
                     59: int vesabios_print(void *, const char *);
                     60:
                     61: int vbegetinfo(struct vbeinfoblock **);
                     62: void vbefreeinfo(struct vbeinfoblock *);
                     63: #ifdef VESABIOSVERBOSE
                     64: const char *mm2txt(unsigned int);
                     65: #endif
                     66:
                     67: struct vesabios_softc *vesabios_softc;
                     68:
                     69: struct cfattach vesabios_ca = {
                     70:        sizeof(struct vesabios_softc), vesabios_match, vesabios_attach
                     71: };
                     72:
                     73: struct cfdriver vesabios_cd = {
                     74:        NULL, "vesabios", DV_DULL
                     75: };
                     76:
                     77: int
                     78: vesabios_match(struct device *parent, void *match, void *aux)
                     79: {
                     80:
                     81:        return (1);
                     82: }
                     83:
                     84: int
                     85: vbegetinfo(struct vbeinfoblock **vip)
                     86: {
                     87:        unsigned char *buf;
                     88:        struct trapframe tf;
                     89:        int res, error;
                     90:
                     91:        if ((buf = kvm86_bios_addpage(KVM86_CALL_TASKVA)) == NULL) {
                     92:                printf("vbegetinfo: kvm86_bios_addpage failed\n");
                     93:                return (ENOMEM);
                     94:        }
                     95:
                     96:        memcpy(buf, "VBE2", 4);
                     97:
                     98:        memset(&tf, 0, sizeof(struct trapframe));
                     99:        tf.tf_eax = VBE_FUNC_CTRLINFO;
                    100:        tf.tf_vm86_es = 0;
                    101:        tf.tf_edi = KVM86_CALL_TASKVA;
                    102:
                    103:        res = kvm86_bioscall(BIOS_VIDEO_INTR, &tf);
                    104:        if (res || VBECALL_SUPPORT(tf.tf_eax) != VBECALL_SUPPORTED) {
                    105:                printf("vbecall: res=%d, ax=%x\n", res, tf.tf_eax);
                    106:                error = ENXIO;
                    107:                goto out;
                    108:        }
                    109:
                    110:        if (memcmp(((struct vbeinfoblock *)buf)->VbeSignature, "VESA", 4)) {
                    111:                error = EIO;
                    112:                goto out;
                    113:        }
                    114:
                    115:        if (vip)
                    116:                *vip = (struct vbeinfoblock *)buf;
                    117:        return (0);
                    118:
                    119: out:
                    120:        kvm86_bios_delpage(KVM86_CALL_TASKVA, buf);
                    121:        return (error);
                    122: }
                    123:
                    124: void
                    125: vbefreeinfo(struct vbeinfoblock *vip)
                    126: {
                    127:
                    128:        kvm86_bios_delpage(KVM86_CALL_TASKVA, vip);
                    129: }
                    130:
                    131: int
                    132: vbeprobe(void)
                    133: {
                    134:        struct vbeinfoblock *vi;
                    135:        int found = 0;
                    136:
                    137:        if (vbegetinfo(&vi))
                    138:                return (0);
                    139:        if (VBE_CTRLINFO_VERSION(vi->VbeVersion) > 1) {
                    140:                /* VESA bios is at least version 2.0 */
                    141:                found = 1;
                    142:        }
                    143:        vbefreeinfo(vi);
                    144:        return (found);
                    145: }
                    146:
                    147: #ifdef VESABIOSVERBOSE
                    148: const char *
                    149: mm2txt(unsigned int mm)
                    150: {
                    151:        static char buf[30];
                    152:        static const char *names[] = {
                    153:                "Text mode",
                    154:                "CGA graphics",
                    155:                "Hercules graphics",
                    156:                "Planar",
                    157:                "Packed pixel",
                    158:                "Non-chain 4, 256 color",
                    159:                "Direct Color",
                    160:                "YUV"
                    161:        };
                    162:
                    163:        if (mm < sizeof(names)/sizeof(names[0]))
                    164:                return (names[mm]);
                    165:        snprintf(buf, sizeof(buf), "unknown memory model %d", mm);
                    166:        return (buf);
                    167: }
                    168: #endif
                    169:
                    170: void
                    171: vesabios_attach(struct device *parent, struct device *self, void *aux)
                    172: {
                    173:        struct vesabios_softc *sc = (struct vesabios_softc *)self;
                    174:        struct vbeinfoblock *vi;
                    175:        unsigned char *buf;
                    176:        struct trapframe tf;
                    177:        int res;
                    178:        char name[256];
                    179: #define MAXMODES 60
                    180:        uint16_t modes[MAXMODES];
                    181:        int rastermodes[MAXMODES];
                    182:        int textmodes[MAXMODES];
                    183:        int nmodes, nrastermodes, ntextmodes, i;
                    184:        uint32_t modeptr;
                    185:        struct modeinfoblock *mi;
                    186:
                    187:        if (vbegetinfo(&vi)) {
                    188:                printf("\n");
                    189:                panic("vesabios_attach: disappeared");
                    190:        }
                    191:
                    192:        printf(": version %d.%d",
                    193:            VBE_CTRLINFO_VERSION(vi->VbeVersion),
                    194:            VBE_CTRLINFO_REVISION(vi->VbeVersion));
                    195:
                    196:
                    197:        res = kvm86_bios_read(FAR2FLATPTR(vi->OemVendorNamePtr),
                    198:            name, sizeof(name));
                    199:
                    200:        sc->sc_size = vi->TotalMemory * 65536;
                    201:        if (res > 0) {
                    202:                name[res - 1] = 0;
                    203:                printf(", %s", name);
                    204:                res = kvm86_bios_read(FAR2FLATPTR(vi->OemProductNamePtr),
                    205:                                      name, sizeof(name));
                    206:                if (res > 0) {
                    207:                        name[res - 1] = 0;
                    208:                        printf(" %s", name);
                    209:                }
                    210:        }
                    211:        printf("\n");
                    212:
                    213:        nmodes = 0;
                    214:        modeptr = FAR2FLATPTR(vi->VideoModePtr);
                    215:        while (nmodes < MAXMODES) {
                    216:                res = kvm86_bios_read(modeptr, (char *)&modes[nmodes], 2);
                    217:                if (res != 2 || modes[nmodes] == 0xffff)
                    218:                        break;
                    219:                nmodes++;
                    220:                modeptr += 2;
                    221:        }
                    222:
                    223:        vbefreeinfo(vi);
                    224:        if (nmodes == 0)
                    225:                return;
                    226:
                    227:        nrastermodes = ntextmodes = 0;
                    228:
                    229:        buf = kvm86_bios_addpage(KVM86_CALL_TASKVA);
                    230:        if (!buf) {
                    231:                printf("%s: kvm86_bios_addpage failed\n",
                    232:                    self->dv_xname);
                    233:                return;
                    234:        }
                    235:        for (i = 0; i < nmodes; i++) {
                    236:
                    237:                memset(&tf, 0, sizeof(struct trapframe));
                    238:                tf.tf_eax = VBE_FUNC_MODEINFO;
                    239:                tf.tf_ecx = modes[i];
                    240:                tf.tf_vm86_es = 0;
                    241:                tf.tf_edi = KVM86_CALL_TASKVA;
                    242:
                    243:                res = kvm86_bioscall(BIOS_VIDEO_INTR, &tf);
                    244:                if (res || VBECALL_SUPPORT(tf.tf_eax) != VBECALL_SUPPORTED) {
                    245:                        printf("%s: vbecall: res=%d, ax=%x\n",
                    246:                            self->dv_xname, res, tf.tf_eax);
                    247:                        printf("%s: error getting info for mode %04x\n",
                    248:                            self->dv_xname, modes[i]);
                    249:                        continue;
                    250:                }
                    251:                mi = (struct modeinfoblock *)buf;
                    252: #ifdef VESABIOSVERBOSE
                    253:                printf("%s: VESA mode %04x: attributes %04x",
                    254:                       self->dv_xname, modes[i], mi->ModeAttributes);
                    255: #endif
                    256:                if (!(mi->ModeAttributes & 1)) {
                    257: #ifdef VESABIOSVERBOSE
                    258:                        printf("\n");
                    259: #endif
                    260:                        continue;
                    261:                }
                    262:                if (mi->ModeAttributes & 0x10) {
                    263:                        /* graphics */
                    264: #ifdef VESABIOSVERBOSE
                    265:                        printf(", %dx%d %dbbp %s\n",
                    266:                               mi->XResolution, mi->YResolution,
                    267:                               mi->BitsPerPixel, mm2txt(mi->MemoryModel));
                    268: #endif
                    269:                        if (mi->ModeAttributes & 0x80) {
                    270:                                /* flat buffer */
                    271:                                rastermodes[nrastermodes++] = modes[i];
                    272:                        }
                    273:                } else {
                    274:                        /* text */
                    275: #ifdef VESABIOSVERBOSE
                    276:                        printf(", text %dx%d\n",
                    277:                               mi->XResolution, mi->YResolution);
                    278: #endif
                    279:                        if (!(mi->ModeAttributes & 0x20)) /* VGA compatible */
                    280:                                textmodes[ntextmodes++] = modes[i];
                    281:                }
                    282:        }
                    283:        kvm86_bios_delpage(KVM86_CALL_TASKVA, buf);
                    284:        if (nrastermodes > 0) {
                    285:                sc->sc_modes =
                    286:                    (uint16_t *)malloc(sizeof(uint16_t)*nrastermodes,
                    287:                        M_DEVBUF, M_NOWAIT);
                    288:                if (sc->sc_modes == NULL) {
                    289:                        sc->sc_nmodes = 0;
                    290:                        return;
                    291:                }
                    292:                sc->sc_nmodes = nrastermodes;
                    293:                for (i = 0; i < nrastermodes; i++)
                    294:                        sc->sc_modes[i] = rastermodes[i];
                    295:        }
                    296:        vesabios_softc = sc;
                    297: }
                    298:
                    299: int
                    300: vesabios_print(aux, pnp)
                    301:        void *aux;
                    302:        const char *pnp;
                    303: {
                    304:        char *busname = aux;
                    305:
                    306:        if (pnp)
                    307:                printf("%s at %s", busname, pnp);
                    308:        return (UNCONF);
                    309: }

CVSweb