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