ofw_rascons.c revision 1.1 1 /* $NetBSD: ofw_rascons.c,v 1.1 2007/11/26 19:58:31 garbled Exp $ */
2
3 /*
4 * Copyright (c) 1995, 1996 Carnegie-Mellon University.
5 * All rights reserved.
6 *
7 * Author: Chris G. Demetriou
8 *
9 * Permission to use, copy, modify and distribute this software and
10 * its documentation is hereby granted, provided that both the copyright
11 * notice and this permission notice appear in all copies of the
12 * software, derivative works or modified versions, and any portions
13 * thereof, and that both notices appear in supporting documentation.
14 *
15 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
16 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
17 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
18 *
19 * Carnegie Mellon requests users of this software to return to
20 *
21 * Software Distribution Coordinator or Software.Distribution (at) CS.CMU.EDU
22 * School of Computer Science
23 * Carnegie Mellon University
24 * Pittsburgh PA 15213-3890
25 *
26 * any improvements or extensions that they make and grant Carnegie the
27 * rights to redistribute these changes.
28 */
29
30 #include <sys/cdefs.h>
31 __KERNEL_RCSID(0, "$NetBSD: ofw_rascons.c,v 1.1 2007/11/26 19:58:31 garbled Exp $");
32
33 #include <sys/param.h>
34 #include <sys/buf.h>
35 #include <sys/conf.h>
36 #include <sys/device.h>
37 #include <sys/ioctl.h>
38 #include <sys/kernel.h>
39 #include <sys/malloc.h>
40 #include <sys/systm.h>
41 #include <powerpc/oea/bat.h>
42
43 #include <dev/ofw/openfirm.h>
44 #include <uvm/uvm_extern.h>
45
46 #include <machine/bus.h>
47 #include <machine/autoconf.h>
48
49 #include <dev/wscons/wsconsio.h>
50 #include <dev/wscons/wsdisplayvar.h>
51 #include <dev/rasops/rasops.h>
52 #include <dev/wsfont/wsfont.h>
53 #include <dev/wscons/wsdisplay_vconsvar.h>
54
55 #include <powerpc/oea/ofw_rasconsvar.h>
56 #include "wsdisplay.h"
57
58 /* we need a wsdisplay to do anything halfway useful */
59 #if NWSDISPLAY > 0
60
61 #if defined(PPC_OEA64) || defined (PPC_OEA64_BRIDGE)
62 int rascons_enable_cache = 0;
63 #else
64 #ifdef OFB_ENABLE_CACHE
65 int rascons_enable_cache = 1;
66 #else
67 int rascons_enable_cache = 0;
68 #endif
69 #endif /* PPC_OEA64 */
70
71 static int copy_rom_font(void);
72 static struct wsdisplay_font openfirm6x11;
73 static vaddr_t fbaddr;
74 static int romfont_loaded = 0;
75
76 struct vcons_screen rascons_console_screen;
77
78 struct wsscreen_descr rascons_stdscreen = {
79 "std",
80 0, 0, /* will be filled in -- XXX shouldn't, it's global */
81 0,
82 0, 0,
83 WSSCREEN_REVERSE
84 };
85
86 int
87 rascons_cnattach(void)
88 {
89 struct rasops_info *ri = &rascons_console_screen.scr_ri;
90 long defattr;
91 int crow = 0;
92 char type[16];
93
94 OF_getprop(console_node, "device_type", type, sizeof(type));
95 if (strcmp(type, "display") != 0)
96 return -1;
97
98 /* get current cursor position */
99 OF_interpret("line#", 0, 1, &crow);
100
101 /* move (rom monitor) cursor to the lowest line - 1 */
102 OF_interpret("#lines 2 - to line#", 0, 0);
103
104 wsfont_init();
105 if (copy_rom_font() == 0) {
106 romfont_loaded = 1;
107 }
108
109 /* set up rasops */
110 rascons_init_rasops(console_node, ri);
111
112 /*
113 * no need to clear the screen here when we're mimicing firmware
114 * output anyway
115 */
116 #if 0
117 if (ri->ri_width >= 1024 && ri->ri_height >= 768) {
118 int i, screenbytes = ri->ri_stride * ri->ri_height;
119
120 for (i = 0; i < screenbytes; i += sizeof(u_int32_t))
121 *(u_int32_t *)(fbaddr + i) = 0xffffffff;
122 crow = 0;
123 }
124 #endif
125
126 rascons_stdscreen.nrows = ri->ri_rows;
127 rascons_stdscreen.ncols = ri->ri_cols;
128 rascons_stdscreen.textops = &ri->ri_ops;
129 rascons_stdscreen.capabilities = ri->ri_caps;
130
131 ri->ri_ops.allocattr(ri, 0, 0, 0, &defattr);
132 wsdisplay_preattach(&rascons_stdscreen, ri, 0, max(0,
133 min(crow, ri->ri_rows - 1)), defattr);
134
135 #if notyet
136 rascons_init_cmap(NULL);
137 #endif
138
139 return 0;
140 }
141
142 static int
143 copy_rom_font()
144 {
145 u_char *romfont;
146 int char_width, char_height;
147 int chosen, mmu, m, e;
148
149 /* Get ROM FONT address. */
150 OF_interpret("font-adr", 0, 1, &romfont);
151 if (romfont == NULL)
152 return -1;
153
154 chosen = OF_finddevice("/chosen");
155 OF_getprop(chosen, "mmu", &mmu, 4);
156
157 /*
158 * Convert to physcal address. We cannot access to Open Firmware's
159 * virtual address space.
160 */
161 OF_call_method("translate", mmu, 1, 3, romfont, &romfont, &m, &e);
162
163 /* Get character size */
164 OF_interpret("char-width", 0, 1, &char_width);
165 OF_interpret("char-height", 0, 1, &char_height);
166
167 openfirm6x11.name = "Open Firmware";
168 openfirm6x11.firstchar = 32;
169 openfirm6x11.numchars = 96;
170 openfirm6x11.encoding = WSDISPLAY_FONTENC_ISO;
171 openfirm6x11.fontwidth = char_width;
172 openfirm6x11.fontheight = char_height;
173 openfirm6x11.stride = 1;
174 openfirm6x11.bitorder = WSDISPLAY_FONTORDER_L2R;
175 openfirm6x11.byteorder = WSDISPLAY_FONTORDER_L2R;
176 openfirm6x11.data = romfont;
177
178 return 0;
179 }
180
181 int
182 rascons_init_rasops(int node, struct rasops_info *ri)
183 {
184 int32_t width, height, linebytes, depth;
185
186 /* XXX /chaos/control doesn't have "width", "height", ... */
187 width = height = -1;
188 if (OF_getprop(node, "width", &width, 4) != 4)
189 OF_interpret("screen-width", 0, 1, &width);
190 if (OF_getprop(node, "height", &height, 4) != 4)
191 OF_interpret("screen-height", 0, 1, &height);
192 if (OF_getprop(node, "linebytes", &linebytes, 4) != 4)
193 linebytes = width; /* XXX */
194 if (OF_getprop(node, "depth", &depth, 4) != 4)
195 depth = 8; /* XXX */
196 if (OF_getprop(node, "address", &fbaddr, 4) != 4)
197 OF_interpret("frame-buffer-adr", 0, 1, &fbaddr);
198
199 if (width == -1 || height == -1 || fbaddr == 0 || fbaddr == -1)
200 return false;
201
202 /* Enable write-through cache. */
203 #if defined (PPC_OEA) && !defined (PPC_OEA64) && !defined (PPC_OEA64_BRIDGE)
204 if (rascons_enable_cache) {
205 vaddr_t va;
206 /*
207 * Let's try to find an empty BAT to use
208 */
209 for (va = SEGMENT_LENGTH; va < (USER_SR << ADDR_SR_SHFT);
210 va += SEGMENT_LENGTH) {
211 if (battable[va >> ADDR_SR_SHFT].batu == 0) {
212 battable[va >> ADDR_SR_SHFT].batl =
213 BATL(fbaddr & 0xf0000000,
214 BAT_G | BAT_W | BAT_M, BAT_PP_RW);
215 battable[va >> ADDR_SR_SHFT].batu =
216 BATL(va, BAT_BL_256M, BAT_Vs);
217 fbaddr &= 0x0fffffff;
218 fbaddr |= va;
219 break;
220 }
221 }
222 }
223 #endif /* PPC_OEA64 */
224
225 /* initialize rasops */
226 ri->ri_width = width;
227 ri->ri_height = height;
228 ri->ri_depth = depth;
229 ri->ri_stride = linebytes;
230 ri->ri_bits = (char *)fbaddr;
231 ri->ri_flg = RI_CENTER | RI_FULLCLEAR;
232
233 /* mimic firmware output if we can find the ROM font */
234 if (romfont_loaded) {
235 int cols, rows;
236
237 /*
238 * XXX this assumes we're the console which may or may not
239 * be the case
240 */
241 OF_interpret("#lines", 0, 1, &rows);
242 OF_interpret("#columns", 0, 1, &cols);
243 ri->ri_font = &openfirm6x11;
244 ri->ri_wsfcookie = -1; /* not using wsfont */
245 rasops_init(ri, rows, cols);
246
247 ri->ri_xorigin = (width - cols * ri->ri_font->fontwidth) >> 1;
248 ri->ri_yorigin = (height - rows * ri->ri_font->fontheight)
249 >> 1;
250 ri->ri_bits = (char *)fbaddr + ri->ri_xorigin +
251 ri->ri_stride * ri->ri_yorigin;
252 } else {
253 /* use as much of the screen as the font permits */
254 rasops_init(ri, height/8, width/8);
255 ri->ri_caps = WSSCREEN_WSCOLORS;
256 rasops_reconfig(ri, height / ri->ri_font->fontheight,
257 width / ri->ri_font->fontwidth);
258 }
259
260 return true;
261 }
262 #else /* NWSDISPLAY > 0 */
263 int
264 rascons_cnattach()
265 {
266 return -1;
267 }
268 #endif
269