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

Annotation of sys/dev/ic/sti.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: sti.c,v 1.55 2007/06/17 13:59:08 miod Exp $   */
        !             2:
        !             3: /*
        !             4:  * Copyright (c) 2000-2003 Michael Shalayeff
        !             5:  * 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 ``AS IS'' AND ANY EXPRESS OR
        !            17:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            18:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            19:  * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
        !            20:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
        !            21:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
        !            22:  * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            23:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        !            24:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
        !            25:  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
        !            26:  * THE POSSIBILITY OF SUCH DAMAGE.
        !            27:  */
        !            28: /*
        !            29:  * TODO:
        !            30:  *     call sti procs asynchronously;
        !            31:  *     implement console scroll-back;
        !            32:  *     X11 support.
        !            33:  */
        !            34:
        !            35: #include <sys/param.h>
        !            36: #include <sys/systm.h>
        !            37: #include <sys/device.h>
        !            38: #include <sys/malloc.h>
        !            39:
        !            40: #include <uvm/uvm.h>
        !            41:
        !            42: #include <machine/bus.h>
        !            43:
        !            44: #include <dev/wscons/wsdisplayvar.h>
        !            45: #include <dev/wscons/wsconsio.h>
        !            46:
        !            47: #include <dev/ic/stireg.h>
        !            48: #include <dev/ic/stivar.h>
        !            49:
        !            50: #include "sti.h"
        !            51:
        !            52: struct cfdriver sti_cd = {
        !            53:        NULL, "sti", DV_DULL
        !            54: };
        !            55:
        !            56: void sti_cursor(void *v, int on, int row, int col);
        !            57: int  sti_mapchar(void *v, int uni, u_int *index);
        !            58: void sti_putchar(void *v, int row, int col, u_int uc, long attr);
        !            59: void sti_copycols(void *v, int row, int srccol, int dstcol, int ncols);
        !            60: void sti_erasecols(void *v, int row, int startcol, int ncols, long attr);
        !            61: void sti_copyrows(void *v, int srcrow, int dstrow, int nrows);
        !            62: void sti_eraserows(void *v, int row, int nrows, long attr);
        !            63: int  sti_alloc_attr(void *v, int fg, int bg, int flags, long *pattr);
        !            64: void sti_unpack_attr(void *v, long attr, int *fg, int *bg, int *ul);
        !            65:
        !            66: struct wsdisplay_emulops sti_emulops = {
        !            67:        sti_cursor,
        !            68:        sti_mapchar,
        !            69:        sti_putchar,
        !            70:        sti_copycols,
        !            71:        sti_erasecols,
        !            72:        sti_copyrows,
        !            73:        sti_eraserows,
        !            74:        sti_alloc_attr,
        !            75:        sti_unpack_attr
        !            76: };
        !            77:
        !            78: int sti_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p);
        !            79: paddr_t sti_mmap(void *v, off_t offset, int prot);
        !            80: int sti_alloc_screen(void *v, const struct wsscreen_descr *type,
        !            81:        void **cookiep, int *cxp, int *cyp, long *defattr);
        !            82:        void sti_free_screen(void *v, void *cookie);
        !            83: int sti_show_screen(void *v, void *cookie, int waitok,
        !            84:        void (*cb)(void *, int, int), void *cbarg);
        !            85: int sti_load_font(void *v, void *cookie, struct wsdisplay_font *);
        !            86:
        !            87: const struct wsdisplay_accessops sti_accessops = {
        !            88:        sti_ioctl,
        !            89:        sti_mmap,
        !            90:        sti_alloc_screen,
        !            91:        sti_free_screen,
        !            92:        sti_show_screen,
        !            93:        sti_load_font
        !            94: };
        !            95:
        !            96: enum sti_bmove_funcs {
        !            97:        bmf_clear, bmf_copy, bmf_invert, bmf_underline
        !            98: };
        !            99:
        !           100: int sti_init(struct sti_screen *scr, int mode);
        !           101: int sti_inqcfg(struct sti_screen *scr, struct sti_inqconfout *out);
        !           102: void sti_bmove(struct sti_screen *scr, int, int, int, int, int, int,
        !           103:     enum sti_bmove_funcs);
        !           104: int sti_setcment(struct sti_screen *scr, u_int i, u_char r, u_char g, u_char b);
        !           105: int sti_fetchfonts(struct sti_screen *scr, struct sti_inqconfout *cfg,
        !           106:     u_int32_t addr);
        !           107: int sti_screen_setup(struct sti_screen *scr, bus_space_tag_t iot,
        !           108:     bus_space_tag_t memt, bus_space_handle_t romh, bus_addr_t *bases,
        !           109:     u_int codebase);
        !           110:
        !           111: #if NSTI_PCI > 0
        !           112: #define        STI_ENABLE_ROM(sc) \
        !           113: do { \
        !           114:        if ((sc) != NULL && (sc)->sc_enable_rom != NULL) \
        !           115:                (*(sc)->sc_enable_rom)(sc); \
        !           116: } while (0)
        !           117: #define        STI_DISABLE_ROM(sc) \
        !           118: do { \
        !           119:        if ((sc) != NULL && (sc)->sc_disable_rom != NULL) \
        !           120:                (*(sc)->sc_disable_rom)(sc); \
        !           121: } while (0)
        !           122: #else
        !           123: #define        STI_ENABLE_ROM(sc)              do { /* nothing */ } while (0)
        !           124: #define        STI_DISABLE_ROM(sc)             do { /* nothing */ } while (0)
        !           125: #endif
        !           126:
        !           127: int
        !           128: sti_attach_common(sc, codebase)
        !           129:        struct sti_softc *sc;
        !           130:        u_int codebase;
        !           131: {
        !           132:        struct sti_screen *scr;
        !           133:        int rc;
        !           134:
        !           135:        scr = malloc(sizeof(struct sti_screen), M_DEVBUF, M_NOWAIT);
        !           136:        if (scr == NULL) {
        !           137:                printf("cannot allocate screen data\n");
        !           138:                return (ENOMEM);
        !           139:        }
        !           140:
        !           141:        bzero(scr, sizeof(struct sti_screen));
        !           142:        sc->sc_scr = scr;
        !           143:        scr->scr_main = sc;
        !           144:
        !           145:        if ((rc = sti_screen_setup(scr, sc->iot, sc->memt, sc->romh, sc->bases,
        !           146:            codebase)) != 0) {
        !           147:                free(scr, M_DEVBUF);
        !           148:                sc->sc_scr = NULL;
        !           149:                return (rc);
        !           150:        }
        !           151:
        !           152:        sti_describe(sc);
        !           153:        return (0);
        !           154: }
        !           155:
        !           156: int
        !           157: sti_screen_setup(struct sti_screen *scr, bus_space_tag_t iot,
        !           158:     bus_space_tag_t memt, bus_space_handle_t romh, bus_addr_t *bases,
        !           159:     u_int codebase)
        !           160: {
        !           161:        struct sti_inqconfout cfg;
        !           162:        struct sti_einqconfout ecfg;
        !           163:        bus_space_handle_t fbh;
        !           164:        struct sti_dd *dd;
        !           165:        struct sti_cfg *cc;
        !           166:        int error, size, i;
        !           167:        int geometry_kluge = 0;
        !           168:
        !           169:        STI_ENABLE_ROM(scr->scr_main);
        !           170:
        !           171:        scr->iot = iot;
        !           172:        scr->memt = memt;
        !           173:        scr->romh = romh;
        !           174:        scr->bases = bases;
        !           175:        scr->scr_devtype = bus_space_read_1(memt, romh, 3);
        !           176:
        !           177:        /* { extern int pmapdebug; pmapdebug = 0xfffff; } */
        !           178:        dd = &scr->scr_dd;
        !           179:        if (scr->scr_devtype == STI_DEVTYPE1) {
        !           180: #define        parseshort(o) \
        !           181:        ((bus_space_read_1(memt, romh, (o) + 3) <<  8) | \
        !           182:         (bus_space_read_1(memt, romh, (o) + 7)))
        !           183: #define        parseword(o) \
        !           184:        ((bus_space_read_1(memt, romh, (o) +  3) << 24) | \
        !           185:         (bus_space_read_1(memt, romh, (o) +  7) << 16) | \
        !           186:         (bus_space_read_1(memt, romh, (o) + 11) <<  8) | \
        !           187:         (bus_space_read_1(memt, romh, (o) + 15)))
        !           188:
        !           189:                dd->dd_type  = bus_space_read_1(memt, romh, 0x03);
        !           190:                dd->dd_nmon  = bus_space_read_1(memt, romh, 0x07);
        !           191:                dd->dd_grrev = bus_space_read_1(memt, romh, 0x0b);
        !           192:                dd->dd_lrrev = bus_space_read_1(memt, romh, 0x0f);
        !           193:                dd->dd_grid[0] = parseword(0x10);
        !           194:                dd->dd_grid[1] = parseword(0x20);
        !           195:                dd->dd_fntaddr = parseword(0x30) & ~3;
        !           196:                dd->dd_maxst   = parseword(0x40);
        !           197:                dd->dd_romend  = parseword(0x50) & ~3;
        !           198:                dd->dd_reglst  = parseword(0x60) & ~3;
        !           199:                dd->dd_maxreent= parseshort(0x70);
        !           200:                dd->dd_maxtimo = parseshort(0x78);
        !           201:                dd->dd_montbl  = parseword(0x80) & ~3;
        !           202:                dd->dd_udaddr  = parseword(0x90) & ~3;
        !           203:                dd->dd_stimemreq=parseword(0xa0);
        !           204:                dd->dd_udsize  = parseword(0xb0);
        !           205:                dd->dd_pwruse  = parseshort(0xc0);
        !           206:                dd->dd_bussup  = bus_space_read_1(memt, romh, 0xcb);
        !           207:                dd->dd_ebussup = bus_space_read_1(memt, romh, 0xcf);
        !           208:                dd->dd_altcodet= bus_space_read_1(memt, romh, 0xd3);
        !           209:                dd->dd_eddst[0]= bus_space_read_1(memt, romh, 0xd7);
        !           210:                dd->dd_eddst[1]= bus_space_read_1(memt, romh, 0xdb);
        !           211:                dd->dd_eddst[2]= bus_space_read_1(memt, romh, 0xdf);
        !           212:                dd->dd_cfbaddr = parseword(0xe0) & ~3;
        !           213:
        !           214:                codebase <<= 2;
        !           215:                dd->dd_pacode[0x0] = parseword(codebase + 0x000) & ~3;
        !           216:                dd->dd_pacode[0x1] = parseword(codebase + 0x010) & ~3;
        !           217:                dd->dd_pacode[0x2] = parseword(codebase + 0x020) & ~3;
        !           218:                dd->dd_pacode[0x3] = parseword(codebase + 0x030) & ~3;
        !           219:                dd->dd_pacode[0x4] = parseword(codebase + 0x040) & ~3;
        !           220:                dd->dd_pacode[0x5] = parseword(codebase + 0x050) & ~3;
        !           221:                dd->dd_pacode[0x6] = parseword(codebase + 0x060) & ~3;
        !           222:                dd->dd_pacode[0x7] = parseword(codebase + 0x070) & ~3;
        !           223:                dd->dd_pacode[0x8] = parseword(codebase + 0x080) & ~3;
        !           224:                dd->dd_pacode[0x9] = parseword(codebase + 0x090) & ~3;
        !           225:                dd->dd_pacode[0xa] = parseword(codebase + 0x0a0) & ~3;
        !           226:                dd->dd_pacode[0xb] = parseword(codebase + 0x0b0) & ~3;
        !           227:                dd->dd_pacode[0xc] = parseword(codebase + 0x0c0) & ~3;
        !           228:                dd->dd_pacode[0xd] = parseword(codebase + 0x0d0) & ~3;
        !           229:                dd->dd_pacode[0xe] = parseword(codebase + 0x0e0) & ~3;
        !           230:                dd->dd_pacode[0xf] = parseword(codebase + 0x0f0) & ~3;
        !           231:        } else {        /* STI_DEVTYPE4 */
        !           232:                bus_space_read_raw_region_4(memt, romh, 0, (u_int8_t *)dd,
        !           233:                    sizeof(*dd));
        !           234:                /* fix pacode... */
        !           235:                bus_space_read_raw_region_4(memt, romh, codebase,
        !           236:                    (u_int8_t *)dd->dd_pacode, sizeof(dd->dd_pacode));
        !           237:        }
        !           238:
        !           239:        STI_DISABLE_ROM(scr->scr_main);
        !           240:
        !           241: #ifdef STIDEBUG
        !           242:        printf("dd:\n"
        !           243:            "devtype=%x, rev=%x;%d, altt=%x, gid=%016llx, font=%x, mss=%x\n"
        !           244:            "end=%x, regions=%x, msto=%x, timo=%d, mont=%x, user=%x[%x]\n"
        !           245:            "memrq=%x, pwr=%d, bus=%x, ebus=%x, cfb=%x\n"
        !           246:            "code=",
        !           247:            dd->dd_type & 0xff, dd->dd_grrev, dd->dd_lrrev, dd->dd_altcodet,
        !           248:            *(u_int64_t *)dd->dd_grid, dd->dd_fntaddr, dd->dd_maxst,
        !           249:            dd->dd_romend, dd->dd_reglst, dd->dd_maxreent, dd->dd_maxtimo,
        !           250:            dd->dd_montbl, dd->dd_udaddr, dd->dd_udsize, dd->dd_stimemreq,
        !           251:            dd->dd_pwruse, dd->dd_bussup, dd->dd_ebussup, dd->dd_cfbaddr);
        !           252:        printf("%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n",
        !           253:            dd->dd_pacode[0x0], dd->dd_pacode[0x1], dd->dd_pacode[0x2],
        !           254:            dd->dd_pacode[0x3], dd->dd_pacode[0x4], dd->dd_pacode[0x5],
        !           255:            dd->dd_pacode[0x6], dd->dd_pacode[0x7], dd->dd_pacode[0x8],
        !           256:            dd->dd_pacode[0x9], dd->dd_pacode[0xa], dd->dd_pacode[0xb],
        !           257:            dd->dd_pacode[0xc], dd->dd_pacode[0xd], dd->dd_pacode[0xe],
        !           258:            dd->dd_pacode[0xf]);
        !           259: #endif
        !           260:        /* divise code size, could be less than STI_END entries */
        !           261:        for (i = STI_END; !dd->dd_pacode[i]; i--);
        !           262:        size = dd->dd_pacode[i] - dd->dd_pacode[STI_BEGIN];
        !           263:        if (scr->scr_devtype == STI_DEVTYPE1)
        !           264:                size = (size + 3) / 4;
        !           265:        if (size == 0) {
        !           266:                printf(": no code for the requested platform\n");
        !           267:                return (EINVAL);
        !           268:        }
        !           269:        if (!(scr->scr_code = uvm_km_alloc(kernel_map, round_page(size)))) {
        !           270:                printf(": cannot allocate %u bytes for code\n", size);
        !           271:                return (ENOMEM);
        !           272:        }
        !           273: #ifdef STIDEBUG
        !           274:        printf("code=0x%x[%x]\n", scr->scr_code, size);
        !           275: #endif
        !           276:
        !           277:        STI_ENABLE_ROM(scr->scr_main);
        !           278:
        !           279:        /* copy code into memory */
        !           280:        if (scr->scr_devtype == STI_DEVTYPE1) {
        !           281:                u_int8_t *p = (u_int8_t *)scr->scr_code;
        !           282:                u_int32_t addr, eaddr;
        !           283:
        !           284:                for (addr = dd->dd_pacode[STI_BEGIN], eaddr = addr + size * 4;
        !           285:                    addr < eaddr; addr += 4 )
        !           286:                        *p++ = bus_space_read_4(memt, romh, addr) & 0xff;
        !           287:
        !           288:        } else  /* STI_DEVTYPE4 */
        !           289:                bus_space_read_raw_region_4(memt, romh,
        !           290:                    dd->dd_pacode[STI_BEGIN], (u_int8_t *)scr->scr_code,
        !           291:                    size);
        !           292:
        !           293:        STI_DISABLE_ROM(scr->scr_main);
        !           294:
        !           295: #define        O(i)    (dd->dd_pacode[(i)]? (scr->scr_code + \
        !           296:        (dd->dd_pacode[(i)] - dd->dd_pacode[0]) / \
        !           297:        (scr->scr_devtype == STI_DEVTYPE1? 4 : 1)) : NULL)
        !           298:
        !           299:        scr->init       = (sti_init_t)  O(STI_INIT_GRAPH);
        !           300:        scr->mgmt       = (sti_mgmt_t)  O(STI_STATE_MGMT);
        !           301:        scr->unpmv      = (sti_unpmv_t) O(STI_FONT_UNPMV);
        !           302:        scr->blkmv      = (sti_blkmv_t) O(STI_BLOCK_MOVE);
        !           303:        scr->test       = (sti_test_t)  O(STI_SELF_TEST);
        !           304:        scr->exhdl      = (sti_exhdl_t) O(STI_EXCEP_HDLR);
        !           305:        scr->inqconf    = (sti_inqconf_t)O(STI_INQ_CONF);
        !           306:        scr->scment     = (sti_scment_t)O(STI_SCM_ENT);
        !           307:        scr->dmac       = (sti_dmac_t)  O(STI_DMA_CTRL);
        !           308:        scr->flowc      = (sti_flowc_t) O(STI_FLOW_CTRL);
        !           309:        scr->utiming    = (sti_utiming_t)O(STI_UTIMING);
        !           310:        scr->pmgr       = (sti_pmgr_t)  O(STI_PROC_MGR);
        !           311:        scr->util       = (sti_util_t)  O(STI_UTIL);
        !           312:
        !           313:        /*
        !           314:         * Set colormap entry is not implemented until 8.04, so force
        !           315:         * a NULL pointer here.
        !           316:         */
        !           317:        if (dd->dd_grrev < STI_REVISION(8,4)) {
        !           318:                scr->scment = NULL;
        !           319:        }
        !           320:
        !           321:        if ((error = uvm_map_protect(kernel_map, scr->scr_code,
        !           322:            scr->scr_code + round_page(size), UVM_PROT_RX, FALSE))) {
        !           323:                printf(": uvm_map_protect failed (%d)\n", error);
        !           324:                uvm_km_free(kernel_map, scr->scr_code, round_page(size));
        !           325:                return (error);
        !           326:        }
        !           327:
        !           328:        cc = &scr->scr_cfg;
        !           329:        bzero(cc, sizeof (*cc));
        !           330:        cc->ext_cfg = &scr->scr_ecfg;
        !           331:        bzero(cc->ext_cfg, sizeof(*cc->ext_cfg));
        !           332:        if (dd->dd_stimemreq) {
        !           333:                scr->scr_ecfg.addr =
        !           334:                    malloc(dd->dd_stimemreq, M_DEVBUF, M_NOWAIT);
        !           335:                if (!scr->scr_ecfg.addr) {
        !           336:                        printf("cannot allocate %d bytes for STI\n",
        !           337:                            dd->dd_stimemreq);
        !           338:                        uvm_km_free(kernel_map, scr->scr_code,
        !           339:                            round_page(size));
        !           340:                        return (ENOMEM);
        !           341:                }
        !           342:        }
        !           343:        {
        !           344:                int i = dd->dd_reglst;
        !           345:                u_int32_t *p;
        !           346:                struct sti_region r;
        !           347:
        !           348: #ifdef STIDEBUG
        !           349:                printf("stiregions @%p:\n", i);
        !           350: #endif
        !           351:
        !           352:                STI_ENABLE_ROM(scr->scr_main);
        !           353:
        !           354:                r.last = 0;
        !           355:                for (p = cc->regions; !r.last &&
        !           356:                     p < &cc->regions[STI_REGION_MAX]; p++) {
        !           357:
        !           358:                        if (scr->scr_devtype == STI_DEVTYPE1)
        !           359:                                *(u_int *)&r = parseword(i), i+= 16;
        !           360:                        else {
        !           361:                                bus_space_read_raw_region_4(memt, romh, i,
        !           362:                                    (u_int8_t *)&r, 4);
        !           363:                                i += 4;
        !           364:                        }
        !           365:
        !           366:                        *p = bases[p - cc->regions] + (r.offset << PGSHIFT);
        !           367: #ifdef STIDEBUG
        !           368:                        STI_DISABLE_ROM(scr->scr_main);
        !           369:                        printf("%08x @ 0x%08x%s%s%s%s\n",
        !           370:                            r.length << PGSHIFT, *p, r.sys_only? " sys" : "",
        !           371:                            r.cache? " cache" : "", r.btlb? " btlb" : "",
        !           372:                            r.last? " last" : "");
        !           373:                        STI_ENABLE_ROM(scr->scr_main);
        !           374: #endif
        !           375:
        !           376:                        /* skip rom if it has already been mapped */
        !           377:                        if (p == cc->regions && romh == bases[0])
        !           378:                                continue;
        !           379:
        !           380:                        if (bus_space_map(memt, *p, r.length << PGSHIFT,
        !           381:                            r.cache ? BUS_SPACE_MAP_CACHEABLE : 0, &fbh)) {
        !           382: #ifdef STIDEBUG
        !           383:                                STI_DISABLE_ROM(scr->scr_main);
        !           384:                                printf("already mapped region\n");
        !           385:                                STI_ENABLE_ROM(scr->scr_main);
        !           386: #endif
        !           387:                        } else {
        !           388:                                if (p - cc->regions == 1) {
        !           389:                                        scr->fbaddr = *p;
        !           390:                                        scr->fblen = r.length << PGSHIFT;
        !           391:                                }
        !           392:                                *p = fbh;
        !           393:                        }
        !           394:                }
        !           395:
        !           396:                STI_DISABLE_ROM(scr->scr_main);
        !           397:        }
        !           398:
        !           399:        if ((error = sti_init(scr, 0))) {
        !           400:                printf(": can not initialize (%d)\n", error);
        !           401:                /* XXX free resources */
        !           402:                return (ENXIO);
        !           403:        }
        !           404:
        !           405:        bzero(&cfg, sizeof(cfg));
        !           406:        bzero(&ecfg, sizeof(ecfg));
        !           407:        cfg.ext = &ecfg;
        !           408:        if ((error = sti_inqcfg(scr, &cfg))) {
        !           409:                printf(": error %d inquiring config\n", error);
        !           410:                /* XXX free resources */
        !           411:                return (ENXIO);
        !           412:        }
        !           413:
        !           414:        /*
        !           415:         * Older (rev 8.02) boards report wrong offset values,
        !           416:         * similar to the displayable area size, at least in m68k mode.
        !           417:         * Attempt to detect this and adjust here.
        !           418:         */
        !           419:        if (cfg.owidth == cfg.width &&
        !           420:            cfg.oheight == cfg.height)
        !           421:                geometry_kluge = 1;
        !           422:
        !           423:        if (geometry_kluge) {
        !           424:                scr->scr_cfg.oscr_width = cfg.owidth =
        !           425:                    cfg.fbwidth - cfg.width;
        !           426:                scr->scr_cfg.oscr_height = cfg.oheight =
        !           427:                    cfg.fbheight - cfg.height;
        !           428:        }
        !           429:
        !           430:        /*
        !           431:         * Save a few fields for sti_describe() later
        !           432:         */
        !           433:        scr->fbheight = cfg.fbheight;
        !           434:        scr->fbwidth = cfg.fbwidth;
        !           435:        scr->oheight = cfg.oheight;
        !           436:        scr->owidth = cfg.owidth;
        !           437:        bcopy(cfg.name, scr->name, sizeof(scr->name));
        !           438:
        !           439:        if ((error = sti_init(scr, STI_TEXTMODE))) {
        !           440:                printf(": can not initialize (%d)\n", error);
        !           441:                /* XXX free resources */
        !           442:                return (ENXIO);
        !           443:        }
        !           444:
        !           445: #ifdef STIDEBUG
        !           446:        printf("conf: bpp=%d planes=%d attr=%b\n"
        !           447:            "crt=0x%x:0x%x:0x%x hw=0x%x:0x%x:0x%x\n", cfg.bpp,
        !           448:            cfg.planes, cfg.attributes, STI_INQCONF_BITS,
        !           449:            ecfg.crt_config[0], ecfg.crt_config[1], ecfg.crt_config[2],
        !           450:            ecfg.crt_hw[0], ecfg.crt_hw[1], ecfg.crt_hw[2]);
        !           451: #endif
        !           452:        scr->scr_bpp = cfg.bppu;
        !           453:
        !           454:        if ((error = sti_fetchfonts(scr, &cfg, dd->dd_fntaddr))) {
        !           455:                printf(": cannot fetch fonts (%d)\n", error);
        !           456:                /* XXX free resources */
        !           457:                return (ENXIO);
        !           458:        }
        !           459:
        !           460:        /*
        !           461:         * setup screen descriptions:
        !           462:         *      figure number of fonts supported;
        !           463:         *      allocate wscons structures;
        !           464:         *      calculate dimensions.
        !           465:         */
        !           466:
        !           467:        strlcpy(scr->scr_wsd.name, "std", sizeof(scr->scr_wsd.name));
        !           468:        scr->scr_wsd.ncols = cfg.width / scr->scr_curfont.width;
        !           469:        scr->scr_wsd.nrows = cfg.height / scr->scr_curfont.height;
        !           470:        scr->scr_wsd.textops = &sti_emulops;
        !           471:        scr->scr_wsd.fontwidth = scr->scr_curfont.width;
        !           472:        scr->scr_wsd.fontheight = scr->scr_curfont.height;
        !           473:        scr->scr_wsd.capabilities = 0;
        !           474:
        !           475:        scr->scr_scrlist[0] = &scr->scr_wsd;
        !           476:        scr->scr_screenlist.nscreens = 1;
        !           477:        scr->scr_screenlist.screens =
        !           478:            (const struct wsscreen_descr **)scr->scr_scrlist;
        !           479:
        !           480:        /* { extern int pmapdebug; pmapdebug = 0; } */
        !           481:
        !           482:        return (0);
        !           483: }
        !           484:
        !           485: void
        !           486: sti_describe(struct sti_softc *sc)
        !           487: {
        !           488:        struct sti_screen *scr = sc->sc_scr;
        !           489:        struct sti_dd *dd = &scr->scr_dd;
        !           490:        struct sti_font *fp = &scr->scr_curfont;
        !           491:
        !           492:        printf(": %s rev %d.%02d;%d, ID 0x%016llX\n",
        !           493:            scr->name, dd->dd_grrev >> 4, dd->dd_grrev & 0xf,
        !           494:            dd->dd_lrrev, *(u_int64_t *)dd->dd_grid);
        !           495:
        !           496:        printf("%s: %dx%d frame buffer, %dx%dx%d display, offset %dx%d\n",
        !           497:            sc->sc_dev.dv_xname, scr->fbwidth, scr->fbheight,
        !           498:            scr->scr_cfg.scr_width, scr->scr_cfg.scr_height, scr->scr_bpp,
        !           499:            scr->owidth, scr->oheight);
        !           500:
        !           501:        printf("%s: %dx%d font type %d, %d bpc, charset %d-%d\n",
        !           502:            sc->sc_dev.dv_xname, fp->width, fp->height,
        !           503:            fp->type, fp->bpc, fp->first, fp->last);
        !           504: }
        !           505:
        !           506: void
        !           507: sti_end_attach(void *v)
        !           508: {
        !           509:        struct sti_softc *sc = v;
        !           510:        struct wsemuldisplaydev_attach_args waa;
        !           511:
        !           512:        sc->sc_wsmode = WSDISPLAYIO_MODE_EMUL;
        !           513:
        !           514:        waa.console = sc->sc_flags & STI_CONSOLE ? 1 : 0;
        !           515:        waa.scrdata = &sc->sc_scr->scr_screenlist;
        !           516:        waa.accessops = &sti_accessops;
        !           517:        waa.accesscookie = sc;
        !           518:        waa.defaultscreens = 0;
        !           519:
        !           520:        /* attach as console if required */
        !           521:        if (waa.console && !ISSET(sc->sc_flags, STI_ATTACHED)) {
        !           522:                long defattr;
        !           523:
        !           524:                sti_alloc_attr(sc, 0, 0, 0, &defattr);
        !           525:                wsdisplay_cnattach(&sc->sc_scr->scr_wsd, sc->sc_scr,
        !           526:                    0, sc->sc_scr->scr_wsd.nrows - 1, defattr);
        !           527:                sc->sc_flags |= STI_ATTACHED;
        !           528:        }
        !           529:
        !           530:        config_found(&sc->sc_dev, &waa, wsemuldisplaydevprint);
        !           531: }
        !           532:
        !           533: u_int
        !           534: sti_rom_size(bus_space_tag_t iot, bus_space_handle_t ioh)
        !           535: {
        !           536:        int devtype;
        !           537:        u_int romend;
        !           538:
        !           539:        devtype = bus_space_read_1(iot, ioh, 3);
        !           540:        if (devtype == STI_DEVTYPE4) {
        !           541:                bus_space_read_raw_region_4(iot, ioh, 0x18,
        !           542:                    (u_int8_t *)&romend, 4);
        !           543:        } else {
        !           544:                romend =
        !           545:                    (bus_space_read_1(iot, ioh, 0x50 +  3) << 24) |
        !           546:                    (bus_space_read_1(iot, ioh, 0x50 +  7) << 16) |
        !           547:                    (bus_space_read_1(iot, ioh, 0x50 + 11) <<  8) |
        !           548:                    (bus_space_read_1(iot, ioh, 0x50 + 15));
        !           549:        }
        !           550:
        !           551:        return (round_page(romend));
        !           552: }
        !           553:
        !           554: int
        !           555: sti_fetchfonts(struct sti_screen *scr, struct sti_inqconfout *cfg,
        !           556:     u_int32_t addr)
        !           557: {
        !           558:        struct sti_font *fp = &scr->scr_curfont;
        !           559:        int size;
        !           560:        bus_space_tag_t memt;
        !           561:        bus_space_handle_t romh;
        !           562: #ifdef notyet
        !           563:        int uc;
        !           564:        struct {
        !           565:                struct sti_unpmvflags flags;
        !           566:                struct sti_unpmvin in;
        !           567:                struct sti_unpmvout out;
        !           568:        } a;
        !           569: #endif
        !           570:
        !           571:        memt = scr->memt;
        !           572:        romh = scr->romh;
        !           573:
        !           574:        /*
        !           575:         * Get the first PROM font in memory
        !           576:         */
        !           577:
        !           578:        STI_ENABLE_ROM(scr->scr_main);
        !           579:
        !           580:        do {
        !           581:                if (scr->scr_devtype == STI_DEVTYPE1) {
        !           582:                        fp->first  = parseshort(addr + 0x00);
        !           583:                        fp->last   = parseshort(addr + 0x08);
        !           584:                        fp->width  = bus_space_read_1(memt, romh,
        !           585:                            addr + 0x13);
        !           586:                        fp->height = bus_space_read_1(memt, romh,
        !           587:                            addr + 0x17);
        !           588:                        fp->type   = bus_space_read_1(memt, romh,
        !           589:                            addr + 0x1b);
        !           590:                        fp->bpc    = bus_space_read_1(memt, romh,
        !           591:                            addr + 0x1f);
        !           592:                        fp->next   = parseword(addr + 0x23);
        !           593:                        fp->uheight= bus_space_read_1(memt, romh,
        !           594:                            addr + 0x33);
        !           595:                        fp->uoffset= bus_space_read_1(memt, romh,
        !           596:                            addr + 0x37);
        !           597:                } else  /* STI_DEVTYPE4 */
        !           598:                        bus_space_read_raw_region_4(memt, romh, addr,
        !           599:                            (u_int8_t *)fp, sizeof(struct sti_font));
        !           600:
        !           601:                size = sizeof(struct sti_font) +
        !           602:                    (fp->last - fp->first + 1) * fp->bpc;
        !           603:                if (scr->scr_devtype == STI_DEVTYPE1)
        !           604:                        size *= 4;
        !           605:                scr->scr_romfont = malloc(size, M_DEVBUF, M_NOWAIT);
        !           606:                if (scr->scr_romfont == NULL)
        !           607:                        return (ENOMEM);
        !           608:
        !           609:                bus_space_read_raw_region_4(memt, romh, addr,
        !           610:                    (u_int8_t *)scr->scr_romfont, size);
        !           611:
        !           612:                addr = NULL; /* fp->next */
        !           613:        } while (addr);
        !           614:
        !           615:        STI_DISABLE_ROM(scr->scr_main);
        !           616:
        !           617: #ifdef notyet
        !           618:        /*
        !           619:         * If there is enough room in the off-screen framebuffer memory,
        !           620:         * display all the characters there in order to display them
        !           621:         * faster with blkmv operations rather than unpmv later on.
        !           622:         */
        !           623:        if (size <= cfg->fbheight *
        !           624:            (cfg->fbwidth - cfg->width - cfg->owidth)) {
        !           625:                bzero(&a, sizeof(a));
        !           626:                a.flags.flags = STI_UNPMVF_WAIT;
        !           627:                a.in.fg_colour = STI_COLOUR_WHITE;
        !           628:                a.in.bg_colour = STI_COLOUR_BLACK;
        !           629:                a.in.font_addr = scr->scr_romfont;
        !           630:
        !           631:                scr->scr_fontmaxcol = cfg->fbheight / fp->height;
        !           632:                scr->scr_fontbase = cfg->width + cfg->owidth;
        !           633:                for (uc = fp->first; uc <= fp->last; uc++) {
        !           634:                        a.in.x = ((uc - fp->first) / scr->scr_fontmaxcol) *
        !           635:                            fp->width + scr->scr_fontbase;
        !           636:                        a.in.y = ((uc - fp->first) % scr->scr_fontmaxcol) *
        !           637:                            fp->height;
        !           638:                        a.in.index = uc;
        !           639:
        !           640:                        (*scr->unpmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg);
        !           641:                        if (a.out.errno) {
        !           642: #ifdef STIDEBUG
        !           643:                                printf("sti_unpmv %d returned %d\n",
        !           644:                                    uc, a.out.errno);
        !           645: #endif
        !           646:                                return (0);
        !           647:                        }
        !           648:                }
        !           649:
        !           650:                free(scr->scr_romfont, M_DEVBUF);
        !           651:                scr->scr_romfont = NULL;
        !           652:        }
        !           653: #endif
        !           654:
        !           655:        return (0);
        !           656: }
        !           657:
        !           658: int
        !           659: sti_init(scr, mode)
        !           660:        struct sti_screen *scr;
        !           661:        int mode;
        !           662: {
        !           663:        struct {
        !           664:                struct sti_initflags flags;
        !           665:                struct sti_initin in;
        !           666:                struct sti_einitin ein;
        !           667:                struct sti_initout out;
        !           668:        } a;
        !           669:
        !           670:        bzero(&a, sizeof(a));
        !           671:
        !           672:        a.flags.flags = STI_INITF_WAIT | STI_INITF_CMB | STI_INITF_EBET |
        !           673:            (mode & STI_TEXTMODE? STI_INITF_TEXT | STI_INITF_PBET |
        !           674:             STI_INITF_PBETI | STI_INITF_ICMT : 0);
        !           675:        a.in.text_planes = 1;
        !           676:        a.in.ext_in = &a.ein;
        !           677: #ifdef STIDEBUG
        !           678:        printf("sti_init,%p(%x, %p, %p, %p)\n",
        !           679:            scr->init, a.flags.flags, &a.in, &a.out, &scr->scr_cfg);
        !           680: #endif
        !           681:        (*scr->init)(&a.flags, &a.in, &a.out, &scr->scr_cfg);
        !           682:        if (a.out.text_planes != a.in.text_planes)
        !           683:                return (-1);    /* not colliding with sti errno values */
        !           684:        return (a.out.errno);
        !           685: }
        !           686:
        !           687: int
        !           688: sti_inqcfg(struct sti_screen *scr, struct sti_inqconfout *out)
        !           689: {
        !           690:        struct {
        !           691:                struct sti_inqconfflags flags;
        !           692:                struct sti_inqconfin in;
        !           693:        } a;
        !           694:
        !           695:        bzero(&a, sizeof(a));
        !           696:
        !           697:        a.flags.flags = STI_INQCONFF_WAIT;
        !           698:        (*scr->inqconf)(&a.flags, &a.in, out, &scr->scr_cfg);
        !           699:
        !           700:        return out->errno;
        !           701: }
        !           702:
        !           703: void
        !           704: sti_bmove(scr, x1, y1, x2, y2, h, w, f)
        !           705:        struct sti_screen *scr;
        !           706:        int x1, y1, x2, y2, h, w;
        !           707:        enum sti_bmove_funcs f;
        !           708: {
        !           709:        struct {
        !           710:                struct sti_blkmvflags flags;
        !           711:                struct sti_blkmvin in;
        !           712:                struct sti_blkmvout out;
        !           713:        } a;
        !           714:
        !           715:        bzero(&a, sizeof(a));
        !           716:
        !           717:        a.flags.flags = STI_BLKMVF_WAIT;
        !           718:        switch (f) {
        !           719:        case bmf_clear:
        !           720:                a.flags.flags |= STI_BLKMVF_CLR;
        !           721:                a.in.bg_colour = STI_COLOUR_BLACK;
        !           722:                break;
        !           723:        case bmf_underline:
        !           724:        case bmf_copy:
        !           725:                a.in.fg_colour = STI_COLOUR_WHITE;
        !           726:                a.in.bg_colour = STI_COLOUR_BLACK;
        !           727:                break;
        !           728:        case bmf_invert:
        !           729:                a.flags.flags |= STI_BLKMVF_COLR;
        !           730:                a.in.fg_colour = STI_COLOUR_BLACK;
        !           731:                a.in.bg_colour = STI_COLOUR_WHITE;
        !           732:                break;
        !           733:        }
        !           734:        a.in.srcx = x1;
        !           735:        a.in.srcy = y1;
        !           736:        a.in.dstx = x2;
        !           737:        a.in.dsty = y2;
        !           738:        a.in.height = h;
        !           739:        a.in.width = w;
        !           740:
        !           741:        (*scr->blkmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg);
        !           742: #ifdef STIDEBUG
        !           743:        if (a.out.errno)
        !           744:                printf("sti_blkmv returned %d\n", a.out.errno);
        !           745: #endif
        !           746: }
        !           747:
        !           748: int
        !           749: sti_setcment(struct sti_screen *scr, u_int i, u_char r, u_char g, u_char b)
        !           750: {
        !           751:        struct {
        !           752:                struct sti_scmentflags flags;
        !           753:                struct sti_scmentin in;
        !           754:                struct sti_scmentout out;
        !           755:        } a;
        !           756:
        !           757:        bzero(&a, sizeof(a));
        !           758:
        !           759:        a.flags.flags = STI_SCMENTF_WAIT;
        !           760:        a.in.entry = i;
        !           761:        a.in.value = (r << 16) | (g << 8) | b;
        !           762:
        !           763:        (*scr->scment)(&a.flags, &a.in, &a.out, &scr->scr_cfg);
        !           764:
        !           765:        return a.out.errno;
        !           766: }
        !           767:
        !           768: int
        !           769: sti_ioctl(v, cmd, data, flag, p)
        !           770:        void *v;
        !           771:        u_long cmd;
        !           772:        caddr_t data;
        !           773:        int flag;
        !           774:        struct proc *p;
        !           775: {
        !           776:        struct sti_softc *sc = v;
        !           777:        struct sti_screen *scr = sc->sc_scr;
        !           778:        struct wsdisplay_fbinfo *wdf;
        !           779:        struct wsdisplay_cmap *cmapp;
        !           780:        u_int mode, idx, count;
        !           781:        int i, ret;
        !           782:
        !           783:        ret = 0;
        !           784:        switch (cmd) {
        !           785:        case WSDISPLAYIO_GMODE:
        !           786:                *(u_int *)data = sc->sc_wsmode;
        !           787:                break;
        !           788:
        !           789:        case WSDISPLAYIO_SMODE:
        !           790:                mode = *(u_int *)data;
        !           791:                if (sc->sc_wsmode == WSDISPLAYIO_MODE_EMUL &&
        !           792:                    mode == WSDISPLAYIO_MODE_DUMBFB)
        !           793:                        ret = sti_init(scr, 0);
        !           794:                else if (sc->sc_wsmode == WSDISPLAYIO_MODE_DUMBFB &&
        !           795:                    mode == WSDISPLAYIO_MODE_EMUL)
        !           796:                        ret = sti_init(scr, STI_TEXTMODE);
        !           797:                sc->sc_wsmode = mode;
        !           798:                break;
        !           799:
        !           800:        case WSDISPLAYIO_GTYPE:
        !           801:                *(u_int *)data = WSDISPLAY_TYPE_STI;
        !           802:                break;
        !           803:
        !           804:        case WSDISPLAYIO_GINFO:
        !           805:                wdf = (struct wsdisplay_fbinfo *)data;
        !           806:                wdf->height = scr->scr_cfg.scr_height;
        !           807:                wdf->width  = scr->scr_cfg.scr_width;
        !           808:                wdf->depth  = scr->scr_bpp;
        !           809:                if (scr->scment == NULL)
        !           810:                        wdf->cmsize = 0;
        !           811:                else
        !           812:                        wdf->cmsize = STI_NCMAP;
        !           813:                break;
        !           814:
        !           815:        case WSDISPLAYIO_LINEBYTES:
        !           816:                *(u_int *)data = scr->scr_cfg.fb_width;
        !           817:                break;
        !           818:
        !           819:        case WSDISPLAYIO_GETCMAP:
        !           820:                if (scr->scment == NULL)
        !           821:                        return ENODEV;
        !           822:                cmapp = (struct wsdisplay_cmap *)data;
        !           823:                idx = cmapp->index;
        !           824:                count = cmapp->count;
        !           825:                if (idx >= STI_NCMAP || idx + count > STI_NCMAP)
        !           826:                        return EINVAL;
        !           827:                if ((ret = copyout(&scr->scr_rcmap[idx], cmapp->red, count)))
        !           828:                        break;
        !           829:                if ((ret = copyout(&scr->scr_gcmap[idx], cmapp->green, count)))
        !           830:                        break;
        !           831:                if ((ret = copyout(&scr->scr_bcmap[idx], cmapp->blue, count)))
        !           832:                        break;
        !           833:                break;
        !           834:
        !           835:        case WSDISPLAYIO_PUTCMAP:
        !           836:                if (scr->scment == NULL)
        !           837:                        return ENODEV;
        !           838:                cmapp = (struct wsdisplay_cmap *)data;
        !           839:                idx = cmapp->index;
        !           840:                count = cmapp->count;
        !           841:                if (idx >= STI_NCMAP || idx + count > STI_NCMAP)
        !           842:                        return EINVAL;
        !           843:                if ((ret = copyin(cmapp->red, &scr->scr_rcmap[idx], count)))
        !           844:                        break;
        !           845:                if ((ret = copyin(cmapp->green, &scr->scr_gcmap[idx], count)))
        !           846:                        break;
        !           847:                if ((ret = copyin(cmapp->blue, &scr->scr_bcmap[idx], count)))
        !           848:                        break;
        !           849:                for (i = idx + count - 1; i >= idx; i--)
        !           850:                        if ((ret = sti_setcment(scr, i, scr->scr_rcmap[i],
        !           851:                            scr->scr_gcmap[i], scr->scr_bcmap[i]))) {
        !           852: #ifdef STIDEBUG
        !           853:                                printf("sti_ioctl: "
        !           854:                                    "sti_setcment(%d, %u, %u, %u): %d\n", i,
        !           855:                                    (u_int)scr->scr_rcmap[i],
        !           856:                                    (u_int)scr->scr_gcmap[i],
        !           857:                                    (u_int)scr->scr_bcmap[i]);
        !           858: #endif
        !           859:                                ret = EINVAL;
        !           860:                                break;
        !           861:                        }
        !           862:                break;
        !           863:
        !           864:        case WSDISPLAYIO_SVIDEO:
        !           865:        case WSDISPLAYIO_GVIDEO:
        !           866:                break;
        !           867:
        !           868:        case WSDISPLAYIO_GCURPOS:
        !           869:        case WSDISPLAYIO_SCURPOS:
        !           870:        case WSDISPLAYIO_GCURMAX:
        !           871:        case WSDISPLAYIO_GCURSOR:
        !           872:        case WSDISPLAYIO_SCURSOR:
        !           873:        default:
        !           874:                return (-1);            /* not supported yet */
        !           875:        }
        !           876:
        !           877:        return (ret);
        !           878: }
        !           879:
        !           880: paddr_t
        !           881: sti_mmap(v, offset, prot)
        !           882:        void *v;
        !           883:        off_t offset;
        !           884:        int prot;
        !           885: {
        !           886:        /* XXX not finished */
        !           887:        return -1;
        !           888: }
        !           889:
        !           890: int
        !           891: sti_alloc_screen(v, type, cookiep, cxp, cyp, defattr)
        !           892:        void *v;
        !           893:        const struct wsscreen_descr *type;
        !           894:        void **cookiep;
        !           895:        int *cxp, *cyp;
        !           896:        long *defattr;
        !           897: {
        !           898:        struct sti_softc *sc = v;
        !           899:
        !           900:        if (sc->sc_nscreens > 0)
        !           901:                return ENOMEM;
        !           902:
        !           903:        *cookiep = sc->sc_scr;
        !           904:        *cxp = 0;
        !           905:        *cyp = 0;
        !           906:        sti_alloc_attr(sc, 0, 0, 0, defattr);
        !           907:        sc->sc_nscreens++;
        !           908:        return 0;
        !           909: }
        !           910:
        !           911: void
        !           912: sti_free_screen(v, cookie)
        !           913:        void *v;
        !           914:        void *cookie;
        !           915: {
        !           916:        struct sti_softc *sc = v;
        !           917:
        !           918:        sc->sc_nscreens--;
        !           919: }
        !           920:
        !           921: int
        !           922: sti_show_screen(v, cookie, waitok, cb, cbarg)
        !           923:        void *v;
        !           924:        void *cookie;
        !           925:        int waitok;
        !           926:        void (*cb)(void *, int, int);
        !           927:        void *cbarg;
        !           928: {
        !           929:        return 0;
        !           930: }
        !           931:
        !           932: int
        !           933: sti_load_font(v, cookie, font)
        !           934:        void *v;
        !           935:        void *cookie;
        !           936:        struct wsdisplay_font *font;
        !           937: {
        !           938:        return -1;
        !           939: }
        !           940:
        !           941: void
        !           942: sti_cursor(v, on, row, col)
        !           943:        void *v;
        !           944:        int on, row, col;
        !           945: {
        !           946:        struct sti_screen *scr = v;
        !           947:        struct sti_font *fp = &scr->scr_curfont;
        !           948:
        !           949:        sti_bmove(scr,
        !           950:            col * fp->width, row * fp->height,
        !           951:            col * fp->width, row * fp->height,
        !           952:            fp->height, fp->width, bmf_invert);
        !           953: }
        !           954:
        !           955: /*
        !           956:  * ISO 8859-1 part of Unicode to HP Roman font index conversion array.
        !           957:  */
        !           958: static const u_int8_t
        !           959: sti_unitoroman[0x100 - 0xa0] = {
        !           960:        0xa0, 0xb8, 0xbf, 0xbb, 0xba, 0xbc,    0, 0xbd,
        !           961:        0xab,    0, 0xf9, 0xfb,    0, 0xf6,    0, 0xb0,
        !           962:
        !           963:        0xb3, 0xfe,    0,    0, 0xa8, 0xf3, 0xf4, 0xf2,
        !           964:           0,    0, 0xfa, 0xfd, 0xf7, 0xf8,    0, 0xb9,
        !           965:
        !           966:        0xa1, 0xe0, 0xa2, 0xe1, 0xd8, 0xd0, 0xd3, 0xb4,
        !           967:        0xa3, 0xdc, 0xa4, 0xa5, 0xe6, 0xe5, 0xa6, 0xa7,
        !           968:
        !           969:        0xe3, 0xb6, 0xe8, 0xe7, 0xdf, 0xe9, 0xda,    0,
        !           970:        0xd2, 0xad, 0xed, 0xae, 0xdb, 0xb1, 0xf0, 0xde,
        !           971:
        !           972:        0xc8, 0xc4, 0xc0, 0xe2, 0xcc, 0xd4, 0xd7, 0xb5,
        !           973:        0xc9, 0xc5, 0xc1, 0xcd, 0xd9, 0xd5, 0xd1, 0xdd,
        !           974:
        !           975:        0xe4, 0xb7, 0xca, 0xc6, 0xc2, 0xea, 0xce,    0,
        !           976:        0xd6, 0xcb, 0xc7, 0xc3, 0xcf, 0xb2, 0xf1, 0xef
        !           977: };
        !           978:
        !           979: int
        !           980: sti_mapchar(v, uni, index)
        !           981:        void *v;
        !           982:        int uni;
        !           983:        u_int *index;
        !           984: {
        !           985:        struct sti_screen *scr = v;
        !           986:        struct sti_font *fp = &scr->scr_curfont;
        !           987:        int c;
        !           988:
        !           989:        switch (fp->type) {
        !           990:        case STI_FONT_HPROMAN8:
        !           991:                if (uni >= 0x80 && uni < 0xa0)
        !           992:                        c = -1;
        !           993:                else if (uni >= 0xa0 && uni < 0x100) {
        !           994:                        c = (int)sti_unitoroman[uni - 0xa0];
        !           995:                        if (c == 0)
        !           996:                                c = -1;
        !           997:                } else
        !           998:                        c = uni;
        !           999:                break;
        !          1000:        default:
        !          1001:                c = uni;
        !          1002:                break;
        !          1003:        }
        !          1004:
        !          1005:        if (c == -1 || c < fp->first || c > fp->last) {
        !          1006:                *index = ' ';
        !          1007:                return (0);
        !          1008:        }
        !          1009:
        !          1010:        *index = c;
        !          1011:        return (5);
        !          1012: }
        !          1013:
        !          1014: void
        !          1015: sti_putchar(v, row, col, uc, attr)
        !          1016:        void *v;
        !          1017:        int row, col;
        !          1018:        u_int uc;
        !          1019:        long attr;
        !          1020: {
        !          1021:        struct sti_screen *scr = v;
        !          1022:        struct sti_font *fp = &scr->scr_curfont;
        !          1023:
        !          1024:        if (scr->scr_romfont != NULL) {
        !          1025:                /*
        !          1026:                 * Font is in memory, use unpmv
        !          1027:                 */
        !          1028:                struct {
        !          1029:                        struct sti_unpmvflags flags;
        !          1030:                        struct sti_unpmvin in;
        !          1031:                        struct sti_unpmvout out;
        !          1032:                } a;
        !          1033:
        !          1034:                bzero(&a, sizeof(a));
        !          1035:
        !          1036:                a.flags.flags = STI_UNPMVF_WAIT;
        !          1037:                /* XXX does not handle text attributes */
        !          1038:                a.in.fg_colour = STI_COLOUR_WHITE;
        !          1039:                a.in.bg_colour = STI_COLOUR_BLACK;
        !          1040:                a.in.x = col * fp->width;
        !          1041:                a.in.y = row * fp->height;
        !          1042:                a.in.font_addr = scr->scr_romfont;
        !          1043:                a.in.index = uc;
        !          1044:
        !          1045:                (*scr->unpmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg);
        !          1046:        } else {
        !          1047:                /*
        !          1048:                 * Font is in frame buffer, use blkmv
        !          1049:                 */
        !          1050:                struct {
        !          1051:                        struct sti_blkmvflags flags;
        !          1052:                        struct sti_blkmvin in;
        !          1053:                        struct sti_blkmvout out;
        !          1054:                } a;
        !          1055:
        !          1056:                bzero(&a, sizeof(a));
        !          1057:
        !          1058:                a.flags.flags = STI_BLKMVF_WAIT;
        !          1059:                /* XXX does not handle text attributes */
        !          1060:                a.in.fg_colour = STI_COLOUR_WHITE;
        !          1061:                a.in.bg_colour = STI_COLOUR_BLACK;
        !          1062:
        !          1063:                a.in.srcx = ((uc - fp->first) / scr->scr_fontmaxcol) *
        !          1064:                    fp->width + scr->scr_fontbase;
        !          1065:                a.in.srcy = ((uc - fp->first) % scr->scr_fontmaxcol) *
        !          1066:                    fp->height;
        !          1067:                a.in.dstx = col * fp->width;
        !          1068:                a.in.dsty = row * fp->height;
        !          1069:                a.in.height = fp->height;
        !          1070:                a.in.width = fp->width;
        !          1071:
        !          1072:                (*scr->blkmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg);
        !          1073:        }
        !          1074: }
        !          1075:
        !          1076: void
        !          1077: sti_copycols(v, row, srccol, dstcol, ncols)
        !          1078:        void *v;
        !          1079:        int row, srccol, dstcol, ncols;
        !          1080: {
        !          1081:        struct sti_screen *scr = v;
        !          1082:        struct sti_font *fp = &scr->scr_curfont;
        !          1083:
        !          1084:        sti_bmove(scr,
        !          1085:            srccol * fp->width, row * fp->height,
        !          1086:            dstcol * fp->width, row * fp->height,
        !          1087:            fp->height, ncols * fp->width, bmf_copy);
        !          1088: }
        !          1089:
        !          1090: void
        !          1091: sti_erasecols(v, row, startcol, ncols, attr)
        !          1092:        void *v;
        !          1093:        int row, startcol, ncols;
        !          1094:        long attr;
        !          1095: {
        !          1096:        struct sti_screen *scr = v;
        !          1097:        struct sti_font *fp = &scr->scr_curfont;
        !          1098:
        !          1099:        sti_bmove(scr,
        !          1100:            startcol * fp->width, row * fp->height,
        !          1101:            startcol * fp->width, row * fp->height,
        !          1102:            fp->height, ncols * fp->width, bmf_clear);
        !          1103: }
        !          1104:
        !          1105: void
        !          1106: sti_copyrows(v, srcrow, dstrow, nrows)
        !          1107:        void *v;
        !          1108:        int srcrow, dstrow, nrows;
        !          1109: {
        !          1110:        struct sti_screen *scr = v;
        !          1111:        struct sti_font *fp = &scr->scr_curfont;
        !          1112:
        !          1113:        sti_bmove(scr, 0, srcrow * fp->height, 0, dstrow * fp->height,
        !          1114:            nrows * fp->height, scr->scr_cfg.scr_width, bmf_copy);
        !          1115: }
        !          1116:
        !          1117: void
        !          1118: sti_eraserows(v, srcrow, nrows, attr)
        !          1119:        void *v;
        !          1120:        int srcrow, nrows;
        !          1121:        long attr;
        !          1122: {
        !          1123:        struct sti_screen *scr = v;
        !          1124:        struct sti_font *fp = &scr->scr_curfont;
        !          1125:
        !          1126:        sti_bmove(scr, 0, srcrow * fp->height, 0, srcrow * fp->height,
        !          1127:            nrows * fp->height, scr->scr_cfg.scr_width, bmf_clear);
        !          1128: }
        !          1129:
        !          1130: int
        !          1131: sti_alloc_attr(v, fg, bg, flags, pattr)
        !          1132:        void *v;
        !          1133:        int fg, bg, flags;
        !          1134:        long *pattr;
        !          1135: {
        !          1136:        /* struct sti_screen *scr = v; */
        !          1137:
        !          1138:        *pattr = 0;
        !          1139:
        !          1140:        return 0;
        !          1141: }
        !          1142:
        !          1143: void
        !          1144: sti_unpack_attr(void *v, long attr, int *fg, int *bg, int *ul)
        !          1145: {
        !          1146:        *fg = WSCOL_WHITE;
        !          1147:        *bg = WSCOL_BLACK;
        !          1148:        if (ul != NULL)
        !          1149:                *ul = 0;
        !          1150: }
        !          1151:
        !          1152: #if NSTI_SGC > 0
        !          1153:
        !          1154: /*
        !          1155:  * Early console support
        !          1156:  */
        !          1157:
        !          1158: void
        !          1159: sti_clear(struct sti_screen *scr)
        !          1160: {
        !          1161:        sti_bmove(scr, 0, 0, 0, 0,
        !          1162:            scr->scr_cfg.scr_height, scr->scr_cfg.scr_width, bmf_clear);
        !          1163: }
        !          1164:
        !          1165: int
        !          1166: sti_cnattach(struct sti_screen *scr, bus_space_tag_t iot, bus_addr_t *bases,
        !          1167:     u_int codebase)
        !          1168: {
        !          1169:        bus_space_handle_t ioh;
        !          1170:        u_int romend;
        !          1171:        int error;
        !          1172:        long defattr;
        !          1173:
        !          1174:        if ((error = bus_space_map(iot, bases[0], PAGE_SIZE, 0, &ioh)) != 0)
        !          1175:                return (error);
        !          1176:
        !          1177:        /*
        !          1178:         * Compute real PROM size
        !          1179:         */
        !          1180:        romend = sti_rom_size(iot, ioh);
        !          1181:
        !          1182:        bus_space_unmap(iot, ioh, PAGE_SIZE);
        !          1183:
        !          1184:        if ((error = bus_space_map(iot, bases[0], romend, 0, &ioh)) != 0)
        !          1185:                return (error);
        !          1186:
        !          1187:        bases[0] = ioh;
        !          1188:        if (sti_screen_setup(scr, iot, iot, ioh, bases, codebase) != 0)
        !          1189:                panic(__func__);
        !          1190:
        !          1191:        sti_alloc_attr(scr, 0, 0, 0, &defattr);
        !          1192:        wsdisplay_cnattach(&scr->scr_wsd, scr, 0, 0, defattr);
        !          1193:
        !          1194:        return (0);
        !          1195: }
        !          1196:
        !          1197: #endif /* NSTI_SGC > 0 */

CVSweb