[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

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