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