1 /* $NetBSD: ofw_rascons.c,v 1.5 2010/05/06 04:32:16 macallan 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@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.5 2010/05/06 04:32:16 macallan 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 93 /* get current cursor position */ 94 OF_interpret("line#", 0, 1, &crow); 95 96 /* move (rom monitor) cursor to the lowest line - 1 */ 97 OF_interpret("#lines 2 - to line#", 0, 0); 98 99 wsfont_init(); 100 if (copy_rom_font() == 0) { 101 romfont_loaded = 1; 102 } 103 104 /* set up rasops */ 105 rascons_init_rasops(console_node, ri); 106 107 /* 108 * no need to clear the screen here when we're mimicing firmware 109 * output anyway 110 */ 111 #if 0 112 if (ri->ri_width >= 1024 && ri->ri_height >= 768) { 113 int i, screenbytes = ri->ri_stride * ri->ri_height; 114 115 for (i = 0; i < screenbytes; i += sizeof(u_int32_t)) 116 *(u_int32_t *)(fbaddr + i) = 0xffffffff; 117 crow = 0; 118 } 119 #endif 120 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; 125 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); 129 130 #if notyet 131 rascons_init_cmap(NULL); 132 #endif 133 134 return 0; 135 } 136 137 static int 138 copy_rom_font(void) 139 { 140 u_char *romfont; 141 int char_width, char_height; 142 int chosen, mmu, m, e; 143 144 /* Get ROM FONT address. */ 145 OF_interpret("font-adr", 0, 1, &romfont); 146 if (romfont == NULL) 147 return -1; 148 149 chosen = OF_finddevice("/chosen"); 150 OF_getprop(chosen, "mmu", &mmu, 4); 151 152 /* 153 * Convert to physcal address. We cannot access to Open Firmware's 154 * virtual address space. 155 */ 156 OF_call_method("translate", mmu, 1, 3, romfont, &romfont, &m, &e); 157 158 /* Get character size */ 159 OF_interpret("char-width", 0, 1, &char_width); 160 OF_interpret("char-height", 0, 1, &char_height); 161 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; 172 173 return 0; 174 } 175 176 int 177 rascons_init_rasops(int node, struct rasops_info *ri) 178 { 179 int32_t width, height, linebytes, depth; 180 181 /* XXX /chaos/control doesn't have "width", "height", ... */ 182 width = height = -1; 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) 190 depth = 8; /* XXX */ 191 if (OF_getprop(node, "address", &fbaddr, 4) != 4) 192 OF_interpret("frame-buffer-adr", 0, 1, &fbaddr); 193 194 if (width == -1 || height == -1 || fbaddr == 0 || fbaddr == -1) 195 return false; 196 197 /* Enable write-through cache. */ 198 #if defined (PPC_OEA) && !defined (PPC_OEA64) && !defined (PPC_OEA64_BRIDGE) 199 if (rascons_enable_cache) { 200 vaddr_t va; 201 /* 202 * Let's try to find an empty BAT to use 203 */ 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; 213 fbaddr |= va; 214 break; 215 } 216 } 217 } 218 #endif /* PPC_OEA64 */ 219 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 | RI_NO_AUTO; 227 228 /* mimic firmware output if we can find the ROM font */ 229 if (romfont_loaded) { 230 int cols, rows; 231 232 /* 233 * XXX this assumes we're the console which may or may not 234 * be the case 235 */ 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); 241 242 ri->ri_xorigin = (width - cols * ri->ri_font->fontwidth) >> 1; 243 ri->ri_yorigin = (height - rows * ri->ri_font->fontheight) 244 >> 1; 245 ri->ri_bits = (char *)fbaddr + ri->ri_xorigin + 246 ri->ri_stride * ri->ri_yorigin; 247 } else { 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); 253 } 254 255 return true; 256 } 257 #else /* NWSDISPLAY > 0 */ 258 int 259 rascons_cnattach(void) 260 { 261 return -1; 262 } 263 #endif 264