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