[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

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