1 /*- 2 * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer as 10 * the first lines of this file unmodified. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * 26 */ 27 28 #include <sys/cdefs.h> 29 __FBSDID("$FreeBSD$"); 30 31 #include "opt_syscons.h" 32 33 #include <sys/param.h> 34 #include <sys/systm.h> 35 #include <sys/malloc.h> 36 #include <sys/fbio.h> 37 #include <sys/consio.h> 38 39 #include <machine/md_var.h> 40 #include <machine/bus.h> 41 42 #include <dev/fb/fbreg.h> 43 #include <dev/syscons/syscons.h> 44 45 #define vtb_wrap(vtb, at, offset) \ 46 (((at) + (offset) + (vtb)->vtb_size)%(vtb)->vtb_size) 47 48 void 49 sc_vtb_init(sc_vtb_t *vtb, int type, int cols, int rows, void *buf, int wait) 50 { 51 vtb->vtb_flags = 0; 52 vtb->vtb_type = type; 53 vtb->vtb_cols = cols; 54 vtb->vtb_rows = rows; 55 vtb->vtb_size = cols*rows; 56 vtb->vtb_buffer = 0; 57 vtb->vtb_tail = 0; 58 59 switch (type) { 60 case VTB_MEMORY: 61 case VTB_RINGBUFFER: 62 if ((buf == NULL) && (cols*rows != 0)) { 63 vtb->vtb_buffer = 64 (vm_offset_t)malloc(cols*rows*sizeof(u_int16_t), 65 M_DEVBUF, 66 (wait) ? M_WAITOK : M_NOWAIT); 67 if (vtb->vtb_buffer != 0) { 68 bzero((void *)sc_vtb_pointer(vtb, 0), 69 cols*rows*sizeof(u_int16_t)); 70 vtb->vtb_flags |= VTB_ALLOCED; 71 } 72 } else { 73 vtb->vtb_buffer = (vm_offset_t)buf; 74 } 75 vtb->vtb_flags |= VTB_VALID; 76 break; 77 #ifndef __sparc64__ 78 case VTB_FRAMEBUFFER: 79 vtb->vtb_buffer = (vm_offset_t)buf; 80 vtb->vtb_flags |= VTB_VALID; 81 break; 82 #endif 83 default: 84 break; 85 } 86 } 87 88 void 89 sc_vtb_destroy(sc_vtb_t *vtb) 90 { 91 vm_offset_t p; 92 93 vtb->vtb_cols = 0; 94 vtb->vtb_rows = 0; 95 vtb->vtb_size = 0; 96 vtb->vtb_tail = 0; 97 98 p = vtb->vtb_buffer; 99 vtb->vtb_buffer = 0; 100 switch (vtb->vtb_type) { 101 case VTB_MEMORY: 102 case VTB_RINGBUFFER: 103 if ((vtb->vtb_flags & VTB_ALLOCED) && (p != 0)) 104 free((void *)p, M_DEVBUF); 105 break; 106 default: 107 break; 108 } 109 vtb->vtb_flags = 0; 110 vtb->vtb_type = VTB_INVALID; 111 } 112 113 size_t 114 sc_vtb_size(int cols, int rows) 115 { 116 return (size_t)(cols*rows*sizeof(u_int16_t)); 117 } 118 119 int 120 sc_vtb_getc(sc_vtb_t *vtb, int at) 121 { 122 #ifndef __sparc64__ 123 if (vtb->vtb_type == VTB_FRAMEBUFFER) 124 return (readw(sc_vtb_pointer(vtb, at)) & 0x00ff); 125 else 126 #endif 127 return (*(u_int16_t *)sc_vtb_pointer(vtb, at) & 0x00ff); 128 } 129 130 int 131 sc_vtb_geta(sc_vtb_t *vtb, int at) 132 { 133 #ifndef __sparc64__ 134 if (vtb->vtb_type == VTB_FRAMEBUFFER) 135 return (readw(sc_vtb_pointer(vtb, at)) & 0xff00); 136 else 137 #endif 138 return (*(u_int16_t *)sc_vtb_pointer(vtb, at) & 0xff00); 139 } 140 141 void 142 sc_vtb_putc(sc_vtb_t *vtb, int at, int c, int a) 143 { 144 #ifndef __sparc64__ 145 if (vtb->vtb_type == VTB_FRAMEBUFFER) 146 writew(sc_vtb_pointer(vtb, at), a | c); 147 else 148 #endif 149 *(u_int16_t *)sc_vtb_pointer(vtb, at) = a | c; 150 } 151 152 vm_offset_t 153 sc_vtb_putchar(sc_vtb_t *vtb, vm_offset_t p, int c, int a) 154 { 155 #ifndef __sparc64__ 156 if (vtb->vtb_type == VTB_FRAMEBUFFER) 157 writew(p, a | c); 158 else 159 #endif 160 *(u_int16_t *)p = a | c; 161 return (p + sizeof(u_int16_t)); 162 } 163 164 vm_offset_t 165 sc_vtb_pointer(sc_vtb_t *vtb, int at) 166 { 167 return (vtb->vtb_buffer + sizeof(u_int16_t)*(at)); 168 } 169 170 int 171 sc_vtb_pos(sc_vtb_t *vtb, int pos, int offset) 172 { 173 return ((pos + offset + vtb->vtb_size)%vtb->vtb_size); 174 } 175 176 void 177 sc_vtb_clear(sc_vtb_t *vtb, int c, int attr) 178 { 179 #ifndef __sparc64__ 180 if (vtb->vtb_type == VTB_FRAMEBUFFER) 181 fillw_io(attr | c, sc_vtb_pointer(vtb, 0), vtb->vtb_size); 182 else 183 #endif 184 fillw(attr | c, (void *)sc_vtb_pointer(vtb, 0), vtb->vtb_size); 185 } 186 187 void 188 sc_vtb_copy(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int to, int count) 189 { 190 #ifndef __sparc64__ 191 /* XXX if both are VTB_VRAMEBUFFER... */ 192 if (vtb2->vtb_type == VTB_FRAMEBUFFER) 193 bcopy_toio(sc_vtb_pointer(vtb1, from), 194 sc_vtb_pointer(vtb2, to), 195 count*sizeof(u_int16_t)); 196 else if (vtb1->vtb_type == VTB_FRAMEBUFFER) 197 bcopy_fromio(sc_vtb_pointer(vtb1, from), 198 sc_vtb_pointer(vtb2, to), 199 count*sizeof(u_int16_t)); 200 else 201 #endif 202 bcopy((void *)sc_vtb_pointer(vtb1, from), 203 (void *)sc_vtb_pointer(vtb2, to), 204 count*sizeof(u_int16_t)); 205 } 206 207 void 208 sc_vtb_append(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int count) 209 { 210 int len; 211 212 if (vtb2->vtb_type != VTB_RINGBUFFER) 213 return; 214 215 while (count > 0) { 216 len = imin(count, vtb2->vtb_size - vtb2->vtb_tail); 217 #ifndef __sparc64__ 218 if (vtb1->vtb_type == VTB_FRAMEBUFFER) 219 bcopy_fromio(sc_vtb_pointer(vtb1, from), 220 sc_vtb_pointer(vtb2, vtb2->vtb_tail), 221 len*sizeof(u_int16_t)); 222 else 223 #endif 224 bcopy((void *)sc_vtb_pointer(vtb1, from), 225 (void *)sc_vtb_pointer(vtb2, vtb2->vtb_tail), 226 len*sizeof(u_int16_t)); 227 from += len; 228 count -= len; 229 vtb2->vtb_tail = vtb_wrap(vtb2, vtb2->vtb_tail, len); 230 } 231 } 232 233 void 234 sc_vtb_seek(sc_vtb_t *vtb, int pos) 235 { 236 vtb->vtb_tail = pos%vtb->vtb_size; 237 } 238 239 void 240 sc_vtb_erase(sc_vtb_t *vtb, int at, int count, int c, int attr) 241 { 242 if (at + count > vtb->vtb_size) 243 count = vtb->vtb_size - at; 244 #ifndef __sparc64__ 245 if (vtb->vtb_type == VTB_FRAMEBUFFER) 246 fillw_io(attr | c, sc_vtb_pointer(vtb, at), count); 247 else 248 #endif 249 fillw(attr | c, (void *)sc_vtb_pointer(vtb, at), count); 250 } 251 252 void 253 sc_vtb_move(sc_vtb_t *vtb, int from, int to, int count) 254 { 255 if (from + count > vtb->vtb_size) 256 count = vtb->vtb_size - from; 257 if (to + count > vtb->vtb_size) 258 count = vtb->vtb_size - to; 259 if (count <= 0) 260 return; 261 #ifndef __sparc64__ 262 if (vtb->vtb_type == VTB_FRAMEBUFFER) 263 bcopy_io(sc_vtb_pointer(vtb, from), 264 sc_vtb_pointer(vtb, to), count*sizeof(u_int16_t)); 265 else 266 #endif 267 bcopy((void *)sc_vtb_pointer(vtb, from), 268 (void *)sc_vtb_pointer(vtb, to), count*sizeof(u_int16_t)); 269 } 270 271 void 272 sc_vtb_delete(sc_vtb_t *vtb, int at, int count, int c, int attr) 273 { 274 int len; 275 276 if (at + count > vtb->vtb_size) 277 count = vtb->vtb_size - at; 278 len = vtb->vtb_size - at - count; 279 if (len > 0) { 280 #ifndef __sparc64__ 281 if (vtb->vtb_type == VTB_FRAMEBUFFER) 282 bcopy_io(sc_vtb_pointer(vtb, at + count), 283 sc_vtb_pointer(vtb, at), 284 len*sizeof(u_int16_t)); 285 else 286 #endif 287 bcopy((void *)sc_vtb_pointer(vtb, at + count), 288 (void *)sc_vtb_pointer(vtb, at), 289 len*sizeof(u_int16_t)); 290 } 291 #ifndef __sparc64__ 292 if (vtb->vtb_type == VTB_FRAMEBUFFER) 293 fillw_io(attr | c, sc_vtb_pointer(vtb, at + len), 294 vtb->vtb_size - at - len); 295 else 296 #endif 297 fillw(attr | c, (void *)sc_vtb_pointer(vtb, at + len), 298 vtb->vtb_size - at - len); 299 } 300 301 void 302 sc_vtb_ins(sc_vtb_t *vtb, int at, int count, int c, int attr) 303 { 304 if (at + count > vtb->vtb_size) 305 count = vtb->vtb_size - at; 306 else { 307 #ifndef __sparc64__ 308 if (vtb->vtb_type == VTB_FRAMEBUFFER) 309 bcopy_io(sc_vtb_pointer(vtb, at), 310 sc_vtb_pointer(vtb, at + count), 311 (vtb->vtb_size - at - count)*sizeof(u_int16_t)); 312 else 313 #endif 314 bcopy((void *)sc_vtb_pointer(vtb, at), 315 (void *)sc_vtb_pointer(vtb, at + count), 316 (vtb->vtb_size - at - count)*sizeof(u_int16_t)); 317 } 318 #ifndef __sparc64__ 319 if (vtb->vtb_type == VTB_FRAMEBUFFER) 320 fillw_io(attr | c, sc_vtb_pointer(vtb, at), count); 321 else 322 #endif 323 fillw(attr | c, (void *)sc_vtb_pointer(vtb, at), count); 324 } 325