1 /* $OpenBSD: sti.c,v 1.61 2009/09/05 14:09:35 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 int sti_alloc_attr(void *, int, int, int, long *); 57 int sti_copycols(void *, int, int, int, int); 58 int sti_copyrows(void *, int, int, int); 59 int sti_cursor(void *, int, int, int); 60 int sti_erasecols(void *, int, int, int, long); 61 int sti_eraserows(void *, int, int, long); 62 int sti_mapchar(void *, int, u_int *); 63 int sti_putchar(void *, int, int, u_int, long); 64 void sti_unpack_attr(void *, long, int *, int *, int *); 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_alloc_screen(void *, const struct wsscreen_descr *, void **, int *, 79 int *, long *); 80 void sti_free_screen(void *, void *); 81 int sti_ioctl(void *, u_long, caddr_t, int, struct proc *); 82 paddr_t sti_mmap(void *, off_t, int); 83 int sti_show_screen(void *, void *, int, void (*)(void *, int, int), 84 void *); 85 86 const struct wsdisplay_accessops sti_accessops = { 87 sti_ioctl, 88 sti_mmap, 89 sti_alloc_screen, 90 sti_free_screen, 91 sti_show_screen, 92 NULL /* load_font */ 93 }; 94 95 enum sti_bmove_funcs { 96 bmf_clear, bmf_copy, bmf_invert, bmf_underline 97 }; 98 99 void sti_bmove(struct sti_screen *, int, int, int, int, int, int, 100 enum sti_bmove_funcs); 101 int sti_init(struct sti_screen *, int); 102 #define STI_TEXTMODE 0x01 103 #define STI_CLEARSCR 0x02 104 int sti_inqcfg(struct sti_screen *, struct sti_inqconfout *); 105 int sti_setcment(struct sti_screen *, u_int, u_char, u_char, u_char); 106 107 struct sti_screen * 108 sti_attach_screen(struct sti_softc *, int); 109 void sti_describe_screen(struct sti_softc *, struct sti_screen *); 110 void sti_end_attach_screen(struct sti_softc *, struct sti_screen *, int); 111 int sti_fetchfonts(struct sti_screen *, struct sti_inqconfout *, u_int32_t, 112 u_int); 113 void sti_region_setup(struct sti_screen *); 114 int sti_rom_setup(struct sti_rom *, bus_space_tag_t, bus_space_tag_t, 115 bus_space_handle_t, bus_addr_t *, u_int); 116 int sti_screen_setup(struct sti_screen *, int); 117 118 #if NSTI_PCI > 0 119 #define STI_ENABLE_ROM(sc) \ 120 do { \ 121 if ((sc) != NULL && (sc)->sc_enable_rom != NULL) \ 122 (*(sc)->sc_enable_rom)(sc); \ 123 } while (0) 124 #define STI_DISABLE_ROM(sc) \ 125 do { \ 126 if ((sc) != NULL && (sc)->sc_disable_rom != NULL) \ 127 (*(sc)->sc_disable_rom)(sc); \ 128 } while (0) 129 #else 130 #define STI_ENABLE_ROM(sc) do { /* nothing */ } while (0) 131 #define STI_DISABLE_ROM(sc) do { /* nothing */ } while (0) 132 #endif 133 134 /* Macros to read larger than 8 bit values from byte roms */ 135 #define parseshort(o) \ 136 ((bus_space_read_1(memt, romh, (o) + 3) << 8) | \ 137 (bus_space_read_1(memt, romh, (o) + 7))) 138 #define parseword(o) \ 139 ((bus_space_read_1(memt, romh, (o) + 3) << 24) | \ 140 (bus_space_read_1(memt, romh, (o) + 7) << 16) | \ 141 (bus_space_read_1(memt, romh, (o) + 11) << 8) | \ 142 (bus_space_read_1(memt, romh, (o) + 15))) 143 144 int 145 sti_attach_common(struct sti_softc *sc, bus_space_tag_t iot, 146 bus_space_tag_t memt, bus_space_handle_t romh, u_int codebase) 147 { 148 struct sti_rom *rom; 149 int rc; 150 151 rom = (struct sti_rom *)malloc(sizeof(*rom), M_DEVBUF, 152 M_NOWAIT | M_ZERO); 153 if (rom == NULL) { 154 printf("cannot allocate rom data\n"); 155 return (ENOMEM); 156 } 157 158 rom->rom_softc = sc; 159 rc = sti_rom_setup(rom, iot, memt, romh, sc->bases, codebase); 160 if (rc != 0) { 161 free(rom, M_DEVBUF); 162 return (rc); 163 } 164 165 sc->sc_rom = rom; 166 167 sti_describe(sc); 168 169 sc->sc_scr = sti_attach_screen(sc, 170 sc->sc_flags & STI_CONSOLE ? 0 : STI_CLEARSCR); 171 if (sc->sc_scr == NULL) 172 rc = ENOMEM; 173 174 return (rc); 175 } 176 177 struct sti_screen * 178 sti_attach_screen(struct sti_softc *sc, int flags) 179 { 180 struct sti_screen *scr; 181 int rc; 182 183 scr = (struct sti_screen *)malloc(sizeof(*scr), M_DEVBUF, 184 M_NOWAIT | M_ZERO); 185 if (scr == NULL) { 186 printf("cannot allocate screen data\n"); 187 return (NULL); 188 } 189 190 scr->scr_rom = sc->sc_rom; 191 rc = sti_screen_setup(scr, flags); 192 if (rc != 0) { 193 free(scr, M_DEVBUF); 194 return (NULL); 195 } 196 197 sti_describe_screen(sc, scr); 198 199 return (scr); 200 } 201 202 int 203 sti_rom_setup(struct sti_rom *rom, bus_space_tag_t iot, bus_space_tag_t memt, 204 bus_space_handle_t romh, bus_addr_t *bases, u_int codebase) 205 { 206 struct sti_dd *dd; 207 int error, size, i; 208 209 STI_ENABLE_ROM(rom->rom_softc); 210 211 rom->iot = iot; 212 rom->memt = memt; 213 rom->romh = romh; 214 rom->bases = bases; 215 216 /* 217 * Get ROM header and code function pointers. 218 */ 219 220 dd = &rom->rom_dd; 221 rom->rom_devtype = bus_space_read_1(memt, romh, 3); 222 if (rom->rom_devtype == STI_DEVTYPE1) { 223 dd->dd_type = bus_space_read_1(memt, romh, 0x03); 224 dd->dd_nmon = bus_space_read_1(memt, romh, 0x07); 225 dd->dd_grrev = bus_space_read_1(memt, romh, 0x0b); 226 dd->dd_lrrev = bus_space_read_1(memt, romh, 0x0f); 227 dd->dd_grid[0] = parseword(0x10); 228 dd->dd_grid[1] = parseword(0x20); 229 dd->dd_fntaddr = parseword(0x30) & ~3; 230 dd->dd_maxst = parseword(0x40); 231 dd->dd_romend = parseword(0x50) & ~3; 232 dd->dd_reglst = parseword(0x60) & ~3; 233 dd->dd_maxreent = parseshort(0x70); 234 dd->dd_maxtimo = parseshort(0x78); 235 dd->dd_montbl = parseword(0x80) & ~3; 236 dd->dd_udaddr = parseword(0x90) & ~3; 237 dd->dd_stimemreq = parseword(0xa0); 238 dd->dd_udsize = parseword(0xb0); 239 dd->dd_pwruse = parseshort(0xc0); 240 dd->dd_bussup = bus_space_read_1(memt, romh, 0xcb); 241 dd->dd_ebussup = bus_space_read_1(memt, romh, 0xcf); 242 dd->dd_altcodet = bus_space_read_1(memt, romh, 0xd3); 243 dd->dd_eddst[0] = bus_space_read_1(memt, romh, 0xd7); 244 dd->dd_eddst[1] = bus_space_read_1(memt, romh, 0xdb); 245 dd->dd_eddst[2] = bus_space_read_1(memt, romh, 0xdf); 246 dd->dd_cfbaddr = parseword(0xe0) & ~3; 247 248 codebase <<= 2; 249 dd->dd_pacode[0x0] = parseword(codebase + 0x000) & ~3; 250 dd->dd_pacode[0x1] = parseword(codebase + 0x010) & ~3; 251 dd->dd_pacode[0x2] = parseword(codebase + 0x020) & ~3; 252 dd->dd_pacode[0x3] = parseword(codebase + 0x030) & ~3; 253 dd->dd_pacode[0x4] = parseword(codebase + 0x040) & ~3; 254 dd->dd_pacode[0x5] = parseword(codebase + 0x050) & ~3; 255 dd->dd_pacode[0x6] = parseword(codebase + 0x060) & ~3; 256 dd->dd_pacode[0x7] = parseword(codebase + 0x070) & ~3; 257 dd->dd_pacode[0x8] = parseword(codebase + 0x080) & ~3; 258 dd->dd_pacode[0x9] = parseword(codebase + 0x090) & ~3; 259 dd->dd_pacode[0xa] = parseword(codebase + 0x0a0) & ~3; 260 dd->dd_pacode[0xb] = parseword(codebase + 0x0b0) & ~3; 261 dd->dd_pacode[0xc] = parseword(codebase + 0x0c0) & ~3; 262 dd->dd_pacode[0xd] = parseword(codebase + 0x0d0) & ~3; 263 dd->dd_pacode[0xe] = parseword(codebase + 0x0e0) & ~3; 264 dd->dd_pacode[0xf] = parseword(codebase + 0x0f0) & ~3; 265 } else { /* STI_DEVTYPE4 */ 266 bus_space_read_raw_region_4(memt, romh, 0, (u_int8_t *)dd, 267 sizeof(*dd)); 268 /* fix pacode... */ 269 bus_space_read_raw_region_4(memt, romh, codebase, 270 (u_int8_t *)dd->dd_pacode, sizeof(dd->dd_pacode)); 271 } 272 273 STI_DISABLE_ROM(rom->rom_softc); 274 275 #ifdef STIDEBUG 276 printf("dd:\n" 277 "devtype=%x, rev=%x;%d, altt=%x, gid=%08x%08x, font=%x, mss=%x\n" 278 "end=%x, regions=%x, msto=%x, timo=%d, mont=%x, user=%x[%x]\n" 279 "memrq=%x, pwr=%d, bus=%x, ebus=%x, cfb=%x\n" 280 "code=", 281 dd->dd_type & 0xff, dd->dd_grrev, dd->dd_lrrev, dd->dd_altcodet, 282 dd->dd_grid[0], dd->dd_grid[1], dd->dd_fntaddr, dd->dd_maxst, 283 dd->dd_romend, dd->dd_reglst, dd->dd_maxreent, dd->dd_maxtimo, 284 dd->dd_montbl, dd->dd_udaddr, dd->dd_udsize, dd->dd_stimemreq, 285 dd->dd_pwruse, dd->dd_bussup, dd->dd_ebussup, dd->dd_cfbaddr); 286 printf("%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n", 287 dd->dd_pacode[0x0], dd->dd_pacode[0x1], dd->dd_pacode[0x2], 288 dd->dd_pacode[0x3], dd->dd_pacode[0x4], dd->dd_pacode[0x5], 289 dd->dd_pacode[0x6], dd->dd_pacode[0x7], dd->dd_pacode[0x8], 290 dd->dd_pacode[0x9], dd->dd_pacode[0xa], dd->dd_pacode[0xb], 291 dd->dd_pacode[0xc], dd->dd_pacode[0xd], dd->dd_pacode[0xe], 292 dd->dd_pacode[0xf]); 293 #endif 294 295 /* 296 * Figure out how much bytes we need for the STI code. 297 * Note there could be fewer than STI_END entries pointer 298 * entries populated, especially on older devices. 299 */ 300 301 for (i = STI_END; !dd->dd_pacode[i]; i--) 302 ; 303 size = dd->dd_pacode[i] - dd->dd_pacode[STI_BEGIN]; 304 if (rom->rom_devtype == STI_DEVTYPE1) 305 size = (size + 3) / 4; 306 if (size == 0) { 307 printf(": no code for the requested platform\n"); 308 return (EINVAL); 309 } 310 311 if (!(rom->rom_code = uvm_km_alloc(kernel_map, round_page(size)))) { 312 printf(": cannot allocate %u bytes for code\n", size); 313 return (ENOMEM); 314 } 315 #ifdef STIDEBUG 316 printf("code=0x%x[%x]\n", rom->rom_code, size); 317 #endif 318 319 /* 320 * Copy code into memory and make it executable. 321 */ 322 323 STI_ENABLE_ROM(rom->rom_softc); 324 325 if (rom->rom_devtype == STI_DEVTYPE1) { 326 u_int8_t *p = (u_int8_t *)rom->rom_code; 327 u_int32_t addr, eaddr; 328 329 for (addr = dd->dd_pacode[STI_BEGIN], eaddr = addr + size * 4; 330 addr < eaddr; addr += 4 ) 331 *p++ = bus_space_read_4(memt, romh, addr) & 0xff; 332 333 } else /* STI_DEVTYPE4 */ 334 bus_space_read_raw_region_4(memt, romh, 335 dd->dd_pacode[STI_BEGIN], (u_int8_t *)rom->rom_code, 336 size); 337 338 STI_DISABLE_ROM(rom->rom_softc); 339 340 if ((error = uvm_map_protect(kernel_map, rom->rom_code, 341 rom->rom_code + round_page(size), UVM_PROT_RX, FALSE))) { 342 printf(": uvm_map_protect failed (%d)\n", error); 343 uvm_km_free(kernel_map, rom->rom_code, round_page(size)); 344 return (error); 345 } 346 347 /* 348 * Setup code function pointers. 349 */ 350 351 #define O(i) \ 352 (dd->dd_pacode[(i)] == 0 ? NULL : \ 353 (rom->rom_code + (dd->dd_pacode[(i)] - dd->dd_pacode[0]) / \ 354 (rom->rom_devtype == STI_DEVTYPE1? 4 : 1))) 355 356 rom->init = (sti_init_t) O(STI_INIT_GRAPH); 357 rom->mgmt = (sti_mgmt_t) O(STI_STATE_MGMT); 358 rom->unpmv = (sti_unpmv_t) O(STI_FONT_UNPMV); 359 rom->blkmv = (sti_blkmv_t) O(STI_BLOCK_MOVE); 360 rom->test = (sti_test_t) O(STI_SELF_TEST); 361 rom->exhdl = (sti_exhdl_t) O(STI_EXCEP_HDLR); 362 rom->inqconf = (sti_inqconf_t)O(STI_INQ_CONF); 363 rom->scment = (sti_scment_t)O(STI_SCM_ENT); 364 rom->dmac = (sti_dmac_t) O(STI_DMA_CTRL); 365 rom->flowc = (sti_flowc_t) O(STI_FLOW_CTRL); 366 rom->utiming = (sti_utiming_t)O(STI_UTIMING); 367 rom->pmgr = (sti_pmgr_t) O(STI_PROC_MGR); 368 rom->util = (sti_util_t) O(STI_UTIL); 369 370 #undef O 371 372 /* 373 * Set colormap entry is not implemented until 8.04, so force 374 * a NULL pointer here. 375 */ 376 if (dd->dd_grrev < STI_REVISION(8,4)) { 377 rom->scment = NULL; 378 } 379 380 return (0); 381 } 382 383 /* 384 * Map all regions. 385 */ 386 void 387 sti_region_setup(struct sti_screen *scr) 388 { 389 struct sti_rom *rom = scr->scr_rom; 390 bus_space_tag_t memt = rom->memt; 391 bus_space_handle_t romh = rom->romh; 392 bus_addr_t *bases = rom->bases; 393 struct sti_dd *dd = &rom->rom_dd; 394 struct sti_cfg *cc = &scr->scr_cfg; 395 bus_space_handle_t bh; 396 struct sti_region regions[STI_REGION_MAX], *r; 397 u_int regno, regcnt; 398 bus_addr_t addr; 399 400 #ifdef STIDEBUG 401 printf("stiregions @%p:\n", dd->dd_reglst); 402 #endif 403 404 /* 405 * Read the region information. 406 */ 407 408 STI_ENABLE_ROM(rom->rom_softc); 409 410 if (rom->rom_devtype == STI_DEVTYPE1) { 411 for (regno = 0; regno < STI_REGION_MAX; regno++) 412 *(u_int *)(regions + regno) = 413 parseword(dd->dd_reglst + regno * 0x10); 414 } else { 415 bus_space_read_raw_region_4(memt, romh, dd->dd_reglst, 416 (u_int8_t *)regions, sizeof regions); 417 } 418 419 STI_DISABLE_ROM(rom->rom_softc); 420 421 /* 422 * Count them. 423 */ 424 425 for (regcnt = 0, r = regions; regcnt < STI_REGION_MAX; regcnt++, r++) 426 if (r->last) 427 break; 428 regcnt++; 429 430 /* 431 * Map them. 432 */ 433 434 for (regno = 0, r = regions; regno < regcnt; regno++, r++) { 435 if (r->length == 0) 436 continue; 437 438 /* 439 * Assume an existing mapping exists. 440 */ 441 addr = bases[regno] + (r->offset << PGSHIFT); 442 443 #ifdef STIDEBUG 444 printf("%08x @ 0x%08x%s%s%s%s\n", 445 r->length << PGSHIFT, addr, r->sys_only ? " sys" : "", 446 r->cache ? " cache" : "", r->btlb ? " btlb" : "", 447 r->last ? " last" : ""); 448 #endif 449 450 /* 451 * Region #0 is always the rom, and it should have been 452 * mapped already. 453 * XXX This expects a 1:1 mapping... 454 */ 455 if (regno == 0 && romh == bases[0]) { 456 cc->regions[0] = addr; 457 continue; 458 } 459 460 if (bus_space_map(memt, addr, r->length << PGSHIFT, 461 r->cache ? BUS_SPACE_MAP_CACHEABLE : 0, &bh)) { 462 #ifdef STIDEBUG 463 printf("already mapped region\n"); 464 #endif 465 } else { 466 /* XXX should use bus_space_vaddr */ 467 addr = (bus_addr_t)bh; 468 if (regno == 1) { 469 scr->fbaddr = addr; 470 scr->fblen = r->length << PGSHIFT; 471 } 472 } 473 474 cc->regions[regno] = addr; 475 } 476 477 #ifdef STIDEBUG 478 /* 479 * Make sure we'll trap accessing unmapped regions 480 */ 481 for (regno = 0; regno < STI_REGION_MAX; regno++) 482 if (cc->regions[regno] == 0) 483 cc->regions[regno] = 0x81234567; 484 #endif 485 } 486 487 int 488 sti_screen_setup(struct sti_screen *scr, int flags) 489 { 490 struct sti_rom *rom = scr->scr_rom; 491 bus_space_tag_t memt = rom->memt; 492 bus_space_handle_t romh = rom->romh; 493 struct sti_dd *dd = &rom->rom_dd; 494 struct sti_cfg *cc = &scr->scr_cfg; 495 struct sti_inqconfout cfg; 496 struct sti_einqconfout ecfg; 497 int error, i; 498 int geometry_kluge = 0; 499 u_int fontindex = 0; 500 501 bzero(cc, sizeof (*cc)); 502 cc->ext_cfg = &scr->scr_ecfg; 503 bzero(cc->ext_cfg, sizeof(*cc->ext_cfg)); 504 505 if (dd->dd_stimemreq) { 506 scr->scr_ecfg.addr = 507 malloc(dd->dd_stimemreq, M_DEVBUF, M_NOWAIT); 508 if (!scr->scr_ecfg.addr) { 509 printf("cannot allocate %d bytes for STI\n", 510 dd->dd_stimemreq); 511 return (ENOMEM); 512 } 513 } 514 515 sti_region_setup(scr); 516 517 if ((error = sti_init(scr, 0))) { 518 printf(": can not initialize (%d)\n", error); 519 goto fail; 520 } 521 522 bzero(&cfg, sizeof(cfg)); 523 bzero(&ecfg, sizeof(ecfg)); 524 cfg.ext = &ecfg; 525 if ((error = sti_inqcfg(scr, &cfg))) { 526 printf(": error %d inquiring config\n", error); 527 goto fail; 528 } 529 530 /* 531 * Older (rev 8.02) boards report wrong offset values, 532 * similar to the displayable area size, at least in m68k mode. 533 * Attempt to detect this and adjust here. 534 */ 535 if (cfg.owidth == cfg.width && 536 cfg.oheight == cfg.height) 537 geometry_kluge = 1; 538 539 if (geometry_kluge) { 540 scr->scr_cfg.oscr_width = cfg.owidth = 541 cfg.fbwidth - cfg.width; 542 scr->scr_cfg.oscr_height = cfg.oheight = 543 cfg.fbheight - cfg.height; 544 } 545 546 /* 547 * Save a few fields for sti_describe_screen() later 548 */ 549 scr->fbheight = cfg.fbheight; 550 scr->fbwidth = cfg.fbwidth; 551 scr->oheight = cfg.oheight; 552 scr->owidth = cfg.owidth; 553 bcopy(cfg.name, scr->name, sizeof(scr->name)); 554 555 if ((error = sti_init(scr, STI_TEXTMODE | flags))) { 556 printf(": can not initialize (%d)\n", error); 557 goto fail; 558 } 559 #ifdef STIDEBUG 560 printf("conf: bpp=%d planes=%d attr=%b\n" 561 "crt=0x%x:0x%x:0x%x hw=0x%x:0x%x:0x%x\n", cfg.bpp, 562 cfg.planes, cfg.attributes, STI_INQCONF_BITS, 563 ecfg.crt_config[0], ecfg.crt_config[1], ecfg.crt_config[2], 564 ecfg.crt_hw[0], ecfg.crt_hw[1], ecfg.crt_hw[2]); 565 #endif 566 scr->scr_bpp = cfg.bppu; 567 568 /* 569 * Although scr->scr_ecfg.current_monitor is not filled by 570 * sti_init() as expected, we can nevertheless walk the monitor 571 * list, if there is any, and if we find a mode matching our 572 * resolution, pick its font index. 573 */ 574 if (dd->dd_montbl != 0) { 575 STI_ENABLE_ROM(rom->rom_softc); 576 577 for (i = 0; i < dd->dd_nmon; i++) { 578 u_int offs = dd->dd_montbl + 8 * i; 579 u_int32_t m[2]; 580 sti_mon_t mon = (void *)m; 581 if (rom->rom_devtype == STI_DEVTYPE1) { 582 m[0] = parseword(4 * offs); 583 m[1] = parseword(4 * (offs + 4)); 584 } else { 585 bus_space_read_raw_region_4(memt, romh, offs, 586 (u_int8_t *)mon, sizeof(*mon)); 587 } 588 589 if (mon->width == scr->scr_cfg.scr_width && 590 mon->height == scr->scr_cfg.scr_height) { 591 fontindex = mon->font; 592 break; 593 } 594 } 595 596 STI_DISABLE_ROM(rom->rom_softc); 597 598 #ifdef STIDEBUG 599 printf("font index: %d\n", fontindex); 600 #endif 601 } 602 603 if ((error = sti_fetchfonts(scr, &cfg, dd->dd_fntaddr, fontindex))) { 604 printf(": cannot fetch fonts (%d)\n", error); 605 goto fail; 606 } 607 608 /* 609 * setup screen descriptions: 610 * figure number of fonts supported; 611 * allocate wscons structures; 612 * calculate dimensions. 613 */ 614 615 strlcpy(scr->scr_wsd.name, "std", sizeof(scr->scr_wsd.name)); 616 scr->scr_wsd.ncols = cfg.width / scr->scr_curfont.width; 617 scr->scr_wsd.nrows = cfg.height / scr->scr_curfont.height; 618 scr->scr_wsd.textops = &sti_emulops; 619 scr->scr_wsd.fontwidth = scr->scr_curfont.width; 620 scr->scr_wsd.fontheight = scr->scr_curfont.height; 621 scr->scr_wsd.capabilities = 0; 622 623 scr->scr_scrlist[0] = &scr->scr_wsd; 624 scr->scr_screenlist.nscreens = 1; 625 scr->scr_screenlist.screens = 626 (const struct wsscreen_descr **)scr->scr_scrlist; 627 628 return (0); 629 630 fail: 631 /* XXX free resources */ 632 if (scr->scr_ecfg.addr != NULL) { 633 free(scr->scr_ecfg.addr, M_DEVBUF); 634 scr->scr_ecfg.addr = NULL; 635 } 636 637 return (ENXIO); 638 } 639 640 void 641 sti_describe_screen(struct sti_softc *sc, struct sti_screen *scr) 642 { 643 struct sti_font *fp = &scr->scr_curfont; 644 645 printf("%s: %s, %dx%d frame buffer, %dx%dx%d display\n", 646 sc->sc_dev.dv_xname, scr->name, scr->fbwidth, scr->fbheight, 647 scr->scr_cfg.scr_width, scr->scr_cfg.scr_height, scr->scr_bpp); 648 649 printf("%s: %dx%d font type %d, %d bpc, charset %d-%d\n", 650 sc->sc_dev.dv_xname, fp->width, fp->height, 651 fp->type, fp->bpc, fp->first, fp->last); 652 } 653 654 void 655 sti_describe(struct sti_softc *sc) 656 { 657 struct sti_rom *rom = sc->sc_rom; 658 struct sti_dd *dd = &rom->rom_dd; 659 660 printf(": rev %d.%02d;%d, ID 0x%08X%08X\n", 661 dd->dd_grrev >> 4, dd->dd_grrev & 0xf, 662 dd->dd_lrrev, dd->dd_grid[0], dd->dd_grid[1]); 663 664 if (sc->sc_scr != NULL) 665 sti_describe_screen(sc, sc->sc_scr); 666 } 667 668 /* 669 * Final part of attachment. On hppa where we use the PDC console 670 * during autoconf, this has to be postponed until autoconf has 671 * completed. 672 */ 673 void 674 sti_end_attach(void *v) 675 { 676 struct sti_softc *sc = (struct sti_softc *)v; 677 678 if (sc->sc_scr != NULL) 679 sti_end_attach_screen(sc, sc->sc_scr, 680 sc->sc_flags & STI_CONSOLE ? 1 : 0); 681 } 682 683 void 684 sti_end_attach_screen(struct sti_softc *sc, struct sti_screen *scr, int console) 685 { 686 struct wsemuldisplaydev_attach_args waa; 687 688 scr->scr_wsmode = WSDISPLAYIO_MODE_EMUL; 689 690 waa.console = console; 691 waa.scrdata = &scr->scr_screenlist; 692 waa.accessops = &sti_accessops; 693 waa.accesscookie = scr; 694 waa.defaultscreens = 0; 695 696 /* attach as console if required */ 697 if (console && !ISSET(sc->sc_flags, STI_ATTACHED)) { 698 long defattr; 699 700 sti_alloc_attr(scr, 0, 0, 0, &defattr); 701 wsdisplay_cnattach(&scr->scr_wsd, scr, 702 0, scr->scr_wsd.nrows - 1, defattr); 703 sc->sc_flags |= STI_ATTACHED; 704 } 705 706 config_found(&sc->sc_dev, &waa, wsemuldisplaydevprint); 707 } 708 709 u_int 710 sti_rom_size(bus_space_tag_t memt, bus_space_handle_t romh) 711 { 712 int devtype; 713 u_int romend; 714 715 devtype = bus_space_read_1(memt, romh, 3); 716 if (devtype == STI_DEVTYPE4) { 717 bus_space_read_raw_region_4(memt, romh, 0x18, 718 (u_int8_t *)&romend, 4); 719 } else { 720 romend = parseword(0x50); 721 } 722 723 return (round_page(romend)); 724 } 725 726 int 727 sti_fetchfonts(struct sti_screen *scr, struct sti_inqconfout *cfg, 728 u_int32_t baseaddr, u_int fontindex) 729 { 730 struct sti_rom *rom = scr->scr_rom; 731 bus_space_tag_t memt = rom->memt; 732 bus_space_handle_t romh = rom->romh; 733 struct sti_font *fp = &scr->scr_curfont; 734 u_int32_t addr; 735 int size; 736 #ifdef notyet 737 int uc; 738 struct { 739 struct sti_unpmvflags flags; 740 struct sti_unpmvin in; 741 struct sti_unpmvout out; 742 } a; 743 #endif 744 745 /* 746 * Get the first PROM font in memory 747 */ 748 749 STI_ENABLE_ROM(rom->rom_softc); 750 751 rescan: 752 addr = baseaddr; 753 do { 754 if (rom->rom_devtype == STI_DEVTYPE1) { 755 fp->first = parseshort(addr + 0x00); 756 fp->last = parseshort(addr + 0x08); 757 fp->width = bus_space_read_1(memt, romh, 758 addr + 0x13); 759 fp->height = bus_space_read_1(memt, romh, 760 addr + 0x17); 761 fp->type = bus_space_read_1(memt, romh, 762 addr + 0x1b); 763 fp->bpc = bus_space_read_1(memt, romh, 764 addr + 0x1f); 765 fp->next = parseword(addr + 0x20); 766 fp->uheight= bus_space_read_1(memt, romh, 767 addr + 0x33); 768 fp->uoffset= bus_space_read_1(memt, romh, 769 addr + 0x37); 770 } else { /* STI_DEVTYPE4 */ 771 bus_space_read_raw_region_4(memt, romh, addr, 772 (u_int8_t *)fp, sizeof(struct sti_font)); 773 } 774 775 #ifdef STIDEBUG 776 STI_DISABLE_ROM(rom->rom_softc); 777 printf("font@%p: %d-%d, %dx%d, type %d, next %x\n", 778 addr, fp->first, fp->last, fp->width, fp->height, fp->type, 779 fp->next); 780 STI_ENABLE_ROM(rom->rom_softc); 781 #endif 782 783 if (fontindex == 0) { 784 size = sizeof(struct sti_font) + 785 (fp->last - fp->first + 1) * fp->bpc; 786 if (rom->rom_devtype == STI_DEVTYPE1) 787 size *= 4; 788 scr->scr_romfont = malloc(size, M_DEVBUF, M_NOWAIT); 789 if (scr->scr_romfont == NULL) 790 return (ENOMEM); 791 792 bus_space_read_raw_region_4(memt, romh, addr, 793 (u_int8_t *)scr->scr_romfont, size); 794 795 break; 796 } 797 798 addr = baseaddr + fp->next; 799 fontindex--; 800 } while (fp->next != 0); 801 802 /* 803 * If our font index was bogus, we did not find the expected font. 804 * In this case, pick the first one and be done with it. 805 */ 806 if (fp->next == 0 && scr->scr_romfont == NULL) { 807 fontindex = 0; 808 goto rescan; 809 } 810 811 STI_DISABLE_ROM(rom->rom_softc); 812 813 #ifdef notyet 814 /* 815 * If there is enough room in the off-screen framebuffer memory, 816 * display all the characters there in order to display them 817 * faster with blkmv operations rather than unpmv later on. 818 */ 819 if (size <= cfg->fbheight * 820 (cfg->fbwidth - cfg->width - cfg->owidth)) { 821 bzero(&a, sizeof(a)); 822 a.flags.flags = STI_UNPMVF_WAIT; 823 a.in.fg_colour = STI_COLOUR_WHITE; 824 a.in.bg_colour = STI_COLOUR_BLACK; 825 a.in.font_addr = scr->scr_romfont; 826 827 scr->scr_fontmaxcol = cfg->fbheight / fp->height; 828 scr->scr_fontbase = cfg->width + cfg->owidth; 829 for (uc = fp->first; uc <= fp->last; uc++) { 830 a.in.x = ((uc - fp->first) / scr->scr_fontmaxcol) * 831 fp->width + scr->scr_fontbase; 832 a.in.y = ((uc - fp->first) % scr->scr_fontmaxcol) * 833 fp->height; 834 a.in.index = uc; 835 836 (*scr->unpmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg); 837 if (a.out.errno) { 838 #ifdef STIDEBUG 839 printf("sti_unpmv %d returned %d\n", 840 uc, a.out.errno); 841 #endif 842 return (0); 843 } 844 } 845 846 free(scr->scr_romfont, M_DEVBUF); 847 scr->scr_romfont = NULL; 848 } 849 #endif 850 851 return (0); 852 } 853 854 /* 855 * Wrappers around STI code pointers 856 */ 857 858 int 859 sti_init(struct sti_screen *scr, int mode) 860 { 861 struct sti_rom *rom = scr->scr_rom; 862 struct { 863 struct sti_initflags flags; 864 struct sti_initin in; 865 struct sti_einitin ein; 866 struct sti_initout out; 867 } a; 868 869 bzero(&a, sizeof(a)); 870 871 a.flags.flags = STI_INITF_WAIT | STI_INITF_CMB | STI_INITF_EBET | 872 (mode & STI_TEXTMODE ? STI_INITF_TEXT | STI_INITF_PBET | 873 STI_INITF_PBETI | STI_INITF_ICMT : 0) | 874 (mode & STI_CLEARSCR ? STI_INITF_CLEAR : 0); 875 a.in.text_planes = 1; 876 a.in.ext_in = &a.ein; 877 #ifdef STIDEBUG 878 printf("sti_init,%p(%x, %p, %p, %p)\n", 879 rom->init, a.flags.flags, &a.in, &a.out, &scr->scr_cfg); 880 #endif 881 (*rom->init)(&a.flags, &a.in, &a.out, &scr->scr_cfg); 882 if (a.out.text_planes != a.in.text_planes) 883 return (-1); /* not colliding with sti errno values */ 884 return (a.out.errno); 885 } 886 887 int 888 sti_inqcfg(struct sti_screen *scr, struct sti_inqconfout *out) 889 { 890 struct sti_rom *rom = scr->scr_rom; 891 struct { 892 struct sti_inqconfflags flags; 893 struct sti_inqconfin in; 894 } a; 895 896 bzero(&a, sizeof(a)); 897 898 a.flags.flags = STI_INQCONFF_WAIT; 899 (*rom->inqconf)(&a.flags, &a.in, out, &scr->scr_cfg); 900 901 return out->errno; 902 } 903 904 void 905 sti_bmove(struct sti_screen *scr, int x1, int y1, int x2, int y2, int h, int w, 906 enum sti_bmove_funcs f) 907 { 908 struct sti_rom *rom = scr->scr_rom; 909 struct { 910 struct sti_blkmvflags flags; 911 struct sti_blkmvin in; 912 struct sti_blkmvout out; 913 } a; 914 915 bzero(&a, sizeof(a)); 916 917 a.flags.flags = STI_BLKMVF_WAIT; 918 switch (f) { 919 case bmf_clear: 920 a.flags.flags |= STI_BLKMVF_CLR; 921 a.in.bg_colour = STI_COLOUR_BLACK; 922 break; 923 case bmf_underline: 924 case bmf_copy: 925 a.in.fg_colour = STI_COLOUR_WHITE; 926 a.in.bg_colour = STI_COLOUR_BLACK; 927 break; 928 case bmf_invert: 929 a.flags.flags |= STI_BLKMVF_COLR; 930 a.in.fg_colour = STI_COLOUR_BLACK; 931 a.in.bg_colour = STI_COLOUR_WHITE; 932 break; 933 } 934 a.in.srcx = x1; 935 a.in.srcy = y1; 936 a.in.dstx = x2; 937 a.in.dsty = y2; 938 a.in.height = h; 939 a.in.width = w; 940 941 (*rom->blkmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg); 942 #ifdef STIDEBUG 943 if (a.out.errno) 944 printf("sti_blkmv returned %d\n", a.out.errno); 945 #endif 946 } 947 948 int 949 sti_setcment(struct sti_screen *scr, u_int i, u_char r, u_char g, u_char b) 950 { 951 struct sti_rom *rom = scr->scr_rom; 952 struct { 953 struct sti_scmentflags flags; 954 struct sti_scmentin in; 955 struct sti_scmentout out; 956 } a; 957 958 bzero(&a, sizeof(a)); 959 960 a.flags.flags = STI_SCMENTF_WAIT; 961 a.in.entry = i; 962 a.in.value = (r << 16) | (g << 8) | b; 963 964 (*rom->scment)(&a.flags, &a.in, &a.out, &scr->scr_cfg); 965 966 return a.out.errno; 967 } 968 969 /* 970 * wsdisplay accessops 971 */ 972 973 int 974 sti_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p) 975 { 976 struct sti_screen *scr = (struct sti_screen *)v; 977 struct sti_rom *rom = scr->scr_rom; 978 struct wsdisplay_fbinfo *wdf; 979 struct wsdisplay_cmap *cmapp; 980 u_int mode, idx, count; 981 int i, ret; 982 983 ret = 0; 984 switch (cmd) { 985 case WSDISPLAYIO_SMODE: 986 mode = *(u_int *)data; 987 if (scr->scr_wsmode == WSDISPLAYIO_MODE_EMUL && 988 mode == WSDISPLAYIO_MODE_DUMBFB) 989 ret = sti_init(scr, 0); 990 else if (scr->scr_wsmode == WSDISPLAYIO_MODE_DUMBFB && 991 mode == WSDISPLAYIO_MODE_EMUL) 992 ret = sti_init(scr, STI_TEXTMODE); 993 scr->scr_wsmode = mode; 994 break; 995 996 case WSDISPLAYIO_GTYPE: 997 *(u_int *)data = WSDISPLAY_TYPE_STI; 998 break; 999 1000 case WSDISPLAYIO_GINFO: 1001 wdf = (struct wsdisplay_fbinfo *)data; 1002 wdf->height = scr->scr_cfg.scr_height; 1003 wdf->width = scr->scr_cfg.scr_width; 1004 wdf->depth = scr->scr_bpp; 1005 if (rom->scment == NULL) 1006 wdf->cmsize = 0; 1007 else 1008 wdf->cmsize = STI_NCMAP; 1009 break; 1010 1011 case WSDISPLAYIO_LINEBYTES: 1012 *(u_int *)data = scr->scr_cfg.fb_width; 1013 break; 1014 1015 case WSDISPLAYIO_GETCMAP: 1016 if (rom->scment == NULL) 1017 return ENODEV; 1018 cmapp = (struct wsdisplay_cmap *)data; 1019 idx = cmapp->index; 1020 count = cmapp->count; 1021 if (idx >= STI_NCMAP || idx + count > STI_NCMAP) 1022 return EINVAL; 1023 if ((ret = copyout(&scr->scr_rcmap[idx], cmapp->red, count))) 1024 break; 1025 if ((ret = copyout(&scr->scr_gcmap[idx], cmapp->green, count))) 1026 break; 1027 if ((ret = copyout(&scr->scr_bcmap[idx], cmapp->blue, count))) 1028 break; 1029 break; 1030 1031 case WSDISPLAYIO_PUTCMAP: 1032 if (rom->scment == NULL) 1033 return ENODEV; 1034 cmapp = (struct wsdisplay_cmap *)data; 1035 idx = cmapp->index; 1036 count = cmapp->count; 1037 if (idx >= STI_NCMAP || idx + count > STI_NCMAP) 1038 return EINVAL; 1039 if ((ret = copyin(cmapp->red, &scr->scr_rcmap[idx], count))) 1040 break; 1041 if ((ret = copyin(cmapp->green, &scr->scr_gcmap[idx], count))) 1042 break; 1043 if ((ret = copyin(cmapp->blue, &scr->scr_bcmap[idx], count))) 1044 break; 1045 for (i = idx + count - 1; i >= idx; i--) 1046 if ((ret = sti_setcment(scr, i, scr->scr_rcmap[i], 1047 scr->scr_gcmap[i], scr->scr_bcmap[i]))) { 1048 #ifdef STIDEBUG 1049 printf("sti_ioctl: " 1050 "sti_setcment(%d, %u, %u, %u): %d\n", i, 1051 (u_int)scr->scr_rcmap[i], 1052 (u_int)scr->scr_gcmap[i], 1053 (u_int)scr->scr_bcmap[i]); 1054 #endif 1055 ret = EINVAL; 1056 break; 1057 } 1058 break; 1059 1060 case WSDISPLAYIO_SVIDEO: 1061 case WSDISPLAYIO_GVIDEO: 1062 break; 1063 1064 default: 1065 return (-1); /* not supported yet */ 1066 } 1067 1068 return (ret); 1069 } 1070 1071 paddr_t 1072 sti_mmap(void *v, off_t offset, int prot) 1073 { 1074 #if 0 1075 struct sti_screen *scr = (struct sti_screen *)v; 1076 #endif 1077 1078 /* XXX not finished */ 1079 return -1; 1080 } 1081 1082 int 1083 sti_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep, 1084 int *cxp, int *cyp, long *defattr) 1085 { 1086 struct sti_screen *scr = (struct sti_screen *)v; 1087 1088 if (scr->scr_nscreens > 0) 1089 return ENOMEM; 1090 1091 *cookiep = scr; 1092 *cxp = 0; 1093 *cyp = 0; 1094 sti_alloc_attr(scr, 0, 0, 0, defattr); 1095 scr->scr_nscreens++; 1096 return 0; 1097 } 1098 1099 void 1100 sti_free_screen(void *v, void *cookie) 1101 { 1102 struct sti_screen *scr = (struct sti_screen *)v; 1103 1104 scr->scr_nscreens--; 1105 } 1106 1107 int 1108 sti_show_screen(void *v, void *cookie, int waitok, 1109 void (*cb)(void *, int, int), void *cbarg) 1110 { 1111 #if 0 1112 struct sti_screen *scr = (struct sti_screen *)v; 1113 #endif 1114 1115 return 0; 1116 } 1117 1118 /* 1119 * wsdisplay emulops 1120 */ 1121 1122 int 1123 sti_cursor(void *v, int on, int row, int col) 1124 { 1125 struct sti_screen *scr = (struct sti_screen *)v; 1126 struct sti_font *fp = &scr->scr_curfont; 1127 1128 sti_bmove(scr, 1129 col * fp->width, row * fp->height, 1130 col * fp->width, row * fp->height, 1131 fp->height, fp->width, bmf_invert); 1132 1133 return 0; 1134 } 1135 1136 /* 1137 * ISO 8859-1 part of Unicode to HP Roman font index conversion array. 1138 */ 1139 static const u_int8_t 1140 sti_unitoroman[0x100 - 0xa0] = { 1141 0xa0, 0xb8, 0xbf, 0xbb, 0xba, 0xbc, 0, 0xbd, 1142 0xab, 0, 0xf9, 0xfb, 0, 0xf6, 0, 0xb0, 1143 1144 0xb3, 0xfe, 0, 0, 0xa8, 0xf3, 0xf4, 0xf2, 1145 0, 0, 0xfa, 0xfd, 0xf7, 0xf8, 0, 0xb9, 1146 1147 0xa1, 0xe0, 0xa2, 0xe1, 0xd8, 0xd0, 0xd3, 0xb4, 1148 0xa3, 0xdc, 0xa4, 0xa5, 0xe6, 0xe5, 0xa6, 0xa7, 1149 1150 0xe3, 0xb6, 0xe8, 0xe7, 0xdf, 0xe9, 0xda, 0, 1151 0xd2, 0xad, 0xed, 0xae, 0xdb, 0xb1, 0xf0, 0xde, 1152 1153 0xc8, 0xc4, 0xc0, 0xe2, 0xcc, 0xd4, 0xd7, 0xb5, 1154 0xc9, 0xc5, 0xc1, 0xcd, 0xd9, 0xd5, 0xd1, 0xdd, 1155 1156 0xe4, 0xb7, 0xca, 0xc6, 0xc2, 0xea, 0xce, 0, 1157 0xd6, 0xcb, 0xc7, 0xc3, 0xcf, 0xb2, 0xf1, 0xef 1158 }; 1159 1160 int 1161 sti_mapchar(void *v, int uni, u_int *index) 1162 { 1163 struct sti_screen *scr = (struct sti_screen *)v; 1164 struct sti_font *fp = &scr->scr_curfont; 1165 int c; 1166 1167 switch (fp->type) { 1168 case STI_FONT_HPROMAN8: 1169 if (uni >= 0x80 && uni < 0xa0) 1170 c = -1; 1171 else if (uni >= 0xa0 && uni < 0x100) { 1172 c = (int)sti_unitoroman[uni - 0xa0]; 1173 if (c == 0) 1174 c = -1; 1175 } else 1176 c = uni; 1177 break; 1178 default: 1179 c = uni; 1180 break; 1181 } 1182 1183 if (c == -1 || c < fp->first || c > fp->last) { 1184 *index = ' '; 1185 return (0); 1186 } 1187 1188 *index = c; 1189 return (5); 1190 } 1191 1192 int 1193 sti_putchar(void *v, int row, int col, u_int uc, long attr) 1194 { 1195 struct sti_screen *scr = (struct sti_screen *)v; 1196 struct sti_rom *rom = scr->scr_rom; 1197 struct sti_font *fp = &scr->scr_curfont; 1198 1199 if (scr->scr_romfont != NULL) { 1200 /* 1201 * Font is in memory, use unpmv 1202 */ 1203 struct { 1204 struct sti_unpmvflags flags; 1205 struct sti_unpmvin in; 1206 struct sti_unpmvout out; 1207 } a; 1208 1209 bzero(&a, sizeof(a)); 1210 1211 a.flags.flags = STI_UNPMVF_WAIT; 1212 /* XXX does not handle text attributes */ 1213 a.in.fg_colour = STI_COLOUR_WHITE; 1214 a.in.bg_colour = STI_COLOUR_BLACK; 1215 a.in.x = col * fp->width; 1216 a.in.y = row * fp->height; 1217 a.in.font_addr = scr->scr_romfont; 1218 a.in.index = uc; 1219 1220 (*rom->unpmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg); 1221 } else { 1222 /* 1223 * Font is in frame buffer, use blkmv 1224 */ 1225 struct { 1226 struct sti_blkmvflags flags; 1227 struct sti_blkmvin in; 1228 struct sti_blkmvout out; 1229 } a; 1230 1231 bzero(&a, sizeof(a)); 1232 1233 a.flags.flags = STI_BLKMVF_WAIT; 1234 /* XXX does not handle text attributes */ 1235 a.in.fg_colour = STI_COLOUR_WHITE; 1236 a.in.bg_colour = STI_COLOUR_BLACK; 1237 1238 a.in.srcx = ((uc - fp->first) / scr->scr_fontmaxcol) * 1239 fp->width + scr->scr_fontbase; 1240 a.in.srcy = ((uc - fp->first) % scr->scr_fontmaxcol) * 1241 fp->height; 1242 a.in.dstx = col * fp->width; 1243 a.in.dsty = row * fp->height; 1244 a.in.height = fp->height; 1245 a.in.width = fp->width; 1246 1247 (*rom->blkmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg); 1248 } 1249 1250 return 0; 1251 } 1252 1253 int 1254 sti_copycols(void *v, int row, int srccol, int dstcol, int ncols) 1255 { 1256 struct sti_screen *scr = (struct sti_screen *)v; 1257 struct sti_font *fp = &scr->scr_curfont; 1258 1259 sti_bmove(scr, 1260 srccol * fp->width, row * fp->height, 1261 dstcol * fp->width, row * fp->height, 1262 fp->height, ncols * fp->width, bmf_copy); 1263 1264 return 0; 1265 } 1266 1267 int 1268 sti_erasecols(void *v, int row, int startcol, int ncols, long attr) 1269 { 1270 struct sti_screen *scr = (struct sti_screen *)v; 1271 struct sti_font *fp = &scr->scr_curfont; 1272 1273 sti_bmove(scr, 1274 startcol * fp->width, row * fp->height, 1275 startcol * fp->width, row * fp->height, 1276 fp->height, ncols * fp->width, bmf_clear); 1277 1278 return 0; 1279 } 1280 1281 int 1282 sti_copyrows(void *v, int srcrow, int dstrow, int nrows) 1283 { 1284 struct sti_screen *scr = (struct sti_screen *)v; 1285 struct sti_font *fp = &scr->scr_curfont; 1286 1287 sti_bmove(scr, 0, srcrow * fp->height, 0, dstrow * fp->height, 1288 nrows * fp->height, scr->scr_cfg.scr_width, bmf_copy); 1289 1290 return 0; 1291 } 1292 1293 int 1294 sti_eraserows(void *v, int srcrow, int nrows, long attr) 1295 { 1296 struct sti_screen *scr = (struct sti_screen *)v; 1297 struct sti_font *fp = &scr->scr_curfont; 1298 1299 sti_bmove(scr, 0, srcrow * fp->height, 0, srcrow * fp->height, 1300 nrows * fp->height, scr->scr_cfg.scr_width, bmf_clear); 1301 1302 return 0; 1303 } 1304 1305 int 1306 sti_alloc_attr(void *v, int fg, int bg, int flags, long *pattr) 1307 { 1308 #if 0 1309 struct sti_screen *scr = (struct sti_screen *)v; 1310 #endif 1311 1312 *pattr = 0; 1313 return 0; 1314 } 1315 1316 void 1317 sti_unpack_attr(void *v, long attr, int *fg, int *bg, int *ul) 1318 { 1319 #if 0 1320 struct sti_screen *scr = (struct sti_screen *)v; 1321 #endif 1322 1323 *fg = WSCOL_WHITE; 1324 *bg = WSCOL_BLACK; 1325 if (ul != NULL) 1326 *ul = 0; 1327 } 1328 1329 #if NSTI_SGC > 0 1330 1331 /* 1332 * Early console support. 1333 * Only used on hp300 with unique sti@sgc attachment. 1334 */ 1335 1336 int 1337 sti_cnattach(struct sti_rom *rom, struct sti_screen *scr, bus_space_tag_t memt, 1338 bus_addr_t *bases, u_int codebase) 1339 { 1340 bus_space_handle_t romh; 1341 u_int romend; 1342 int error; 1343 long defattr; 1344 1345 if ((error = bus_space_map(memt, bases[0], PAGE_SIZE, 0, &romh)) != 0) 1346 return (error); 1347 1348 /* 1349 * Compute real PROM size 1350 */ 1351 romend = sti_rom_size(memt, romh); 1352 1353 bus_space_unmap(memt, romh, PAGE_SIZE); 1354 1355 if ((error = bus_space_map(memt, bases[0], romend, 0, &romh)) != 0) 1356 return (error); 1357 1358 bases[0] = romh; 1359 if (sti_rom_setup(rom, memt, memt, romh, bases, codebase) != 0) 1360 panic(__func__); 1361 scr->scr_rom = rom; 1362 if (sti_screen_setup(scr, STI_CLEARSCR) != 0) 1363 panic(__func__); 1364 1365 sti_alloc_attr(scr, 0, 0, 0, &defattr); 1366 wsdisplay_cnattach(&scr->scr_wsd, scr, 0, 0, defattr); 1367 1368 return (0); 1369 } 1370 1371 #endif /* NSTI_SGC > 0 */ 1372