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