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