[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     ! 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