Home | History | Annotate | Line # | Download | only in ic
      1  1.47   tsutsui /*	$NetBSD: sti.c,v 1.47 2025/05/30 19:42:28 tsutsui 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.23   tsutsui  *	X11 support on more models.
     35   1.1     jkunz  */
     36   1.1     jkunz 
     37   1.1     jkunz #include <sys/cdefs.h>
     38  1.47   tsutsui __KERNEL_RCSID(0, "$NetBSD: sti.c,v 1.47 2025/05/30 19:42:28 tsutsui 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.22  riastrad #include <uvm/uvm_extern.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.40  macallan #include <dev/ic/summitreg.h>
     56   1.1     jkunz #include <dev/ic/stivar.h>
     57   1.1     jkunz 
     58  1.13     skrll #ifdef STIDEBUG
     59  1.13     skrll 
     60  1.13     skrll #define	DPRINTF(s)	do {	\
     61  1.13     skrll 	if (stidebug)		\
     62  1.13     skrll 		printf s;	\
     63  1.13     skrll } while(0)
     64  1.13     skrll 
     65  1.13     skrll int stidebug = 1;
     66  1.13     skrll #else
     67  1.13     skrll #define	DPRINTF(s)	/* */
     68  1.13     skrll #endif
     69  1.13     skrll 
     70   1.1     jkunz void sti_cursor(void *, int, int, int);
     71   1.1     jkunz int  sti_mapchar(void *, int, u_int *);
     72   1.1     jkunz void sti_putchar(void *, int, int, u_int, long);
     73   1.1     jkunz void sti_copycols(void *, int, int, int, int);
     74   1.1     jkunz void sti_erasecols(void *, int, int, int, long);
     75   1.1     jkunz void sti_copyrows(void *, int, int, int);
     76   1.1     jkunz void sti_eraserows(void *, int, int, long);
     77   1.1     jkunz int  sti_alloc_attr(void *, int, int, int, long *);
     78   1.1     jkunz 
     79  1.24   tsutsui /* pseudo attribute ops for sti ROM putchar function */
     80  1.24   tsutsui #define WSATTR_FG_SHIFT	24
     81  1.24   tsutsui #define WSATTR_BG_SHIFT	16
     82  1.24   tsutsui #define WSATTR_UNPACK_FG(attr)	(((attr) >> WSATTR_FG_SHIFT) & 0xff)
     83  1.24   tsutsui #define WSATTR_UNPACK_BG(attr)	(((attr) >> WSATTR_BG_SHIFT) & 0xff)
     84  1.24   tsutsui #define WSATTR_UNPACK_FLAG(attr) ((attr) & WSATTR_USERMASK)
     85  1.24   tsutsui #define WSATTR_PACK_FG(fg)	((fg) << WSATTR_FG_SHIFT)
     86  1.24   tsutsui #define WSATTR_PACK_BG(bg)	((bg) << WSATTR_BG_SHIFT)
     87  1.24   tsutsui #define WSATTR_PACK_FLAG(flag)	((flag))
     88  1.24   tsutsui #define WSATTR_PACK(fg, bg, flag)	\
     89  1.24   tsutsui     (WSATTR_PACK_FG(fg) | WSATTR_PACK_BG(bg) | WSATTR_PACK_FLAG(flag))
     90  1.24   tsutsui 
     91   1.1     jkunz struct wsdisplay_emulops sti_emulops = {
     92  1.23   tsutsui 	.cursor = sti_cursor,
     93  1.23   tsutsui 	.mapchar = sti_mapchar,
     94  1.23   tsutsui 	.putchar = sti_putchar,
     95  1.23   tsutsui 	.copycols = sti_copycols,
     96  1.23   tsutsui 	.erasecols = sti_erasecols,
     97  1.23   tsutsui 	.copyrows = sti_copyrows,
     98  1.23   tsutsui 	.eraserows = sti_eraserows,
     99  1.23   tsutsui 	.allocattr = sti_alloc_attr
    100   1.1     jkunz };
    101   1.1     jkunz 
    102   1.1     jkunz const struct wsdisplay_accessops sti_accessops = {
    103  1.23   tsutsui 	.ioctl = sti_ioctl,
    104  1.23   tsutsui 	.mmap = sti_mmap,
    105  1.23   tsutsui 	.alloc_screen = sti_alloc_screen,
    106  1.23   tsutsui 	.free_screen = sti_free_screen,
    107  1.23   tsutsui 	.show_screen = sti_show_screen,
    108  1.23   tsutsui 	.load_font = sti_load_font
    109   1.1     jkunz };
    110   1.1     jkunz 
    111  1.13     skrll enum sti_bmove_funcs {
    112  1.13     skrll 	bmf_clear, bmf_copy, bmf_invert, bmf_underline
    113   1.1     jkunz };
    114   1.1     jkunz 
    115  1.13     skrll void	sti_bmove(struct sti_screen *, int, int, int, int, int, int,
    116  1.13     skrll 	    enum sti_bmove_funcs);
    117  1.23   tsutsui int	sti_inqcfg(struct sti_screen *, struct sti_inqconfout *);
    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.23   tsutsui int	ngle_default_putcmap(struct sti_screen *, u_int, u_int);
    131  1.23   tsutsui 
    132  1.23   tsutsui #ifndef SMALL_KERNEL
    133  1.23   tsutsui void	ngle_artist_setupfb(struct sti_screen *);
    134  1.23   tsutsui void	ngle_elk_setupfb(struct sti_screen *);
    135  1.23   tsutsui void	ngle_timber_setupfb(struct sti_screen *);
    136  1.40  macallan void	summit_setupfb(struct sti_screen *);
    137  1.23   tsutsui int	ngle_putcmap(struct sti_screen *, u_int, u_int);
    138  1.37  macallan int	ngle_hcrx_putcmap(struct sti_screen *, u_int, u_int);
    139  1.40  macallan int	summit_putcmap(struct sti_screen *, u_int, u_int);
    140  1.23   tsutsui #endif
    141  1.23   tsutsui 
    142  1.13     skrll #define	STI_ENABLE_ROM(sc) \
    143  1.13     skrll do { \
    144  1.13     skrll 	if ((sc) != NULL && (sc)->sc_enable_rom != NULL) \
    145  1.13     skrll 		(*(sc)->sc_enable_rom)(sc); \
    146  1.13     skrll } while (0)
    147  1.13     skrll #define	STI_DISABLE_ROM(sc) \
    148  1.13     skrll do { \
    149  1.13     skrll 	if ((sc) != NULL && (sc)->sc_disable_rom != NULL) \
    150  1.13     skrll 		(*(sc)->sc_disable_rom)(sc); \
    151  1.13     skrll } while (0)
    152  1.13     skrll 
    153  1.13     skrll /* Macros to read larger than 8 bit values from byte roms */
    154  1.13     skrll #define	parseshort(o) \
    155  1.13     skrll 	((bus_space_read_1(memt, romh, (o) + 3) <<  8) | \
    156  1.13     skrll 	 (bus_space_read_1(memt, romh, (o) + 7)))
    157  1.13     skrll #define	parseword(o) \
    158  1.13     skrll 	((bus_space_read_1(memt, romh, (o) +  3) << 24) | \
    159  1.13     skrll 	 (bus_space_read_1(memt, romh, (o) +  7) << 16) | \
    160  1.13     skrll 	 (bus_space_read_1(memt, romh, (o) + 11) <<  8) | \
    161  1.13     skrll 	 (bus_space_read_1(memt, romh, (o) + 15)))
    162  1.13     skrll 
    163  1.13     skrll int
    164  1.13     skrll sti_attach_common(struct sti_softc *sc, bus_space_tag_t iot,
    165  1.13     skrll     bus_space_tag_t memt, bus_space_handle_t romh, u_int codebase)
    166  1.13     skrll {
    167  1.13     skrll 	struct sti_rom *rom;
    168  1.13     skrll 	int rc;
    169  1.13     skrll 
    170  1.13     skrll 	rom = (struct sti_rom *)malloc(sizeof(*rom), M_DEVBUF,
    171  1.20       chs 	    M_WAITOK | M_ZERO);
    172  1.13     skrll 	rom->rom_softc = sc;
    173  1.13     skrll 	rc = sti_rom_setup(rom, iot, memt, romh, sc->bases, codebase);
    174  1.13     skrll 	if (rc != 0) {
    175  1.13     skrll 		free(rom, M_DEVBUF);
    176  1.13     skrll 		return rc;
    177  1.13     skrll 	}
    178  1.13     skrll 
    179  1.13     skrll 	sc->sc_rom = rom;
    180  1.13     skrll 
    181  1.13     skrll 	sti_describe(sc);
    182  1.13     skrll 
    183  1.13     skrll 	sc->sc_scr = sti_attach_screen(sc,
    184  1.13     skrll 	    sc->sc_flags & STI_CONSOLE ? 0 : STI_CLEARSCR);
    185  1.13     skrll 	if (sc->sc_scr == NULL)
    186  1.13     skrll 		rc = ENOMEM;
    187  1.13     skrll 
    188  1.13     skrll 	return rc;
    189  1.13     skrll }
    190  1.13     skrll 
    191  1.13     skrll struct sti_screen *
    192  1.13     skrll sti_attach_screen(struct sti_softc *sc, int flags)
    193  1.13     skrll {
    194  1.13     skrll 	struct sti_screen *scr;
    195  1.13     skrll 	int rc;
    196  1.13     skrll 
    197  1.13     skrll 	scr = (struct sti_screen *)malloc(sizeof(*scr), M_DEVBUF,
    198  1.20       chs 	    M_WAITOK | M_ZERO);
    199  1.13     skrll 	scr->scr_rom = sc->sc_rom;
    200  1.13     skrll 	rc = sti_screen_setup(scr, flags);
    201  1.13     skrll 	if (rc != 0) {
    202  1.13     skrll 		free(scr, M_DEVBUF);
    203  1.13     skrll 		return NULL;
    204  1.13     skrll 	}
    205   1.1     jkunz 
    206  1.13     skrll 	sti_describe_screen(sc, scr);
    207   1.1     jkunz 
    208  1.13     skrll 	return scr;
    209  1.13     skrll }
    210   1.1     jkunz 
    211  1.13     skrll int
    212  1.13     skrll sti_rom_setup(struct sti_rom *rom, bus_space_tag_t iot, bus_space_tag_t memt,
    213  1.13     skrll     bus_space_handle_t romh, bus_addr_t *bases, u_int codebase)
    214   1.1     jkunz {
    215   1.1     jkunz 	struct sti_dd *dd;
    216   1.1     jkunz 	int error, size, i;
    217   1.1     jkunz 
    218  1.13     skrll 	KASSERT(rom != NULL);
    219  1.13     skrll 	STI_ENABLE_ROM(rom->rom_softc);
    220  1.13     skrll 
    221  1.13     skrll 	rom->iot = iot;
    222  1.13     skrll 	rom->memt = memt;
    223  1.13     skrll 	rom->romh = romh;
    224  1.13     skrll 	rom->bases = bases;
    225  1.13     skrll 
    226  1.13     skrll 	/*
    227  1.13     skrll 	 * Get ROM header and code function pointers.
    228  1.13     skrll 	 */
    229  1.23   tsutsui 
    230  1.13     skrll 	dd = &rom->rom_dd;
    231  1.13     skrll 	rom->rom_devtype = bus_space_read_1(memt, romh, 3);
    232  1.13     skrll 	if (rom->rom_devtype == STI_DEVTYPE1) {
    233  1.23   tsutsui 		dd->dd_type      = bus_space_read_1(memt, romh, 0x03);
    234  1.23   tsutsui 		dd->dd_nmon      = bus_space_read_1(memt, romh, 0x07);
    235  1.23   tsutsui 		dd->dd_grrev     = bus_space_read_1(memt, romh, 0x0b);
    236  1.23   tsutsui 		dd->dd_lrrev     = bus_space_read_1(memt, romh, 0x0f);
    237  1.23   tsutsui 		dd->dd_grid[0]   = parseword(0x10);
    238  1.23   tsutsui 		dd->dd_grid[1]   = parseword(0x20);
    239  1.23   tsutsui 		dd->dd_fntaddr   = parseword(0x30) & ~3;
    240  1.23   tsutsui 		dd->dd_maxst     = parseword(0x40);
    241  1.23   tsutsui 		dd->dd_romend    = parseword(0x50) & ~3;
    242  1.23   tsutsui 		dd->dd_reglst    = parseword(0x60) & ~3;
    243  1.23   tsutsui 		dd->dd_maxreent  = parseshort(0x70);
    244  1.23   tsutsui 		dd->dd_maxtimo   = parseshort(0x78);
    245  1.23   tsutsui 		dd->dd_montbl    = parseword(0x80) & ~3;
    246  1.23   tsutsui 		dd->dd_udaddr    = parseword(0x90) & ~3;
    247  1.23   tsutsui 		dd->dd_stimemreq = parseword(0xa0);
    248  1.23   tsutsui 		dd->dd_udsize    = parseword(0xb0);
    249  1.23   tsutsui 		dd->dd_pwruse    = parseshort(0xc0);
    250  1.23   tsutsui 		dd->dd_bussup    = bus_space_read_1(memt, romh, 0xcb);
    251  1.23   tsutsui 		dd->dd_ebussup   = bus_space_read_1(memt, romh, 0xcf);
    252  1.23   tsutsui 		dd->dd_altcodet  = bus_space_read_1(memt, romh, 0xd3);
    253  1.23   tsutsui 		dd->dd_eddst[0]  = bus_space_read_1(memt, romh, 0xd7);
    254  1.23   tsutsui 		dd->dd_eddst[1]  = bus_space_read_1(memt, romh, 0xdb);
    255  1.23   tsutsui 		dd->dd_eddst[2]  = bus_space_read_1(memt, romh, 0xdf);
    256  1.23   tsutsui 		dd->dd_cfbaddr   = parseword(0xe0) & ~3;
    257   1.1     jkunz 
    258  1.13     skrll 		codebase <<= 2;
    259  1.23   tsutsui 		dd->dd_pacode[0x0] = parseword(codebase + 0x000) & ~3;
    260  1.23   tsutsui 		dd->dd_pacode[0x1] = parseword(codebase + 0x010) & ~3;
    261  1.23   tsutsui 		dd->dd_pacode[0x2] = parseword(codebase + 0x020) & ~3;
    262  1.23   tsutsui 		dd->dd_pacode[0x3] = parseword(codebase + 0x030) & ~3;
    263  1.23   tsutsui 		dd->dd_pacode[0x4] = parseword(codebase + 0x040) & ~3;
    264  1.23   tsutsui 		dd->dd_pacode[0x5] = parseword(codebase + 0x050) & ~3;
    265  1.23   tsutsui 		dd->dd_pacode[0x6] = parseword(codebase + 0x060) & ~3;
    266  1.23   tsutsui 		dd->dd_pacode[0x7] = parseword(codebase + 0x070) & ~3;
    267  1.23   tsutsui 		dd->dd_pacode[0x8] = parseword(codebase + 0x080) & ~3;
    268  1.23   tsutsui 		dd->dd_pacode[0x9] = parseword(codebase + 0x090) & ~3;
    269  1.23   tsutsui 		dd->dd_pacode[0xa] = parseword(codebase + 0x0a0) & ~3;
    270  1.23   tsutsui 		dd->dd_pacode[0xb] = parseword(codebase + 0x0b0) & ~3;
    271  1.23   tsutsui 		dd->dd_pacode[0xc] = parseword(codebase + 0x0c0) & ~3;
    272  1.23   tsutsui 		dd->dd_pacode[0xd] = parseword(codebase + 0x0d0) & ~3;
    273  1.23   tsutsui 		dd->dd_pacode[0xe] = parseword(codebase + 0x0e0) & ~3;
    274  1.23   tsutsui 		dd->dd_pacode[0xf] = parseword(codebase + 0x0f0) & ~3;
    275  1.13     skrll 	} else {	/* STI_DEVTYPE4 */
    276  1.13     skrll 		bus_space_read_region_stream_4(memt, romh, 0, (uint32_t *)dd,
    277   1.1     jkunz 		    sizeof(*dd) / 4);
    278  1.13     skrll 		/* fix pacode... */
    279  1.13     skrll 		bus_space_read_region_stream_4(memt, romh, codebase,
    280  1.13     skrll 		    (uint32_t *)dd->dd_pacode, sizeof(dd->dd_pacode) / 4);
    281  1.13     skrll 	}
    282  1.13     skrll 
    283  1.13     skrll 	STI_DISABLE_ROM(rom->rom_softc);
    284   1.1     jkunz 
    285  1.13     skrll 	DPRINTF(("dd:\n"
    286  1.13     skrll 	    "devtype=%x, rev=%x;%d, altt=%x, gid=%08x%08x, font=%x, mss=%x\n"
    287   1.1     jkunz 	    "end=%x, regions=%x, msto=%x, timo=%d, mont=%x, user=%x[%x]\n"
    288   1.1     jkunz 	    "memrq=%x, pwr=%d, bus=%x, ebus=%x, cfb=%x\n"
    289   1.1     jkunz 	    "code=",
    290   1.1     jkunz 	    dd->dd_type & 0xff, dd->dd_grrev, dd->dd_lrrev, dd->dd_altcodet,
    291  1.13     skrll 	    dd->dd_grid[0], dd->dd_grid[1], dd->dd_fntaddr, dd->dd_maxst,
    292   1.1     jkunz 	    dd->dd_romend, dd->dd_reglst, dd->dd_maxreent, dd->dd_maxtimo,
    293   1.1     jkunz 	    dd->dd_montbl, dd->dd_udaddr, dd->dd_udsize, dd->dd_stimemreq,
    294  1.13     skrll 	    dd->dd_pwruse, dd->dd_bussup, dd->dd_ebussup, dd->dd_cfbaddr));
    295  1.13     skrll 	DPRINTF(("%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n",
    296   1.1     jkunz 	    dd->dd_pacode[0x0], dd->dd_pacode[0x1], dd->dd_pacode[0x2],
    297   1.1     jkunz 	    dd->dd_pacode[0x3], dd->dd_pacode[0x4], dd->dd_pacode[0x5],
    298   1.1     jkunz 	    dd->dd_pacode[0x6], dd->dd_pacode[0x7], dd->dd_pacode[0x8],
    299   1.1     jkunz 	    dd->dd_pacode[0x9], dd->dd_pacode[0xa], dd->dd_pacode[0xb],
    300   1.1     jkunz 	    dd->dd_pacode[0xc], dd->dd_pacode[0xd], dd->dd_pacode[0xe],
    301  1.13     skrll 	    dd->dd_pacode[0xf]));
    302  1.13     skrll 
    303  1.13     skrll 	/*
    304  1.13     skrll 	 * Figure out how many bytes we need for the STI code.
    305  1.13     skrll 	 * Note there could be fewer than STI_END pointer entries
    306  1.13     skrll 	 * populated, especially on older devices.
    307  1.13     skrll 	 */
    308  1.23   tsutsui 	for (i = STI_END; dd->dd_pacode[i] == 0; i--)
    309  1.13     skrll 		;
    310  1.13     skrll 
    311   1.1     jkunz 	size = dd->dd_pacode[i] - dd->dd_pacode[STI_BEGIN];
    312  1.13     skrll 
    313  1.13     skrll 	if (rom->rom_devtype == STI_DEVTYPE1)
    314   1.1     jkunz 		size = (size + 3) / 4;
    315  1.13     skrll 	if (size == 0) {
    316  1.13     skrll 		aprint_error(": no code for the requested platform\n");
    317  1.13     skrll 		return EINVAL;
    318  1.13     skrll 	}
    319  1.13     skrll 
    320  1.13     skrll 	if (!(rom->rom_code = uvm_km_alloc(kernel_map, round_page(size), 0,
    321   1.4      yamt 	    UVM_KMF_WIRED))) {
    322  1.13     skrll 		aprint_error(": cannot allocate %u bytes for code\n", size);
    323  1.13     skrll 		return ENOMEM;
    324   1.1     jkunz 	}
    325  1.23   tsutsui 	DPRINTF(("code=0x%lx[%x]\n", rom->rom_code, size));
    326   1.1     jkunz 
    327  1.13     skrll 	/*
    328  1.13     skrll 	 * Copy code into memory and make it executable.
    329  1.13     skrll 	 */
    330  1.13     skrll 
    331  1.13     skrll 	STI_ENABLE_ROM(rom->rom_softc);
    332  1.13     skrll 
    333  1.13     skrll 	if (rom->rom_devtype == STI_DEVTYPE1) {
    334  1.13     skrll 		uint8_t *p;
    335  1.13     skrll 		uint32_t addr, eaddr;
    336  1.13     skrll 
    337  1.13     skrll 		p = (uint8_t *)rom->rom_code;
    338  1.13     skrll 
    339   1.1     jkunz 		for (addr = dd->dd_pacode[STI_BEGIN], eaddr = addr + size * 4;
    340  1.13     skrll 		    addr < eaddr; addr += 4 ) {
    341  1.23   tsutsui 			*p++ = bus_space_read_4(memt, romh, addr) & 0xff;
    342  1.13     skrll 		}
    343  1.13     skrll 	} else {	/* STI_DEVTYPE4 */
    344  1.13     skrll 		bus_space_read_region_stream_4(memt, romh,
    345  1.13     skrll 		    dd->dd_pacode[STI_BEGIN], (uint32_t *)rom->rom_code,
    346  1.13     skrll 		    size / 4);
    347  1.13     skrll 	}
    348   1.1     jkunz 
    349  1.13     skrll 	STI_DISABLE_ROM(rom->rom_softc);
    350   1.1     jkunz 
    351  1.13     skrll 	if ((error = uvm_map_protect(kernel_map, rom->rom_code,
    352  1.13     skrll 	    rom->rom_code + round_page(size), UVM_PROT_RX, FALSE))) {
    353  1.13     skrll 		aprint_error(": uvm_map_protect failed (%d)\n", error);
    354  1.13     skrll 		uvm_km_free(kernel_map, rom->rom_code, round_page(size),
    355   1.4      yamt 		    UVM_KMF_WIRED);
    356  1.13     skrll 		return error;
    357  1.13     skrll 	}
    358  1.13     skrll 
    359  1.13     skrll 	/*
    360  1.13     skrll 	 * Setup code function pointers.
    361  1.13     skrll 	 */
    362  1.13     skrll 
    363  1.13     skrll #define	O(i) \
    364  1.13     skrll 	(dd->dd_pacode[(i)] == 0 ? 0 : \
    365  1.13     skrll 	    (rom->rom_code + (dd->dd_pacode[(i)] - dd->dd_pacode[0]) /	\
    366  1.13     skrll 	    (rom->rom_devtype == STI_DEVTYPE1 ? 4 : 1)))
    367  1.23   tsutsui 
    368  1.23   tsutsui 	rom->init	= (sti_init_t)O(STI_INIT_GRAPH);
    369  1.23   tsutsui 	rom->mgmt	= (sti_mgmt_t)O(STI_STATE_MGMT);
    370  1.23   tsutsui 	rom->unpmv	= (sti_unpmv_t)O(STI_FONT_UNPMV);
    371  1.23   tsutsui 	rom->blkmv	= (sti_blkmv_t)O(STI_BLOCK_MOVE);
    372  1.23   tsutsui 	rom->test	= (sti_test_t)O(STI_SELF_TEST);
    373  1.23   tsutsui 	rom->exhdl	= (sti_exhdl_t)O(STI_EXCEP_HDLR);
    374  1.13     skrll 	rom->inqconf	= (sti_inqconf_t)O(STI_INQ_CONF);
    375  1.13     skrll 	rom->scment	= (sti_scment_t)O(STI_SCM_ENT);
    376  1.23   tsutsui 	rom->dmac	= (sti_dmac_t)O(STI_DMA_CTRL);
    377  1.23   tsutsui 	rom->flowc	= (sti_flowc_t)O(STI_FLOW_CTRL);
    378  1.13     skrll 	rom->utiming	= (sti_utiming_t)O(STI_UTIMING);
    379  1.23   tsutsui 	rom->pmgr	= (sti_pmgr_t)O(STI_PROC_MGR);
    380  1.23   tsutsui 	rom->util	= (sti_util_t)O(STI_UTIL);
    381  1.13     skrll 
    382  1.13     skrll #undef O
    383  1.23   tsutsui 
    384  1.13     skrll 	/*
    385  1.13     skrll 	 * Set colormap entry is not implemented until 8.04, so force
    386  1.13     skrll 	 * a NULL pointer here.
    387  1.13     skrll 	 */
    388  1.13     skrll 	if (dd->dd_grrev < STI_REVISION(8, 4)) {
    389  1.13     skrll 		rom->scment = NULL;
    390  1.13     skrll 	}
    391  1.13     skrll 
    392  1.13     skrll 	return 0;
    393  1.13     skrll }
    394  1.13     skrll 
    395  1.13     skrll /*
    396  1.13     skrll  * Map all regions.
    397  1.13     skrll  */
    398  1.13     skrll void
    399  1.13     skrll sti_region_setup(struct sti_screen *scr)
    400  1.13     skrll {
    401  1.13     skrll 	struct sti_rom *rom = scr->scr_rom;
    402  1.13     skrll 	bus_space_tag_t memt = rom->memt;
    403  1.13     skrll 	bus_space_handle_t romh = rom->romh;
    404  1.13     skrll 	bus_addr_t *bases = rom->bases;
    405  1.13     skrll 	struct sti_dd *dd = &rom->rom_dd;
    406  1.13     skrll 	struct sti_cfg *cc = &scr->scr_cfg;
    407  1.13     skrll 	struct sti_region regions[STI_REGION_MAX], *r;
    408  1.13     skrll 	u_int regno, regcnt;
    409  1.13     skrll 	bus_addr_t addr;
    410  1.13     skrll 
    411  1.13     skrll 	DPRINTF(("stiregions @ %x:\n", dd->dd_reglst));
    412  1.13     skrll 
    413  1.13     skrll 	/*
    414  1.13     skrll 	 * Read the region information.
    415  1.13     skrll 	 */
    416  1.13     skrll 
    417  1.13     skrll 	STI_ENABLE_ROM(rom->rom_softc);
    418  1.13     skrll 
    419  1.13     skrll 	if (rom->rom_devtype == STI_DEVTYPE1) {
    420  1.13     skrll 		for (regno = 0; regno < STI_REGION_MAX; regno++)
    421  1.13     skrll 			*(u_int *)(regions + regno) =
    422  1.13     skrll 			    parseword(dd->dd_reglst + regno * 0x10);
    423  1.13     skrll 	} else {
    424  1.13     skrll 		bus_space_read_region_stream_4(memt, romh, dd->dd_reglst,
    425  1.13     skrll 		    (uint32_t *)regions, sizeof(regions) / 4);
    426   1.1     jkunz 	}
    427   1.1     jkunz 
    428  1.13     skrll 	STI_DISABLE_ROM(rom->rom_softc);
    429  1.13     skrll 
    430  1.13     skrll 	/*
    431  1.13     skrll 	 * Count them.
    432  1.13     skrll 	 */
    433  1.13     skrll 
    434  1.13     skrll 	for (regcnt = 0, r = regions; regcnt < STI_REGION_MAX; regcnt++, r++)
    435  1.13     skrll 		if (r->last)
    436  1.13     skrll 			break;
    437  1.13     skrll 	regcnt++;
    438  1.13     skrll 
    439  1.13     skrll 	/*
    440  1.13     skrll 	 * Map them.
    441  1.13     skrll 	 */
    442  1.13     skrll 
    443  1.13     skrll 	for (regno = 0, r = regions; regno < regcnt; regno++, r++) {
    444  1.13     skrll 		if (r->length == 0)
    445  1.13     skrll 			continue;
    446  1.13     skrll 
    447  1.13     skrll 		/*
    448  1.13     skrll 		 * Assume an existing mapping exists.
    449  1.13     skrll 		 */
    450  1.46   tsutsui 		addr = bases[regno] + (r->offset << STI_PGSHIFT);
    451  1.13     skrll 		DPRINTF(("%08x @ 0x%08x%s%s%s%s",
    452  1.46   tsutsui 		    r->length << STI_PGSHIFT, (int)addr,
    453  1.46   tsutsui 		    r->sys_only ? " sys" : "",
    454  1.13     skrll 		    r->cache ? " cache" : "", r->btlb ? " btlb" : "",
    455  1.13     skrll 		    r->last ? " last" : ""));
    456  1.13     skrll 
    457  1.13     skrll 		/*
    458  1.13     skrll 		 * Region #0 is always the rom, and it should have been
    459  1.13     skrll 		 * mapped already.
    460  1.13     skrll 		 * XXX This expects a 1:1 mapping...
    461  1.13     skrll 		 */
    462  1.13     skrll 		if (regno == 0 && romh == bases[0]) {
    463  1.13     skrll 			cc->regions[0] = addr;
    464  1.14     skrll 			DPRINTF(("\n"));
    465  1.13     skrll 			continue;
    466  1.13     skrll 		}
    467  1.13     skrll 
    468  1.46   tsutsui 		if (bus_space_map(memt, addr, r->length << STI_PGSHIFT,
    469  1.23   tsutsui 		    BUS_SPACE_MAP_LINEAR | (r->cache ?
    470  1.23   tsutsui 		    BUS_SPACE_MAP_CACHEABLE : 0), &rom->regh[regno]) != 0) {
    471  1.23   tsutsui 			rom->regh[regno] = romh;	/* XXX */
    472  1.13     skrll 			DPRINTF((" - already mapped region\n"));
    473  1.13     skrll 		} else {
    474  1.23   tsutsui 			addr = (bus_addr_t)
    475  1.23   tsutsui 			    bus_space_vaddr(memt, rom->regh[regno]);
    476  1.13     skrll 			if (regno == 1) {
    477  1.14     skrll 				DPRINTF((" - fb"));
    478  1.13     skrll 				scr->fbaddr = addr;
    479  1.46   tsutsui 				scr->fblen = r->length << STI_PGSHIFT;
    480  1.13     skrll 			}
    481  1.14     skrll 			DPRINTF(("\n"));
    482  1.13     skrll 		}
    483   1.1     jkunz 
    484  1.13     skrll 		cc->regions[regno] = addr;
    485  1.13     skrll 	}
    486   1.1     jkunz 
    487   1.1     jkunz #ifdef STIDEBUG
    488  1.13     skrll 	/*
    489  1.13     skrll 	 * Make sure we'll trap accessing unmapped regions
    490  1.13     skrll 	 */
    491  1.13     skrll 	for (regno = 0; regno < STI_REGION_MAX; regno++)
    492  1.13     skrll 		if (cc->regions[regno] == 0)
    493  1.47   tsutsui 			cc->regions[regno] = 0x81234567;
    494   1.1     jkunz #endif
    495  1.13     skrll }
    496   1.1     jkunz 
    497  1.13     skrll int
    498  1.13     skrll sti_screen_setup(struct sti_screen *scr, int flags)
    499  1.13     skrll {
    500  1.13     skrll 	struct sti_rom *rom = scr->scr_rom;
    501  1.13     skrll 	bus_space_tag_t memt = rom->memt;
    502  1.13     skrll 	bus_space_handle_t romh = rom->romh;
    503  1.13     skrll 	struct sti_dd *dd = &rom->rom_dd;
    504  1.13     skrll 	struct sti_cfg *cc = &scr->scr_cfg;
    505  1.13     skrll 	struct sti_inqconfout cfg;
    506  1.13     skrll 	struct sti_einqconfout ecfg;
    507   1.1     jkunz #ifdef STIDEBUG
    508  1.13     skrll 	char buf[256];
    509   1.1     jkunz #endif
    510  1.13     skrll 	int error, i;
    511  1.13     skrll 	int geometry_kluge = 0;
    512  1.13     skrll 	u_int fontindex = 0;
    513  1.13     skrll 
    514  1.13     skrll 	KASSERT(scr != NULL);
    515  1.13     skrll 	memset(cc, 0, sizeof(*cc));
    516  1.13     skrll 	cc->ext_cfg = &scr->scr_ecfg;
    517  1.13     skrll 	memset(cc->ext_cfg, 0, sizeof(*cc->ext_cfg));
    518  1.13     skrll 
    519  1.13     skrll 	if (dd->dd_stimemreq) {
    520  1.13     skrll 		scr->scr_ecfg.addr =
    521  1.20       chs 		    malloc(dd->dd_stimemreq, M_DEVBUF, M_WAITOK);
    522   1.1     jkunz 	}
    523   1.1     jkunz 
    524  1.13     skrll 	sti_region_setup(scr);
    525  1.13     skrll 
    526  1.13     skrll 	if ((error = sti_init(scr, 0))) {
    527  1.13     skrll 		aprint_error(": cannot initialize (%d)\n", error);
    528  1.13     skrll 		goto fail;
    529   1.1     jkunz 	}
    530   1.1     jkunz 
    531   1.1     jkunz 	memset(&cfg, 0, sizeof(cfg));
    532   1.1     jkunz 	memset(&ecfg, 0, sizeof(ecfg));
    533   1.1     jkunz 	cfg.ext = &ecfg;
    534  1.13     skrll 	if ((error = sti_inqcfg(scr, &cfg))) {
    535  1.13     skrll 		aprint_error(": error %d inquiring config\n", error);
    536  1.13     skrll 		goto fail;
    537   1.1     jkunz 	}
    538   1.1     jkunz 
    539  1.13     skrll 	/*
    540  1.13     skrll 	 * Older (rev 8.02) boards report wrong offset values,
    541  1.13     skrll 	 * similar to the displayable area size, at least in m68k mode.
    542  1.13     skrll 	 * Attempt to detect this and adjust here.
    543  1.13     skrll 	 */
    544  1.13     skrll 	if (cfg.owidth == cfg.width &&
    545  1.13     skrll 	    cfg.oheight == cfg.height)
    546  1.13     skrll 		geometry_kluge = 1;
    547  1.13     skrll 
    548  1.13     skrll 	if (geometry_kluge) {
    549  1.13     skrll 		scr->scr_cfg.oscr_width = cfg.owidth =
    550  1.13     skrll 		    cfg.fbwidth - cfg.width;
    551  1.13     skrll 		scr->scr_cfg.oscr_height = cfg.oheight =
    552  1.13     skrll 		    cfg.fbheight - cfg.height;
    553   1.1     jkunz 	}
    554   1.1     jkunz 
    555  1.13     skrll 	/*
    556  1.13     skrll 	 * Save a few fields for sti_describe_screen() later
    557  1.13     skrll 	 */
    558  1.13     skrll 	scr->fbheight = cfg.fbheight;
    559  1.13     skrll 	scr->fbwidth = cfg.fbwidth;
    560  1.13     skrll 	scr->oheight = cfg.oheight;
    561  1.13     skrll 	scr->owidth = cfg.owidth;
    562  1.13     skrll 	memcpy(scr->name, cfg.name, sizeof(scr->name));
    563  1.13     skrll 
    564  1.35  macallan 	if (flags & STI_FBMODE) {
    565  1.35  macallan 		/* we're done here */
    566  1.35  macallan 		sti_init(scr, STI_FBMODE);
    567  1.35  macallan 		return 0;
    568  1.35  macallan 	}
    569  1.35  macallan 
    570  1.13     skrll 	if ((error = sti_init(scr, STI_TEXTMODE | flags))) {
    571  1.13     skrll 		aprint_error(": cannot initialize (%d)\n", error);
    572  1.13     skrll 		goto fail;
    573  1.13     skrll 	}
    574   1.1     jkunz #ifdef STIDEBUG
    575  1.13     skrll 	snprintb(buf, sizeof(buf), STI_INQCONF_BITS, cfg.attributes);
    576  1.13     skrll 	DPRINTF(("conf: bpp=%d planes=%d attr=%s\n"
    577  1.13     skrll 	    "crt=0x%x:0x%x:0x%x hw=0x%x:0x%x:0x%x\n", cfg.bpp,
    578  1.13     skrll 	    cfg.planes, buf,
    579   1.1     jkunz 	    ecfg.crt_config[0], ecfg.crt_config[1], ecfg.crt_config[2],
    580  1.13     skrll 	    ecfg.crt_hw[0], ecfg.crt_hw[1], ecfg.crt_hw[2]));
    581   1.1     jkunz #endif
    582  1.13     skrll 	scr->scr_bpp = cfg.bppu;
    583  1.13     skrll 
    584  1.13     skrll 	/*
    585  1.13     skrll 	 * Although scr->scr_ecfg.current_monitor is not filled by
    586  1.13     skrll 	 * sti_init() as expected, we can nevertheless walk the monitor
    587  1.13     skrll 	 * list, if there is any, and if we find a mode matching our
    588  1.13     skrll 	 * resolution, pick its font index.
    589  1.13     skrll 	 */
    590  1.13     skrll 	if (dd->dd_montbl != 0) {
    591  1.13     skrll 		STI_ENABLE_ROM(rom->rom_softc);
    592  1.13     skrll 
    593  1.13     skrll 		for (i = 0; i < dd->dd_nmon; i++) {
    594  1.13     skrll 			u_int offs = dd->dd_montbl + 8 * i;
    595  1.13     skrll 			uint32_t m[2];
    596  1.13     skrll 			sti_mon_t mon = (void *)m;
    597  1.13     skrll 			if (rom->rom_devtype == STI_DEVTYPE1) {
    598  1.13     skrll 				m[0] = parseword(4 * offs);
    599  1.13     skrll 				m[1] = parseword(4 * (offs + 4));
    600  1.13     skrll 			} else {
    601  1.13     skrll 				bus_space_read_region_stream_4(memt, romh, offs,
    602  1.13     skrll 				    (uint32_t *)mon, sizeof(*mon) / 4);
    603  1.13     skrll 			}
    604  1.13     skrll 
    605  1.13     skrll 			if (mon->width == scr->scr_cfg.scr_width &&
    606  1.13     skrll 			    mon->height == scr->scr_cfg.scr_height) {
    607  1.13     skrll 				fontindex = mon->font;
    608  1.13     skrll 				break;
    609  1.13     skrll 			}
    610  1.13     skrll 		}
    611  1.13     skrll 
    612  1.13     skrll 		STI_DISABLE_ROM(rom->rom_softc);
    613  1.13     skrll 
    614  1.13     skrll 		DPRINTF(("font index: %d\n", fontindex));
    615  1.13     skrll 	}
    616  1.13     skrll 
    617  1.13     skrll 	if ((error = sti_fetchfonts(scr, &cfg, dd->dd_fntaddr, fontindex))) {
    618  1.13     skrll 		aprint_error(": cannot fetch fonts (%d)\n", error);
    619  1.13     skrll 		goto fail;
    620   1.1     jkunz 	}
    621   1.1     jkunz 
    622   1.1     jkunz 	/*
    623  1.13     skrll 	 * setup screen descriptions:
    624   1.1     jkunz 	 *	figure number of fonts supported;
    625   1.1     jkunz 	 *	allocate wscons structures;
    626   1.1     jkunz 	 *	calculate dimensions.
    627   1.1     jkunz 	 */
    628   1.1     jkunz 
    629  1.13     skrll 	scr->scr_wsd.name = "std";
    630  1.13     skrll 	scr->scr_wsd.ncols = cfg.width / scr->scr_curfont.width;
    631  1.13     skrll 	scr->scr_wsd.nrows = cfg.height / scr->scr_curfont.height;
    632  1.13     skrll 	scr->scr_wsd.textops = &sti_emulops;
    633  1.13     skrll 	scr->scr_wsd.fontwidth = scr->scr_curfont.width;
    634  1.13     skrll 	scr->scr_wsd.fontheight = scr->scr_curfont.height;
    635  1.24   tsutsui 	scr->scr_wsd.capabilities = WSSCREEN_REVERSE;
    636  1.13     skrll 
    637  1.13     skrll 	scr->scr_scrlist[0] = &scr->scr_wsd;
    638  1.13     skrll 	scr->scr_screenlist.nscreens = 1;
    639  1.16      matt 	scr->scr_screenlist.screens = scr->scr_scrlist;
    640   1.1     jkunz 
    641  1.23   tsutsui #ifndef SMALL_KERNEL
    642  1.23   tsutsui 	/*
    643  1.23   tsutsui 	 * Decide which board-specific routines to use.
    644  1.23   tsutsui 	 */
    645  1.23   tsutsui 
    646  1.23   tsutsui 	switch (dd->dd_grid[0]) {
    647  1.23   tsutsui 	case STI_DD_CRX:
    648  1.23   tsutsui 		scr->setupfb = ngle_elk_setupfb;
    649  1.23   tsutsui 		scr->putcmap = ngle_putcmap;
    650  1.23   tsutsui 
    651  1.23   tsutsui 		scr->reg10_value = 0x13601000;
    652  1.23   tsutsui 		if (scr->scr_bpp > 8)
    653  1.23   tsutsui 			scr->reg12_value = NGLE_BUFF1_CMAP3;
    654  1.23   tsutsui 		else
    655  1.23   tsutsui 			scr->reg12_value = NGLE_BUFF1_CMAP0;
    656  1.23   tsutsui 		scr->cmap_finish_register = NGLE_REG_1;
    657  1.23   tsutsui 		break;
    658  1.23   tsutsui 
    659  1.23   tsutsui 	case STI_DD_TIMBER:
    660  1.23   tsutsui 		scr->setupfb = ngle_timber_setupfb;
    661  1.23   tsutsui 		scr->putcmap = ngle_putcmap;
    662  1.23   tsutsui 
    663  1.23   tsutsui 		scr->reg10_value = 0x13602000;
    664  1.23   tsutsui 		scr->reg12_value = NGLE_BUFF1_CMAP0;
    665  1.23   tsutsui 		scr->cmap_finish_register = NGLE_REG_1;
    666  1.23   tsutsui 		break;
    667  1.23   tsutsui 
    668  1.23   tsutsui 	case STI_DD_ARTIST:
    669  1.23   tsutsui 		scr->setupfb = ngle_artist_setupfb;
    670  1.23   tsutsui 		scr->putcmap = ngle_putcmap;
    671  1.23   tsutsui 
    672  1.23   tsutsui 		scr->reg10_value = 0x13601000;
    673  1.23   tsutsui 		scr->reg12_value = NGLE_ARTIST_CMAP0;
    674  1.23   tsutsui 		scr->cmap_finish_register = NGLE_REG_26;
    675  1.23   tsutsui 		break;
    676  1.23   tsutsui 
    677  1.23   tsutsui 	case STI_DD_EG:
    678  1.23   tsutsui 		scr->setupfb = ngle_artist_setupfb;
    679  1.23   tsutsui 		scr->putcmap = ngle_putcmap;
    680  1.23   tsutsui 
    681  1.23   tsutsui 		scr->reg10_value = 0x13601000;
    682  1.23   tsutsui 		if (scr->scr_bpp > 8) {
    683  1.23   tsutsui 			scr->reg12_value = NGLE_BUFF1_CMAP3;
    684  1.23   tsutsui 			scr->cmap_finish_register = NGLE_REG_1;
    685  1.23   tsutsui 		} else {
    686  1.23   tsutsui 			scr->reg12_value = NGLE_ARTIST_CMAP0;
    687  1.23   tsutsui 			scr->cmap_finish_register = NGLE_REG_26;
    688  1.23   tsutsui 		}
    689  1.23   tsutsui 		break;
    690  1.23   tsutsui 
    691  1.36  macallan 	case STI_DD_HCRX:
    692  1.36  macallan 		scr->setupfb = ngle_elk_setupfb;
    693  1.37  macallan 		scr->putcmap = ngle_hcrx_putcmap;
    694  1.36  macallan 
    695  1.36  macallan 		if (scr->scr_bpp > 8) {
    696  1.36  macallan 			scr->reg12_value = NGLE_BUFF1_CMAP3;
    697  1.36  macallan 			scr->reg10_value = 0xBBA0A000;
    698  1.36  macallan 		} else {
    699  1.36  macallan 			scr->reg12_value = NGLE_BUFF1_CMAP0;
    700  1.36  macallan 			scr->reg10_value = 0x13602000;
    701  1.36  macallan 		}
    702  1.37  macallan 		scr->cmap_finish_register = NGLE_REG_38;
    703  1.36  macallan 		break;
    704  1.36  macallan 
    705  1.40  macallan 	case STI_DD_SUMMIT:
    706  1.42  macallan 	case STI_DD_LEGO:
    707  1.40  macallan 		scr->setupfb = summit_setupfb;
    708  1.40  macallan 		scr->putcmap = summit_putcmap;
    709  1.40  macallan 		scr->scr_bpp = 8;	/* for now */
    710  1.40  macallan 		break;
    711  1.40  macallan 
    712  1.44   tsutsui 	case STI_DD_EVRX:
    713  1.44   tsutsui 	case STI_DD_382C:
    714  1.44   tsutsui 	case STI_DD_3X2V:
    715  1.44   tsutsui 		/*
    716  1.44   tsutsui 		 * EVRX, 382C, and 3X2V are available only on hp300 models
    717  1.44   tsutsui 		 * and board specific routines are handled by MD
    718  1.44   tsutsui 		 * sti_machdep_attach() in arch/hp300/dev/sti_machdep.c.
    719  1.44   tsutsui 		 */
    720  1.44   tsutsui 		break;
    721  1.44   tsutsui 
    722  1.23   tsutsui 	case STI_DD_GRX:
    723  1.23   tsutsui 	case STI_DD_CRX24:
    724  1.23   tsutsui 	case STI_DD_DUAL_CRX:
    725  1.23   tsutsui 	case STI_DD_PINNACLE:
    726  1.23   tsutsui 	default:
    727  1.23   tsutsui 		scr->setupfb = NULL;
    728  1.23   tsutsui 		scr->putcmap =
    729  1.23   tsutsui 		    rom->scment == NULL ? NULL : ngle_default_putcmap;
    730  1.23   tsutsui 		break;
    731  1.23   tsutsui 	}
    732  1.23   tsutsui #endif
    733  1.23   tsutsui 
    734  1.13     skrll 	return 0;
    735  1.13     skrll 
    736  1.13     skrll fail:
    737  1.13     skrll 	/* XXX free resources */
    738  1.13     skrll 	if (scr->scr_ecfg.addr != NULL) {
    739  1.13     skrll 		free(scr->scr_ecfg.addr, M_DEVBUF);
    740  1.13     skrll 		scr->scr_ecfg.addr = NULL;
    741  1.13     skrll 	}
    742  1.13     skrll 
    743  1.13     skrll 	return ENXIO;
    744  1.13     skrll }
    745  1.13     skrll 
    746  1.13     skrll void
    747  1.13     skrll sti_describe_screen(struct sti_softc *sc, struct sti_screen *scr)
    748  1.13     skrll {
    749  1.13     skrll 	struct sti_font *fp = &scr->scr_curfont;
    750  1.13     skrll 
    751  1.13     skrll 	aprint_normal("%s: %s, %dx%d frame buffer, %dx%dx%d display\n",
    752  1.13     skrll 	    device_xname(sc->sc_dev), scr->name, scr->fbwidth, scr->fbheight,
    753  1.13     skrll 	    scr->scr_cfg.scr_width, scr->scr_cfg.scr_height, scr->scr_bpp);
    754  1.13     skrll 
    755  1.13     skrll 	aprint_normal("%s: %dx%d font type %d, %d bpc, charset %d-%d\n",
    756  1.13     skrll 	    device_xname(sc->sc_dev), fp->width, fp->height,
    757  1.13     skrll 	    fp->type, fp->bpc, fp->first, fp->last);
    758  1.13     skrll }
    759  1.13     skrll 
    760  1.13     skrll void
    761  1.13     skrll sti_describe(struct sti_softc *sc)
    762  1.13     skrll {
    763  1.13     skrll 	struct sti_rom *rom = sc->sc_rom;
    764  1.13     skrll 	struct sti_dd *dd = &rom->rom_dd;
    765  1.13     skrll 
    766  1.13     skrll 	aprint_normal(": rev %d.%02d;%d, ID 0x%08X%08X\n",
    767  1.13     skrll 	    dd->dd_grrev >> 4, dd->dd_grrev & 0xf,
    768  1.13     skrll 	    dd->dd_lrrev, dd->dd_grid[0], dd->dd_grid[1]);
    769   1.1     jkunz 
    770  1.13     skrll 	if (sc->sc_scr != NULL)
    771  1.13     skrll 		sti_describe_screen(sc, sc->sc_scr);
    772   1.1     jkunz }
    773   1.1     jkunz 
    774  1.23   tsutsui /*
    775  1.23   tsutsui  * Final part of attachment. On hppa where we use the PDC console
    776  1.23   tsutsui  * during autoconf, this has to be postponed until autoconf has
    777  1.23   tsutsui  * completed.
    778  1.23   tsutsui  */
    779   1.1     jkunz void
    780  1.13     skrll sti_end_attach(struct sti_softc *sc)
    781   1.1     jkunz {
    782  1.13     skrll 	struct sti_screen *scr = sc->sc_scr;
    783  1.13     skrll 
    784  1.13     skrll 	if (scr == NULL)
    785  1.13     skrll 		return;
    786  1.13     skrll #if NWSDISPLAY > 0
    787  1.13     skrll 	else {
    788  1.13     skrll 		struct wsemuldisplaydev_attach_args waa;
    789  1.13     skrll 		scr->scr_wsmode = WSDISPLAYIO_MODE_EMUL;
    790  1.13     skrll 
    791  1.13     skrll 		waa.console = sc->sc_flags & STI_CONSOLE ? 1 : 0;
    792  1.13     skrll 		waa.scrdata = &scr->scr_screenlist;
    793  1.13     skrll 		waa.accessops = &sti_accessops;
    794  1.13     skrll 		waa.accesscookie = scr;
    795  1.13     skrll 
    796  1.13     skrll 		/* attach as console if required */
    797  1.13     skrll 		if (waa.console && !ISSET(sc->sc_flags, STI_ATTACHED)) {
    798  1.13     skrll 			long defattr;
    799  1.13     skrll 
    800  1.13     skrll 			sti_alloc_attr(scr, 0, 0, 0, &defattr);
    801  1.13     skrll 			wsdisplay_cnattach(&scr->scr_wsd, scr,
    802  1.13     skrll 			    0, scr->scr_wsd.nrows - 1, defattr);
    803  1.13     skrll 			sc->sc_flags |= STI_ATTACHED;
    804  1.13     skrll 		}
    805  1.13     skrll 
    806  1.30   thorpej 		config_found(sc->sc_dev, &waa, wsemuldisplaydevprint,
    807  1.31   thorpej 		    CFARGS_NONE);
    808  1.13     skrll 	}
    809  1.13     skrll #endif
    810  1.13     skrll }
    811   1.1     jkunz 
    812  1.13     skrll u_int
    813  1.13     skrll sti_rom_size(bus_space_tag_t memt, bus_space_handle_t romh)
    814  1.13     skrll {
    815  1.13     skrll 	int devtype;
    816  1.13     skrll 	u_int romend;
    817   1.1     jkunz 
    818  1.13     skrll 	devtype = bus_space_read_1(memt, romh, 3);
    819  1.13     skrll 	if (devtype == STI_DEVTYPE4) {
    820  1.13     skrll 		bus_space_read_region_stream_4(memt, romh, STI_DEV4_DD_ROMEND,
    821  1.13     skrll 		    (uint32_t *)&romend, 1);
    822  1.13     skrll 	} else {
    823  1.13     skrll 		romend = parseword(STI_DEV1_DD_ROMEND);
    824   1.1     jkunz 	}
    825   1.1     jkunz 
    826  1.13     skrll 	DPRINTF(("%s: %08x (%08x)\n", __func__, romend, round_page(romend)));
    827  1.13     skrll 
    828  1.13     skrll 	return round_page(romend);
    829   1.1     jkunz }
    830   1.1     jkunz 
    831   1.1     jkunz int
    832  1.13     skrll sti_fetchfonts(struct sti_screen *scr, struct sti_inqconfout *cfg,
    833  1.13     skrll     uint32_t baseaddr, u_int fontindex)
    834   1.1     jkunz {
    835  1.13     skrll 	struct sti_rom *rom = scr->scr_rom;
    836  1.13     skrll 	bus_space_tag_t memt = rom->memt;
    837  1.13     skrll 	bus_space_handle_t romh = rom->romh;
    838  1.13     skrll 	struct sti_font *fp = &scr->scr_curfont;
    839  1.13     skrll 	uint32_t addr;
    840   1.1     jkunz 	int size;
    841   1.1     jkunz #ifdef notyet
    842   1.1     jkunz 	int uc;
    843   1.1     jkunz 	struct {
    844   1.1     jkunz 		struct sti_unpmvflags flags;
    845   1.1     jkunz 		struct sti_unpmvin in;
    846   1.1     jkunz 		struct sti_unpmvout out;
    847   1.1     jkunz 	} a;
    848   1.1     jkunz #endif
    849   1.1     jkunz 
    850   1.1     jkunz 	/*
    851   1.1     jkunz 	 * Get the first PROM font in memory
    852   1.1     jkunz 	 */
    853  1.13     skrll 
    854  1.13     skrll 	STI_ENABLE_ROM(rom->rom_softc);
    855  1.13     skrll 
    856  1.13     skrll rescan:
    857  1.13     skrll 	addr = baseaddr;
    858   1.1     jkunz 	do {
    859  1.13     skrll 		if (rom->rom_devtype == STI_DEVTYPE1) {
    860   1.1     jkunz 			fp->first  = parseshort(addr + 0x00);
    861   1.1     jkunz 			fp->last   = parseshort(addr + 0x08);
    862  1.13     skrll 			fp->width  = bus_space_read_1(memt, romh, addr + 0x13);
    863  1.13     skrll 			fp->height = bus_space_read_1(memt, romh, addr + 0x17);
    864  1.13     skrll 			fp->type   = bus_space_read_1(memt, romh, addr + 0x1b);
    865  1.13     skrll 			fp->bpc    = bus_space_read_1(memt, romh, addr + 0x1f);
    866  1.13     skrll 			fp->next   = parseword(addr + 0x20);
    867  1.13     skrll 			fp->uheight= bus_space_read_1(memt, romh, addr + 0x33);
    868  1.13     skrll 			fp->uoffset= bus_space_read_1(memt, romh, addr + 0x37);
    869  1.13     skrll 		} else {	/* STI_DEVTYPE4 */
    870  1.13     skrll 			bus_space_read_region_stream_4(memt, romh, addr,
    871  1.12     skrll 			    (uint32_t *)fp, sizeof(struct sti_font) / 4);
    872  1.13     skrll 		}
    873   1.1     jkunz 
    874  1.13     skrll #ifdef STIDEBUG
    875  1.13     skrll 		STI_DISABLE_ROM(rom->rom_softc);
    876  1.13     skrll 		DPRINTF(("%s: %dx%d font type %d, %d bpc, charset %d-%d\n",
    877  1.45   tsutsui 		    scr->scr_rom->rom_softc == NULL ? __func__ :
    878  1.13     skrll 		    device_xname(scr->scr_rom->rom_softc->sc_dev), fp->width,
    879  1.13     skrll 		    fp->height, fp->type, fp->bpc, fp->first, fp->last));
    880  1.13     skrll 		STI_ENABLE_ROM(rom->rom_softc);
    881  1.13     skrll #endif
    882   1.1     jkunz 
    883  1.13     skrll 		if (fontindex == 0) {
    884  1.13     skrll 			size = sizeof(struct sti_font) +
    885  1.13     skrll 			    (fp->last - fp->first + 1) * fp->bpc;
    886  1.13     skrll 			if (rom->rom_devtype == STI_DEVTYPE1)
    887  1.13     skrll 				size *= 4;
    888  1.20       chs 			scr->scr_romfont = malloc(size, M_DEVBUF, M_WAITOK);
    889   1.1     jkunz 
    890  1.13     skrll 			bus_space_read_region_stream_4(memt, romh, addr,
    891  1.13     skrll 			    (uint32_t *)scr->scr_romfont, size / 4);
    892  1.13     skrll 			break;
    893  1.13     skrll 		}
    894  1.13     skrll 
    895  1.13     skrll 		addr = baseaddr + fp->next;
    896  1.13     skrll 		fontindex--;
    897  1.13     skrll 	} while (fp->next != 0);
    898  1.13     skrll 
    899  1.13     skrll 	/*
    900  1.13     skrll 	 * If our font index was bogus, we did not find the expected font.
    901  1.13     skrll 	 * In this case, pick the first one and be done with it.
    902  1.13     skrll 	 */
    903  1.13     skrll 	if (fp->next == 0 && scr->scr_romfont == NULL) {
    904  1.13     skrll 		fontindex = 0;
    905  1.13     skrll 		goto rescan;
    906  1.13     skrll 	}
    907  1.13     skrll 
    908  1.13     skrll 	STI_DISABLE_ROM(rom->rom_softc);
    909   1.1     jkunz 
    910   1.1     jkunz #ifdef notyet
    911   1.1     jkunz 	/*
    912   1.1     jkunz 	 * If there is enough room in the off-screen framebuffer memory,
    913   1.1     jkunz 	 * display all the characters there in order to display them
    914   1.1     jkunz 	 * faster with blkmv operations rather than unpmv later on.
    915   1.1     jkunz 	 */
    916   1.1     jkunz 	if (size <= cfg->fbheight *
    917   1.1     jkunz 	    (cfg->fbwidth - cfg->width - cfg->owidth)) {
    918   1.1     jkunz 		memset(&a, 0, sizeof(a));
    919   1.1     jkunz 		a.flags.flags = STI_UNPMVF_WAIT;
    920   1.1     jkunz 		a.in.fg_colour = STI_COLOUR_WHITE;
    921   1.1     jkunz 		a.in.bg_colour = STI_COLOUR_BLACK;
    922  1.13     skrll 		a.in.font_addr = scr->scr_romfont;
    923   1.1     jkunz 
    924  1.13     skrll 		scr->scr_fontmaxcol = cfg->fbheight / fp->height;
    925  1.13     skrll 		scr->scr_fontbase = cfg->width + cfg->owidth;
    926   1.1     jkunz 		for (uc = fp->first; uc <= fp->last; uc++) {
    927  1.13     skrll 			a.in.x = ((uc - fp->first) / scr->scr_fontmaxcol) *
    928  1.13     skrll 			    fp->width + scr->scr_fontbase;
    929  1.13     skrll 			a.in.y = ((uc - fp->first) % scr->scr_fontmaxcol) *
    930   1.1     jkunz 			    fp->height;
    931   1.1     jkunz 			a.in.index = uc;
    932   1.1     jkunz 
    933  1.13     skrll 			(*scr->unpmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg);
    934   1.1     jkunz 			if (a.out.errno) {
    935  1.13     skrll 				aprint_error_dev(sc->sc_dev, "unpmv %d "
    936  1.13     skrll 				    "returned %d\n", uc, a.out.errno);
    937  1.13     skrll 				return 0;
    938   1.1     jkunz 			}
    939   1.1     jkunz 		}
    940   1.1     jkunz 
    941  1.13     skrll 		free(scr->scr_romfont, M_DEVBUF);
    942  1.13     skrll 		scr->scr_romfont = NULL;
    943   1.1     jkunz 	}
    944   1.1     jkunz #endif
    945   1.1     jkunz 
    946  1.13     skrll 	return 0;
    947   1.1     jkunz }
    948   1.1     jkunz 
    949  1.13     skrll /*
    950  1.13     skrll  * Wrappers around STI code pointers
    951  1.13     skrll  */
    952  1.23   tsutsui 
    953   1.1     jkunz int
    954  1.13     skrll sti_init(struct sti_screen *scr, int mode)
    955   1.1     jkunz {
    956  1.13     skrll 	struct sti_rom *rom = scr->scr_rom;
    957   1.1     jkunz 	struct {
    958   1.1     jkunz 		struct sti_initflags flags;
    959   1.1     jkunz 		struct sti_initin in;
    960  1.13     skrll 		struct sti_einitin ein;
    961   1.1     jkunz 		struct sti_initout out;
    962   1.1     jkunz 	} a;
    963   1.1     jkunz 
    964  1.13     skrll 	KASSERT(rom != NULL);
    965   1.1     jkunz 	memset(&a, 0, sizeof(a));
    966   1.1     jkunz 
    967  1.32  macallan 	a.flags.flags = STI_INITF_WAIT | STI_INITF_PBET | STI_INITF_PBETI;
    968  1.21   tsutsui 	if ((mode & STI_TEXTMODE) != 0) {
    969  1.21   tsutsui 		a.flags.flags |= STI_INITF_TEXT | STI_INITF_CMB |
    970  1.21   tsutsui 		    STI_INITF_PBET | STI_INITF_PBETI | STI_INITF_ICMT;
    971  1.32  macallan 		a.in.text_planes = 1;
    972  1.21   tsutsui 	} else {
    973  1.32  macallan 		a.flags.flags |= STI_INITF_TEXT | STI_INITF_NTEXT;
    974  1.34     skrll 		/*
    975  1.34     skrll 		 * Request as many text planes as STI will allow.
    976  1.32  macallan 		 * The reason to do this - when switching to framebuffer mode
    977  1.32  macallan 		 * for X we need access to all planes. In theory STI should do
    978  1.32  macallan 		 * just that when we request access to both text and non-text
    979  1.32  macallan 		 * planes as above.
    980  1.32  macallan 		 * In reality though, at least on my PCI Visualize EG, some
    981  1.32  macallan 		 * planes and/or colour registers remain inaccessible if we
    982  1.32  macallan 		 * request only one text plane.
    983  1.32  macallan 		 * Clearly we're missing a register write or two here, but so
    984  1.32  macallan 		 * far I haven't found it.
    985  1.32  macallan 		 */
    986  1.32  macallan 		a.in.text_planes = 3;
    987  1.21   tsutsui 	}
    988  1.21   tsutsui 	if ((mode & STI_CLEARSCR) != 0)
    989  1.21   tsutsui 		a.flags.flags |= STI_INITF_CLEAR;
    990  1.21   tsutsui 
    991  1.13     skrll 	a.in.ext_in = &a.ein;
    992  1.13     skrll 
    993  1.13     skrll 	DPRINTF(("%s: init,%p(%x, %p, %p, %p)\n",
    994  1.45   tsutsui 	    rom->rom_softc == NULL ? __func__ :
    995  1.13     skrll 	    device_xname(rom->rom_softc->sc_dev), rom->init, a.flags.flags,
    996  1.13     skrll 	    &a.in, &a.out, &scr->scr_cfg));
    997  1.13     skrll 
    998  1.13     skrll 	(*rom->init)(&a.flags, &a.in, &a.out, &scr->scr_cfg);
    999  1.13     skrll 
   1000  1.13     skrll 	if (a.out.text_planes != a.in.text_planes)
   1001  1.13     skrll 		return -1;	/* not colliding with sti errno values */
   1002  1.13     skrll 	return a.out.errno;
   1003   1.1     jkunz }
   1004   1.1     jkunz 
   1005   1.1     jkunz int
   1006  1.13     skrll sti_inqcfg(struct sti_screen *scr, struct sti_inqconfout *out)
   1007   1.1     jkunz {
   1008  1.13     skrll 	struct sti_rom *rom = scr->scr_rom;
   1009   1.1     jkunz 	struct {
   1010   1.1     jkunz 		struct sti_inqconfflags flags;
   1011   1.1     jkunz 		struct sti_inqconfin in;
   1012   1.1     jkunz 	} a;
   1013   1.1     jkunz 
   1014   1.1     jkunz 	memset(&a, 0, sizeof(a));
   1015   1.1     jkunz 
   1016   1.1     jkunz 	a.flags.flags = STI_INQCONFF_WAIT;
   1017  1.13     skrll 	(*rom->inqconf)(&a.flags, &a.in, out, &scr->scr_cfg);
   1018   1.1     jkunz 
   1019   1.1     jkunz 	return out->errno;
   1020   1.1     jkunz }
   1021   1.1     jkunz 
   1022   1.1     jkunz void
   1023  1.13     skrll sti_bmove(struct sti_screen *scr, int x1, int y1, int x2, int y2, int h, int w,
   1024   1.1     jkunz     enum sti_bmove_funcs f)
   1025   1.1     jkunz {
   1026  1.13     skrll 	struct sti_rom *rom = scr->scr_rom;
   1027   1.1     jkunz 	struct {
   1028   1.1     jkunz 		struct sti_blkmvflags flags;
   1029   1.1     jkunz 		struct sti_blkmvin in;
   1030   1.1     jkunz 		struct sti_blkmvout out;
   1031   1.1     jkunz 	} a;
   1032   1.1     jkunz 
   1033   1.1     jkunz 	memset(&a, 0, sizeof(a));
   1034   1.1     jkunz 
   1035   1.1     jkunz 	a.flags.flags = STI_BLKMVF_WAIT;
   1036   1.1     jkunz 	switch (f) {
   1037   1.1     jkunz 	case bmf_clear:
   1038   1.1     jkunz 		a.flags.flags |= STI_BLKMVF_CLR;
   1039   1.1     jkunz 		a.in.bg_colour = STI_COLOUR_BLACK;
   1040   1.1     jkunz 		break;
   1041   1.1     jkunz 	case bmf_underline:
   1042   1.1     jkunz 	case bmf_copy:
   1043   1.1     jkunz 		a.in.fg_colour = STI_COLOUR_WHITE;
   1044   1.1     jkunz 		a.in.bg_colour = STI_COLOUR_BLACK;
   1045   1.1     jkunz 		break;
   1046   1.1     jkunz 	case bmf_invert:
   1047   1.1     jkunz 		a.flags.flags |= STI_BLKMVF_COLR;
   1048   1.1     jkunz 		a.in.fg_colour = STI_COLOUR_BLACK;
   1049   1.1     jkunz 		a.in.bg_colour = STI_COLOUR_WHITE;
   1050   1.1     jkunz 		break;
   1051   1.1     jkunz 	}
   1052   1.1     jkunz 	a.in.srcx = x1;
   1053   1.1     jkunz 	a.in.srcy = y1;
   1054   1.1     jkunz 	a.in.dstx = x2;
   1055   1.1     jkunz 	a.in.dsty = y2;
   1056   1.1     jkunz 	a.in.height = h;
   1057   1.1     jkunz 	a.in.width = w;
   1058   1.1     jkunz 
   1059  1.13     skrll 	(*rom->blkmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg);
   1060   1.1     jkunz #ifdef STIDEBUG
   1061   1.1     jkunz 	if (a.out.errno)
   1062  1.13     skrll 		printf("%s: blkmv returned %d\n",
   1063  1.45   tsutsui 		    rom->rom_softc == NULL ? __func__ :
   1064  1.13     skrll 		    device_xname(rom->rom_softc->sc_dev), a.out.errno);
   1065   1.1     jkunz #endif
   1066   1.1     jkunz }
   1067   1.1     jkunz 
   1068   1.1     jkunz int
   1069  1.13     skrll sti_setcment(struct sti_screen *scr, u_int i, u_char r, u_char g, u_char b)
   1070   1.1     jkunz {
   1071  1.13     skrll 	struct sti_rom *rom = scr->scr_rom;
   1072   1.1     jkunz 	struct {
   1073   1.1     jkunz 		struct sti_scmentflags flags;
   1074   1.1     jkunz 		struct sti_scmentin in;
   1075   1.1     jkunz 		struct sti_scmentout out;
   1076   1.1     jkunz 	} a;
   1077   1.1     jkunz 
   1078   1.1     jkunz 	memset(&a, 0, sizeof(a));
   1079   1.1     jkunz 
   1080   1.1     jkunz 	a.flags.flags = STI_SCMENTF_WAIT;
   1081   1.1     jkunz 	a.in.entry = i;
   1082   1.1     jkunz 	a.in.value = (r << 16) | (g << 8) | b;
   1083   1.1     jkunz 
   1084  1.13     skrll 	(*rom->scment)(&a.flags, &a.in, &a.out, &scr->scr_cfg);
   1085   1.1     jkunz 
   1086   1.1     jkunz 	return a.out.errno;
   1087   1.1     jkunz }
   1088   1.1     jkunz 
   1089  1.13     skrll /*
   1090  1.13     skrll  * wsdisplay accessops
   1091  1.13     skrll  */
   1092   1.1     jkunz int
   1093   1.7  christos sti_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l)
   1094   1.1     jkunz {
   1095  1.13     skrll 	struct sti_screen *scr = (struct sti_screen *)v;
   1096  1.38  macallan 	struct sti_rom *rom = scr->scr_rom;
   1097   1.1     jkunz 	struct wsdisplay_fbinfo *wdf;
   1098   1.1     jkunz 	struct wsdisplay_cmap *cmapp;
   1099   1.1     jkunz 	u_int mode, idx, count;
   1100  1.23   tsutsui 	int ret;
   1101   1.1     jkunz 
   1102   1.1     jkunz 	ret = 0;
   1103   1.1     jkunz 	switch (cmd) {
   1104  1.38  macallan 	case GCID:
   1105  1.39     skrll 		*(u_int *)data = rom->rom_dd.dd_grid[0];
   1106  1.38  macallan 		break;
   1107  1.38  macallan 
   1108   1.1     jkunz 	case WSDISPLAYIO_GMODE:
   1109  1.13     skrll 		*(u_int *)data = scr->scr_wsmode;
   1110   1.1     jkunz 		break;
   1111   1.1     jkunz 
   1112   1.1     jkunz 	case WSDISPLAYIO_SMODE:
   1113   1.1     jkunz 		mode = *(u_int *)data;
   1114  1.23   tsutsui 		switch (mode) {
   1115  1.23   tsutsui 		case WSDISPLAYIO_MODE_EMUL:
   1116  1.23   tsutsui 			if (scr->scr_wsmode != WSDISPLAYIO_MODE_EMUL)
   1117  1.23   tsutsui 				ret = sti_init(scr, STI_TEXTMODE);
   1118  1.23   tsutsui 			break;
   1119  1.23   tsutsui 		case WSDISPLAYIO_MODE_DUMBFB:
   1120  1.23   tsutsui 			if (scr->scr_wsmode != WSDISPLAYIO_MODE_DUMBFB) {
   1121  1.32  macallan 				ret = sti_init(scr, 0);
   1122  1.23   tsutsui 				if (scr->setupfb != NULL)
   1123  1.23   tsutsui 					scr->setupfb(scr);
   1124  1.23   tsutsui 				else
   1125  1.23   tsutsui #if 0
   1126  1.23   tsutsui 					ret = sti_init(scr, STI_FBMODE);
   1127  1.23   tsutsui #else
   1128  1.23   tsutsui 					ret = EINVAL;
   1129  1.23   tsutsui #endif
   1130  1.23   tsutsui 			}
   1131  1.23   tsutsui 			break;
   1132  1.23   tsutsui 		case WSDISPLAYIO_MODE_MAPPED:
   1133  1.23   tsutsui 		default:
   1134  1.23   tsutsui 			ret = EINVAL;
   1135  1.23   tsutsui 			break;
   1136  1.23   tsutsui 		}
   1137  1.23   tsutsui 		if (ret == 0)
   1138  1.23   tsutsui 			scr->scr_wsmode = mode;
   1139   1.1     jkunz 		break;
   1140   1.1     jkunz 
   1141   1.1     jkunz 	case WSDISPLAYIO_GTYPE:
   1142   1.1     jkunz 		*(u_int *)data = WSDISPLAY_TYPE_STI;
   1143   1.1     jkunz 		break;
   1144   1.1     jkunz 
   1145   1.1     jkunz 	case WSDISPLAYIO_GINFO:
   1146   1.1     jkunz 		wdf = (struct wsdisplay_fbinfo *)data;
   1147  1.13     skrll 		wdf->height = scr->scr_cfg.scr_height;
   1148  1.13     skrll 		wdf->width  = scr->scr_cfg.scr_width;
   1149  1.13     skrll 		wdf->depth  = scr->scr_bpp;
   1150  1.23   tsutsui 		if (scr->putcmap == NULL || scr->scr_bpp > 8)
   1151  1.13     skrll 			wdf->cmsize = 0;
   1152  1.13     skrll 		else
   1153  1.13     skrll 			wdf->cmsize = STI_NCMAP;
   1154   1.1     jkunz 		break;
   1155   1.1     jkunz 
   1156   1.1     jkunz 	case WSDISPLAYIO_LINEBYTES:
   1157  1.23   tsutsui 		if (scr->scr_bpp > 8)
   1158  1.23   tsutsui 			*(u_int *)data = scr->scr_cfg.fb_width * 4;
   1159  1.23   tsutsui 		else
   1160  1.23   tsutsui 			*(u_int *)data = scr->scr_cfg.fb_width;
   1161   1.1     jkunz 		break;
   1162   1.1     jkunz 
   1163   1.1     jkunz 	case WSDISPLAYIO_GETCMAP:
   1164  1.23   tsutsui 		if (scr->putcmap == NULL || scr->scr_bpp > 8)
   1165  1.23   tsutsui 			return ENODEV;
   1166   1.1     jkunz 		cmapp = (struct wsdisplay_cmap *)data;
   1167   1.1     jkunz 		idx = cmapp->index;
   1168   1.1     jkunz 		count = cmapp->count;
   1169  1.19       spz 		if (idx >= STI_NCMAP || count > STI_NCMAP - idx)
   1170   1.1     jkunz 			return EINVAL;
   1171  1.13     skrll 		if ((ret = copyout(&scr->scr_rcmap[idx], cmapp->red, count)))
   1172   1.1     jkunz 			break;
   1173  1.13     skrll 		if ((ret = copyout(&scr->scr_gcmap[idx], cmapp->green, count)))
   1174   1.1     jkunz 			break;
   1175  1.13     skrll 		if ((ret = copyout(&scr->scr_bcmap[idx], cmapp->blue, count)))
   1176   1.1     jkunz 			break;
   1177   1.1     jkunz 		break;
   1178   1.1     jkunz 
   1179   1.1     jkunz 	case WSDISPLAYIO_PUTCMAP:
   1180  1.23   tsutsui 		if (scr->putcmap == NULL || scr->scr_bpp > 8)
   1181  1.23   tsutsui 			return ENODEV;
   1182  1.25   tsutsui 		if (scr->scr_wsmode == WSDISPLAYIO_MODE_EMUL) {
   1183  1.25   tsutsui 			/*
   1184  1.25   tsutsui 			 * The hardware palette settings are handled by
   1185  1.25   tsutsui 			 * the STI ROM in STI_TEXTMODE and changing cmap
   1186  1.25   tsutsui 			 * could cause mangled text colors at least on CRX.
   1187  1.25   tsutsui 			 * Updating CMAP in EMUL mode isn't expected anyway
   1188  1.25   tsutsui 			 * so just ignore it.
   1189  1.25   tsutsui 			 */
   1190  1.25   tsutsui 			return 0;
   1191  1.25   tsutsui 		}
   1192   1.1     jkunz 		cmapp = (struct wsdisplay_cmap *)data;
   1193   1.1     jkunz 		idx = cmapp->index;
   1194   1.1     jkunz 		count = cmapp->count;
   1195  1.19       spz 		if (idx >= STI_NCMAP || count > STI_NCMAP - idx)
   1196   1.1     jkunz 			return EINVAL;
   1197  1.13     skrll 		if ((ret = copyin(cmapp->red, &scr->scr_rcmap[idx], count)))
   1198   1.1     jkunz 			break;
   1199  1.13     skrll 		if ((ret = copyin(cmapp->green, &scr->scr_gcmap[idx], count)))
   1200   1.1     jkunz 			break;
   1201  1.13     skrll 		if ((ret = copyin(cmapp->blue, &scr->scr_bcmap[idx], count)))
   1202   1.1     jkunz 			break;
   1203  1.23   tsutsui 		ret = scr->putcmap(scr, idx, count);
   1204   1.1     jkunz 		break;
   1205   1.1     jkunz 
   1206   1.1     jkunz 	case WSDISPLAYIO_SVIDEO:
   1207   1.1     jkunz 	case WSDISPLAYIO_GVIDEO:
   1208   1.1     jkunz 	case WSDISPLAYIO_GCURPOS:
   1209   1.1     jkunz 	case WSDISPLAYIO_SCURPOS:
   1210   1.1     jkunz 	case WSDISPLAYIO_GCURMAX:
   1211   1.1     jkunz 	case WSDISPLAYIO_GCURSOR:
   1212   1.1     jkunz 	case WSDISPLAYIO_SCURSOR:
   1213   1.1     jkunz 	default:
   1214  1.13     skrll 		return ENOTTY;	/* not supported yet */
   1215   1.1     jkunz 	}
   1216   1.1     jkunz 
   1217  1.13     skrll 	return ret;
   1218   1.1     jkunz }
   1219   1.1     jkunz 
   1220   1.1     jkunz paddr_t
   1221   1.6      jmmv sti_mmap(void *v, void *vs, off_t offset, int prot)
   1222   1.1     jkunz {
   1223  1.23   tsutsui 	struct sti_screen *scr = (struct sti_screen *)v;
   1224  1.23   tsutsui 	struct sti_rom *rom = scr->scr_rom;
   1225  1.23   tsutsui 	paddr_t pa;
   1226  1.23   tsutsui 
   1227  1.23   tsutsui 	if ((offset & PAGE_MASK) != 0)
   1228  1.23   tsutsui 		return -1;
   1229  1.23   tsutsui 
   1230  1.23   tsutsui 	if (offset < 0 || offset >= scr->fblen)
   1231  1.23   tsutsui 		return -1;
   1232  1.23   tsutsui 
   1233  1.27     skrll 	if (scr->scr_wsmode != WSDISPLAYIO_MODE_DUMBFB)
   1234  1.27     skrll 		return -1;
   1235  1.27     skrll 
   1236  1.23   tsutsui 	pa = bus_space_mmap(rom->memt, scr->fbaddr, offset, prot,
   1237  1.23   tsutsui 	    BUS_SPACE_MAP_LINEAR);
   1238  1.27     skrll 
   1239  1.27     skrll 	if (pa == -1)
   1240  1.27     skrll 		pa = scr->fbaddr + offset;
   1241  1.23   tsutsui 
   1242  1.23   tsutsui 	return pa;
   1243   1.1     jkunz }
   1244   1.1     jkunz 
   1245   1.1     jkunz int
   1246   1.3     perry sti_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
   1247   1.1     jkunz     int *cxp, int *cyp, long *defattr)
   1248   1.1     jkunz {
   1249  1.13     skrll 	struct sti_screen *scr = (struct sti_screen *)v;
   1250   1.1     jkunz 
   1251  1.13     skrll 	if (scr->scr_nscreens > 0)
   1252   1.1     jkunz 		return ENOMEM;
   1253   1.1     jkunz 
   1254  1.13     skrll 	*cookiep = scr;
   1255   1.1     jkunz 	*cxp = 0;
   1256   1.1     jkunz 	*cyp = 0;
   1257  1.13     skrll 	sti_alloc_attr(scr, 0, 0, 0, defattr);
   1258  1.13     skrll 	scr->scr_nscreens++;
   1259   1.1     jkunz 	return 0;
   1260   1.1     jkunz }
   1261   1.1     jkunz 
   1262   1.1     jkunz void
   1263   1.1     jkunz sti_free_screen(void *v, void *cookie)
   1264   1.1     jkunz {
   1265  1.13     skrll 	struct sti_screen *scr = (struct sti_screen *)v;
   1266   1.1     jkunz 
   1267  1.13     skrll 	scr->scr_nscreens--;
   1268   1.1     jkunz }
   1269   1.1     jkunz 
   1270   1.1     jkunz int
   1271  1.13     skrll sti_show_screen(void *v, void *cookie, int waitok, void (*cb)(void *, int, int),
   1272  1.13     skrll     void *cbarg)
   1273   1.1     jkunz {
   1274  1.13     skrll #if 0
   1275  1.13     skrll 	struct sti_screen *scr = (struct sti_screen *)v;
   1276  1.13     skrll #endif
   1277  1.13     skrll 
   1278   1.1     jkunz 	return 0;
   1279   1.1     jkunz }
   1280   1.1     jkunz 
   1281   1.1     jkunz int
   1282   1.1     jkunz sti_load_font(void *v, void *cookie, struct wsdisplay_font *font)
   1283   1.1     jkunz {
   1284  1.13     skrll #if 0
   1285  1.13     skrll 	struct sti_screen *scr = (struct sti_screen *)v;
   1286  1.13     skrll #endif
   1287  1.13     skrll 
   1288   1.1     jkunz 	return -1;
   1289   1.1     jkunz }
   1290   1.1     jkunz 
   1291  1.13     skrll /*
   1292  1.13     skrll  * wsdisplay emulops
   1293  1.13     skrll  */
   1294   1.1     jkunz void
   1295   1.1     jkunz sti_cursor(void *v, int on, int row, int col)
   1296   1.1     jkunz {
   1297  1.13     skrll 	struct sti_screen *scr = (struct sti_screen *)v;
   1298  1.13     skrll 	struct sti_font *fp = &scr->scr_curfont;
   1299   1.1     jkunz 
   1300  1.23   tsutsui 	sti_bmove(scr,
   1301  1.23   tsutsui 	    col * fp->width, row * fp->height,
   1302  1.23   tsutsui 	    col * fp->width, row * fp->height,
   1303  1.23   tsutsui 	    fp->height, fp->width, bmf_invert);
   1304   1.1     jkunz }
   1305   1.1     jkunz 
   1306  1.13     skrll /*
   1307  1.13     skrll  * ISO 8859-1 part of Unicode to HP Roman font index conversion array.
   1308  1.13     skrll  */
   1309  1.43  macallan const uint8_t
   1310  1.13     skrll sti_unitoroman[0x100 - 0xa0] = {
   1311  1.13     skrll 	0xa0, 0xb8, 0xbf, 0xbb, 0xba, 0xbc,    0, 0xbd,
   1312  1.13     skrll 	0xab,    0, 0xf9, 0xfb,    0, 0xf6,    0, 0xb0,
   1313  1.26     skrll 
   1314  1.13     skrll 	0xb3, 0xfe,    0,    0, 0xa8, 0xf3, 0xf4, 0xf2,
   1315  1.13     skrll 	   0,    0, 0xfa, 0xfd, 0xf7, 0xf8,    0, 0xb9,
   1316  1.13     skrll 
   1317  1.13     skrll 	0xa1, 0xe0, 0xa2, 0xe1, 0xd8, 0xd0, 0xd3, 0xb4,
   1318  1.13     skrll 	0xa3, 0xdc, 0xa4, 0xa5, 0xe6, 0xe5, 0xa6, 0xa7,
   1319  1.13     skrll 
   1320  1.13     skrll 	0xe3, 0xb6, 0xe8, 0xe7, 0xdf, 0xe9, 0xda,    0,
   1321  1.13     skrll 	0xd2, 0xad, 0xed, 0xae, 0xdb, 0xb1, 0xf0, 0xde,
   1322  1.13     skrll 
   1323  1.13     skrll 	0xc8, 0xc4, 0xc0, 0xe2, 0xcc, 0xd4, 0xd7, 0xb5,
   1324  1.13     skrll 	0xc9, 0xc5, 0xc1, 0xcd, 0xd9, 0xd5, 0xd1, 0xdd,
   1325  1.13     skrll 
   1326  1.13     skrll 	0xe4, 0xb7, 0xca, 0xc6, 0xc2, 0xea, 0xce,    0,
   1327  1.13     skrll 	0xd6, 0xcb, 0xc7, 0xc3, 0xcf, 0xb2, 0xf1, 0xef
   1328  1.13     skrll };
   1329  1.13     skrll 
   1330   1.1     jkunz int
   1331   1.1     jkunz sti_mapchar(void *v, int uni, u_int *index)
   1332   1.1     jkunz {
   1333  1.13     skrll 	struct sti_screen *scr = (struct sti_screen *)v;
   1334  1.13     skrll 	struct sti_font *fp = &scr->scr_curfont;
   1335  1.13     skrll 	int c;
   1336  1.13     skrll 
   1337  1.13     skrll 	switch (fp->type) {
   1338  1.13     skrll 	case STI_FONT_HPROMAN8:
   1339  1.13     skrll 		if (uni >= 0x80 && uni < 0xa0)
   1340  1.13     skrll 			c = -1;
   1341  1.13     skrll 		else if (uni >= 0xa0 && uni < 0x100) {
   1342  1.13     skrll 			c = (int)sti_unitoroman[uni - 0xa0];
   1343  1.13     skrll 			if (c == 0)
   1344  1.13     skrll 				c = -1;
   1345  1.13     skrll 		} else
   1346  1.13     skrll 			c = uni;
   1347  1.13     skrll 		break;
   1348  1.13     skrll 	default:
   1349  1.13     skrll 		c = uni;
   1350  1.13     skrll 		break;
   1351  1.13     skrll 	}
   1352   1.1     jkunz 
   1353  1.13     skrll 	if (c == -1 || c < fp->first || c > fp->last) {
   1354  1.13     skrll 		*index = ' ';
   1355  1.13     skrll 		return 0;
   1356  1.13     skrll 	}
   1357  1.13     skrll 
   1358  1.13     skrll 	*index = c;
   1359  1.13     skrll 	return 5;
   1360   1.1     jkunz }
   1361   1.1     jkunz 
   1362   1.1     jkunz void
   1363   1.1     jkunz sti_putchar(void *v, int row, int col, u_int uc, long attr)
   1364   1.1     jkunz {
   1365  1.13     skrll 	struct sti_screen *scr = (struct sti_screen *)v;
   1366  1.13     skrll 	struct sti_rom *rom = scr->scr_rom;
   1367  1.13     skrll 	struct sti_font *fp = &scr->scr_curfont;
   1368  1.24   tsutsui 	int bg, fg;
   1369  1.24   tsutsui 
   1370  1.24   tsutsui 	fg = WSATTR_UNPACK_FG(attr);
   1371  1.24   tsutsui 	bg = WSATTR_UNPACK_BG(attr);
   1372   1.1     jkunz 
   1373  1.13     skrll 	if (scr->scr_romfont != NULL) {
   1374   1.1     jkunz 		/*
   1375   1.1     jkunz 		 * Font is in memory, use unpmv
   1376   1.1     jkunz 		 */
   1377   1.1     jkunz 		struct {
   1378   1.1     jkunz 			struct sti_unpmvflags flags;
   1379   1.1     jkunz 			struct sti_unpmvin in;
   1380   1.1     jkunz 			struct sti_unpmvout out;
   1381   1.1     jkunz 		} a;
   1382   1.1     jkunz 
   1383   1.1     jkunz 		memset(&a, 0, sizeof(a));
   1384   1.1     jkunz 
   1385   1.1     jkunz 		a.flags.flags = STI_UNPMVF_WAIT;
   1386  1.24   tsutsui 		a.in.fg_colour = fg;
   1387  1.24   tsutsui 		a.in.bg_colour = bg;
   1388   1.1     jkunz 		a.in.x = col * fp->width;
   1389   1.1     jkunz 		a.in.y = row * fp->height;
   1390  1.13     skrll 		a.in.font_addr = scr->scr_romfont;
   1391   1.1     jkunz 		a.in.index = uc;
   1392   1.1     jkunz 
   1393  1.13     skrll 		(*rom->unpmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg);
   1394   1.1     jkunz 	} else {
   1395   1.1     jkunz 		/*
   1396   1.1     jkunz 		 * Font is in frame buffer, use blkmv
   1397   1.1     jkunz 		 */
   1398   1.1     jkunz 		struct {
   1399   1.1     jkunz 			struct sti_blkmvflags flags;
   1400   1.1     jkunz 			struct sti_blkmvin in;
   1401   1.1     jkunz 			struct sti_blkmvout out;
   1402   1.1     jkunz 		} a;
   1403   1.1     jkunz 
   1404   1.1     jkunz 		memset(&a, 0, sizeof(a));
   1405   1.1     jkunz 
   1406   1.1     jkunz 		a.flags.flags = STI_BLKMVF_WAIT;
   1407  1.24   tsutsui 		a.in.fg_colour = fg;
   1408  1.24   tsutsui 		a.in.bg_colour = bg;
   1409   1.1     jkunz 
   1410  1.13     skrll 		a.in.srcx = ((uc - fp->first) / scr->scr_fontmaxcol) *
   1411  1.13     skrll 		    fp->width + scr->scr_fontbase;
   1412  1.13     skrll 		a.in.srcy = ((uc - fp->first) % scr->scr_fontmaxcol) *
   1413   1.1     jkunz 		    fp->height;
   1414   1.1     jkunz 		a.in.dstx = col * fp->width;
   1415   1.1     jkunz 		a.in.dsty = row * fp->height;
   1416   1.1     jkunz 		a.in.height = fp->height;
   1417   1.1     jkunz 		a.in.width = fp->width;
   1418   1.1     jkunz 
   1419  1.13     skrll 		(*rom->blkmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg);
   1420   1.1     jkunz 	}
   1421   1.1     jkunz }
   1422   1.1     jkunz 
   1423   1.1     jkunz void
   1424   1.1     jkunz sti_copycols(void *v, int row, int srccol, int dstcol, int ncols)
   1425   1.1     jkunz {
   1426  1.13     skrll 	struct sti_screen *scr = (struct sti_screen *)v;
   1427  1.13     skrll 	struct sti_font *fp = &scr->scr_curfont;
   1428   1.1     jkunz 
   1429  1.23   tsutsui 	sti_bmove(scr,
   1430  1.23   tsutsui 	    srccol * fp->width, row * fp->height,
   1431  1.23   tsutsui 	    dstcol * fp->width, row * fp->height,
   1432  1.23   tsutsui 	    fp->height, ncols * fp->width, bmf_copy);
   1433   1.1     jkunz }
   1434   1.1     jkunz 
   1435   1.1     jkunz void
   1436   1.1     jkunz sti_erasecols(void *v, int row, int startcol, int ncols, long attr)
   1437   1.1     jkunz {
   1438  1.13     skrll 	struct sti_screen *scr = (struct sti_screen *)v;
   1439  1.13     skrll 	struct sti_font *fp = &scr->scr_curfont;
   1440   1.1     jkunz 
   1441  1.23   tsutsui 	sti_bmove(scr,
   1442  1.23   tsutsui 	    startcol * fp->width, row * fp->height,
   1443  1.23   tsutsui 	    startcol * fp->width, row * fp->height,
   1444  1.23   tsutsui 	    fp->height, ncols * fp->width, bmf_clear);
   1445   1.1     jkunz }
   1446   1.1     jkunz 
   1447   1.1     jkunz void
   1448   1.1     jkunz sti_copyrows(void *v, int srcrow, int dstrow, int nrows)
   1449   1.1     jkunz {
   1450  1.13     skrll 	struct sti_screen *scr = (struct sti_screen *)v;
   1451  1.13     skrll 	struct sti_font *fp = &scr->scr_curfont;
   1452   1.1     jkunz 
   1453  1.13     skrll 	sti_bmove(scr, 0, srcrow * fp->height, 0, dstrow * fp->height,
   1454  1.13     skrll 	    nrows * fp->height, scr->scr_cfg.scr_width, bmf_copy);
   1455   1.1     jkunz }
   1456   1.1     jkunz 
   1457   1.1     jkunz void
   1458   1.1     jkunz sti_eraserows(void *v, int srcrow, int nrows, long attr)
   1459   1.1     jkunz {
   1460  1.13     skrll 	struct sti_screen *scr = (struct sti_screen *)v;
   1461  1.13     skrll 	struct sti_font *fp = &scr->scr_curfont;
   1462   1.1     jkunz 
   1463  1.13     skrll 	sti_bmove(scr, 0, srcrow * fp->height, 0, srcrow * fp->height,
   1464  1.13     skrll 	    nrows * fp->height, scr->scr_cfg.scr_width, bmf_clear);
   1465   1.1     jkunz }
   1466   1.1     jkunz 
   1467   1.1     jkunz int
   1468   1.1     jkunz sti_alloc_attr(void *v, int fg, int bg, int flags, long *pattr)
   1469   1.1     jkunz {
   1470  1.13     skrll #if 0
   1471  1.13     skrll 	struct sti_screen *scr = (struct sti_screen *)v;
   1472  1.13     skrll #endif
   1473   1.1     jkunz 
   1474  1.24   tsutsui 	if ((flags & (WSATTR_HILIT | WSATTR_BLINK |
   1475  1.24   tsutsui 	    WSATTR_UNDERLINE | WSATTR_WSCOLORS)) != 0)
   1476  1.24   tsutsui 		return EINVAL;
   1477  1.24   tsutsui 	if ((flags & WSATTR_REVERSE) != 0) {
   1478  1.26     skrll 		fg = STI_COLOUR_BLACK;
   1479  1.24   tsutsui 		bg = STI_COLOUR_WHITE;
   1480  1.24   tsutsui 	} else {
   1481  1.24   tsutsui 		fg = STI_COLOUR_WHITE;
   1482  1.26     skrll 		bg = STI_COLOUR_BLACK;
   1483  1.24   tsutsui 	}
   1484   1.1     jkunz 
   1485  1.24   tsutsui 	*pattr = WSATTR_PACK(fg, bg, flags);
   1486   1.1     jkunz 	return 0;
   1487   1.1     jkunz }
   1488  1.17   tsutsui 
   1489  1.17   tsutsui /*
   1490  1.29     skrll  * Early console support.  Only used on hp300, currently
   1491  1.17   tsutsui  */
   1492  1.17   tsutsui int
   1493  1.17   tsutsui sti_cnattach(struct sti_rom *rom, struct sti_screen *scr, bus_space_tag_t memt,
   1494  1.17   tsutsui     bus_addr_t *bases, u_int codebase)
   1495  1.17   tsutsui {
   1496  1.17   tsutsui 	bus_space_handle_t romh;
   1497  1.17   tsutsui 	u_int romend;
   1498  1.17   tsutsui 	int error;
   1499  1.17   tsutsui 	long defattr;
   1500  1.17   tsutsui 
   1501  1.17   tsutsui 	if ((error = bus_space_map(memt, bases[0], PAGE_SIZE, 0, &romh)) != 0)
   1502  1.17   tsutsui 		return error;
   1503  1.17   tsutsui 
   1504  1.17   tsutsui 	/*
   1505  1.17   tsutsui 	 * Compute real PROM size
   1506  1.17   tsutsui 	 */
   1507  1.17   tsutsui 	romend = sti_rom_size(memt, romh);
   1508  1.17   tsutsui 
   1509  1.17   tsutsui 	bus_space_unmap(memt, romh, PAGE_SIZE);
   1510  1.17   tsutsui 
   1511  1.17   tsutsui 	if ((error = bus_space_map(memt, bases[0], romend, 0, &romh)) != 0)
   1512  1.17   tsutsui 		return error;
   1513  1.17   tsutsui 
   1514  1.17   tsutsui 	bases[0] = romh;
   1515  1.17   tsutsui 	if (sti_rom_setup(rom, memt, memt, romh, bases, codebase) != 0)
   1516  1.17   tsutsui 		return -1;
   1517  1.17   tsutsui 	scr->scr_rom = rom;
   1518  1.17   tsutsui 	if (sti_screen_setup(scr, STI_CLEARSCR) != 0)
   1519  1.17   tsutsui 		return -1;
   1520  1.17   tsutsui 
   1521  1.17   tsutsui 	sti_alloc_attr(scr, 0, 0, 0, &defattr);
   1522  1.17   tsutsui 	wsdisplay_cnattach(&scr->scr_wsd, scr, 0, 0, defattr);
   1523  1.17   tsutsui 
   1524  1.17   tsutsui 	return 0;
   1525  1.17   tsutsui }
   1526  1.23   tsutsui 
   1527  1.23   tsutsui int
   1528  1.23   tsutsui ngle_default_putcmap(struct sti_screen *scr, u_int idx, u_int count)
   1529  1.23   tsutsui {
   1530  1.23   tsutsui 	int i, ret;
   1531  1.23   tsutsui 
   1532  1.23   tsutsui 	for (i = idx + count - 1; i >= (int)idx; i--)
   1533  1.23   tsutsui 		if ((ret = sti_setcment(scr, i, scr->scr_rcmap[i],
   1534  1.23   tsutsui 		    scr->scr_gcmap[i], scr->scr_bcmap[i])))
   1535  1.23   tsutsui 			return EINVAL;
   1536  1.23   tsutsui 
   1537  1.23   tsutsui 	return 0;
   1538  1.23   tsutsui }
   1539  1.23   tsutsui 
   1540  1.23   tsutsui #ifndef SMALL_KERNEL
   1541  1.23   tsutsui 
   1542  1.23   tsutsui void	ngle_setup_hw(bus_space_tag_t, bus_space_handle_t);
   1543  1.23   tsutsui void	ngle_setup_fb(bus_space_tag_t, bus_space_handle_t, uint32_t);
   1544  1.23   tsutsui void	ngle_setup_attr_planes(struct sti_screen *scr);
   1545  1.23   tsutsui void	ngle_setup_bt458(struct sti_screen *scr);
   1546  1.23   tsutsui 
   1547  1.23   tsutsui #define	ngle_bt458_write(memt, memh, r, v) \
   1548  1.32  macallan 	bus_space_write_stream_4(memt, memh, NGLE_REG_RAMDAC + ((r) << 2), (v) << 24)
   1549  1.23   tsutsui 
   1550  1.23   tsutsui void
   1551  1.23   tsutsui ngle_artist_setupfb(struct sti_screen *scr)
   1552  1.23   tsutsui {
   1553  1.23   tsutsui 	struct sti_rom *rom = scr->scr_rom;
   1554  1.23   tsutsui 	bus_space_tag_t memt = rom->memt;
   1555  1.23   tsutsui 	bus_space_handle_t memh = rom->regh[2];
   1556  1.23   tsutsui 
   1557  1.23   tsutsui 	ngle_setup_bt458(scr);
   1558  1.23   tsutsui 
   1559  1.23   tsutsui 	ngle_setup_hw(memt, memh);
   1560  1.23   tsutsui 	ngle_setup_fb(memt, memh, scr->reg10_value);
   1561  1.23   tsutsui 
   1562  1.23   tsutsui 	ngle_setup_attr_planes(scr);
   1563  1.23   tsutsui 
   1564  1.23   tsutsui 	ngle_setup_hw(memt, memh);
   1565  1.32  macallan 	bus_space_write_stream_4(memt, memh, NGLE_REG_21,
   1566  1.32  macallan 	    bus_space_read_stream_4(memt, memh, NGLE_REG_21) | 0x0a000000);
   1567  1.32  macallan 	bus_space_write_stream_4(memt, memh, NGLE_REG_27,
   1568  1.32  macallan 	    bus_space_read_stream_4(memt, memh, NGLE_REG_27) | 0x00800000);
   1569  1.23   tsutsui }
   1570  1.23   tsutsui 
   1571  1.23   tsutsui void
   1572  1.23   tsutsui ngle_elk_setupfb(struct sti_screen *scr)
   1573  1.23   tsutsui {
   1574  1.23   tsutsui 	struct sti_rom *rom = scr->scr_rom;
   1575  1.23   tsutsui 	bus_space_tag_t memt = rom->memt;
   1576  1.23   tsutsui 	bus_space_handle_t memh = rom->regh[2];
   1577  1.23   tsutsui 
   1578  1.23   tsutsui 	ngle_setup_bt458(scr);
   1579  1.23   tsutsui 
   1580  1.23   tsutsui 	ngle_setup_hw(memt, memh);
   1581  1.23   tsutsui 	ngle_setup_fb(memt, memh, scr->reg10_value);
   1582  1.23   tsutsui 
   1583  1.23   tsutsui 	ngle_setup_attr_planes(scr);
   1584  1.23   tsutsui 
   1585  1.23   tsutsui 	ngle_setup_hw(memt, memh);
   1586  1.23   tsutsui 	/* enable overlay planes in Bt458 command register */
   1587  1.23   tsutsui 	ngle_bt458_write(memt, memh, 0x0c, 0x06);
   1588  1.23   tsutsui 	ngle_bt458_write(memt, memh, 0x0e, 0x43);
   1589  1.23   tsutsui }
   1590  1.23   tsutsui 
   1591  1.23   tsutsui void
   1592  1.23   tsutsui ngle_timber_setupfb(struct sti_screen *scr)
   1593  1.23   tsutsui {
   1594  1.23   tsutsui 	struct sti_rom *rom = scr->scr_rom;
   1595  1.23   tsutsui 	bus_space_tag_t memt = rom->memt;
   1596  1.23   tsutsui 	bus_space_handle_t memh = rom->regh[2];
   1597  1.23   tsutsui 
   1598  1.23   tsutsui 	ngle_setup_bt458(scr);
   1599  1.23   tsutsui 
   1600  1.23   tsutsui 	ngle_setup_hw(memt, memh);
   1601  1.23   tsutsui 	/* enable overlay planes in Bt458 command register */
   1602  1.23   tsutsui 	ngle_bt458_write(memt, memh, 0x0c, 0x06);
   1603  1.23   tsutsui 	ngle_bt458_write(memt, memh, 0x0e, 0x43);
   1604  1.23   tsutsui }
   1605  1.23   tsutsui 
   1606  1.40  macallan static void
   1607  1.40  macallan summit_wait(struct sti_screen *scr)
   1608  1.40  macallan {
   1609  1.40  macallan 	struct sti_rom *rom = scr->scr_rom;
   1610  1.40  macallan 	bus_space_tag_t memt = rom->memt;
   1611  1.40  macallan 	bus_space_handle_t memh = rom->regh[0];
   1612  1.40  macallan 
   1613  1.40  macallan 	while (bus_space_read_stream_4(memt, memh, VISFX_STATUS) != 0)
   1614  1.40  macallan 		continue;
   1615  1.40  macallan }
   1616  1.40  macallan 
   1617  1.40  macallan void
   1618  1.40  macallan summit_setupfb(struct sti_screen *scr)
   1619  1.40  macallan {
   1620  1.40  macallan 	struct sti_rom *rom = scr->scr_rom;
   1621  1.40  macallan 	bus_space_tag_t memt = rom->memt;
   1622  1.40  macallan 	bus_space_handle_t memh = rom->regh[0];
   1623  1.40  macallan 
   1624  1.40  macallan 	summit_wait(scr);
   1625  1.40  macallan 	bus_space_write_stream_4(memt, memh, 0xb08044, 0x1b);
   1626  1.40  macallan 	bus_space_write_stream_4(memt, memh, 0xb08048, 0x1b);
   1627  1.40  macallan 	bus_space_write_stream_4(memt, memh, 0x920860, 0xe4);
   1628  1.40  macallan 	bus_space_write_stream_4(memt, memh, 0xa00818, 0);
   1629  1.40  macallan 	bus_space_write_stream_4(memt, memh, 0xa00404, 0);
   1630  1.40  macallan 	bus_space_write_stream_4(memt, memh, 0x921110, 0);
   1631  1.40  macallan 	bus_space_write_stream_4(memt, memh, 0x9211d8, 0);
   1632  1.40  macallan 	bus_space_write_stream_4(memt, memh, 0xa0086c, 0);
   1633  1.40  macallan 	bus_space_write_stream_4(memt, memh, 0x921114, 0);
   1634  1.40  macallan 	bus_space_write_stream_4(memt, memh, 0xac1050, 0);
   1635  1.41  macallan 
   1636  1.41  macallan 	bus_space_write_stream_4(memt, memh, VISFX_APERTURE_ACCESS,
   1637  1.41  macallan 	    VISFX_DEPTH_8);
   1638  1.40  macallan 
   1639  1.40  macallan 	bus_space_write_stream_4(memt, memh, VISFX_PIXEL_MASK, 0xffffffff);
   1640  1.40  macallan 	bus_space_write_stream_4(memt, memh, VISFX_PLANE_MASK, 0xffffffff);
   1641  1.40  macallan 	bus_space_write_stream_4(memt, memh, VISFX_VRAM_WRITE_MODE,
   1642  1.40  macallan 	    VISFX_WRITE_MODE_PLAIN);
   1643  1.41  macallan 	bus_space_write_stream_4(memt, memh, VISFX_VRAM_READ_MODE,
   1644  1.41  macallan 	    VISFX_READ_MODE_COPY);
   1645  1.40  macallan }
   1646  1.40  macallan 
   1647  1.23   tsutsui void
   1648  1.23   tsutsui ngle_setup_bt458(struct sti_screen *scr)
   1649  1.23   tsutsui {
   1650  1.23   tsutsui 	struct sti_rom *rom = scr->scr_rom;
   1651  1.23   tsutsui 	bus_space_tag_t memt = rom->memt;
   1652  1.23   tsutsui 	bus_space_handle_t memh = rom->regh[2];
   1653  1.23   tsutsui 
   1654  1.23   tsutsui 	ngle_setup_hw(memt, memh);
   1655  1.23   tsutsui 	/* set Bt458 read mask register to all planes */
   1656  1.23   tsutsui 	ngle_bt458_write(memt, memh, 0x08, 0x04);
   1657  1.23   tsutsui 	ngle_bt458_write(memt, memh, 0x0a, 0xff);
   1658  1.23   tsutsui }
   1659  1.23   tsutsui 
   1660  1.23   tsutsui void
   1661  1.23   tsutsui ngle_setup_attr_planes(struct sti_screen *scr)
   1662  1.23   tsutsui {
   1663  1.23   tsutsui 	struct sti_rom *rom = scr->scr_rom;
   1664  1.23   tsutsui 	bus_space_tag_t memt = rom->memt;
   1665  1.23   tsutsui 	bus_space_handle_t memh = rom->regh[2];
   1666  1.23   tsutsui 
   1667  1.23   tsutsui 	ngle_setup_hw(memt, memh);
   1668  1.32  macallan 	bus_space_write_stream_4(memt, memh, NGLE_REG_11, 0x2ea0d000);
   1669  1.32  macallan 	bus_space_write_stream_4(memt, memh, NGLE_REG_14, 0x23000302);
   1670  1.32  macallan 	bus_space_write_stream_4(memt, memh, NGLE_REG_12, scr->reg12_value);
   1671  1.32  macallan 	bus_space_write_stream_4(memt, memh, NGLE_REG_8, 0xffffffff);
   1672  1.23   tsutsui 
   1673  1.32  macallan 	bus_space_write_stream_4(memt, memh, NGLE_REG_6, 0x00000000);
   1674  1.32  macallan 	bus_space_write_stream_4(memt, memh, NGLE_REG_9,
   1675  1.23   tsutsui 	    (scr->scr_cfg.scr_width << 16) | scr->scr_cfg.scr_height);
   1676  1.32  macallan 	bus_space_write_stream_4(memt, memh, NGLE_REG_6, 0x05000000);
   1677  1.32  macallan 	bus_space_write_stream_4(memt, memh, NGLE_REG_9, 0x00040001);
   1678  1.23   tsutsui 
   1679  1.23   tsutsui 	ngle_setup_hw(memt, memh);
   1680  1.32  macallan 	bus_space_write_stream_4(memt, memh, NGLE_REG_12, 0x00000000);
   1681  1.23   tsutsui 
   1682  1.23   tsutsui 	ngle_setup_fb(memt, memh, scr->reg10_value);
   1683  1.23   tsutsui }
   1684  1.23   tsutsui 
   1685  1.23   tsutsui int
   1686  1.23   tsutsui ngle_putcmap(struct sti_screen *scr, u_int idx, u_int count)
   1687  1.23   tsutsui {
   1688  1.23   tsutsui 	struct sti_rom *rom = scr->scr_rom;
   1689  1.23   tsutsui 	bus_space_tag_t memt = rom->memt;
   1690  1.23   tsutsui 	bus_space_handle_t memh = rom->regh[2];
   1691  1.23   tsutsui 	uint8_t *r, *g, *b;
   1692  1.23   tsutsui 	uint32_t cmap_finish;
   1693  1.23   tsutsui 
   1694  1.23   tsutsui 	if (scr->scr_bpp > 8)
   1695  1.23   tsutsui 		cmap_finish = 0x83000100;
   1696  1.23   tsutsui 	else
   1697  1.23   tsutsui 		cmap_finish = 0x80000100;
   1698  1.23   tsutsui 
   1699  1.23   tsutsui 	r = scr->scr_rcmap + idx;
   1700  1.23   tsutsui 	g = scr->scr_gcmap + idx;
   1701  1.23   tsutsui 	b = scr->scr_bcmap + idx;
   1702  1.23   tsutsui 
   1703  1.23   tsutsui 	ngle_setup_hw(memt, memh);
   1704  1.32  macallan 	bus_space_write_stream_4(memt, memh, NGLE_REG_10, 0xbbe0f000);
   1705  1.32  macallan 	bus_space_write_stream_4(memt, memh, NGLE_REG_14, 0x03000300);
   1706  1.32  macallan 	bus_space_write_stream_4(memt, memh, NGLE_REG_13, 0xffffffff);
   1707  1.23   tsutsui 
   1708  1.23   tsutsui 	while (count-- != 0) {
   1709  1.23   tsutsui 		ngle_setup_hw(memt, memh);
   1710  1.32  macallan 		bus_space_write_stream_4(memt, memh, NGLE_REG_3,
   1711  1.32  macallan 		    0x400 | (idx << 2));
   1712  1.32  macallan 		bus_space_write_stream_4(memt, memh, NGLE_REG_4,
   1713  1.23   tsutsui 		    (*r << 16) | (*g << 8) | *b);
   1714  1.23   tsutsui 
   1715  1.23   tsutsui 		idx++;
   1716  1.23   tsutsui 		r++, g++, b++;
   1717  1.23   tsutsui 	}
   1718  1.23   tsutsui 
   1719  1.37  macallan 
   1720  1.32  macallan 	bus_space_write_stream_4(memt, memh, NGLE_REG_2, 0x400);
   1721  1.32  macallan 	bus_space_write_stream_4(memt, memh, scr->cmap_finish_register,
   1722  1.32  macallan 	    cmap_finish);
   1723  1.23   tsutsui 	ngle_setup_fb(memt, memh, scr->reg10_value);
   1724  1.23   tsutsui 
   1725  1.23   tsutsui 
   1726  1.23   tsutsui 	return 0;
   1727  1.23   tsutsui }
   1728  1.23   tsutsui 
   1729  1.37  macallan int
   1730  1.37  macallan ngle_hcrx_putcmap(struct sti_screen *scr, u_int idx, u_int count)
   1731  1.37  macallan {
   1732  1.37  macallan 	struct sti_rom *rom = scr->scr_rom;
   1733  1.37  macallan 	bus_space_tag_t memt = rom->memt;
   1734  1.37  macallan 	bus_space_handle_t memh = rom->regh[2];
   1735  1.37  macallan 	uint8_t *r, *g, *b;
   1736  1.37  macallan 	uint32_t cmap_finish;
   1737  1.37  macallan 
   1738  1.37  macallan 	if (scr->scr_bpp > 8)
   1739  1.37  macallan 		cmap_finish = 0x80000100;
   1740  1.37  macallan 	else
   1741  1.37  macallan 		cmap_finish = 0x82000100;
   1742  1.37  macallan 
   1743  1.37  macallan 	r = scr->scr_rcmap + idx;
   1744  1.37  macallan 	g = scr->scr_gcmap + idx;
   1745  1.37  macallan 	b = scr->scr_bcmap + idx;
   1746  1.37  macallan 
   1747  1.37  macallan 	ngle_setup_hw(memt, memh);
   1748  1.37  macallan 	bus_space_write_stream_4(memt, memh, NGLE_REG_10, 0xbbe0f000);
   1749  1.37  macallan 	bus_space_write_stream_4(memt, memh, NGLE_REG_14, 0x03000300);
   1750  1.37  macallan 	bus_space_write_stream_4(memt, memh, NGLE_REG_13, 0xffffffff);
   1751  1.37  macallan 
   1752  1.37  macallan 	while (count-- != 0) {
   1753  1.37  macallan 		ngle_setup_hw(memt, memh);
   1754  1.37  macallan 		bus_space_write_stream_4(memt, memh, NGLE_REG_3,
   1755  1.37  macallan 		    0x400 | (idx << 2));
   1756  1.37  macallan 		bus_space_write_stream_4(memt, memh, NGLE_REG_4,
   1757  1.37  macallan 		    (*r << 16) | (*g << 8) | *b);
   1758  1.37  macallan 
   1759  1.37  macallan 		idx++;
   1760  1.37  macallan 		r++, g++, b++;
   1761  1.37  macallan 	}
   1762  1.37  macallan 
   1763  1.37  macallan 
   1764  1.37  macallan 	bus_space_write_stream_4(memt, memh, NGLE_REG_2, 0x400);
   1765  1.37  macallan 	bus_space_write_stream_4(memt, memh, NGLE_REG_38, cmap_finish);
   1766  1.37  macallan 	ngle_setup_fb(memt, memh, scr->reg10_value);
   1767  1.37  macallan 
   1768  1.37  macallan 
   1769  1.37  macallan 	return 0;
   1770  1.37  macallan }
   1771  1.37  macallan 
   1772  1.40  macallan int
   1773  1.40  macallan summit_putcmap(struct sti_screen *scr, u_int idx, u_int count)
   1774  1.40  macallan {
   1775  1.40  macallan 	struct sti_rom *rom = scr->scr_rom;
   1776  1.40  macallan 	bus_space_tag_t memt = rom->memt;
   1777  1.40  macallan 	bus_space_handle_t memh = rom->regh[0];
   1778  1.40  macallan 	uint8_t *r, *g, *b;
   1779  1.40  macallan 
   1780  1.40  macallan 	r = scr->scr_rcmap + idx;
   1781  1.40  macallan 	g = scr->scr_gcmap + idx;
   1782  1.40  macallan 	b = scr->scr_bcmap + idx;
   1783  1.40  macallan 
   1784  1.42  macallan 	if (rom->rom_dd.dd_grid[0] == STI_DD_LEGO) {
   1785  1.42  macallan 		bus_space_write_stream_4(memt, memh, VISFX_COLOR_INDEX, idx);
   1786  1.42  macallan 	} else
   1787  1.42  macallan 		bus_space_write_stream_4(memt, memh, VISFX_COLOR_INDEX,
   1788  1.42  macallan 		     0xc0005100 + idx);
   1789  1.40  macallan 
   1790  1.40  macallan 	while (count-- != 0) {
   1791  1.40  macallan 		bus_space_write_stream_4(memt, memh,
   1792  1.40  macallan 		     VISFX_COLOR_VALUE, (*r << 16) | (*g << 8) | *b);
   1793  1.40  macallan 		r++, g++, b++;
   1794  1.40  macallan 	}
   1795  1.40  macallan 	bus_space_write_stream_4(memt, memh, VISFX_COLOR_MASK, 0xff);
   1796  1.40  macallan 	bus_space_write_stream_4(memt, memh, 0x80004c, 0xc);
   1797  1.40  macallan 	bus_space_write_stream_4(memt, memh, 0x800000, 0);
   1798  1.40  macallan 
   1799  1.40  macallan 	return 0;
   1800  1.40  macallan }
   1801  1.40  macallan 
   1802  1.23   tsutsui void
   1803  1.23   tsutsui ngle_setup_hw(bus_space_tag_t memt, bus_space_handle_t memh)
   1804  1.23   tsutsui {
   1805  1.23   tsutsui 	uint8_t stat;
   1806  1.23   tsutsui 
   1807  1.23   tsutsui 	do {
   1808  1.23   tsutsui 		stat = bus_space_read_1(memt, memh, NGLE_REG_15b0);
   1809  1.23   tsutsui 		if (stat == 0)
   1810  1.23   tsutsui 			stat = bus_space_read_1(memt, memh, NGLE_REG_15b0);
   1811  1.23   tsutsui 	} while (stat != 0);
   1812  1.23   tsutsui }
   1813  1.23   tsutsui 
   1814  1.23   tsutsui void
   1815  1.23   tsutsui ngle_setup_fb(bus_space_tag_t memt, bus_space_handle_t memh, uint32_t reg10)
   1816  1.23   tsutsui {
   1817  1.23   tsutsui 
   1818  1.23   tsutsui 	ngle_setup_hw(memt, memh);
   1819  1.32  macallan 	bus_space_write_stream_4(memt, memh, NGLE_REG_10, reg10);
   1820  1.32  macallan 	bus_space_write_stream_4(memt, memh, NGLE_REG_14, 0x83000300);
   1821  1.23   tsutsui 	ngle_setup_hw(memt, memh);
   1822  1.23   tsutsui 	bus_space_write_1(memt, memh, NGLE_REG_16b1, 1);
   1823  1.23   tsutsui }
   1824  1.23   tsutsui #endif	/* SMALL_KERNEL */
   1825