sti.c revision 1.31
1/* $OpenBSD: sti.c,v 1.31 2003/08/19 02:52:38 mickey 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 "wsdisplay.h" 36 37#include <sys/param.h> 38#include <sys/systm.h> 39#include <sys/device.h> 40#include <sys/malloc.h> 41 42#include <uvm/uvm.h> 43 44#include <machine/bus.h> 45 46#include <dev/wscons/wsdisplayvar.h> 47#include <dev/wscons/wsconsio.h> 48 49#include <dev/ic/stireg.h> 50#include <dev/ic/stivar.h> 51 52struct cfdriver sti_cd = { 53 NULL, "sti", DV_DULL 54}; 55 56void sti_cursor(void *v, int on, int row, int col); 57int sti_mapchar(void *v, int uni, u_int *index); 58void sti_putchar(void *v, int row, int col, u_int uc, long attr); 59void sti_copycols(void *v, int row, int srccol, int dstcol, int ncols); 60void sti_erasecols(void *v, int row, int startcol, int ncols, long attr); 61void sti_copyrows(void *v, int srcrow, int dstrow, int nrows); 62void sti_eraserows(void *v, int row, int nrows, long attr); 63int sti_alloc_attr(void *v, int fg, int bg, int flags, long *); 64 65struct wsdisplay_emulops sti_emulops = { 66 sti_cursor, 67 sti_mapchar, 68 sti_putchar, 69 sti_copycols, 70 sti_erasecols, 71 sti_copyrows, 72 sti_eraserows, 73 sti_alloc_attr 74}; 75 76int sti_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p); 77paddr_t sti_mmap(void *v, off_t offset, int prot); 78int sti_alloc_screen(void *v, const struct wsscreen_descr *type, 79 void **cookiep, int *cxp, int *cyp, long *defattr); 80 void sti_free_screen(void *v, void *cookie); 81int sti_show_screen(void *v, void *cookie, int waitok, 82 void (*cb)(void *, int, int), void *cbarg); 83int sti_load_font(void *v, void *cookie, struct wsdisplay_font *); 84 85const struct wsdisplay_accessops sti_accessops = { 86 sti_ioctl, 87 sti_mmap, 88 sti_alloc_screen, 89 sti_free_screen, 90 sti_show_screen, 91 sti_load_font 92}; 93 94struct wsscreen_descr sti_default_screen = { 95 "default", 0, 0, 96 &sti_emulops, 97 0, 0, 98 WSSCREEN_REVERSE | WSSCREEN_UNDERLINE 99}; 100 101const struct wsscreen_descr *sti_default_scrlist[] = { 102 &sti_default_screen 103}; 104 105struct wsscreen_list sti_default_screenlist = { 106 sizeof(sti_default_scrlist) / sizeof(sti_default_scrlist[0]), 107 sti_default_scrlist 108}; 109 110enum sti_bmove_funcs { 111 bmf_clear, bmf_copy, bmf_invert, bmf_underline 112}; 113 114int sti_init(struct sti_softc *sc, int mode); 115int sti_inqcfg(struct sti_softc *sc, struct sti_inqconfout *out); 116void sti_bmove(struct sti_softc *sc, int, int, int, int, int, int, 117 enum sti_bmove_funcs); 118int sti_setcment(struct sti_softc *sc, u_int i, u_char r, u_char g, u_char b); 119int sti_fetchfonts(struct sti_softc *sc, struct sti_inqconfout *cfg, 120 u_int32_t addr); 121void sti_attach_deferred(void *); 122 123void 124sti_attach_common(sc) 125 struct sti_softc *sc; 126{ 127 struct sti_inqconfout cfg; 128 struct sti_einqconfout ecfg; 129 bus_space_handle_t fbh; 130 struct sti_dd *dd; 131 struct sti_cfg *cc; 132 int error, size, i; 133 134 /* { extern int pmapdebug; pmapdebug = 0xfffff; } */ 135 dd = &sc->sc_dd; 136 if (sc->sc_devtype == STI_DEVTYPE1) { 137#define parseshort(o) \ 138 ((bus_space_read_1(sc->memt, sc->romh, (o) + 3) << 8) | \ 139 (bus_space_read_1(sc->memt, sc->romh, (o) + 7))) 140#define parseword(o) \ 141 ((bus_space_read_1(sc->memt, sc->romh, (o) + 3) << 24) | \ 142 (bus_space_read_1(sc->memt, sc->romh, (o) + 7) << 16) | \ 143 (bus_space_read_1(sc->memt, sc->romh, (o) + 11) << 8) | \ 144 (bus_space_read_1(sc->memt, sc->romh, (o) + 15))) 145 146 dd->dd_type = bus_space_read_1(sc->memt, sc->romh, 3); 147 dd->dd_nmon = bus_space_read_1(sc->memt, sc->romh, 7); 148 dd->dd_grrev = bus_space_read_1(sc->memt, sc->romh, 11); 149 dd->dd_lrrev = bus_space_read_1(sc->memt, sc->romh, 15); 150 dd->dd_grid[0] = parseword(0x10); 151 dd->dd_grid[1] = parseword(0x20); 152 dd->dd_fntaddr = parseword(0x30) & ~3; 153 dd->dd_maxst = parseword(0x40); 154 dd->dd_romend = parseword(0x50) & ~3; 155 dd->dd_reglst = parseword(0x60) & ~3; 156 dd->dd_maxreent= parseshort(0x70); 157 dd->dd_maxtimo = parseshort(0x78); 158 /* what happened to 0x80 ? */ 159 dd->dd_montbl = parseword(0x90); 160 dd->dd_udaddr = parseword(0xa0) & ~3; 161 dd->dd_stimemreq=parseword(0xb0); 162 dd->dd_udsize = parseword(0xc0); 163 dd->dd_pwruse = parseshort(0xd0); 164 dd->dd_bussup = bus_space_read_1(sc->memt, sc->romh, 0xdb); 165 dd->dd_ebussup = bus_space_read_1(sc->memt, sc->romh, 0xdf); 166 dd->dd_altcodet= bus_space_read_1(sc->memt, sc->romh, 0xe3); 167 dd->dd_cfbaddr = parseword(0xf0) & ~3; 168 169 dd->dd_pacode[0x0] = parseword(0x100) & ~3; 170 dd->dd_pacode[0x1] = parseword(0x110) & ~3; 171 dd->dd_pacode[0x2] = parseword(0x120) & ~3; 172 dd->dd_pacode[0x3] = parseword(0x130) & ~3; 173 dd->dd_pacode[0x4] = parseword(0x140) & ~3; 174 dd->dd_pacode[0x5] = parseword(0x150) & ~3; 175 dd->dd_pacode[0x6] = parseword(0x160) & ~3; 176 dd->dd_pacode[0x7] = parseword(0x170) & ~3; 177 dd->dd_pacode[0x8] = parseword(0x180) & ~3; 178 dd->dd_pacode[0x9] = parseword(0x190) & ~3; 179 dd->dd_pacode[0xa] = parseword(0x1a0) & ~3; 180 dd->dd_pacode[0xb] = parseword(0x1b0) & ~3; 181 dd->dd_pacode[0xc] = parseword(0x1c0) & ~3; 182 dd->dd_pacode[0xd] = parseword(0x1d0) & ~3; 183 dd->dd_pacode[0xe] = parseword(0x1e0) & ~3; 184 dd->dd_pacode[0xf] = parseword(0x1f0) & ~3; 185 } else /* STI_DEVTYPE4 */ 186 bus_space_read_region_4(sc->memt, sc->romh, 0, (u_int32_t *)dd, 187 sizeof(*dd) / 4); 188 189#ifdef STIDEBUG 190 printf("dd:\n" 191 "devtype=%x, rev=%x;%d, altt=%x, gid=%016llx, font=%x, mss=%x\n" 192 "end=%x, regions=%x, msto=%x, timo=%d, mont=%x, user=%x[%x]\n" 193 "memrq=%x, pwr=%d, bus=%x, ebus=%x, cfb=%x\n" 194 "code=", 195 dd->dd_type & 0xff, dd->dd_grrev, dd->dd_lrrev, dd->dd_altcodet, 196 *(u_int64_t *)dd->dd_grid, dd->dd_fntaddr, dd->dd_maxst, 197 dd->dd_romend, dd->dd_reglst, dd->dd_maxreent, dd->dd_maxtimo, 198 dd->dd_montbl, dd->dd_udaddr, dd->dd_udsize, dd->dd_stimemreq, 199 dd->dd_pwruse, dd->dd_bussup, dd->dd_ebussup, dd->dd_cfbaddr); 200 printf("%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n", 201 dd->dd_pacode[0x0], dd->dd_pacode[0x1], dd->dd_pacode[0x2], 202 dd->dd_pacode[0x3], dd->dd_pacode[0x4], dd->dd_pacode[0x5], 203 dd->dd_pacode[0x6], dd->dd_pacode[0x7], dd->dd_pacode[0x8], 204 dd->dd_pacode[0x9], dd->dd_pacode[0xa], dd->dd_pacode[0xb], 205 dd->dd_pacode[0xc], dd->dd_pacode[0xd], dd->dd_pacode[0xe], 206 dd->dd_pacode[0xf]); 207#endif 208 /* divise code size, could be less than STI_END entries */ 209 for (i = STI_END; !dd->dd_pacode[i]; i--); 210 size = dd->dd_pacode[i] - dd->dd_pacode[STI_BEGIN]; 211 if (sc->sc_devtype == STI_DEVTYPE1) 212 size = (size + 3) / 4; 213 if (!(sc->sc_code = uvm_km_alloc1(kernel_map, round_page(size), 0))) { 214 printf(": cannot allocate %u bytes for code\n", size); 215 return; 216 } 217#ifdef STIDEBUG 218 printf("code=0x%x[%x]\n", sc->sc_code, size); 219#endif 220 221 /* copy code into memory */ 222 if (sc->sc_devtype == STI_DEVTYPE1) { 223 u_int8_t *p = (u_int8_t *)sc->sc_code; 224 u_int32_t addr, eaddr; 225 226 for (addr = dd->dd_pacode[STI_BEGIN], eaddr = addr + size * 4; 227 addr < eaddr; addr += 4 ) 228 *p++ = bus_space_read_4(sc->memt, sc->romh, addr) & 0xff; 229 230 } else /* STI_DEVTYPE4 */ 231 bus_space_read_region_4(sc->memt, sc->romh, 232 dd->dd_pacode[STI_BEGIN], (u_int32_t *)sc->sc_code, 233 size / 4); 234 235#define O(i) (dd->dd_pacode[(i)]? (sc->sc_code + \ 236 (dd->dd_pacode[(i)] - dd->dd_pacode[0]) / \ 237 (sc->sc_devtype == STI_DEVTYPE1? 4 : 1)) : NULL) 238 sc->init = (sti_init_t) O(STI_INIT_GRAPH); 239 sc->mgmt = (sti_mgmt_t) O(STI_STATE_MGMT); 240 sc->unpmv = (sti_unpmv_t) O(STI_FONT_UNPMV); 241 sc->blkmv = (sti_blkmv_t) O(STI_BLOCK_MOVE); 242 sc->test = (sti_test_t) O(STI_SELF_TEST); 243 sc->exhdl = (sti_exhdl_t) O(STI_EXCEP_HDLR); 244 sc->inqconf = (sti_inqconf_t)O(STI_INQ_CONF); 245 sc->scment = (sti_scment_t)O(STI_SCM_ENT); 246 sc->dmac = (sti_dmac_t) O(STI_DMA_CTRL); 247 sc->flowc = (sti_flowc_t) O(STI_FLOW_CTRL); 248 sc->utiming = (sti_utiming_t)O(STI_UTIMING); 249 sc->pmgr = (sti_pmgr_t) O(STI_PROC_MGR); 250 sc->util = (sti_util_t) O(STI_UTIL); 251 252 if ((error = uvm_map_protect(kernel_map, sc->sc_code, 253 sc->sc_code + round_page(size), UVM_PROT_RX, FALSE))) { 254 printf(": uvm_map_protect failed (%d)\n", error); 255 uvm_km_free(kernel_map, sc->sc_code, round_page(size)); 256 return; 257 } 258 259 cc = &sc->sc_cfg; 260 bzero(cc, sizeof (*cc)); 261 { 262 int i = dd->dd_reglst; 263 u_int32_t *p; 264 struct sti_region r; 265 266#ifdef STIDEBUG 267 printf("stiregions @%p:\n", i); 268#endif 269 r.last = 0; 270 for (p = cc->regions; !r.last && 271 p < &cc->regions[STI_REGION_MAX]; p++) { 272 273 if (sc->sc_devtype == STI_DEVTYPE1) 274 *(u_int *)&r = parseword(i), i+= 16; 275 else 276 *(u_int *)&r = bus_space_read_4(sc->memt, sc->romh, i), i += 4; 277 278 *p = (p == cc->regions? sc->romh : sc->ioh) + 279 (r.offset << PGSHIFT); 280#ifdef STIDEBUG 281 printf("%x @ 0x%x%s%s%s%s\n", 282 r.length << PGSHIFT, *p, r.sys_only? " sys" : "", 283 r.cache? " cache" : "", r.btlb? " btlb" : "", 284 r.last? " last" : ""); 285#endif 286 287 /* rom has already been mapped */ 288 if (p != cc->regions) { 289 if (bus_space_map(sc->memt, *p, 290 r.length << PGSHIFT, 0, &fbh)) { 291#ifdef STIDEBUG 292 printf("already mapped region\n"); 293#endif 294 } else if (p - cc->regions == 1) 295 sc->fbh = fbh; 296 } 297 } 298 } 299 300 if ((error = sti_init(sc, 0))) { 301 printf(": can not initialize (%d)\n", error); 302 return; 303 } 304 305 bzero(&cfg, sizeof(cfg)); 306 bzero(&ecfg, sizeof(ecfg)); 307 cfg.ext = &ecfg; 308 if ((error = sti_inqcfg(sc, &cfg))) { 309 printf(": error %d inquiring config\n", error); 310 return; 311 } 312 313 if ((error = sti_init(sc, STI_TEXTMODE))) { 314 printf(": can not initialize (%d)\n", error); 315 return; 316 } 317 318#ifdef STIDEBUG 319 printf("conf: bpp=%d planes=%d attr=%b\n" 320 "crt=0x%x:0x%x:0x%x hw=0x%x:0x%x:0x%x\n", cfg.bpp, 321 cfg.planes, cfg.attributes, STI_INQCONF_BITS, 322 ecfg.crt_config[0], ecfg.crt_config[1], ecfg.crt_config[2], 323 ecfg.crt_hw[0], ecfg.crt_hw[1], ecfg.crt_hw[2]); 324#endif 325 sc->sc_wsmode = WSDISPLAYIO_MODE_EMUL; 326 printf(": %s rev %d.%02d;%d, ID 0x%016llX\n" 327 "%s: %dx%d frame buffer, %dx%dx%d display, offset %dx%d\n", 328 cfg.name, dd->dd_grrev >> 4, dd->dd_grrev & 0xf, dd->dd_lrrev, 329 *(u_int64_t *)dd->dd_grid, 330 sc->sc_dev.dv_xname, cfg.fbwidth, cfg.fbheight, 331 cfg.width, cfg.height, cfg.bppu, cfg.owidth, cfg.oheight); 332 333 if ((error = sti_fetchfonts(sc, &cfg, dd->dd_fntaddr))) { 334 printf("%s: cannot fetch fonts (%d)\n", 335 sc->sc_dev.dv_xname, error); 336 return; 337 } 338 339 /* 340 * parse screen descriptions: 341 * figure number of fonts supported; 342 * allocate wscons structures; 343 * calculate dimentions. 344 */ 345 346 sti_default_screen.ncols = cfg.width / sc->sc_curfont.width; 347 sti_default_screen.nrows = cfg.height / sc->sc_curfont.height; 348 sti_default_screen.fontwidth = sc->sc_curfont.width; 349 sti_default_screen.fontheight = sc->sc_curfont.height; 350 351#if NWSDISPLAY > 0 352 startuphook_establish(sti_attach_deferred, sc); 353#endif 354 355 /* { extern int pmapdebug; pmapdebug = 0; } */ 356} 357 358void 359sti_attach_deferred(void *v) 360{ 361 struct sti_softc *sc = v; 362 struct wsemuldisplaydev_attach_args waa; 363 364 waa.console = sc->sc_flags & STI_CONSOLE? 1 : 0; 365 waa.scrdata = &sti_default_screenlist; 366 waa.accessops = &sti_accessops; 367 waa.accesscookie = sc; 368 369 /* attach as console if required */ 370 if (waa.console) { 371 long defattr; 372 373 sti_alloc_attr(sc, 0, 0, 0, &defattr); 374 wsdisplay_cnattach(&sti_default_screen, sc, 375 0, sti_default_screen.nrows - 1, defattr); 376 } 377 378 config_found(&sc->sc_dev, &waa, wsemuldisplaydevprint); 379} 380 381int 382sti_fetchfonts(struct sti_softc *sc, struct sti_inqconfout *cfg, u_int32_t addr) 383{ 384 struct sti_font *fp = &sc->sc_curfont; 385 int size; 386#ifdef notyet 387 int uc; 388 struct { 389 struct sti_unpmvflags flags; 390 struct sti_unpmvin in; 391 struct sti_unpmvout out; 392 } a; 393#endif 394 395 /* 396 * Get the first PROM font in memory 397 */ 398 do { 399 if (sc->sc_devtype == STI_DEVTYPE1) { 400 fp->first = parseshort(addr + 0x00); 401 fp->last = parseshort(addr + 0x08); 402 fp->width = bus_space_read_1(sc->memt, sc->romh, 403 addr + 0x13); 404 fp->height = bus_space_read_1(sc->memt, sc->romh, 405 addr + 0x17); 406 fp->type = bus_space_read_1(sc->memt, sc->romh, 407 addr + 0x1b); 408 fp->bpc = bus_space_read_1(sc->memt, sc->romh, 409 addr + 0x1f); 410 fp->next = parseword(addr + 0x23); 411 fp->uheight= bus_space_read_1(sc->memt, sc->romh, 412 addr + 0x33); 413 fp->uoffset= bus_space_read_1(sc->memt, sc->romh, 414 addr + 0x37); 415 } else /* STI_DEVTYPE4 */ 416 bus_space_read_region_4(sc->memt, sc->romh, addr, 417 (u_int32_t *)fp, sizeof(struct sti_font) / 4); 418 419 printf("%s: %dx%d font type %d, %d bpc, charset %d-%d\n", 420 sc->sc_dev.dv_xname, fp->width, fp->height, 421 fp->type, fp->bpc, fp->first, fp->last); 422 423 size = sizeof(struct sti_font) + 424 (fp->last - fp->first + 1) * fp->bpc; 425 if (sc->sc_devtype == STI_DEVTYPE1) 426 size *= 4; 427 sc->sc_romfont = malloc(size, M_DEVBUF, M_NOWAIT); 428 if (sc->sc_romfont == NULL) 429 return (ENOMEM); 430 431 bus_space_read_region_4(sc->memt, sc->romh, addr, 432 (u_int32_t *)sc->sc_romfont, size / 4); 433 434 addr = NULL; /* fp->next */ 435 } while (addr); 436 437#ifdef notyet 438 /* 439 * If there is enough room in the off-screen framebuffer memory, 440 * display all the characters there in order to display them 441 * faster with blkmv operations rather than unpmv later on. 442 */ 443 if (size <= cfg->fbheight * 444 (cfg->fbwidth - cfg->width - cfg->owidth)) { 445 bzero(&a, sizeof(a)); 446 a.flags.flags = STI_UNPMVF_WAIT; 447 a.in.fg_colour = STI_COLOUR_WHITE; 448 a.in.bg_colour = STI_COLOUR_BLACK; 449 a.in.font_addr = sc->sc_romfont; 450 451 sc->sc_fontmaxcol = cfg->fbheight / fp->height; 452 sc->sc_fontbase = cfg->width + cfg->owidth; 453 for (uc = fp->first; uc <= fp->last; uc++) { 454 a.in.x = ((uc - fp->first) / sc->sc_fontmaxcol) * 455 fp->width + sc->sc_fontbase; 456 a.in.y = ((uc - fp->first) % sc->sc_fontmaxcol) * 457 fp->height; 458 a.in.index = uc; 459 460 (*sc->unpmv)(&a.flags, &a.in, &a.out, &sc->sc_cfg); 461 if (a.out.errno) { 462 printf("%s: unpmv %d returned %d\n", 463 sc->sc_dev.dv_xname, uc, a.out.errno); 464 return (0); 465 } 466 } 467 468 free(sc->sc_romfont, M_DEVBUF); 469 sc->sc_romfont = NULL; 470 } 471#endif 472 473 return (0); 474} 475 476int 477sti_init(sc, mode) 478 struct sti_softc *sc; 479 int mode; 480{ 481 struct { 482 struct sti_initflags flags; 483 struct sti_initin in; 484 struct sti_initout out; 485 } a; 486 487 bzero(&a, sizeof(a)); 488 489 a.flags.flags = STI_INITF_WAIT | STI_INITF_CMB | STI_INITF_EBET | 490 (mode & STI_TEXTMODE? STI_INITF_TEXT | STI_INITF_PBET | 491 STI_INITF_PBETI | STI_INITF_ICMT : 0); 492 a.in.text_planes = 1; 493#ifdef STIDEBUG 494 printf("%s: init,%p(%x, %p, %p, %p)\n", sc->sc_dev.dv_xname, 495 sc->init, a.flags.flags, &a.in, &a.out, &sc->sc_cfg); 496#endif 497 (*sc->init)(&a.flags, &a.in, &a.out, &sc->sc_cfg); 498 return (a.out.text_planes != a.in.text_planes || a.out.errno); 499} 500 501int 502sti_inqcfg(sc, out) 503 struct sti_softc *sc; 504 struct sti_inqconfout *out; 505{ 506 struct { 507 struct sti_inqconfflags flags; 508 struct sti_inqconfin in; 509 } a; 510 511 bzero(&a, sizeof(a)); 512 513 a.flags.flags = STI_INQCONFF_WAIT; 514 (*sc->inqconf)(&a.flags, &a.in, out, &sc->sc_cfg); 515 516 return out->errno; 517} 518 519void 520sti_bmove(sc, x1, y1, x2, y2, h, w, f) 521 struct sti_softc *sc; 522 int x1, y1, x2, y2, h, w; 523 enum sti_bmove_funcs f; 524{ 525 struct { 526 struct sti_blkmvflags flags; 527 struct sti_blkmvin in; 528 struct sti_blkmvout out; 529 } a; 530 531 bzero(&a, sizeof(a)); 532 533 a.flags.flags = STI_BLKMVF_WAIT; 534 switch (f) { 535 case bmf_clear: 536 a.flags.flags |= STI_BLKMVF_CLR; 537 a.in.bg_colour = STI_COLOUR_BLACK; 538 break; 539 case bmf_underline: 540 case bmf_copy: 541 a.in.fg_colour = STI_COLOUR_WHITE; 542 a.in.bg_colour = STI_COLOUR_BLACK; 543 break; 544 case bmf_invert: 545 a.flags.flags |= STI_BLKMVF_COLR; 546 a.in.fg_colour = STI_COLOUR_BLACK; 547 a.in.bg_colour = STI_COLOUR_WHITE; 548 break; 549 } 550 a.in.srcx = x1; 551 a.in.srcy = y1; 552 a.in.dstx = x2; 553 a.in.dsty = y2; 554 a.in.height = h; 555 a.in.width = w; 556 557 (*sc->blkmv)(&a.flags, &a.in, &a.out, &sc->sc_cfg); 558#ifdef STIDEBUG 559 if (a.out.errno) 560 printf("%s: blkmv returned %d\n", 561 sc->sc_dev.dv_xname, a.out.errno); 562#endif 563} 564 565int 566sti_setcment(struct sti_softc *sc, u_int i, u_char r, u_char g, u_char b) 567{ 568 struct { 569 struct sti_scmentflags flags; 570 struct sti_scmentin in; 571 struct sti_scmentout out; 572 } a; 573 574 bzero(&a, sizeof(a)); 575 576 a.flags.flags = STI_SCMENTF_WAIT; 577 a.in.entry = i; 578 a.in.value = (r << 16) | (g << 8) | b; 579 580 (*sc->scment)(&a.flags, &a.in, &a.out, &sc->sc_cfg); 581 582 return a.out.errno; 583} 584 585int 586sti_ioctl(v, cmd, data, flag, p) 587 void *v; 588 u_long cmd; 589 caddr_t data; 590 int flag; 591 struct proc *p; 592{ 593 struct sti_softc *sc = v; 594 struct wsdisplay_fbinfo *wdf; 595 struct wsdisplay_cmap *cmapp; 596 u_int mode, idx, count; 597 int i, ret; 598 599 ret = 0; 600 switch (cmd) { 601 case WSDISPLAYIO_GMODE: 602 *(u_int *)data = sc->sc_wsmode; 603 break; 604 605 case WSDISPLAYIO_SMODE: 606 mode = *(u_int *)data; 607 if (sc->sc_wsmode == WSDISPLAYIO_MODE_EMUL && 608 mode == WSDISPLAYIO_MODE_DUMBFB) 609 ret = sti_init(sc, 0); 610 else if (sc->sc_wsmode == WSDISPLAYIO_MODE_DUMBFB && 611 mode == WSDISPLAYIO_MODE_EMUL) 612 ret = sti_init(sc, STI_TEXTMODE); 613 sc->sc_wsmode = mode; 614 break; 615 616 case WSDISPLAYIO_GTYPE: 617 *(u_int *)data = WSDISPLAY_TYPE_STI; 618 break; 619 620 case WSDISPLAYIO_GINFO: 621 wdf = (struct wsdisplay_fbinfo *)data; 622 wdf->height = sc->sc_cfg.scr_height; 623 wdf->width = sc->sc_cfg.scr_width; 624 wdf->depth = 8; /* XXX */ 625 wdf->cmsize = 256; 626 break; 627 628 case WSDISPLAYIO_LINEBYTES: 629 *(u_int *)data = sc->sc_cfg.fb_width; 630 break; 631 632 case WSDISPLAYIO_GETCMAP: 633 if (sc->scment == NULL) 634 return ENOTTY; 635 cmapp = (struct wsdisplay_cmap *)data; 636 idx = cmapp->index; 637 count = cmapp->count; 638 if (idx > STI_NCMAP || idx + count >= STI_NCMAP) 639 return EINVAL; 640 if ((ret = copyout(&sc->sc_rcmap[idx], cmapp->red, count))) 641 break; 642 if ((ret = copyout(&sc->sc_gcmap[idx], cmapp->green, count))) 643 break; 644 if ((ret = copyout(&sc->sc_bcmap[idx], cmapp->blue, count))) 645 break; 646 break; 647 648 case WSDISPLAYIO_PUTCMAP: 649 if (sc->scment == NULL) 650 return ENOTTY; 651 cmapp = (struct wsdisplay_cmap *)data; 652 idx = cmapp->index; 653 count = cmapp->count; 654 if (idx > STI_NCMAP || idx + count >= STI_NCMAP) 655 return EINVAL; 656 if ((ret = copyin(cmapp->red, &sc->sc_rcmap[idx], count))) 657 break; 658 if ((ret = copyin(cmapp->green, &sc->sc_gcmap[idx], count))) 659 break; 660 if ((ret = copyin(cmapp->blue, &sc->sc_bcmap[idx], count))) 661 break; 662 for (i = idx + count - 1; i >= idx; i--) 663 if ((ret = sti_setcment(sc, i, sc->sc_rcmap[i], 664 sc->sc_gcmap[i], sc->sc_bcmap[i]))) { 665#ifdef STIDEBUG 666 printf("sti_ioctl: " 667 "sti_setcment(%d, %u, %u, %u): %d\n", i, 668 (u_int)sc->sc_rcmap[i], 669 (u_int)sc->sc_gcmap[i], 670 (u_int)sc->sc_bcmap[i]); 671#endif 672 ret = EINVAL; 673 break; 674 } 675 break; 676 677 case WSDISPLAYIO_SVIDEO: 678 case WSDISPLAYIO_GVIDEO: 679 case WSDISPLAYIO_GCURPOS: 680 case WSDISPLAYIO_SCURPOS: 681 case WSDISPLAYIO_GCURMAX: 682 case WSDISPLAYIO_GCURSOR: 683 case WSDISPLAYIO_SCURSOR: 684 default: 685 return (ENOTTY); /* not supported yet */ 686 } 687 688 return (ret); 689} 690 691paddr_t 692sti_mmap(v, offset, prot) 693 void *v; 694 off_t offset; 695 int prot; 696{ 697 /* XXX not finished */ 698 return -1; 699} 700 701int 702sti_alloc_screen(v, type, cookiep, cxp, cyp, defattr) 703 void *v; 704 const struct wsscreen_descr *type; 705 void **cookiep; 706 int *cxp, *cyp; 707 long *defattr; 708{ 709 struct sti_softc *sc = v; 710 711 if (sc->sc_nscreens > 0) 712 return ENOMEM; 713 714 *cookiep = sc; 715 *cxp = 0; 716 *cyp = 0; 717 sti_alloc_attr(sc, 0, 0, 0, defattr); 718 sc->sc_nscreens++; 719 return 0; 720} 721 722void 723sti_free_screen(v, cookie) 724 void *v; 725 void *cookie; 726{ 727 struct sti_softc *sc = v; 728 729 sc->sc_nscreens--; 730} 731 732int 733sti_show_screen(v, cookie, waitok, cb, cbarg) 734 void *v; 735 void *cookie; 736 int waitok; 737 void (*cb)(void *, int, int); 738 void *cbarg; 739{ 740 return 0; 741} 742 743int 744sti_load_font(v, cookie, font) 745 void *v; 746 void *cookie; 747 struct wsdisplay_font *font; 748{ 749 return -1; 750} 751 752void 753sti_cursor(v, on, row, col) 754 void *v; 755 int on, row, col; 756{ 757 struct sti_softc *sc = v; 758 struct sti_font *fp = &sc->sc_curfont; 759 760 sti_bmove(sc, 761 col * fp->width, row * fp->height, 762 col * fp->width, row * fp->height, 763 fp->height, fp->width, bmf_invert); 764} 765 766int 767sti_mapchar(v, uni, index) 768 void *v; 769 int uni; 770 u_int *index; 771{ 772 if (uni < 256) 773 *index = uni; 774 775 return 1; 776} 777 778void 779sti_putchar(v, row, col, uc, attr) 780 void *v; 781 int row, col; 782 u_int uc; 783 long attr; 784{ 785 struct sti_softc *sc = v; 786 struct sti_font *fp = &sc->sc_curfont; 787 788 if (sc->sc_romfont != NULL) { 789 /* 790 * Font is in memory, use unpmv 791 */ 792 struct { 793 struct sti_unpmvflags flags; 794 struct sti_unpmvin in; 795 struct sti_unpmvout out; 796 } a; 797 798 bzero(&a, sizeof(a)); 799 800 a.flags.flags = STI_UNPMVF_WAIT; 801 /* XXX does not handle text attributes */ 802 a.in.fg_colour = STI_COLOUR_WHITE; 803 a.in.bg_colour = STI_COLOUR_BLACK; 804 a.in.x = col * fp->width; 805 a.in.y = row * fp->height; 806 a.in.font_addr = sc->sc_romfont; 807 a.in.index = uc; 808 809 (*sc->unpmv)(&a.flags, &a.in, &a.out, &sc->sc_cfg); 810 } else { 811 /* 812 * Font is in frame buffer, use blkmv 813 */ 814 struct { 815 struct sti_blkmvflags flags; 816 struct sti_blkmvin in; 817 struct sti_blkmvout out; 818 } a; 819 820 bzero(&a, sizeof(a)); 821 822 a.flags.flags = STI_BLKMVF_WAIT; 823 /* XXX does not handle text attributes */ 824 a.in.fg_colour = STI_COLOUR_WHITE; 825 a.in.bg_colour = STI_COLOUR_BLACK; 826 827 a.in.srcx = ((uc - fp->first) / sc->sc_fontmaxcol) * 828 fp->width + sc->sc_fontbase; 829 a.in.srcy = ((uc - fp->first) % sc->sc_fontmaxcol) * 830 fp->height; 831 a.in.dstx = col * fp->width; 832 a.in.dsty = row * fp->height; 833 a.in.height = fp->height; 834 a.in.width = fp->width; 835 836 (*sc->blkmv)(&a.flags, &a.in, &a.out, &sc->sc_cfg); 837 } 838} 839 840void 841sti_copycols(v, row, srccol, dstcol, ncols) 842 void *v; 843 int row, srccol, dstcol, ncols; 844{ 845 struct sti_softc *sc = v; 846 struct sti_font *fp = &sc->sc_curfont; 847 848 sti_bmove(sc, 849 srccol * fp->width, row * fp->height, 850 dstcol * fp->width, row * fp->height, 851 fp->height, ncols * fp->width, bmf_copy); 852} 853 854void 855sti_erasecols(v, row, startcol, ncols, attr) 856 void *v; 857 int row, startcol, ncols; 858 long attr; 859{ 860 struct sti_softc *sc = v; 861 struct sti_font *fp = &sc->sc_curfont; 862 863 sti_bmove(sc, 864 startcol * fp->width, row * fp->height, 865 startcol * fp->width, row * fp->height, 866 fp->height, ncols * fp->width, bmf_clear); 867} 868 869void 870sti_copyrows(v, srcrow, dstrow, nrows) 871 void *v; 872 int srcrow, dstrow, nrows; 873{ 874 struct sti_softc *sc = v; 875 struct sti_font *fp = &sc->sc_curfont; 876 877 sti_bmove(sc, sc->sc_cfg.oscr_width, srcrow * fp->height, 878 sc->sc_cfg.oscr_width, dstrow * fp->height, 879 nrows * fp->height, sc->sc_cfg.scr_width, bmf_copy); 880} 881 882void 883sti_eraserows(v, srcrow, nrows, attr) 884 void *v; 885 int srcrow, nrows; 886 long attr; 887{ 888 struct sti_softc *sc = v; 889 struct sti_font *fp = &sc->sc_curfont; 890 891 sti_bmove(sc, sc->sc_cfg.oscr_width, srcrow * fp->height, 892 sc->sc_cfg.oscr_width, srcrow * fp->height, 893 nrows * fp->height, sc->sc_cfg.scr_width, bmf_clear); 894} 895 896int 897sti_alloc_attr(v, fg, bg, flags, pattr) 898 void *v; 899 int fg, bg, flags; 900 long *pattr; 901{ 902 /* struct sti_softc *sc = v; */ 903 904 *pattr = 0; 905 906 return 0; 907} 908 909