This source file includes following definitions.
- sti_attach_common
- sti_screen_setup
- sti_describe
- sti_end_attach
- sti_rom_size
- sti_fetchfonts
- sti_init
- sti_inqcfg
- sti_bmove
- sti_setcment
- sti_ioctl
- sti_mmap
- sti_alloc_screen
- sti_free_screen
- sti_show_screen
- sti_load_font
- sti_cursor
- sti_mapchar
- sti_putchar
- sti_copycols
- sti_erasecols
- sti_copyrows
- sti_eraserows
- sti_alloc_attr
- sti_unpack_attr
- sti_clear
- sti_cnattach
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/device.h>
38 #include <sys/malloc.h>
39
40 #include <uvm/uvm.h>
41
42 #include <machine/bus.h>
43
44 #include <dev/wscons/wsdisplayvar.h>
45 #include <dev/wscons/wsconsio.h>
46
47 #include <dev/ic/stireg.h>
48 #include <dev/ic/stivar.h>
49
50 #include "sti.h"
51
52 struct cfdriver sti_cd = {
53 NULL, "sti", DV_DULL
54 };
55
56 void sti_cursor(void *v, int on, int row, int col);
57 int sti_mapchar(void *v, int uni, u_int *index);
58 void sti_putchar(void *v, int row, int col, u_int uc, long attr);
59 void sti_copycols(void *v, int row, int srccol, int dstcol, int ncols);
60 void sti_erasecols(void *v, int row, int startcol, int ncols, long attr);
61 void sti_copyrows(void *v, int srcrow, int dstrow, int nrows);
62 void sti_eraserows(void *v, int row, int nrows, long attr);
63 int sti_alloc_attr(void *v, int fg, int bg, int flags, long *pattr);
64 void sti_unpack_attr(void *v, long attr, int *fg, int *bg, int *ul);
65
66 struct wsdisplay_emulops sti_emulops = {
67 sti_cursor,
68 sti_mapchar,
69 sti_putchar,
70 sti_copycols,
71 sti_erasecols,
72 sti_copyrows,
73 sti_eraserows,
74 sti_alloc_attr,
75 sti_unpack_attr
76 };
77
78 int sti_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p);
79 paddr_t sti_mmap(void *v, off_t offset, int prot);
80 int sti_alloc_screen(void *v, const struct wsscreen_descr *type,
81 void **cookiep, int *cxp, int *cyp, long *defattr);
82 void sti_free_screen(void *v, void *cookie);
83 int sti_show_screen(void *v, void *cookie, int waitok,
84 void (*cb)(void *, int, int), void *cbarg);
85 int sti_load_font(void *v, void *cookie, struct wsdisplay_font *);
86
87 const struct wsdisplay_accessops sti_accessops = {
88 sti_ioctl,
89 sti_mmap,
90 sti_alloc_screen,
91 sti_free_screen,
92 sti_show_screen,
93 sti_load_font
94 };
95
96 enum sti_bmove_funcs {
97 bmf_clear, bmf_copy, bmf_invert, bmf_underline
98 };
99
100 int sti_init(struct sti_screen *scr, int mode);
101 int sti_inqcfg(struct sti_screen *scr, struct sti_inqconfout *out);
102 void sti_bmove(struct sti_screen *scr, int, int, int, int, int, int,
103 enum sti_bmove_funcs);
104 int sti_setcment(struct sti_screen *scr, u_int i, u_char r, u_char g, u_char b);
105 int sti_fetchfonts(struct sti_screen *scr, struct sti_inqconfout *cfg,
106 u_int32_t addr);
107 int sti_screen_setup(struct sti_screen *scr, bus_space_tag_t iot,
108 bus_space_tag_t memt, bus_space_handle_t romh, bus_addr_t *bases,
109 u_int codebase);
110
111 #if NSTI_PCI > 0
112 #define STI_ENABLE_ROM(sc) \
113 do { \
114 if ((sc) != NULL && (sc)->sc_enable_rom != NULL) \
115 (*(sc)->sc_enable_rom)(sc); \
116 } while (0)
117 #define STI_DISABLE_ROM(sc) \
118 do { \
119 if ((sc) != NULL && (sc)->sc_disable_rom != NULL) \
120 (*(sc)->sc_disable_rom)(sc); \
121 } while (0)
122 #else
123 #define STI_ENABLE_ROM(sc) do { } while (0)
124 #define STI_DISABLE_ROM(sc) do { } while (0)
125 #endif
126
127 int
128 sti_attach_common(sc, codebase)
129 struct sti_softc *sc;
130 u_int codebase;
131 {
132 struct sti_screen *scr;
133 int rc;
134
135 scr = malloc(sizeof(struct sti_screen), M_DEVBUF, M_NOWAIT);
136 if (scr == NULL) {
137 printf("cannot allocate screen data\n");
138 return (ENOMEM);
139 }
140
141 bzero(scr, sizeof(struct sti_screen));
142 sc->sc_scr = scr;
143 scr->scr_main = sc;
144
145 if ((rc = sti_screen_setup(scr, sc->iot, sc->memt, sc->romh, sc->bases,
146 codebase)) != 0) {
147 free(scr, M_DEVBUF);
148 sc->sc_scr = NULL;
149 return (rc);
150 }
151
152 sti_describe(sc);
153 return (0);
154 }
155
156 int
157 sti_screen_setup(struct sti_screen *scr, bus_space_tag_t iot,
158 bus_space_tag_t memt, bus_space_handle_t romh, bus_addr_t *bases,
159 u_int codebase)
160 {
161 struct sti_inqconfout cfg;
162 struct sti_einqconfout ecfg;
163 bus_space_handle_t fbh;
164 struct sti_dd *dd;
165 struct sti_cfg *cc;
166 int error, size, i;
167 int geometry_kluge = 0;
168
169 STI_ENABLE_ROM(scr->scr_main);
170
171 scr->iot = iot;
172 scr->memt = memt;
173 scr->romh = romh;
174 scr->bases = bases;
175 scr->scr_devtype = bus_space_read_1(memt, romh, 3);
176
177
178 dd = &scr->scr_dd;
179 if (scr->scr_devtype == STI_DEVTYPE1) {
180 #define parseshort(o) \
181 ((bus_space_read_1(memt, romh, (o) + 3) << 8) | \
182 (bus_space_read_1(memt, romh, (o) + 7)))
183 #define parseword(o) \
184 ((bus_space_read_1(memt, romh, (o) + 3) << 24) | \
185 (bus_space_read_1(memt, romh, (o) + 7) << 16) | \
186 (bus_space_read_1(memt, romh, (o) + 11) << 8) | \
187 (bus_space_read_1(memt, romh, (o) + 15)))
188
189 dd->dd_type = bus_space_read_1(memt, romh, 0x03);
190 dd->dd_nmon = bus_space_read_1(memt, romh, 0x07);
191 dd->dd_grrev = bus_space_read_1(memt, romh, 0x0b);
192 dd->dd_lrrev = bus_space_read_1(memt, romh, 0x0f);
193 dd->dd_grid[0] = parseword(0x10);
194 dd->dd_grid[1] = parseword(0x20);
195 dd->dd_fntaddr = parseword(0x30) & ~3;
196 dd->dd_maxst = parseword(0x40);
197 dd->dd_romend = parseword(0x50) & ~3;
198 dd->dd_reglst = parseword(0x60) & ~3;
199 dd->dd_maxreent= parseshort(0x70);
200 dd->dd_maxtimo = parseshort(0x78);
201 dd->dd_montbl = parseword(0x80) & ~3;
202 dd->dd_udaddr = parseword(0x90) & ~3;
203 dd->dd_stimemreq=parseword(0xa0);
204 dd->dd_udsize = parseword(0xb0);
205 dd->dd_pwruse = parseshort(0xc0);
206 dd->dd_bussup = bus_space_read_1(memt, romh, 0xcb);
207 dd->dd_ebussup = bus_space_read_1(memt, romh, 0xcf);
208 dd->dd_altcodet= bus_space_read_1(memt, romh, 0xd3);
209 dd->dd_eddst[0]= bus_space_read_1(memt, romh, 0xd7);
210 dd->dd_eddst[1]= bus_space_read_1(memt, romh, 0xdb);
211 dd->dd_eddst[2]= bus_space_read_1(memt, romh, 0xdf);
212 dd->dd_cfbaddr = parseword(0xe0) & ~3;
213
214 codebase <<= 2;
215 dd->dd_pacode[0x0] = parseword(codebase + 0x000) & ~3;
216 dd->dd_pacode[0x1] = parseword(codebase + 0x010) & ~3;
217 dd->dd_pacode[0x2] = parseword(codebase + 0x020) & ~3;
218 dd->dd_pacode[0x3] = parseword(codebase + 0x030) & ~3;
219 dd->dd_pacode[0x4] = parseword(codebase + 0x040) & ~3;
220 dd->dd_pacode[0x5] = parseword(codebase + 0x050) & ~3;
221 dd->dd_pacode[0x6] = parseword(codebase + 0x060) & ~3;
222 dd->dd_pacode[0x7] = parseword(codebase + 0x070) & ~3;
223 dd->dd_pacode[0x8] = parseword(codebase + 0x080) & ~3;
224 dd->dd_pacode[0x9] = parseword(codebase + 0x090) & ~3;
225 dd->dd_pacode[0xa] = parseword(codebase + 0x0a0) & ~3;
226 dd->dd_pacode[0xb] = parseword(codebase + 0x0b0) & ~3;
227 dd->dd_pacode[0xc] = parseword(codebase + 0x0c0) & ~3;
228 dd->dd_pacode[0xd] = parseword(codebase + 0x0d0) & ~3;
229 dd->dd_pacode[0xe] = parseword(codebase + 0x0e0) & ~3;
230 dd->dd_pacode[0xf] = parseword(codebase + 0x0f0) & ~3;
231 } else {
232 bus_space_read_raw_region_4(memt, romh, 0, (u_int8_t *)dd,
233 sizeof(*dd));
234
235 bus_space_read_raw_region_4(memt, romh, codebase,
236 (u_int8_t *)dd->dd_pacode, sizeof(dd->dd_pacode));
237 }
238
239 STI_DISABLE_ROM(scr->scr_main);
240
241 #ifdef STIDEBUG
242 printf("dd:\n"
243 "devtype=%x, rev=%x;%d, altt=%x, gid=%016llx, font=%x, mss=%x\n"
244 "end=%x, regions=%x, msto=%x, timo=%d, mont=%x, user=%x[%x]\n"
245 "memrq=%x, pwr=%d, bus=%x, ebus=%x, cfb=%x\n"
246 "code=",
247 dd->dd_type & 0xff, dd->dd_grrev, dd->dd_lrrev, dd->dd_altcodet,
248 *(u_int64_t *)dd->dd_grid, dd->dd_fntaddr, dd->dd_maxst,
249 dd->dd_romend, dd->dd_reglst, dd->dd_maxreent, dd->dd_maxtimo,
250 dd->dd_montbl, dd->dd_udaddr, dd->dd_udsize, dd->dd_stimemreq,
251 dd->dd_pwruse, dd->dd_bussup, dd->dd_ebussup, dd->dd_cfbaddr);
252 printf("%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n",
253 dd->dd_pacode[0x0], dd->dd_pacode[0x1], dd->dd_pacode[0x2],
254 dd->dd_pacode[0x3], dd->dd_pacode[0x4], dd->dd_pacode[0x5],
255 dd->dd_pacode[0x6], dd->dd_pacode[0x7], dd->dd_pacode[0x8],
256 dd->dd_pacode[0x9], dd->dd_pacode[0xa], dd->dd_pacode[0xb],
257 dd->dd_pacode[0xc], dd->dd_pacode[0xd], dd->dd_pacode[0xe],
258 dd->dd_pacode[0xf]);
259 #endif
260
261 for (i = STI_END; !dd->dd_pacode[i]; i--);
262 size = dd->dd_pacode[i] - dd->dd_pacode[STI_BEGIN];
263 if (scr->scr_devtype == STI_DEVTYPE1)
264 size = (size + 3) / 4;
265 if (size == 0) {
266 printf(": no code for the requested platform\n");
267 return (EINVAL);
268 }
269 if (!(scr->scr_code = uvm_km_alloc(kernel_map, round_page(size)))) {
270 printf(": cannot allocate %u bytes for code\n", size);
271 return (ENOMEM);
272 }
273 #ifdef STIDEBUG
274 printf("code=0x%x[%x]\n", scr->scr_code, size);
275 #endif
276
277 STI_ENABLE_ROM(scr->scr_main);
278
279
280 if (scr->scr_devtype == STI_DEVTYPE1) {
281 u_int8_t *p = (u_int8_t *)scr->scr_code;
282 u_int32_t addr, eaddr;
283
284 for (addr = dd->dd_pacode[STI_BEGIN], eaddr = addr + size * 4;
285 addr < eaddr; addr += 4 )
286 *p++ = bus_space_read_4(memt, romh, addr) & 0xff;
287
288 } else
289 bus_space_read_raw_region_4(memt, romh,
290 dd->dd_pacode[STI_BEGIN], (u_int8_t *)scr->scr_code,
291 size);
292
293 STI_DISABLE_ROM(scr->scr_main);
294
295 #define O(i) (dd->dd_pacode[(i)]? (scr->scr_code + \
296 (dd->dd_pacode[(i)] - dd->dd_pacode[0]) / \
297 (scr->scr_devtype == STI_DEVTYPE1? 4 : 1)) : NULL)
298
299 scr->init = (sti_init_t) O(STI_INIT_GRAPH);
300 scr->mgmt = (sti_mgmt_t) O(STI_STATE_MGMT);
301 scr->unpmv = (sti_unpmv_t) O(STI_FONT_UNPMV);
302 scr->blkmv = (sti_blkmv_t) O(STI_BLOCK_MOVE);
303 scr->test = (sti_test_t) O(STI_SELF_TEST);
304 scr->exhdl = (sti_exhdl_t) O(STI_EXCEP_HDLR);
305 scr->inqconf = (sti_inqconf_t)O(STI_INQ_CONF);
306 scr->scment = (sti_scment_t)O(STI_SCM_ENT);
307 scr->dmac = (sti_dmac_t) O(STI_DMA_CTRL);
308 scr->flowc = (sti_flowc_t) O(STI_FLOW_CTRL);
309 scr->utiming = (sti_utiming_t)O(STI_UTIMING);
310 scr->pmgr = (sti_pmgr_t) O(STI_PROC_MGR);
311 scr->util = (sti_util_t) O(STI_UTIL);
312
313
314
315
316
317 if (dd->dd_grrev < STI_REVISION(8,4)) {
318 scr->scment = NULL;
319 }
320
321 if ((error = uvm_map_protect(kernel_map, scr->scr_code,
322 scr->scr_code + round_page(size), UVM_PROT_RX, FALSE))) {
323 printf(": uvm_map_protect failed (%d)\n", error);
324 uvm_km_free(kernel_map, scr->scr_code, round_page(size));
325 return (error);
326 }
327
328 cc = &scr->scr_cfg;
329 bzero(cc, sizeof (*cc));
330 cc->ext_cfg = &scr->scr_ecfg;
331 bzero(cc->ext_cfg, sizeof(*cc->ext_cfg));
332 if (dd->dd_stimemreq) {
333 scr->scr_ecfg.addr =
334 malloc(dd->dd_stimemreq, M_DEVBUF, M_NOWAIT);
335 if (!scr->scr_ecfg.addr) {
336 printf("cannot allocate %d bytes for STI\n",
337 dd->dd_stimemreq);
338 uvm_km_free(kernel_map, scr->scr_code,
339 round_page(size));
340 return (ENOMEM);
341 }
342 }
343 {
344 int i = dd->dd_reglst;
345 u_int32_t *p;
346 struct sti_region r;
347
348 #ifdef STIDEBUG
349 printf("stiregions @%p:\n", i);
350 #endif
351
352 STI_ENABLE_ROM(scr->scr_main);
353
354 r.last = 0;
355 for (p = cc->regions; !r.last &&
356 p < &cc->regions[STI_REGION_MAX]; p++) {
357
358 if (scr->scr_devtype == STI_DEVTYPE1)
359 *(u_int *)&r = parseword(i), i+= 16;
360 else {
361 bus_space_read_raw_region_4(memt, romh, i,
362 (u_int8_t *)&r, 4);
363 i += 4;
364 }
365
366 *p = bases[p - cc->regions] + (r.offset << PGSHIFT);
367 #ifdef STIDEBUG
368 STI_DISABLE_ROM(scr->scr_main);
369 printf("%08x @ 0x%08x%s%s%s%s\n",
370 r.length << PGSHIFT, *p, r.sys_only? " sys" : "",
371 r.cache? " cache" : "", r.btlb? " btlb" : "",
372 r.last? " last" : "");
373 STI_ENABLE_ROM(scr->scr_main);
374 #endif
375
376
377 if (p == cc->regions && romh == bases[0])
378 continue;
379
380 if (bus_space_map(memt, *p, r.length << PGSHIFT,
381 r.cache ? BUS_SPACE_MAP_CACHEABLE : 0, &fbh)) {
382 #ifdef STIDEBUG
383 STI_DISABLE_ROM(scr->scr_main);
384 printf("already mapped region\n");
385 STI_ENABLE_ROM(scr->scr_main);
386 #endif
387 } else {
388 if (p - cc->regions == 1) {
389 scr->fbaddr = *p;
390 scr->fblen = r.length << PGSHIFT;
391 }
392 *p = fbh;
393 }
394 }
395
396 STI_DISABLE_ROM(scr->scr_main);
397 }
398
399 if ((error = sti_init(scr, 0))) {
400 printf(": can not initialize (%d)\n", error);
401
402 return (ENXIO);
403 }
404
405 bzero(&cfg, sizeof(cfg));
406 bzero(&ecfg, sizeof(ecfg));
407 cfg.ext = &ecfg;
408 if ((error = sti_inqcfg(scr, &cfg))) {
409 printf(": error %d inquiring config\n", error);
410
411 return (ENXIO);
412 }
413
414
415
416
417
418
419 if (cfg.owidth == cfg.width &&
420 cfg.oheight == cfg.height)
421 geometry_kluge = 1;
422
423 if (geometry_kluge) {
424 scr->scr_cfg.oscr_width = cfg.owidth =
425 cfg.fbwidth - cfg.width;
426 scr->scr_cfg.oscr_height = cfg.oheight =
427 cfg.fbheight - cfg.height;
428 }
429
430
431
432
433 scr->fbheight = cfg.fbheight;
434 scr->fbwidth = cfg.fbwidth;
435 scr->oheight = cfg.oheight;
436 scr->owidth = cfg.owidth;
437 bcopy(cfg.name, scr->name, sizeof(scr->name));
438
439 if ((error = sti_init(scr, STI_TEXTMODE))) {
440 printf(": can not initialize (%d)\n", error);
441
442 return (ENXIO);
443 }
444
445 #ifdef STIDEBUG
446 printf("conf: bpp=%d planes=%d attr=%b\n"
447 "crt=0x%x:0x%x:0x%x hw=0x%x:0x%x:0x%x\n", cfg.bpp,
448 cfg.planes, cfg.attributes, STI_INQCONF_BITS,
449 ecfg.crt_config[0], ecfg.crt_config[1], ecfg.crt_config[2],
450 ecfg.crt_hw[0], ecfg.crt_hw[1], ecfg.crt_hw[2]);
451 #endif
452 scr->scr_bpp = cfg.bppu;
453
454 if ((error = sti_fetchfonts(scr, &cfg, dd->dd_fntaddr))) {
455 printf(": cannot fetch fonts (%d)\n", error);
456
457 return (ENXIO);
458 }
459
460
461
462
463
464
465
466
467 strlcpy(scr->scr_wsd.name, "std", sizeof(scr->scr_wsd.name));
468 scr->scr_wsd.ncols = cfg.width / scr->scr_curfont.width;
469 scr->scr_wsd.nrows = cfg.height / scr->scr_curfont.height;
470 scr->scr_wsd.textops = &sti_emulops;
471 scr->scr_wsd.fontwidth = scr->scr_curfont.width;
472 scr->scr_wsd.fontheight = scr->scr_curfont.height;
473 scr->scr_wsd.capabilities = 0;
474
475 scr->scr_scrlist[0] = &scr->scr_wsd;
476 scr->scr_screenlist.nscreens = 1;
477 scr->scr_screenlist.screens =
478 (const struct wsscreen_descr **)scr->scr_scrlist;
479
480
481
482 return (0);
483 }
484
485 void
486 sti_describe(struct sti_softc *sc)
487 {
488 struct sti_screen *scr = sc->sc_scr;
489 struct sti_dd *dd = &scr->scr_dd;
490 struct sti_font *fp = &scr->scr_curfont;
491
492 printf(": %s rev %d.%02d;%d, ID 0x%016llX\n",
493 scr->name, dd->dd_grrev >> 4, dd->dd_grrev & 0xf,
494 dd->dd_lrrev, *(u_int64_t *)dd->dd_grid);
495
496 printf("%s: %dx%d frame buffer, %dx%dx%d display, offset %dx%d\n",
497 sc->sc_dev.dv_xname, scr->fbwidth, scr->fbheight,
498 scr->scr_cfg.scr_width, scr->scr_cfg.scr_height, scr->scr_bpp,
499 scr->owidth, scr->oheight);
500
501 printf("%s: %dx%d font type %d, %d bpc, charset %d-%d\n",
502 sc->sc_dev.dv_xname, fp->width, fp->height,
503 fp->type, fp->bpc, fp->first, fp->last);
504 }
505
506 void
507 sti_end_attach(void *v)
508 {
509 struct sti_softc *sc = v;
510 struct wsemuldisplaydev_attach_args waa;
511
512 sc->sc_wsmode = WSDISPLAYIO_MODE_EMUL;
513
514 waa.console = sc->sc_flags & STI_CONSOLE ? 1 : 0;
515 waa.scrdata = &sc->sc_scr->scr_screenlist;
516 waa.accessops = &sti_accessops;
517 waa.accesscookie = sc;
518 waa.defaultscreens = 0;
519
520
521 if (waa.console && !ISSET(sc->sc_flags, STI_ATTACHED)) {
522 long defattr;
523
524 sti_alloc_attr(sc, 0, 0, 0, &defattr);
525 wsdisplay_cnattach(&sc->sc_scr->scr_wsd, sc->sc_scr,
526 0, sc->sc_scr->scr_wsd.nrows - 1, defattr);
527 sc->sc_flags |= STI_ATTACHED;
528 }
529
530 config_found(&sc->sc_dev, &waa, wsemuldisplaydevprint);
531 }
532
533 u_int
534 sti_rom_size(bus_space_tag_t iot, bus_space_handle_t ioh)
535 {
536 int devtype;
537 u_int romend;
538
539 devtype = bus_space_read_1(iot, ioh, 3);
540 if (devtype == STI_DEVTYPE4) {
541 bus_space_read_raw_region_4(iot, ioh, 0x18,
542 (u_int8_t *)&romend, 4);
543 } else {
544 romend =
545 (bus_space_read_1(iot, ioh, 0x50 + 3) << 24) |
546 (bus_space_read_1(iot, ioh, 0x50 + 7) << 16) |
547 (bus_space_read_1(iot, ioh, 0x50 + 11) << 8) |
548 (bus_space_read_1(iot, ioh, 0x50 + 15));
549 }
550
551 return (round_page(romend));
552 }
553
554 int
555 sti_fetchfonts(struct sti_screen *scr, struct sti_inqconfout *cfg,
556 u_int32_t addr)
557 {
558 struct sti_font *fp = &scr->scr_curfont;
559 int size;
560 bus_space_tag_t memt;
561 bus_space_handle_t romh;
562 #ifdef notyet
563 int uc;
564 struct {
565 struct sti_unpmvflags flags;
566 struct sti_unpmvin in;
567 struct sti_unpmvout out;
568 } a;
569 #endif
570
571 memt = scr->memt;
572 romh = scr->romh;
573
574
575
576
577
578 STI_ENABLE_ROM(scr->scr_main);
579
580 do {
581 if (scr->scr_devtype == STI_DEVTYPE1) {
582 fp->first = parseshort(addr + 0x00);
583 fp->last = parseshort(addr + 0x08);
584 fp->width = bus_space_read_1(memt, romh,
585 addr + 0x13);
586 fp->height = bus_space_read_1(memt, romh,
587 addr + 0x17);
588 fp->type = bus_space_read_1(memt, romh,
589 addr + 0x1b);
590 fp->bpc = bus_space_read_1(memt, romh,
591 addr + 0x1f);
592 fp->next = parseword(addr + 0x23);
593 fp->uheight= bus_space_read_1(memt, romh,
594 addr + 0x33);
595 fp->uoffset= bus_space_read_1(memt, romh,
596 addr + 0x37);
597 } else
598 bus_space_read_raw_region_4(memt, romh, addr,
599 (u_int8_t *)fp, sizeof(struct sti_font));
600
601 size = sizeof(struct sti_font) +
602 (fp->last - fp->first + 1) * fp->bpc;
603 if (scr->scr_devtype == STI_DEVTYPE1)
604 size *= 4;
605 scr->scr_romfont = malloc(size, M_DEVBUF, M_NOWAIT);
606 if (scr->scr_romfont == NULL)
607 return (ENOMEM);
608
609 bus_space_read_raw_region_4(memt, romh, addr,
610 (u_int8_t *)scr->scr_romfont, size);
611
612 addr = NULL;
613 } while (addr);
614
615 STI_DISABLE_ROM(scr->scr_main);
616
617 #ifdef notyet
618
619
620
621
622
623 if (size <= cfg->fbheight *
624 (cfg->fbwidth - cfg->width - cfg->owidth)) {
625 bzero(&a, sizeof(a));
626 a.flags.flags = STI_UNPMVF_WAIT;
627 a.in.fg_colour = STI_COLOUR_WHITE;
628 a.in.bg_colour = STI_COLOUR_BLACK;
629 a.in.font_addr = scr->scr_romfont;
630
631 scr->scr_fontmaxcol = cfg->fbheight / fp->height;
632 scr->scr_fontbase = cfg->width + cfg->owidth;
633 for (uc = fp->first; uc <= fp->last; uc++) {
634 a.in.x = ((uc - fp->first) / scr->scr_fontmaxcol) *
635 fp->width + scr->scr_fontbase;
636 a.in.y = ((uc - fp->first) % scr->scr_fontmaxcol) *
637 fp->height;
638 a.in.index = uc;
639
640 (*scr->unpmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg);
641 if (a.out.errno) {
642 #ifdef STIDEBUG
643 printf("sti_unpmv %d returned %d\n",
644 uc, a.out.errno);
645 #endif
646 return (0);
647 }
648 }
649
650 free(scr->scr_romfont, M_DEVBUF);
651 scr->scr_romfont = NULL;
652 }
653 #endif
654
655 return (0);
656 }
657
658 int
659 sti_init(scr, mode)
660 struct sti_screen *scr;
661 int mode;
662 {
663 struct {
664 struct sti_initflags flags;
665 struct sti_initin in;
666 struct sti_einitin ein;
667 struct sti_initout out;
668 } a;
669
670 bzero(&a, sizeof(a));
671
672 a.flags.flags = STI_INITF_WAIT | STI_INITF_CMB | STI_INITF_EBET |
673 (mode & STI_TEXTMODE? STI_INITF_TEXT | STI_INITF_PBET |
674 STI_INITF_PBETI | STI_INITF_ICMT : 0);
675 a.in.text_planes = 1;
676 a.in.ext_in = &a.ein;
677 #ifdef STIDEBUG
678 printf("sti_init,%p(%x, %p, %p, %p)\n",
679 scr->init, a.flags.flags, &a.in, &a.out, &scr->scr_cfg);
680 #endif
681 (*scr->init)(&a.flags, &a.in, &a.out, &scr->scr_cfg);
682 if (a.out.text_planes != a.in.text_planes)
683 return (-1);
684 return (a.out.errno);
685 }
686
687 int
688 sti_inqcfg(struct sti_screen *scr, struct sti_inqconfout *out)
689 {
690 struct {
691 struct sti_inqconfflags flags;
692 struct sti_inqconfin in;
693 } a;
694
695 bzero(&a, sizeof(a));
696
697 a.flags.flags = STI_INQCONFF_WAIT;
698 (*scr->inqconf)(&a.flags, &a.in, out, &scr->scr_cfg);
699
700 return out->errno;
701 }
702
703 void
704 sti_bmove(scr, x1, y1, x2, y2, h, w, f)
705 struct sti_screen *scr;
706 int x1, y1, x2, y2, h, w;
707 enum sti_bmove_funcs f;
708 {
709 struct {
710 struct sti_blkmvflags flags;
711 struct sti_blkmvin in;
712 struct sti_blkmvout out;
713 } a;
714
715 bzero(&a, sizeof(a));
716
717 a.flags.flags = STI_BLKMVF_WAIT;
718 switch (f) {
719 case bmf_clear:
720 a.flags.flags |= STI_BLKMVF_CLR;
721 a.in.bg_colour = STI_COLOUR_BLACK;
722 break;
723 case bmf_underline:
724 case bmf_copy:
725 a.in.fg_colour = STI_COLOUR_WHITE;
726 a.in.bg_colour = STI_COLOUR_BLACK;
727 break;
728 case bmf_invert:
729 a.flags.flags |= STI_BLKMVF_COLR;
730 a.in.fg_colour = STI_COLOUR_BLACK;
731 a.in.bg_colour = STI_COLOUR_WHITE;
732 break;
733 }
734 a.in.srcx = x1;
735 a.in.srcy = y1;
736 a.in.dstx = x2;
737 a.in.dsty = y2;
738 a.in.height = h;
739 a.in.width = w;
740
741 (*scr->blkmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg);
742 #ifdef STIDEBUG
743 if (a.out.errno)
744 printf("sti_blkmv returned %d\n", a.out.errno);
745 #endif
746 }
747
748 int
749 sti_setcment(struct sti_screen *scr, u_int i, u_char r, u_char g, u_char b)
750 {
751 struct {
752 struct sti_scmentflags flags;
753 struct sti_scmentin in;
754 struct sti_scmentout out;
755 } a;
756
757 bzero(&a, sizeof(a));
758
759 a.flags.flags = STI_SCMENTF_WAIT;
760 a.in.entry = i;
761 a.in.value = (r << 16) | (g << 8) | b;
762
763 (*scr->scment)(&a.flags, &a.in, &a.out, &scr->scr_cfg);
764
765 return a.out.errno;
766 }
767
768 int
769 sti_ioctl(v, cmd, data, flag, p)
770 void *v;
771 u_long cmd;
772 caddr_t data;
773 int flag;
774 struct proc *p;
775 {
776 struct sti_softc *sc = v;
777 struct sti_screen *scr = sc->sc_scr;
778 struct wsdisplay_fbinfo *wdf;
779 struct wsdisplay_cmap *cmapp;
780 u_int mode, idx, count;
781 int i, ret;
782
783 ret = 0;
784 switch (cmd) {
785 case WSDISPLAYIO_GMODE:
786 *(u_int *)data = sc->sc_wsmode;
787 break;
788
789 case WSDISPLAYIO_SMODE:
790 mode = *(u_int *)data;
791 if (sc->sc_wsmode == WSDISPLAYIO_MODE_EMUL &&
792 mode == WSDISPLAYIO_MODE_DUMBFB)
793 ret = sti_init(scr, 0);
794 else if (sc->sc_wsmode == WSDISPLAYIO_MODE_DUMBFB &&
795 mode == WSDISPLAYIO_MODE_EMUL)
796 ret = sti_init(scr, STI_TEXTMODE);
797 sc->sc_wsmode = mode;
798 break;
799
800 case WSDISPLAYIO_GTYPE:
801 *(u_int *)data = WSDISPLAY_TYPE_STI;
802 break;
803
804 case WSDISPLAYIO_GINFO:
805 wdf = (struct wsdisplay_fbinfo *)data;
806 wdf->height = scr->scr_cfg.scr_height;
807 wdf->width = scr->scr_cfg.scr_width;
808 wdf->depth = scr->scr_bpp;
809 if (scr->scment == NULL)
810 wdf->cmsize = 0;
811 else
812 wdf->cmsize = STI_NCMAP;
813 break;
814
815 case WSDISPLAYIO_LINEBYTES:
816 *(u_int *)data = scr->scr_cfg.fb_width;
817 break;
818
819 case WSDISPLAYIO_GETCMAP:
820 if (scr->scment == NULL)
821 return ENODEV;
822 cmapp = (struct wsdisplay_cmap *)data;
823 idx = cmapp->index;
824 count = cmapp->count;
825 if (idx >= STI_NCMAP || idx + count > STI_NCMAP)
826 return EINVAL;
827 if ((ret = copyout(&scr->scr_rcmap[idx], cmapp->red, count)))
828 break;
829 if ((ret = copyout(&scr->scr_gcmap[idx], cmapp->green, count)))
830 break;
831 if ((ret = copyout(&scr->scr_bcmap[idx], cmapp->blue, count)))
832 break;
833 break;
834
835 case WSDISPLAYIO_PUTCMAP:
836 if (scr->scment == NULL)
837 return ENODEV;
838 cmapp = (struct wsdisplay_cmap *)data;
839 idx = cmapp->index;
840 count = cmapp->count;
841 if (idx >= STI_NCMAP || idx + count > STI_NCMAP)
842 return EINVAL;
843 if ((ret = copyin(cmapp->red, &scr->scr_rcmap[idx], count)))
844 break;
845 if ((ret = copyin(cmapp->green, &scr->scr_gcmap[idx], count)))
846 break;
847 if ((ret = copyin(cmapp->blue, &scr->scr_bcmap[idx], count)))
848 break;
849 for (i = idx + count - 1; i >= idx; i--)
850 if ((ret = sti_setcment(scr, i, scr->scr_rcmap[i],
851 scr->scr_gcmap[i], scr->scr_bcmap[i]))) {
852 #ifdef STIDEBUG
853 printf("sti_ioctl: "
854 "sti_setcment(%d, %u, %u, %u): %d\n", i,
855 (u_int)scr->scr_rcmap[i],
856 (u_int)scr->scr_gcmap[i],
857 (u_int)scr->scr_bcmap[i]);
858 #endif
859 ret = EINVAL;
860 break;
861 }
862 break;
863
864 case WSDISPLAYIO_SVIDEO:
865 case WSDISPLAYIO_GVIDEO:
866 break;
867
868 case WSDISPLAYIO_GCURPOS:
869 case WSDISPLAYIO_SCURPOS:
870 case WSDISPLAYIO_GCURMAX:
871 case WSDISPLAYIO_GCURSOR:
872 case WSDISPLAYIO_SCURSOR:
873 default:
874 return (-1);
875 }
876
877 return (ret);
878 }
879
880 paddr_t
881 sti_mmap(v, offset, prot)
882 void *v;
883 off_t offset;
884 int prot;
885 {
886
887 return -1;
888 }
889
890 int
891 sti_alloc_screen(v, type, cookiep, cxp, cyp, defattr)
892 void *v;
893 const struct wsscreen_descr *type;
894 void **cookiep;
895 int *cxp, *cyp;
896 long *defattr;
897 {
898 struct sti_softc *sc = v;
899
900 if (sc->sc_nscreens > 0)
901 return ENOMEM;
902
903 *cookiep = sc->sc_scr;
904 *cxp = 0;
905 *cyp = 0;
906 sti_alloc_attr(sc, 0, 0, 0, defattr);
907 sc->sc_nscreens++;
908 return 0;
909 }
910
911 void
912 sti_free_screen(v, cookie)
913 void *v;
914 void *cookie;
915 {
916 struct sti_softc *sc = v;
917
918 sc->sc_nscreens--;
919 }
920
921 int
922 sti_show_screen(v, cookie, waitok, cb, cbarg)
923 void *v;
924 void *cookie;
925 int waitok;
926 void (*cb)(void *, int, int);
927 void *cbarg;
928 {
929 return 0;
930 }
931
932 int
933 sti_load_font(v, cookie, font)
934 void *v;
935 void *cookie;
936 struct wsdisplay_font *font;
937 {
938 return -1;
939 }
940
941 void
942 sti_cursor(v, on, row, col)
943 void *v;
944 int on, row, col;
945 {
946 struct sti_screen *scr = v;
947 struct sti_font *fp = &scr->scr_curfont;
948
949 sti_bmove(scr,
950 col * fp->width, row * fp->height,
951 col * fp->width, row * fp->height,
952 fp->height, fp->width, bmf_invert);
953 }
954
955
956
957
958 static const u_int8_t
959 sti_unitoroman[0x100 - 0xa0] = {
960 0xa0, 0xb8, 0xbf, 0xbb, 0xba, 0xbc, 0, 0xbd,
961 0xab, 0, 0xf9, 0xfb, 0, 0xf6, 0, 0xb0,
962
963 0xb3, 0xfe, 0, 0, 0xa8, 0xf3, 0xf4, 0xf2,
964 0, 0, 0xfa, 0xfd, 0xf7, 0xf8, 0, 0xb9,
965
966 0xa1, 0xe0, 0xa2, 0xe1, 0xd8, 0xd0, 0xd3, 0xb4,
967 0xa3, 0xdc, 0xa4, 0xa5, 0xe6, 0xe5, 0xa6, 0xa7,
968
969 0xe3, 0xb6, 0xe8, 0xe7, 0xdf, 0xe9, 0xda, 0,
970 0xd2, 0xad, 0xed, 0xae, 0xdb, 0xb1, 0xf0, 0xde,
971
972 0xc8, 0xc4, 0xc0, 0xe2, 0xcc, 0xd4, 0xd7, 0xb5,
973 0xc9, 0xc5, 0xc1, 0xcd, 0xd9, 0xd5, 0xd1, 0xdd,
974
975 0xe4, 0xb7, 0xca, 0xc6, 0xc2, 0xea, 0xce, 0,
976 0xd6, 0xcb, 0xc7, 0xc3, 0xcf, 0xb2, 0xf1, 0xef
977 };
978
979 int
980 sti_mapchar(v, uni, index)
981 void *v;
982 int uni;
983 u_int *index;
984 {
985 struct sti_screen *scr = v;
986 struct sti_font *fp = &scr->scr_curfont;
987 int c;
988
989 switch (fp->type) {
990 case STI_FONT_HPROMAN8:
991 if (uni >= 0x80 && uni < 0xa0)
992 c = -1;
993 else if (uni >= 0xa0 && uni < 0x100) {
994 c = (int)sti_unitoroman[uni - 0xa0];
995 if (c == 0)
996 c = -1;
997 } else
998 c = uni;
999 break;
1000 default:
1001 c = uni;
1002 break;
1003 }
1004
1005 if (c == -1 || c < fp->first || c > fp->last) {
1006 *index = ' ';
1007 return (0);
1008 }
1009
1010 *index = c;
1011 return (5);
1012 }
1013
1014 void
1015 sti_putchar(v, row, col, uc, attr)
1016 void *v;
1017 int row, col;
1018 u_int uc;
1019 long attr;
1020 {
1021 struct sti_screen *scr = v;
1022 struct sti_font *fp = &scr->scr_curfont;
1023
1024 if (scr->scr_romfont != NULL) {
1025
1026
1027
1028 struct {
1029 struct sti_unpmvflags flags;
1030 struct sti_unpmvin in;
1031 struct sti_unpmvout out;
1032 } a;
1033
1034 bzero(&a, sizeof(a));
1035
1036 a.flags.flags = STI_UNPMVF_WAIT;
1037
1038 a.in.fg_colour = STI_COLOUR_WHITE;
1039 a.in.bg_colour = STI_COLOUR_BLACK;
1040 a.in.x = col * fp->width;
1041 a.in.y = row * fp->height;
1042 a.in.font_addr = scr->scr_romfont;
1043 a.in.index = uc;
1044
1045 (*scr->unpmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg);
1046 } else {
1047
1048
1049
1050 struct {
1051 struct sti_blkmvflags flags;
1052 struct sti_blkmvin in;
1053 struct sti_blkmvout out;
1054 } a;
1055
1056 bzero(&a, sizeof(a));
1057
1058 a.flags.flags = STI_BLKMVF_WAIT;
1059
1060 a.in.fg_colour = STI_COLOUR_WHITE;
1061 a.in.bg_colour = STI_COLOUR_BLACK;
1062
1063 a.in.srcx = ((uc - fp->first) / scr->scr_fontmaxcol) *
1064 fp->width + scr->scr_fontbase;
1065 a.in.srcy = ((uc - fp->first) % scr->scr_fontmaxcol) *
1066 fp->height;
1067 a.in.dstx = col * fp->width;
1068 a.in.dsty = row * fp->height;
1069 a.in.height = fp->height;
1070 a.in.width = fp->width;
1071
1072 (*scr->blkmv)(&a.flags, &a.in, &a.out, &scr->scr_cfg);
1073 }
1074 }
1075
1076 void
1077 sti_copycols(v, row, srccol, dstcol, ncols)
1078 void *v;
1079 int row, srccol, dstcol, ncols;
1080 {
1081 struct sti_screen *scr = v;
1082 struct sti_font *fp = &scr->scr_curfont;
1083
1084 sti_bmove(scr,
1085 srccol * fp->width, row * fp->height,
1086 dstcol * fp->width, row * fp->height,
1087 fp->height, ncols * fp->width, bmf_copy);
1088 }
1089
1090 void
1091 sti_erasecols(v, row, startcol, ncols, attr)
1092 void *v;
1093 int row, startcol, ncols;
1094 long attr;
1095 {
1096 struct sti_screen *scr = v;
1097 struct sti_font *fp = &scr->scr_curfont;
1098
1099 sti_bmove(scr,
1100 startcol * fp->width, row * fp->height,
1101 startcol * fp->width, row * fp->height,
1102 fp->height, ncols * fp->width, bmf_clear);
1103 }
1104
1105 void
1106 sti_copyrows(v, srcrow, dstrow, nrows)
1107 void *v;
1108 int srcrow, dstrow, nrows;
1109 {
1110 struct sti_screen *scr = v;
1111 struct sti_font *fp = &scr->scr_curfont;
1112
1113 sti_bmove(scr, 0, srcrow * fp->height, 0, dstrow * fp->height,
1114 nrows * fp->height, scr->scr_cfg.scr_width, bmf_copy);
1115 }
1116
1117 void
1118 sti_eraserows(v, srcrow, nrows, attr)
1119 void *v;
1120 int srcrow, nrows;
1121 long attr;
1122 {
1123 struct sti_screen *scr = v;
1124 struct sti_font *fp = &scr->scr_curfont;
1125
1126 sti_bmove(scr, 0, srcrow * fp->height, 0, srcrow * fp->height,
1127 nrows * fp->height, scr->scr_cfg.scr_width, bmf_clear);
1128 }
1129
1130 int
1131 sti_alloc_attr(v, fg, bg, flags, pattr)
1132 void *v;
1133 int fg, bg, flags;
1134 long *pattr;
1135 {
1136
1137
1138 *pattr = 0;
1139
1140 return 0;
1141 }
1142
1143 void
1144 sti_unpack_attr(void *v, long attr, int *fg, int *bg, int *ul)
1145 {
1146 *fg = WSCOL_WHITE;
1147 *bg = WSCOL_BLACK;
1148 if (ul != NULL)
1149 *ul = 0;
1150 }
1151
1152 #if NSTI_SGC > 0
1153
1154
1155
1156
1157
1158 void
1159 sti_clear(struct sti_screen *scr)
1160 {
1161 sti_bmove(scr, 0, 0, 0, 0,
1162 scr->scr_cfg.scr_height, scr->scr_cfg.scr_width, bmf_clear);
1163 }
1164
1165 int
1166 sti_cnattach(struct sti_screen *scr, bus_space_tag_t iot, bus_addr_t *bases,
1167 u_int codebase)
1168 {
1169 bus_space_handle_t ioh;
1170 u_int romend;
1171 int error;
1172 long defattr;
1173
1174 if ((error = bus_space_map(iot, bases[0], PAGE_SIZE, 0, &ioh)) != 0)
1175 return (error);
1176
1177
1178
1179
1180 romend = sti_rom_size(iot, ioh);
1181
1182 bus_space_unmap(iot, ioh, PAGE_SIZE);
1183
1184 if ((error = bus_space_map(iot, bases[0], romend, 0, &ioh)) != 0)
1185 return (error);
1186
1187 bases[0] = ioh;
1188 if (sti_screen_setup(scr, iot, iot, ioh, bases, codebase) != 0)
1189 panic(__func__);
1190
1191 sti_alloc_attr(scr, 0, 0, 0, &defattr);
1192 wsdisplay_cnattach(&scr->scr_wsd, scr, 0, 0, defattr);
1193
1194 return (0);
1195 }
1196
1197 #endif