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

Annotation of sys/dev/isa/pcdisplay.c, Revision 1.1

1.1     ! nbrk        1: /* $OpenBSD: pcdisplay.c,v 1.9 2006/11/29 19:08:22 miod Exp $ */
        !             2: /* $NetBSD: pcdisplay.c,v 1.9.4.1 2000/06/30 16:27:48 simonb Exp $ */
        !             3:
        !             4: /*
        !             5:  * Copyright (c) 1998
        !             6:  *     Matthias Drochner.  All rights reserved.
        !             7:  *
        !             8:  * Redistribution and use in source and binary forms, with or without
        !             9:  * modification, are permitted provided that the following conditions
        !            10:  * are met:
        !            11:  * 1. Redistributions of source code must retain the above copyright
        !            12:  *    notice, this list of conditions and the following disclaimer.
        !            13:  * 2. Redistributions in binary form must reproduce the above copyright
        !            14:  *    notice, this list of conditions and the following disclaimer in the
        !            15:  *    documentation and/or other materials provided with the distribution.
        !            16:  *
        !            17:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            18:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            19:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            20:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            21:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            22:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            23:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            24:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            25:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
        !            26:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            27:  *
        !            28:  */
        !            29:
        !            30: #include <sys/param.h>
        !            31: #include <sys/systm.h>
        !            32: #include <sys/kernel.h>
        !            33: #include <sys/device.h>
        !            34: #include <sys/malloc.h>
        !            35: #include <machine/bus.h>
        !            36:
        !            37: #include <dev/isa/isavar.h>
        !            38: #include <dev/isa/isareg.h>
        !            39:
        !            40: #include <dev/ic/mc6845reg.h>
        !            41: #include <dev/ic/pcdisplayvar.h>
        !            42: #include <dev/isa/pcdisplayvar.h>
        !            43:
        !            44: #include <dev/ic/pcdisplay.h>
        !            45:
        !            46: #include <dev/wscons/wsconsio.h>
        !            47: #include <dev/wscons/wsdisplayvar.h>
        !            48:
        !            49: struct pcdisplay_config {
        !            50:        struct pcdisplayscreen pcs;
        !            51:        struct pcdisplay_handle dc_ph;
        !            52:        int mono;
        !            53: };
        !            54:
        !            55: struct pcdisplay_softc {
        !            56:        struct device sc_dev;
        !            57:        struct pcdisplay_config *sc_dc;
        !            58:        int nscreens;
        !            59: };
        !            60:
        !            61: static int pcdisplayconsole, pcdisplay_console_attached;
        !            62: static struct pcdisplay_config pcdisplay_console_dc;
        !            63:
        !            64: int    pcdisplay_match(struct device *, void *, void *);
        !            65: void   pcdisplay_attach(struct device *, struct device *, void *);
        !            66:
        !            67: static int pcdisplay_is_console(bus_space_tag_t);
        !            68: static int pcdisplay_probe_col(bus_space_tag_t, bus_space_tag_t);
        !            69: static int pcdisplay_probe_mono(bus_space_tag_t, bus_space_tag_t);
        !            70: static void pcdisplay_init(struct pcdisplay_config *,
        !            71:                             bus_space_tag_t, bus_space_tag_t,
        !            72:                             int);
        !            73: static int pcdisplay_alloc_attr(void *, int, int, int, long *);
        !            74: static void pcdisplay_unpack_attr(void *, long, int *, int *, int *);
        !            75:
        !            76: struct cfattach pcdisplay_ca = {
        !            77:        sizeof(struct pcdisplay_softc), pcdisplay_match, pcdisplay_attach,
        !            78: };
        !            79:
        !            80: const struct wsdisplay_emulops pcdisplay_emulops = {
        !            81:        pcdisplay_cursor,
        !            82:        pcdisplay_mapchar,
        !            83:        pcdisplay_putchar,
        !            84:        pcdisplay_copycols,
        !            85:        pcdisplay_erasecols,
        !            86:        pcdisplay_copyrows,
        !            87:        pcdisplay_eraserows,
        !            88:        pcdisplay_alloc_attr,
        !            89:        pcdisplay_unpack_attr
        !            90: };
        !            91:
        !            92: const struct wsscreen_descr pcdisplay_scr = {
        !            93:        "80x25", 80, 25,
        !            94:        &pcdisplay_emulops,
        !            95:        0, 0, /* no font support */
        !            96:        WSSCREEN_REVERSE /* that's minimal... */
        !            97: };
        !            98:
        !            99: const struct wsscreen_descr *_pcdisplay_scrlist[] = {
        !           100:        &pcdisplay_scr,
        !           101: };
        !           102:
        !           103: const struct wsscreen_list pcdisplay_screenlist = {
        !           104:        sizeof(_pcdisplay_scrlist) / sizeof(struct wsscreen_descr *),
        !           105:        _pcdisplay_scrlist
        !           106: };
        !           107:
        !           108: static int pcdisplay_ioctl(void *, u_long, caddr_t, int, struct proc *);
        !           109: static paddr_t pcdisplay_mmap(void *, off_t, int);
        !           110: static int pcdisplay_alloc_screen(void *, const struct wsscreen_descr *,
        !           111:                                       void **, int *, int *, long *);
        !           112: static void pcdisplay_free_screen(void *, void *);
        !           113: static int pcdisplay_show_screen(void *, void *, int,
        !           114:                                 void (*) (void *, int, int), void *);
        !           115:
        !           116: const struct wsdisplay_accessops pcdisplay_accessops = {
        !           117:        pcdisplay_ioctl,
        !           118:        pcdisplay_mmap,
        !           119:        pcdisplay_alloc_screen,
        !           120:        pcdisplay_free_screen,
        !           121:        pcdisplay_show_screen,
        !           122:        0 /* load_font */
        !           123: };
        !           124:
        !           125: static int
        !           126: pcdisplay_probe_col(iot, memt)
        !           127:        bus_space_tag_t iot, memt;
        !           128: {
        !           129:        bus_space_handle_t memh, ioh_6845;
        !           130:        u_int16_t oldval, val;
        !           131:
        !           132:        if (bus_space_map(memt, 0xb8000, 0x8000, 0, &memh))
        !           133:                return (0);
        !           134:        oldval = bus_space_read_2(memt, memh, 0);
        !           135:        bus_space_write_2(memt, memh, 0, 0xa55a);
        !           136:        val = bus_space_read_2(memt, memh, 0);
        !           137:        bus_space_write_2(memt, memh, 0, oldval);
        !           138:        bus_space_unmap(memt, memh, 0x8000);
        !           139:        if (val != 0xa55a)
        !           140:                return (0);
        !           141:
        !           142:        if (bus_space_map(iot, 0x3d0, 0x10, 0, &ioh_6845))
        !           143:                return (0);
        !           144:        bus_space_unmap(iot, ioh_6845, 0x10);
        !           145:
        !           146:        return (1);
        !           147: }
        !           148:
        !           149: static int
        !           150: pcdisplay_probe_mono(iot, memt)
        !           151:        bus_space_tag_t iot, memt;
        !           152: {
        !           153:        bus_space_handle_t memh, ioh_6845;
        !           154:        u_int16_t oldval, val;
        !           155:
        !           156:        if (bus_space_map(memt, 0xb0000, 0x8000, 0, &memh))
        !           157:                return (0);
        !           158:        oldval = bus_space_read_2(memt, memh, 0);
        !           159:        bus_space_write_2(memt, memh, 0, 0xa55a);
        !           160:        val = bus_space_read_2(memt, memh, 0);
        !           161:        bus_space_write_2(memt, memh, 0, oldval);
        !           162:        bus_space_unmap(memt, memh, 0x8000);
        !           163:        if (val != 0xa55a)
        !           164:                return (0);
        !           165:
        !           166:        if (bus_space_map(iot, 0x3b0, 0x10, 0, &ioh_6845))
        !           167:                return (0);
        !           168:        bus_space_unmap(iot, ioh_6845, 0x10);
        !           169:
        !           170:        return (1);
        !           171: }
        !           172:
        !           173: static void
        !           174: pcdisplay_init(dc, iot, memt, mono)
        !           175:        struct pcdisplay_config *dc;
        !           176:        bus_space_tag_t iot, memt;
        !           177:        int mono;
        !           178: {
        !           179:        struct pcdisplay_handle *ph = &dc->dc_ph;
        !           180:        int cpos;
        !           181:
        !           182:         ph->ph_iot = iot;
        !           183:         ph->ph_memt = memt;
        !           184:        dc->mono = mono;
        !           185:
        !           186:        if (bus_space_map(memt, mono ? 0xb0000 : 0xb8000, 0x8000,
        !           187:                          0, &ph->ph_memh))
        !           188:                panic("pcdisplay_init: cannot map memory");
        !           189:        if (bus_space_map(iot, mono ? 0x3b0 : 0x3d0, 0x10,
        !           190:                          0, &ph->ph_ioh_6845))
        !           191:                panic("pcdisplay_init: cannot map io");
        !           192:
        !           193:        /*
        !           194:         * initialize the only screen
        !           195:         */
        !           196:        dc->pcs.hdl = ph;
        !           197:        dc->pcs.type = &pcdisplay_scr;
        !           198:        dc->pcs.active = 1;
        !           199:        dc->pcs.mem = NULL;
        !           200:
        !           201:        cpos = pcdisplay_6845_read(ph, cursorh) << 8;
        !           202:        cpos |= pcdisplay_6845_read(ph, cursorl);
        !           203:
        !           204:        /* make sure we have a valid cursor position */
        !           205:        if (cpos < 0 || cpos >= pcdisplay_scr.nrows * pcdisplay_scr.ncols)
        !           206:                cpos = 0;
        !           207:
        !           208:        dc->pcs.dispoffset = 0;
        !           209:        dc->pcs.visibleoffset = 0;
        !           210:
        !           211:        dc->pcs.vc_crow = cpos / pcdisplay_scr.ncols;
        !           212:        dc->pcs.vc_ccol = cpos % pcdisplay_scr.ncols;
        !           213:        pcdisplay_cursor_init(&dc->pcs, 1);
        !           214: }
        !           215:
        !           216: int
        !           217: pcdisplay_match(parent, match, aux)
        !           218:        struct device *parent;
        !           219:        void *match;
        !           220:        void *aux;
        !           221: {
        !           222:        struct isa_attach_args *ia = aux;
        !           223:        int mono;
        !           224:
        !           225:        /* If values are hardwired to something that they can't be, punt. */
        !           226:        if ((ia->ia_iobase != IOBASEUNK &&
        !           227:             ia->ia_iobase != 0x3d0 &&
        !           228:             ia->ia_iobase != 0x3b0) ||
        !           229:            /* ia->ia_iosize != 0 || XXX isa.c */
        !           230:            (ia->ia_maddr != MADDRUNK &&
        !           231:             ia->ia_maddr != 0xb8000 &&
        !           232:             ia->ia_maddr != 0xb0000) ||
        !           233:            (ia->ia_msize != 0 && ia->ia_msize != 0x8000) ||
        !           234:            ia->ia_irq != IRQUNK || ia->ia_drq != DRQUNK)
        !           235:                return (0);
        !           236:
        !           237:        if (pcdisplay_is_console(ia->ia_iot))
        !           238:                mono = pcdisplay_console_dc.mono;
        !           239:        else if (ia->ia_iobase != 0x3b0 && ia->ia_maddr != 0xb0000 &&
        !           240:                 pcdisplay_probe_col(ia->ia_iot, ia->ia_memt))
        !           241:                mono = 0;
        !           242:        else if (ia->ia_iobase != 0x3d0 && ia->ia_maddr != 0xb8000 &&
        !           243:                 pcdisplay_probe_mono(ia->ia_iot, ia->ia_memt))
        !           244:                mono = 1;
        !           245:        else
        !           246:                return (0);
        !           247:
        !           248:        ia->ia_iobase = mono ? 0x3b0 : 0x3d0;
        !           249:        ia->ia_iosize = 0x10;
        !           250:        ia->ia_maddr = mono ? 0xb0000 : 0xb8000;
        !           251:        ia->ia_msize = 0x8000;
        !           252:        return (1);
        !           253: }
        !           254:
        !           255: void
        !           256: pcdisplay_attach(parent, self, aux)
        !           257:        struct device *parent, *self;
        !           258:        void *aux;
        !           259: {
        !           260:        struct isa_attach_args *ia = aux;
        !           261:        struct pcdisplay_softc *sc = (struct pcdisplay_softc *)self;
        !           262:        int console;
        !           263:        struct pcdisplay_config *dc;
        !           264:        struct wsemuldisplaydev_attach_args aa;
        !           265:
        !           266:        printf("\n");
        !           267:
        !           268:        console = pcdisplay_is_console(ia->ia_iot);
        !           269:
        !           270:        if (console) {
        !           271:                dc = &pcdisplay_console_dc;
        !           272:                sc->nscreens = 1;
        !           273:                pcdisplay_console_attached = 1;
        !           274:        } else {
        !           275:                dc = malloc(sizeof(struct pcdisplay_config),
        !           276:                            M_DEVBUF, M_WAITOK);
        !           277:                if (ia->ia_iobase != 0x3b0 && ia->ia_maddr != 0xb0000 &&
        !           278:                    pcdisplay_probe_col(ia->ia_iot, ia->ia_memt))
        !           279:                        pcdisplay_init(dc, ia->ia_iot, ia->ia_memt, 0);
        !           280:                else if (ia->ia_iobase != 0x3d0 && ia->ia_maddr != 0xb8000 &&
        !           281:                         pcdisplay_probe_mono(ia->ia_iot, ia->ia_memt))
        !           282:                        pcdisplay_init(dc, ia->ia_iot, ia->ia_memt, 1);
        !           283:                else
        !           284:                        panic("pcdisplay_attach: display disappeared");
        !           285:        }
        !           286:        sc->sc_dc = dc;
        !           287:
        !           288:        aa.console = console;
        !           289:        aa.scrdata = &pcdisplay_screenlist;
        !           290:        aa.accessops = &pcdisplay_accessops;
        !           291:        aa.accesscookie = sc;
        !           292:        aa.defaultscreens = 0;
        !           293:
        !           294:         config_found(self, &aa, wsemuldisplaydevprint);
        !           295: }
        !           296:
        !           297:
        !           298: int
        !           299: pcdisplay_cnattach(iot, memt)
        !           300:        bus_space_tag_t iot, memt;
        !           301: {
        !           302:        int mono;
        !           303:
        !           304:        if (pcdisplay_probe_col(iot, memt))
        !           305:                mono = 0;
        !           306:        else if (pcdisplay_probe_mono(iot, memt))
        !           307:                mono = 1;
        !           308:        else
        !           309:                return (ENXIO);
        !           310:
        !           311:        pcdisplay_init(&pcdisplay_console_dc, iot, memt, mono);
        !           312:
        !           313:        wsdisplay_cnattach(&pcdisplay_scr, &pcdisplay_console_dc,
        !           314:                           pcdisplay_console_dc.pcs.vc_ccol,
        !           315:                           pcdisplay_console_dc.pcs.vc_crow,
        !           316:                           FG_LIGHTGREY | BG_BLACK);
        !           317:
        !           318:        pcdisplayconsole = 1;
        !           319:        return (0);
        !           320: }
        !           321:
        !           322: static int
        !           323: pcdisplay_is_console(iot)
        !           324:        bus_space_tag_t iot;
        !           325: {
        !           326:        if (pcdisplayconsole &&
        !           327:            !pcdisplay_console_attached &&
        !           328:            iot == pcdisplay_console_dc.dc_ph.ph_iot)
        !           329:                return (1);
        !           330:        return (0);
        !           331: }
        !           332:
        !           333: static int
        !           334: pcdisplay_ioctl(v, cmd, data, flag, p)
        !           335:        void *v;
        !           336:        u_long cmd;
        !           337:        caddr_t data;
        !           338:        int flag;
        !           339:        struct proc *p;
        !           340: {
        !           341:        /*
        !           342:         * XXX "do something!"
        !           343:         */
        !           344:        return (-1);
        !           345: }
        !           346:
        !           347: static paddr_t
        !           348: pcdisplay_mmap(v, offset, prot)
        !           349:        void *v;
        !           350:        off_t offset;
        !           351:        int prot;
        !           352: {
        !           353:        return (-1);
        !           354: }
        !           355:
        !           356: static int
        !           357: pcdisplay_alloc_screen(v, type, cookiep, curxp, curyp, defattrp)
        !           358:        void *v;
        !           359:        const struct wsscreen_descr *type;
        !           360:        void **cookiep;
        !           361:        int *curxp, *curyp;
        !           362:        long *defattrp;
        !           363: {
        !           364:        struct pcdisplay_softc *sc = v;
        !           365:
        !           366:        if (sc->nscreens > 0)
        !           367:                return (ENOMEM);
        !           368:
        !           369:        *cookiep = sc->sc_dc;
        !           370:        *curxp = 0;
        !           371:        *curyp = 0;
        !           372:        *defattrp = FG_LIGHTGREY | BG_BLACK;
        !           373:        sc->nscreens++;
        !           374:        return (0);
        !           375: }
        !           376:
        !           377: static void
        !           378: pcdisplay_free_screen(v, cookie)
        !           379:        void *v;
        !           380:        void *cookie;
        !           381: {
        !           382:        struct pcdisplay_softc *sc = v;
        !           383:
        !           384:        if (sc->sc_dc == &pcdisplay_console_dc)
        !           385:                panic("pcdisplay_free_screen: console");
        !           386:
        !           387:        sc->nscreens--;
        !           388: }
        !           389:
        !           390: static int
        !           391: pcdisplay_show_screen(v, cookie, waitok, cb, cbarg)
        !           392:        void *v;
        !           393:        void *cookie;
        !           394:        int waitok;
        !           395:        void (*cb)(void *, int, int);
        !           396:        void *cbarg;
        !           397: {
        !           398: #ifdef DIAGNOSTIC
        !           399:        struct pcdisplay_softc *sc = v;
        !           400:
        !           401:        if (cookie != sc->sc_dc)
        !           402:                panic("pcdisplay_show_screen: bad screen");
        !           403: #endif
        !           404:        return (0);
        !           405: }
        !           406:
        !           407: static int
        !           408: pcdisplay_alloc_attr(id, fg, bg, flags, attrp)
        !           409:        void *id;
        !           410:        int fg, bg;
        !           411:        int flags;
        !           412:        long *attrp;
        !           413: {
        !           414:        if (flags & WSATTR_REVERSE)
        !           415:                *attrp = FG_BLACK | BG_LIGHTGREY;
        !           416:        else
        !           417:                *attrp = FG_LIGHTGREY | BG_BLACK;
        !           418:        return (0);
        !           419: }
        !           420:
        !           421: static void
        !           422: pcdisplay_unpack_attr(id, attr, fg, bg, ul)
        !           423:        void *id;
        !           424:        long attr;
        !           425:        int *fg, *bg, *ul;
        !           426: {
        !           427:        if (attr == (FG_BLACK | BG_LIGHTGREY)) {
        !           428:                *fg = WSCOL_BLACK;
        !           429:                *bg = WSCOL_WHITE;
        !           430:        } else {
        !           431:                *fg = WSCOL_WHITE;
        !           432:                *bg = WSCOL_BLACK;
        !           433:        }
        !           434:        if (ul != NULL)
        !           435:                *ul = 0;
        !           436: }
        !           437:
        !           438: struct cfdriver pcdisplay_cd = {
        !           439:        NULL, "pcdisplay", DV_DULL
        !           440: };

CVSweb