1 /* $NetBSD: ofw_rascons.c,v 1.2 2008/03/03 17:15:57 phx Exp $ */
4 * Copyright (c) 1995, 1996 Carnegie-Mellon University.
7 * Author: Chris G. Demetriou
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.
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.
19 * Carnegie Mellon requests users of this software to return to
21 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
22 * School of Computer Science
23 * Carnegie Mellon University
24 * Pittsburgh PA 15213-3890
26 * any improvements or extensions that they make and grant Carnegie the
27 * rights to redistribute these changes.
30 #include <sys/cdefs.h>
31 __KERNEL_RCSID(0, "$NetBSD: ofw_rascons.c,v 1.2 2008/03/03 17:15:57 phx Exp $");
33 #include <sys/param.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>
43 #include <dev/ofw/openfirm.h>
44 #include <uvm/uvm_extern.h>
46 #include <machine/bus.h>
47 #include <machine/autoconf.h>
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>
55 #include <powerpc/oea/ofw_rasconsvar.h>
56 #include "wsdisplay.h"
58 /* we need a wsdisplay to do anything halfway useful */
61 #if defined(PPC_OEA64) || defined (PPC_OEA64_BRIDGE)
62 int rascons_enable_cache
= 0;
64 #ifdef OFB_ENABLE_CACHE
65 int rascons_enable_cache
= 1;
67 int rascons_enable_cache
= 0;
69 #endif /* PPC_OEA64 */
71 static int copy_rom_font(void);
72 static struct wsdisplay_font openfirm6x11
;
73 static vaddr_t fbaddr
;
74 static int romfont_loaded
= 0;
76 struct vcons_screen rascons_console_screen
;
78 struct wsscreen_descr rascons_stdscreen
= {
80 0, 0, /* will be filled in -- XXX shouldn't, it's global */
87 rascons_cnattach(void)
89 struct rasops_info
*ri
= &rascons_console_screen
.scr_ri
;
93 /* get current cursor position */
94 OF_interpret("line#", 0, 1, &crow
);
96 /* move (rom monitor) cursor to the lowest line - 1 */
97 OF_interpret("#lines 2 - to line#", 0, 0);
100 if (copy_rom_font() == 0) {
105 rascons_init_rasops(console_node
, ri
);
108 * no need to clear the screen here when we're mimicing firmware
112 if (ri
->ri_width
>= 1024 && ri
->ri_height
>= 768) {
113 int i
, screenbytes
= ri
->ri_stride
* ri
->ri_height
;
115 for (i
= 0; i
< screenbytes
; i
+= sizeof(u_int32_t
))
116 *(u_int32_t
*)(fbaddr
+ i
) = 0xffffffff;
121 rascons_stdscreen
.nrows
= ri
->ri_rows
;
122 rascons_stdscreen
.ncols
= ri
->ri_cols
;
123 rascons_stdscreen
.textops
= &ri
->ri_ops
;
124 rascons_stdscreen
.capabilities
= ri
->ri_caps
;
126 ri
->ri_ops
.allocattr(ri
, 0, 0, 0, &defattr
);
127 wsdisplay_preattach(&rascons_stdscreen
, ri
, 0, max(0,
128 min(crow
, ri
->ri_rows
- 1)), defattr
);
131 rascons_init_cmap(NULL
);
141 int char_width
, char_height
;
142 int chosen
, mmu
, m
, e
;
144 /* Get ROM FONT address. */
145 OF_interpret("font-adr", 0, 1, &romfont
);
149 chosen
= OF_finddevice("/chosen");
150 OF_getprop(chosen
, "mmu", &mmu
, 4);
153 * Convert to physcal address. We cannot access to Open Firmware's
154 * virtual address space.
156 OF_call_method("translate", mmu
, 1, 3, romfont
, &romfont
, &m
, &e
);
158 /* Get character size */
159 OF_interpret("char-width", 0, 1, &char_width
);
160 OF_interpret("char-height", 0, 1, &char_height
);
162 openfirm6x11
.name
= "Open Firmware";
163 openfirm6x11
.firstchar
= 32;
164 openfirm6x11
.numchars
= 96;
165 openfirm6x11
.encoding
= WSDISPLAY_FONTENC_ISO
;
166 openfirm6x11
.fontwidth
= char_width
;
167 openfirm6x11
.fontheight
= char_height
;
168 openfirm6x11
.stride
= 1;
169 openfirm6x11
.bitorder
= WSDISPLAY_FONTORDER_L2R
;
170 openfirm6x11
.byteorder
= WSDISPLAY_FONTORDER_L2R
;
171 openfirm6x11
.data
= romfont
;
177 rascons_init_rasops(int node
, struct rasops_info
*ri
)
179 int32_t width
, height
, linebytes
, depth
;
181 /* XXX /chaos/control doesn't have "width", "height", ... */
183 if (OF_getprop(node
, "width", &width
, 4) != 4)
184 OF_interpret("screen-width", 0, 1, &width
);
185 if (OF_getprop(node
, "height", &height
, 4) != 4)
186 OF_interpret("screen-height", 0, 1, &height
);
187 if (OF_getprop(node
, "linebytes", &linebytes
, 4) != 4)
188 linebytes
= width
; /* XXX */
189 if (OF_getprop(node
, "depth", &depth
, 4) != 4)
191 if (OF_getprop(node
, "address", &fbaddr
, 4) != 4)
192 OF_interpret("frame-buffer-adr", 0, 1, &fbaddr
);
194 if (width
== -1 || height
== -1 || fbaddr
== 0 || fbaddr
== -1)
197 /* Enable write-through cache. */
198 #if defined (PPC_OEA) && !defined (PPC_OEA64) && !defined (PPC_OEA64_BRIDGE)
199 if (rascons_enable_cache
) {
202 * Let's try to find an empty BAT to use
204 for (va
= SEGMENT_LENGTH
; va
< (USER_SR
<< ADDR_SR_SHFT
);
205 va
+= SEGMENT_LENGTH
) {
206 if (battable
[va
>> ADDR_SR_SHFT
].batu
== 0) {
207 battable
[va
>> ADDR_SR_SHFT
].batl
=
208 BATL(fbaddr
& 0xf0000000,
209 BAT_G
| BAT_W
| BAT_M
, BAT_PP_RW
);
210 battable
[va
>> ADDR_SR_SHFT
].batu
=
211 BATL(va
, BAT_BL_256M
, BAT_Vs
);
212 fbaddr
&= 0x0fffffff;
218 #endif /* PPC_OEA64 */
220 /* initialize rasops */
221 ri
->ri_width
= width
;
222 ri
->ri_height
= height
;
223 ri
->ri_depth
= depth
;
224 ri
->ri_stride
= linebytes
;
225 ri
->ri_bits
= (char *)fbaddr
;
226 ri
->ri_flg
= RI_CENTER
| RI_FULLCLEAR
;
228 /* mimic firmware output if we can find the ROM font */
229 if (romfont_loaded
) {
233 * XXX this assumes we're the console which may or may not
236 OF_interpret("#lines", 0, 1, &rows
);
237 OF_interpret("#columns", 0, 1, &cols
);
238 ri
->ri_font
= &openfirm6x11
;
239 ri
->ri_wsfcookie
= -1; /* not using wsfont */
240 rasops_init(ri
, rows
, cols
);
242 ri
->ri_xorigin
= (width
- cols
* ri
->ri_font
->fontwidth
) >> 1;
243 ri
->ri_yorigin
= (height
- rows
* ri
->ri_font
->fontheight
)
245 ri
->ri_bits
= (char *)fbaddr
+ ri
->ri_xorigin
+
246 ri
->ri_stride
* ri
->ri_yorigin
;
248 /* use as much of the screen as the font permits */
249 rasops_init(ri
, height
/8, width
/8);
250 ri
->ri_caps
= WSSCREEN_WSCOLORS
;
251 rasops_reconfig(ri
, height
/ ri
->ri_font
->fontheight
,
252 width
/ ri
->ri_font
->fontwidth
);
257 #else /* NWSDISPLAY > 0 */
259 rascons_cnattach(void)