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