gsfb.c revision 1.1.4.2 1 1.1.4.2 nathanw /* $NetBSD: gsfb.c,v 1.1.4.2 2002/04/01 07:41:51 nathanw Exp $ */
2 1.1.4.2 nathanw
3 1.1.4.2 nathanw /*-
4 1.1.4.2 nathanw * Copyright (c) 2001 The NetBSD Foundation, Inc.
5 1.1.4.2 nathanw * All rights reserved.
6 1.1.4.2 nathanw *
7 1.1.4.2 nathanw * This code is derived from software contributed to The NetBSD Foundation
8 1.1.4.2 nathanw * by UCHIYAMA Yasushi.
9 1.1.4.2 nathanw *
10 1.1.4.2 nathanw * Redistribution and use in source and binary forms, with or without
11 1.1.4.2 nathanw * modification, are permitted provided that the following conditions
12 1.1.4.2 nathanw * are met:
13 1.1.4.2 nathanw * 1. Redistributions of source code must retain the above copyright
14 1.1.4.2 nathanw * notice, this list of conditions and the following disclaimer.
15 1.1.4.2 nathanw * 2. Redistributions in binary form must reproduce the above copyright
16 1.1.4.2 nathanw * notice, this list of conditions and the following disclaimer in the
17 1.1.4.2 nathanw * documentation and/or other materials provided with the distribution.
18 1.1.4.2 nathanw * 3. All advertising materials mentioning features or use of this software
19 1.1.4.2 nathanw * must display the following acknowledgement:
20 1.1.4.2 nathanw * This product includes software developed by the NetBSD
21 1.1.4.2 nathanw * Foundation, Inc. and its contributors.
22 1.1.4.2 nathanw * 4. Neither the name of The NetBSD Foundation nor the names of its
23 1.1.4.2 nathanw * contributors may be used to endorse or promote products derived
24 1.1.4.2 nathanw * from this software without specific prior written permission.
25 1.1.4.2 nathanw *
26 1.1.4.2 nathanw * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 1.1.4.2 nathanw * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 1.1.4.2 nathanw * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 1.1.4.2 nathanw * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 1.1.4.2 nathanw * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 1.1.4.2 nathanw * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 1.1.4.2 nathanw * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 1.1.4.2 nathanw * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 1.1.4.2 nathanw * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 1.1.4.2 nathanw * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 1.1.4.2 nathanw * POSSIBILITY OF SUCH DAMAGE.
37 1.1.4.2 nathanw */
38 1.1.4.2 nathanw
39 1.1.4.2 nathanw #include "debug_playstation2.h"
40 1.1.4.2 nathanw
41 1.1.4.2 nathanw #include <sys/param.h>
42 1.1.4.2 nathanw #include <sys/systm.h>
43 1.1.4.2 nathanw
44 1.1.4.2 nathanw #include <machine/autoconf.h>
45 1.1.4.2 nathanw
46 1.1.4.2 nathanw #include <dev/cons.h>
47 1.1.4.2 nathanw
48 1.1.4.2 nathanw #include <dev/wscons/wsconsio.h>
49 1.1.4.2 nathanw #include <dev/wscons/wsdisplayvar.h>
50 1.1.4.2 nathanw #include <dev/wscons/wscons_callbacks.h>
51 1.1.4.2 nathanw
52 1.1.4.2 nathanw #include <dev/wsfont/wsfont.h>
53 1.1.4.2 nathanw
54 1.1.4.2 nathanw #include <playstation2/ee/eevar.h>
55 1.1.4.2 nathanw #include <playstation2/ee/gsvar.h>
56 1.1.4.2 nathanw #include <playstation2/ee/gsreg.h>
57 1.1.4.2 nathanw #include <playstation2/ee/dmacvar.h>
58 1.1.4.2 nathanw #include <playstation2/ee/dmacreg.h>
59 1.1.4.2 nathanw
60 1.1.4.2 nathanw #ifdef DEBUG
61 1.1.4.2 nathanw #define STATIC
62 1.1.4.2 nathanw #else
63 1.1.4.2 nathanw #define STATIC static
64 1.1.4.2 nathanw #endif
65 1.1.4.2 nathanw
66 1.1.4.2 nathanw STATIC struct gsfb {
67 1.1.4.2 nathanw int initialized;
68 1.1.4.2 nathanw int attached;
69 1.1.4.2 nathanw int is_console;
70 1.1.4.2 nathanw const struct wsscreen_descr *screen;
71 1.1.4.2 nathanw struct wsdisplay_font *font;
72 1.1.4.2 nathanw } gsfb;
73 1.1.4.2 nathanw
74 1.1.4.2 nathanw STATIC void gsfb_dma_kick(paddr_t, size_t);
75 1.1.4.2 nathanw STATIC void gsfb_font_expand_psmct32(const struct wsdisplay_font *, u_int,
76 1.1.4.2 nathanw long, u_int32_t *);
77 1.1.4.2 nathanw STATIC __inline__ void gsfb_set_cursor_pos(u_int32_t *, int, int, int, int);
78 1.1.4.2 nathanw
79 1.1.4.2 nathanw #define ATTR_FG_GET(a) (((a )>> 24) & 0xf)
80 1.1.4.2 nathanw #define ATTR_BG_GET(a) (((a )>> 16) & 0xf)
81 1.1.4.2 nathanw #define ATTR_FG_SET(x) (((x) << 24) & 0x0f000000)
82 1.1.4.2 nathanw #define ATTR_BG_SET(x) (((x) << 16) & 0x000f0000)
83 1.1.4.2 nathanw
84 1.1.4.2 nathanw STATIC const u_int32_t gsfb_ansi_psmct32[] = {
85 1.1.4.2 nathanw 0x80000000, /* black */
86 1.1.4.2 nathanw 0x800000aa, /* red */
87 1.1.4.2 nathanw 0x8000aa00, /* green */
88 1.1.4.2 nathanw 0x8000aaaa, /* brown */
89 1.1.4.2 nathanw 0x80aa0000, /* blue */
90 1.1.4.2 nathanw 0x80aa00aa, /* magenta */
91 1.1.4.2 nathanw 0x80aaaa00, /* cyan */
92 1.1.4.2 nathanw 0x80aaaaaa, /* white */
93 1.1.4.2 nathanw 0x80000000, /* black */
94 1.1.4.2 nathanw 0x800000ff, /* red */
95 1.1.4.2 nathanw 0x8000ff00, /* green */
96 1.1.4.2 nathanw 0x8000ffff, /* brown */
97 1.1.4.2 nathanw 0x80ff0000, /* blue */
98 1.1.4.2 nathanw 0x80ff00ff, /* magenta */
99 1.1.4.2 nathanw 0x80ffff00, /* cyan */
100 1.1.4.2 nathanw 0x80ffffff, /* black */
101 1.1.4.2 nathanw };
102 1.1.4.2 nathanw
103 1.1.4.2 nathanw #define TRXPOS_DXY(f, x, y) \
104 1.1.4.2 nathanw ({ \
105 1.1.4.2 nathanw f[9] = ((x) & 0x000007ff) | (((y) << 16) & 0x07ff0000); \
106 1.1.4.2 nathanw })
107 1.1.4.2 nathanw
108 1.1.4.2 nathanw #define TRXPOS_SY_DY(f, sy, dy) \
109 1.1.4.2 nathanw ({ \
110 1.1.4.2 nathanw f[8] = (((sy) << 16) & 0x07ff0000); \
111 1.1.4.2 nathanw f[9] = (((dy) << 16) & 0x07ff0000); \
112 1.1.4.2 nathanw })
113 1.1.4.2 nathanw
114 1.1.4.2 nathanw #define TRXPOS_DXY_SXY(f, dx, dy, sx, sy) \
115 1.1.4.2 nathanw ({ \
116 1.1.4.2 nathanw f[8] = ((((sy) << 16) & 0x07ff0000) | ((sx) & 0x000007ff)); \
117 1.1.4.2 nathanw f[9] = ((((dy) << 16) & 0x07ff0000) | ((dx) & 0x000007ff)); \
118 1.1.4.2 nathanw })
119 1.1.4.2 nathanw
120 1.1.4.2 nathanw STATIC u_int32_t gsfb_scroll_cmd_640x16[] __attribute__((__aligned__(16))) = {
121 1.1.4.2 nathanw 0x00008004, 0x10000000, 0x0000000e, 0x00000000,
122 1.1.4.2 nathanw 0x000a0000, 0x000a0000, 0x00000050, 0x00000000,
123 1.1.4.2 nathanw 0x07ff0000, 0x07ff0000, 0x00000051, 0x00000000,
124 1.1.4.2 nathanw 0x00000280, 0x00000010, 0x00000052, 0x00000000,
125 1.1.4.2 nathanw 0x00000002, 0x00000000, 0x00000053, 0x00000000,
126 1.1.4.2 nathanw };
127 1.1.4.2 nathanw
128 1.1.4.2 nathanw STATIC u_int32_t gsfb_cursor_cmd[] __attribute__((__aligned__(16))) = {
129 1.1.4.2 nathanw 0x00008007, 0x10000000, 0x0000000e, 0x00000000,
130 1.1.4.2 nathanw 0x00000001, 0x00000000, 0x0000001a, 0x00000000,
131 1.1.4.2 nathanw 0x000000a4, 0x00000080, 0x00000042, 0x00000000,
132 1.1.4.2 nathanw 0x00000046, 0x00000000, 0x00000000, 0x00000000,
133 1.1.4.2 nathanw 0x80ffffff, 0x00000000, 0x00000001, 0x00000000,
134 1.1.4.2 nathanw 0x00000000, 0x00000000, 0x0000000d, 0x00000000,
135 1.1.4.2 nathanw 0x80ffffff, 0x00000000, 0x00000001, 0x00000000,
136 1.1.4.2 nathanw 0x00000000, 0x00000000, 0x00000005, 0x00000000,
137 1.1.4.2 nathanw };
138 1.1.4.2 nathanw
139 1.1.4.2 nathanw STATIC u_int32_t gsfb_copy_cmd_8x16[] __attribute__((__aligned__(16))) = {
140 1.1.4.2 nathanw 0x00008004, 0x10000000, 0x0000000e, 0x00000000,
141 1.1.4.2 nathanw 0x000a0000, 0x000a0000, 0x00000050, 0x00000000,
142 1.1.4.2 nathanw 0x07ff07ff, 0x07ff07ff, 0x00000051, 0x00000000,
143 1.1.4.2 nathanw 0x00000008, 0x00000010, 0x00000052, 0x00000000,
144 1.1.4.2 nathanw 0x00000002, 0x00000000, 0x00000053, 0x00000000,
145 1.1.4.2 nathanw };
146 1.1.4.2 nathanw
147 1.1.4.2 nathanw STATIC u_int32_t gsfb_init_cmd_640x480[] __attribute__((__aligned__(16))) = {
148 1.1.4.2 nathanw 0x00008008, 0x10000000, 0x0000000e, 0x00000000,
149 1.1.4.2 nathanw 0x000a0000, 0x00000000, 0x0000004c, 0x00000000,
150 1.1.4.2 nathanw 0x00000096, 0x00000000, 0x0000004e, 0x00000000,
151 1.1.4.2 nathanw 0x02800000, 0x01e00000, 0x00000040, 0x00000000,
152 1.1.4.2 nathanw 0x00000006, 0x00000000, 0x00000000, 0x00000000,
153 1.1.4.2 nathanw 0x80000000, 0x00000000, 0x00000001, 0x00000000,
154 1.1.4.2 nathanw 0x00000000, 0x00000000, 0x0000000d, 0x00000000,
155 1.1.4.2 nathanw 0x80000000, 0x00000000, 0x00000001, 0x00000000,
156 1.1.4.2 nathanw 0x1e002800, 0x00000000, 0x00000005, 0x00000000,
157 1.1.4.2 nathanw };
158 1.1.4.2 nathanw
159 1.1.4.2 nathanw STATIC u_int32_t gsfb_load_cmd_8x16_psmct32[(6 + 32) * 4]
160 1.1.4.2 nathanw __attribute__((__aligned__(16))) = {
161 1.1.4.2 nathanw /* GIF tag + GS command */
162 1.1.4.2 nathanw 0x00000004, 0x10000000, 0x0000000e, 0x00000000,
163 1.1.4.2 nathanw 0x00000000, 0x000a0000, 0x00000050, 0x00000000,
164 1.1.4.2 nathanw 0x00000000, 0x00000000, 0x00000051, 0x00000000,
165 1.1.4.2 nathanw 0x00000008, 0x00000016, 0x00000052, 0x00000000,
166 1.1.4.2 nathanw 0x00000000, 0x00000000, 0x00000053, 0x00000000,
167 1.1.4.2 nathanw 0x00008020, 0x08000000, 0x00000000, 0x00000000,
168 1.1.4.2 nathanw /* Load area */
169 1.1.4.2 nathanw #define FONT_SCRATCH_BASE (6 * 4)
170 1.1.4.2 nathanw };
171 1.1.4.2 nathanw
172 1.1.4.2 nathanw #ifdef GSFB_DEBUG_MONITOR
173 1.1.4.2 nathanw #include <machine/stdarg.h>
174 1.1.4.2 nathanw STATIC const struct _gsfb_debug_window {
175 1.1.4.2 nathanw int start, nrow, attr;
176 1.1.4.2 nathanw } _gsfb_debug_window[3] = {
177 1.1.4.2 nathanw { 24, 2 , ATTR_BG_SET(WSCOL_BROWN) | ATTR_FG_SET(WSCOL_BLUE) },
178 1.1.4.2 nathanw { 26, 2 , ATTR_BG_SET(WSCOL_CYAN) | ATTR_FG_SET(WSCOL_BLUE) },
179 1.1.4.2 nathanw { 28, 2 , ATTR_BG_SET(WSCOL_WHITE) | ATTR_FG_SET(WSCOL_BLUE) },
180 1.1.4.2 nathanw };
181 1.1.4.2 nathanw STATIC char _gsfb_debug_buf[80 * 2];
182 1.1.4.2 nathanw #endif /* GSFB_DEBUG_MONITOR */
183 1.1.4.2 nathanw
184 1.1.4.2 nathanw STATIC int gsfb_match(struct device *, struct cfdata *, void *);
185 1.1.4.2 nathanw STATIC void gsfb_attach(struct device *, struct device *, void *);
186 1.1.4.2 nathanw
187 1.1.4.2 nathanw struct cfattach gsfb_ca = {
188 1.1.4.2 nathanw sizeof(struct device), gsfb_match, gsfb_attach
189 1.1.4.2 nathanw };
190 1.1.4.2 nathanw
191 1.1.4.2 nathanw STATIC void gsfb_hwinit(void);
192 1.1.4.2 nathanw STATIC int gsfb_swinit(void);
193 1.1.4.2 nathanw
194 1.1.4.2 nathanw /* console */
195 1.1.4.2 nathanw void gsfbcnprobe(struct consdev *);
196 1.1.4.2 nathanw void gsfbcninit(struct consdev *);
197 1.1.4.2 nathanw
198 1.1.4.2 nathanw /* emul ops */
199 1.1.4.2 nathanw STATIC void _gsfb_cursor(void *, int, int, int);
200 1.1.4.2 nathanw STATIC int _gsfb_mapchar(void *, int, unsigned int *);
201 1.1.4.2 nathanw STATIC void _gsfb_putchar(void *, int, int, u_int, long);
202 1.1.4.2 nathanw STATIC void _gsfb_copycols(void *, int, int, int, int);
203 1.1.4.2 nathanw STATIC void _gsfb_erasecols(void *, int, int, int, long);
204 1.1.4.2 nathanw STATIC void _gsfb_copyrows(void *, int, int, int);
205 1.1.4.2 nathanw STATIC void _gsfb_eraserows(void *, int, int, long);
206 1.1.4.2 nathanw STATIC int _gsfb_alloc_attr(void *, int, int, int, long *);
207 1.1.4.2 nathanw
208 1.1.4.2 nathanw /* access ops */
209 1.1.4.2 nathanw STATIC int _gsfb_ioctl(void *, u_long, caddr_t, int, struct proc *);
210 1.1.4.2 nathanw STATIC paddr_t _gsfb_mmap(void *, off_t, int);
211 1.1.4.2 nathanw STATIC int _gsfb_alloc_screen(void *, const struct wsscreen_descr *, void **,
212 1.1.4.2 nathanw int *, int *, long *);
213 1.1.4.2 nathanw STATIC void _gsfb_free_screen(void *, void *);
214 1.1.4.2 nathanw STATIC int _gsfb_show_screen(void *, void *, int, void (*)(void *, int, int),
215 1.1.4.2 nathanw void *);
216 1.1.4.2 nathanw STATIC void _gsfb_pollc(void *, int);
217 1.1.4.2 nathanw
218 1.1.4.2 nathanw /*
219 1.1.4.2 nathanw * wsdisplay attach args
220 1.1.4.2 nathanw * std: screen size 640 x 480, font size 8 x 16
221 1.1.4.2 nathanw */
222 1.1.4.2 nathanw #define GSFB_STD_SCREEN_WIDTH 640
223 1.1.4.2 nathanw #define GSFB_STD_SCREEN_HEIGHT 480
224 1.1.4.2 nathanw #define GSFB_STD_FONT_WIDTH 8
225 1.1.4.2 nathanw #define GSFB_STD_FONT_HEIGHT 16
226 1.1.4.2 nathanw const struct wsdisplay_emulops _gsfb_emulops = {
227 1.1.4.2 nathanw .cursor = _gsfb_cursor,
228 1.1.4.2 nathanw .mapchar = _gsfb_mapchar,
229 1.1.4.2 nathanw .putchar = _gsfb_putchar,
230 1.1.4.2 nathanw .copycols = _gsfb_copycols,
231 1.1.4.2 nathanw .erasecols = _gsfb_erasecols,
232 1.1.4.2 nathanw .copyrows = _gsfb_copyrows,
233 1.1.4.2 nathanw .eraserows = _gsfb_eraserows,
234 1.1.4.2 nathanw .alloc_attr = _gsfb_alloc_attr
235 1.1.4.2 nathanw };
236 1.1.4.2 nathanw
237 1.1.4.2 nathanw const struct wsscreen_descr _gsfb_std_screen = {
238 1.1.4.2 nathanw .name = "std",
239 1.1.4.2 nathanw .ncols = 80,
240 1.1.4.2 nathanw #ifdef GSFB_DEBUG_MONITOR
241 1.1.4.2 nathanw .nrows = 24,
242 1.1.4.2 nathanw #else
243 1.1.4.2 nathanw .nrows = 30,
244 1.1.4.2 nathanw #endif
245 1.1.4.2 nathanw .textops = &_gsfb_emulops,
246 1.1.4.2 nathanw .fontwidth = 8,
247 1.1.4.2 nathanw .fontheight = 16,
248 1.1.4.2 nathanw .capabilities = WSSCREEN_UNDERLINE | WSSCREEN_HILIT |
249 1.1.4.2 nathanw WSSCREEN_WSCOLORS
250 1.1.4.2 nathanw };
251 1.1.4.2 nathanw
252 1.1.4.2 nathanw const struct wsscreen_descr *_gsfb_screen_table[] = {
253 1.1.4.2 nathanw &_gsfb_std_screen,
254 1.1.4.2 nathanw };
255 1.1.4.2 nathanw
256 1.1.4.2 nathanw struct wsscreen_list _gsfb_screen_list = {
257 1.1.4.2 nathanw .nscreens = sizeof(_gsfb_screen_table) /
258 1.1.4.2 nathanw sizeof(_gsfb_screen_table[0]),
259 1.1.4.2 nathanw .screens = _gsfb_screen_table
260 1.1.4.2 nathanw };
261 1.1.4.2 nathanw
262 1.1.4.2 nathanw struct wsdisplay_accessops _gsfb_accessops = {
263 1.1.4.2 nathanw .ioctl = _gsfb_ioctl,
264 1.1.4.2 nathanw .mmap = _gsfb_mmap,
265 1.1.4.2 nathanw .alloc_screen = _gsfb_alloc_screen,
266 1.1.4.2 nathanw .free_screen = _gsfb_free_screen,
267 1.1.4.2 nathanw .show_screen = _gsfb_show_screen,
268 1.1.4.2 nathanw .load_font = 0,
269 1.1.4.2 nathanw .pollc = _gsfb_pollc
270 1.1.4.2 nathanw };
271 1.1.4.2 nathanw
272 1.1.4.2 nathanw int
273 1.1.4.2 nathanw gsfb_match(struct device *parent, struct cfdata *cf, void *aux)
274 1.1.4.2 nathanw {
275 1.1.4.2 nathanw extern struct cfdriver gsfb_cd;
276 1.1.4.2 nathanw struct mainbus_attach_args *ma = aux;
277 1.1.4.2 nathanw
278 1.1.4.2 nathanw if (strcmp(ma->ma_name, gsfb_cd.cd_name) != 0)
279 1.1.4.2 nathanw return (0);
280 1.1.4.2 nathanw
281 1.1.4.2 nathanw return (!gsfb.attached);
282 1.1.4.2 nathanw }
283 1.1.4.2 nathanw
284 1.1.4.2 nathanw void
285 1.1.4.2 nathanw gsfb_attach(struct device *parent, struct device *self, void *aux)
286 1.1.4.2 nathanw {
287 1.1.4.2 nathanw struct wsemuldisplaydev_attach_args wa;
288 1.1.4.2 nathanw
289 1.1.4.2 nathanw gsfb.attached = 1;
290 1.1.4.2 nathanw if (!gsfb.is_console && gsfb_swinit() != 0)
291 1.1.4.2 nathanw return;
292 1.1.4.2 nathanw
293 1.1.4.2 nathanw printf("\n");
294 1.1.4.2 nathanw
295 1.1.4.2 nathanw wa.console = gsfb.is_console;
296 1.1.4.2 nathanw wa.scrdata = &_gsfb_screen_list;
297 1.1.4.2 nathanw wa.accessops = &_gsfb_accessops;
298 1.1.4.2 nathanw wa.accesscookie = &gsfb;
299 1.1.4.2 nathanw
300 1.1.4.2 nathanw config_found(self, &wa, wsdisplaydevprint);
301 1.1.4.2 nathanw }
302 1.1.4.2 nathanw
303 1.1.4.2 nathanw /*
304 1.1.4.2 nathanw * console
305 1.1.4.2 nathanw */
306 1.1.4.2 nathanw void
307 1.1.4.2 nathanw gsfbcnprobe(struct consdev *cndev)
308 1.1.4.2 nathanw {
309 1.1.4.2 nathanw
310 1.1.4.2 nathanw cndev->cn_pri = CN_INTERNAL;
311 1.1.4.2 nathanw }
312 1.1.4.2 nathanw
313 1.1.4.2 nathanw void
314 1.1.4.2 nathanw gsfbcninit(struct consdev *cndev)
315 1.1.4.2 nathanw {
316 1.1.4.2 nathanw paddr_t paddr = MIPS_KSEG0_TO_PHYS(gsfb_init_cmd_640x480);
317 1.1.4.2 nathanw long defattr = ATTR_BG_SET(WSCOL_BLACK) | ATTR_FG_SET(WSCOL_WHITE);
318 1.1.4.2 nathanw
319 1.1.4.2 nathanw gsfb.is_console = 1;
320 1.1.4.2 nathanw
321 1.1.4.2 nathanw gsfb_hwinit();
322 1.1.4.2 nathanw gsfb_swinit();
323 1.1.4.2 nathanw
324 1.1.4.2 nathanw gsfb_dma_kick(paddr, sizeof gsfb_init_cmd_640x480);
325 1.1.4.2 nathanw #ifdef GSFB_DEBUG_MONITOR
326 1.1.4.2 nathanw {
327 1.1.4.2 nathanw const struct _gsfb_debug_window *win;
328 1.1.4.2 nathanw int i;
329 1.1.4.2 nathanw
330 1.1.4.2 nathanw for (i = 0; i < 3; i++) {
331 1.1.4.2 nathanw win = &_gsfb_debug_window[i];
332 1.1.4.2 nathanw _gsfb_eraserows(0, win->start, win->nrow, win->attr);
333 1.1.4.2 nathanw }
334 1.1.4.2 nathanw }
335 1.1.4.2 nathanw #endif /* GSFB_DEBUG_MONITOR */
336 1.1.4.2 nathanw
337 1.1.4.2 nathanw wsdisplay_cnattach(&_gsfb_std_screen, &gsfb, 0, 0, defattr);
338 1.1.4.2 nathanw }
339 1.1.4.2 nathanw
340 1.1.4.2 nathanw void
341 1.1.4.2 nathanw gsfb_hwinit()
342 1.1.4.2 nathanw {
343 1.1.4.2 nathanw gs_init(VESA_1A);
344 1.1.4.2 nathanw dmac_init();
345 1.1.4.2 nathanw
346 1.1.4.2 nathanw /* reset GIF channel DMA */
347 1.1.4.2 nathanw _reg_write_4(D2_QWC_REG, 0);
348 1.1.4.2 nathanw _reg_write_4(D2_MADR_REG, 0);
349 1.1.4.2 nathanw _reg_write_4(D2_TADR_REG, 0);
350 1.1.4.2 nathanw _reg_write_4(D2_CHCR_REG, 0);
351 1.1.4.2 nathanw }
352 1.1.4.2 nathanw
353 1.1.4.2 nathanw int
354 1.1.4.2 nathanw gsfb_swinit()
355 1.1.4.2 nathanw {
356 1.1.4.2 nathanw int font;
357 1.1.4.2 nathanw
358 1.1.4.2 nathanw wsfont_init();
359 1.1.4.2 nathanw font = wsfont_find(NULL, 8, 16, 0, WSDISPLAY_FONTORDER_L2R,
360 1.1.4.2 nathanw WSDISPLAY_FONTORDER_L2R);
361 1.1.4.2 nathanw if (font < 0)
362 1.1.4.2 nathanw return (1);
363 1.1.4.2 nathanw
364 1.1.4.2 nathanw if (wsfont_lock(font, &gsfb.font))
365 1.1.4.2 nathanw return (1);
366 1.1.4.2 nathanw
367 1.1.4.2 nathanw gsfb.screen = &_gsfb_std_screen;
368 1.1.4.2 nathanw gsfb.initialized = 1;
369 1.1.4.2 nathanw
370 1.1.4.2 nathanw return (0);
371 1.1.4.2 nathanw }
372 1.1.4.2 nathanw
373 1.1.4.2 nathanw /*
374 1.1.4.2 nathanw * wsdisplay
375 1.1.4.2 nathanw */
376 1.1.4.2 nathanw void
377 1.1.4.2 nathanw _gsfb_cursor(void *cookie, int on, int row, int col)
378 1.1.4.2 nathanw {
379 1.1.4.2 nathanw paddr_t paddr = MIPS_KSEG0_TO_PHYS(gsfb_cursor_cmd);
380 1.1.4.2 nathanw u_int32_t *buf = (void *)MIPS_PHYS_TO_KSEG1(paddr);
381 1.1.4.2 nathanw struct wsdisplay_font *font = gsfb.font;
382 1.1.4.2 nathanw
383 1.1.4.2 nathanw gsfb_set_cursor_pos(buf, col, row, font->fontwidth, font->fontheight);
384 1.1.4.2 nathanw
385 1.1.4.2 nathanw gsfb_dma_kick(paddr, sizeof gsfb_cursor_cmd);
386 1.1.4.2 nathanw }
387 1.1.4.2 nathanw
388 1.1.4.2 nathanw __inline__ void
389 1.1.4.2 nathanw gsfb_set_cursor_pos(u_int32_t *p, int x, int y, int w, int h)
390 1.1.4.2 nathanw {
391 1.1.4.2 nathanw
392 1.1.4.2 nathanw x *= w;
393 1.1.4.2 nathanw y *= h;
394 1.1.4.2 nathanw p[20] = ((x << 4) & 0xffff) | ((y << 20) & 0xffff0000);
395 1.1.4.2 nathanw p[28] = (((x + w - 1) << 4) & 0xffff) |
396 1.1.4.2 nathanw (((y + h - 1) << 20) & 0xffff0000);
397 1.1.4.2 nathanw }
398 1.1.4.2 nathanw
399 1.1.4.2 nathanw int
400 1.1.4.2 nathanw _gsfb_mapchar(void *cookie, int c, unsigned int *cp)
401 1.1.4.2 nathanw {
402 1.1.4.2 nathanw struct wsdisplay_font *font = gsfb.font;
403 1.1.4.2 nathanw
404 1.1.4.2 nathanw if (font->encoding != WSDISPLAY_FONTENC_ISO)
405 1.1.4.2 nathanw if ((c = wsfont_map_unichar(font, c)) < 0)
406 1.1.4.2 nathanw goto nomap;
407 1.1.4.2 nathanw
408 1.1.4.2 nathanw if (c < font->firstchar || c >= font->firstchar + font->numchars)
409 1.1.4.2 nathanw goto nomap;
410 1.1.4.2 nathanw
411 1.1.4.2 nathanw *cp = c;
412 1.1.4.2 nathanw return (5);
413 1.1.4.2 nathanw
414 1.1.4.2 nathanw nomap:
415 1.1.4.2 nathanw *cp = ' ';
416 1.1.4.2 nathanw return (0);
417 1.1.4.2 nathanw }
418 1.1.4.2 nathanw
419 1.1.4.2 nathanw void
420 1.1.4.2 nathanw _gsfb_putchar(void *cookie, int row, int col, u_int uc, long attr)
421 1.1.4.2 nathanw {
422 1.1.4.2 nathanw paddr_t paddr = MIPS_KSEG0_TO_PHYS(gsfb_load_cmd_8x16_psmct32);
423 1.1.4.2 nathanw u_int32_t *buf = (void *)MIPS_PHYS_TO_KSEG1(paddr);
424 1.1.4.2 nathanw struct wsdisplay_font *font = gsfb.font;
425 1.1.4.2 nathanw
426 1.1.4.2 nathanw /* copy font data to DMA region */
427 1.1.4.2 nathanw gsfb_font_expand_psmct32(font, uc, attr, &buf[FONT_SCRATCH_BASE]);
428 1.1.4.2 nathanw
429 1.1.4.2 nathanw /* set destination position */
430 1.1.4.2 nathanw TRXPOS_DXY(buf, col * font->fontwidth, row * font->fontheight);
431 1.1.4.2 nathanw
432 1.1.4.2 nathanw /* kick to GIF */
433 1.1.4.2 nathanw gsfb_dma_kick(paddr, sizeof gsfb_load_cmd_8x16_psmct32);
434 1.1.4.2 nathanw }
435 1.1.4.2 nathanw
436 1.1.4.2 nathanw void
437 1.1.4.2 nathanw _gsfb_copycols(void *cookie, int row, int srccol, int dstcol, int ncols)
438 1.1.4.2 nathanw {
439 1.1.4.2 nathanw paddr_t paddr = MIPS_KSEG0_TO_PHYS(gsfb_copy_cmd_8x16);
440 1.1.4.2 nathanw u_int32_t *cmd = (void *)MIPS_PHYS_TO_KSEG1(paddr);
441 1.1.4.2 nathanw int y = gsfb.font->fontheight * row;
442 1.1.4.2 nathanw int w = gsfb.font->fontwidth;
443 1.1.4.2 nathanw int i;
444 1.1.4.2 nathanw
445 1.1.4.2 nathanw if (dstcol > srccol) {
446 1.1.4.2 nathanw for (i = ncols - 1; i >= 0; i--) {
447 1.1.4.2 nathanw TRXPOS_DXY_SXY(cmd, (dstcol + i) * w, y, (srccol + i) * w, y);
448 1.1.4.2 nathanw gsfb_dma_kick(paddr, sizeof gsfb_copy_cmd_8x16);
449 1.1.4.2 nathanw }
450 1.1.4.2 nathanw } else {
451 1.1.4.2 nathanw for (i = 0; i < ncols; i++) {
452 1.1.4.2 nathanw TRXPOS_DXY_SXY(cmd, (dstcol + i) * w, y, (srccol + i) * w, y);
453 1.1.4.2 nathanw gsfb_dma_kick(paddr, sizeof gsfb_copy_cmd_8x16);
454 1.1.4.2 nathanw }
455 1.1.4.2 nathanw }
456 1.1.4.2 nathanw }
457 1.1.4.2 nathanw
458 1.1.4.2 nathanw void
459 1.1.4.2 nathanw _gsfb_erasecols(void *cookie, int row, int startcol, int ncols, long attr)
460 1.1.4.2 nathanw {
461 1.1.4.2 nathanw int i;
462 1.1.4.2 nathanw
463 1.1.4.2 nathanw for (i = 0; i < ncols; i++)
464 1.1.4.2 nathanw _gsfb_putchar(cookie, row, startcol + i, ' ', attr);
465 1.1.4.2 nathanw }
466 1.1.4.2 nathanw
467 1.1.4.2 nathanw void
468 1.1.4.2 nathanw _gsfb_copyrows(void *cookie, int src, int dst, int num)
469 1.1.4.2 nathanw {
470 1.1.4.2 nathanw paddr_t paddr = MIPS_KSEG0_TO_PHYS(gsfb_scroll_cmd_640x16);
471 1.1.4.2 nathanw u_int32_t *cmd = (void *)MIPS_PHYS_TO_KSEG1(paddr);
472 1.1.4.2 nathanw int i;
473 1.1.4.2 nathanw int h = gsfb.font->fontheight;
474 1.1.4.2 nathanw
475 1.1.4.2 nathanw if (dst > src) {
476 1.1.4.2 nathanw for (i = num - 1; i >= 0; i--) {
477 1.1.4.2 nathanw TRXPOS_SY_DY(cmd, (src + i) * h, (dst + i) * h);
478 1.1.4.2 nathanw gsfb_dma_kick(paddr, sizeof gsfb_scroll_cmd_640x16);
479 1.1.4.2 nathanw }
480 1.1.4.2 nathanw } else {
481 1.1.4.2 nathanw for (i = 0; i < num; i++) {
482 1.1.4.2 nathanw TRXPOS_SY_DY(cmd, (src + i) * h, (dst + i) * h);
483 1.1.4.2 nathanw gsfb_dma_kick(paddr, sizeof gsfb_scroll_cmd_640x16);
484 1.1.4.2 nathanw }
485 1.1.4.2 nathanw }
486 1.1.4.2 nathanw }
487 1.1.4.2 nathanw
488 1.1.4.2 nathanw void
489 1.1.4.2 nathanw _gsfb_eraserows(void *cookie, int row, int nrow, long attr)
490 1.1.4.2 nathanw {
491 1.1.4.2 nathanw int i, j;
492 1.1.4.2 nathanw
493 1.1.4.2 nathanw for (j = 0; j < nrow; j++)
494 1.1.4.2 nathanw for (i = 0; i < gsfb.screen->ncols; i++)
495 1.1.4.2 nathanw _gsfb_putchar(cookie, row + j, i, ' ', attr);
496 1.1.4.2 nathanw }
497 1.1.4.2 nathanw
498 1.1.4.2 nathanw int
499 1.1.4.2 nathanw _gsfb_alloc_attr(void *cookie, int fg, int bg, int flags, long *attr)
500 1.1.4.2 nathanw {
501 1.1.4.2 nathanw
502 1.1.4.2 nathanw if ((flags & WSATTR_BLINK) != 0)
503 1.1.4.2 nathanw return (EINVAL);
504 1.1.4.2 nathanw
505 1.1.4.2 nathanw if ((flags & WSATTR_WSCOLORS) == 0) {
506 1.1.4.2 nathanw fg = WSCOL_WHITE;
507 1.1.4.2 nathanw bg = WSCOL_BLACK;
508 1.1.4.2 nathanw }
509 1.1.4.2 nathanw
510 1.1.4.2 nathanw if ((flags & WSATTR_HILIT) != 0)
511 1.1.4.2 nathanw fg += 8;
512 1.1.4.2 nathanw
513 1.1.4.2 nathanw flags = (flags & WSATTR_UNDERLINE) ? 1 : 0;
514 1.1.4.2 nathanw
515 1.1.4.2 nathanw
516 1.1.4.2 nathanw *attr = ATTR_BG_SET(bg) | ATTR_FG_SET(fg) | flags;
517 1.1.4.2 nathanw
518 1.1.4.2 nathanw return (0);
519 1.1.4.2 nathanw }
520 1.1.4.2 nathanw
521 1.1.4.2 nathanw int
522 1.1.4.2 nathanw _gsfb_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
523 1.1.4.2 nathanw {
524 1.1.4.2 nathanw
525 1.1.4.2 nathanw return (EPASSTHROUGH); /* Inappropriate ioctl for device */
526 1.1.4.2 nathanw }
527 1.1.4.2 nathanw
528 1.1.4.2 nathanw paddr_t
529 1.1.4.2 nathanw _gsfb_mmap(void *v, off_t offset, int prot)
530 1.1.4.2 nathanw {
531 1.1.4.2 nathanw
532 1.1.4.2 nathanw return (NULL); /* can't mmap */
533 1.1.4.2 nathanw }
534 1.1.4.2 nathanw
535 1.1.4.2 nathanw int
536 1.1.4.2 nathanw _gsfb_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
537 1.1.4.2 nathanw int *curxp, int *curyp, long *attrp)
538 1.1.4.2 nathanw {
539 1.1.4.2 nathanw
540 1.1.4.2 nathanw *attrp = ATTR_BG_SET(WSCOL_BLACK) | ATTR_FG_SET(WSCOL_WHITE);
541 1.1.4.2 nathanw
542 1.1.4.2 nathanw return (0);
543 1.1.4.2 nathanw }
544 1.1.4.2 nathanw
545 1.1.4.2 nathanw void
546 1.1.4.2 nathanw _gsfb_free_screen(void *v, void *cookie)
547 1.1.4.2 nathanw {
548 1.1.4.2 nathanw }
549 1.1.4.2 nathanw
550 1.1.4.2 nathanw int
551 1.1.4.2 nathanw _gsfb_show_screen(void *v, void *cookie, int waitok,
552 1.1.4.2 nathanw void (*cb)(void *, int, int), void *cbarg)
553 1.1.4.2 nathanw {
554 1.1.4.2 nathanw
555 1.1.4.2 nathanw return (0);
556 1.1.4.2 nathanw }
557 1.1.4.2 nathanw
558 1.1.4.2 nathanw void
559 1.1.4.2 nathanw _gsfb_pollc(void *v, int on)
560 1.1.4.2 nathanw {
561 1.1.4.2 nathanw
562 1.1.4.2 nathanw }
563 1.1.4.2 nathanw
564 1.1.4.2 nathanw /*
565 1.1.4.2 nathanw * font expansion
566 1.1.4.2 nathanw * PSMCT32 only
567 1.1.4.2 nathanw */
568 1.1.4.2 nathanw void
569 1.1.4.2 nathanw gsfb_font_expand_psmct32(const struct wsdisplay_font *font, u_int c, long attr,
570 1.1.4.2 nathanw u_int32_t *buf)
571 1.1.4.2 nathanw {
572 1.1.4.2 nathanw u_int32_t fg, bg;
573 1.1.4.2 nathanw u_int8_t *bitmap;
574 1.1.4.2 nathanw int i, j;
575 1.1.4.2 nathanw
576 1.1.4.2 nathanw KDASSERT(((u_int32_t)buf & 15) == 0);
577 1.1.4.2 nathanw
578 1.1.4.2 nathanw fg = gsfb_ansi_psmct32[ATTR_FG_GET(attr)];
579 1.1.4.2 nathanw bg = gsfb_ansi_psmct32[ATTR_BG_GET(attr)];
580 1.1.4.2 nathanw
581 1.1.4.2 nathanw bitmap = (u_int8_t *)font->data + (c - font->firstchar) *
582 1.1.4.2 nathanw font->fontheight * font->stride;
583 1.1.4.2 nathanw for (i = 0; i < font->fontheight; i++, bitmap++) {
584 1.1.4.2 nathanw u_int32_t b = *bitmap;
585 1.1.4.2 nathanw for (j = 0; j < font->fontwidth; j++, b <<= 1)
586 1.1.4.2 nathanw *buf++ = (b & 0x80) ? fg : bg;
587 1.1.4.2 nathanw }
588 1.1.4.2 nathanw }
589 1.1.4.2 nathanw
590 1.1.4.2 nathanw void
591 1.1.4.2 nathanw gsfb_dma_kick(paddr_t addr, size_t size)
592 1.1.4.2 nathanw {
593 1.1.4.2 nathanw /* Wait for previous DMA request complete */
594 1.1.4.2 nathanw while (_reg_read_4(D2_QWC_REG))
595 1.1.4.2 nathanw ;
596 1.1.4.2 nathanw
597 1.1.4.2 nathanw /* Wait until GS FIFO empty */
598 1.1.4.2 nathanw while ((_reg_read_8(GS_S_CSR_REG) & (3 << 14)) != (1 << 14))
599 1.1.4.2 nathanw ;
600 1.1.4.2 nathanw
601 1.1.4.2 nathanw /* wait for DMA complete */
602 1.1.4.2 nathanw dmac_bus_poll(D_CH2_GIF);
603 1.1.4.2 nathanw
604 1.1.4.2 nathanw /* transfer addr */
605 1.1.4.2 nathanw _reg_write_4(D2_MADR_REG, addr);
606 1.1.4.2 nathanw /* transfer data size (unit qword) */
607 1.1.4.2 nathanw _reg_write_4(D2_QWC_REG, bytetoqwc(size));
608 1.1.4.2 nathanw
609 1.1.4.2 nathanw /* kick DMA (normal-mode) */
610 1.1.4.2 nathanw dmac_chcr_write(D_CH2_GIF, D_CHCR_STR);
611 1.1.4.2 nathanw }
612 1.1.4.2 nathanw
613 1.1.4.2 nathanw #ifdef GSFB_DEBUG_MONITOR
614 1.1.4.2 nathanw void
615 1.1.4.2 nathanw __gsfb_print(int window, const char *fmt, ...)
616 1.1.4.2 nathanw {
617 1.1.4.2 nathanw const struct _gsfb_debug_window *win;
618 1.1.4.2 nathanw int i, s, x, y, n, a;
619 1.1.4.2 nathanw u_int c;
620 1.1.4.2 nathanw va_list ap;
621 1.1.4.2 nathanw
622 1.1.4.2 nathanw if (!gsfb.initialized)
623 1.1.4.2 nathanw return;
624 1.1.4.2 nathanw
625 1.1.4.2 nathanw s = _intr_suspend();
626 1.1.4.2 nathanw win = &_gsfb_debug_window[window];
627 1.1.4.2 nathanw x = 0;
628 1.1.4.2 nathanw y = win->start;
629 1.1.4.2 nathanw n = win->nrow * 80;
630 1.1.4.2 nathanw a = win->attr;
631 1.1.4.2 nathanw
632 1.1.4.2 nathanw va_start(ap, fmt);
633 1.1.4.2 nathanw vsnprintf(_gsfb_debug_buf, n, fmt, ap);
634 1.1.4.2 nathanw va_end(ap);
635 1.1.4.2 nathanw
636 1.1.4.2 nathanw _gsfb_eraserows(0, y, win->nrow, a);
637 1.1.4.2 nathanw
638 1.1.4.2 nathanw for (i = 0; i < n &&
639 1.1.4.2 nathanw (c = (u_int)_gsfb_debug_buf[i] & 0x7f) != 0; i++) {
640 1.1.4.2 nathanw if (c == '\n')
641 1.1.4.2 nathanw x = 0, y++;
642 1.1.4.2 nathanw else
643 1.1.4.2 nathanw _gsfb_putchar(0, y, x++, c, a);
644 1.1.4.2 nathanw }
645 1.1.4.2 nathanw
646 1.1.4.2 nathanw _intr_resume(s);
647 1.1.4.2 nathanw }
648 1.1.4.2 nathanw
649 1.1.4.2 nathanw void
650 1.1.4.2 nathanw __gsfb_print_hex(int a0, int a1, int a2, int a3)
651 1.1.4.2 nathanw {
652 1.1.4.2 nathanw __gsfb_print(2, "a0=%08x a1=%08x a2=%08x a3=%08x",
653 1.1.4.2 nathanw a0, a1, a2, a3);
654 1.1.4.2 nathanw }
655 1.1.4.2 nathanw #endif /* GSFB_DEBUG_MONITOR */
656