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