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