148104Syokota/*- 248104Syokota * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp> 348104Syokota * All rights reserved. 448104Syokota * 548104Syokota * Redistribution and use in source and binary forms, with or without 648104Syokota * modification, are permitted provided that the following conditions 748104Syokota * are met: 848104Syokota * 1. Redistributions of source code must retain the above copyright 948104Syokota * notice, this list of conditions and the following disclaimer as 1048104Syokota * the first lines of this file unmodified. 1148104Syokota * 2. Redistributions in binary form must reproduce the above copyright 1248104Syokota * notice, this list of conditions and the following disclaimer in the 1348104Syokota * documentation and/or other materials provided with the distribution. 1448104Syokota * 1548104Syokota * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 1648104Syokota * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1748104Syokota * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1848104Syokota * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 1948104Syokota * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2048104Syokota * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2148104Syokota * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2248104Syokota * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2348104Syokota * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2448104Syokota * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2548104Syokota * 2648104Syokota */ 2748104Syokota 28119420Sobrien#include <sys/cdefs.h> 29119420Sobrien__FBSDID("$FreeBSD$"); 30119420Sobrien 3148104Syokota#include "opt_syscons.h" 3248104Syokota 3348104Syokota#include <sys/param.h> 3448104Syokota#include <sys/systm.h> 3548104Syokota#include <sys/malloc.h> 3666834Sphk#include <sys/fbio.h> 3766834Sphk#include <sys/consio.h> 3848104Syokota 3948104Syokota#include <machine/md_var.h> 4065176Sdfr#include <machine/bus.h> 4148104Syokota 4248104Syokota#include <dev/fb/fbreg.h> 4348104Syokota#include <dev/syscons/syscons.h> 4448104Syokota 4548104Syokota#define vtb_wrap(vtb, at, offset) \ 4648104Syokota (((at) + (offset) + (vtb)->vtb_size)%(vtb)->vtb_size) 4748104Syokota 4848104Syokotavoid 4948104Syokotasc_vtb_init(sc_vtb_t *vtb, int type, int cols, int rows, void *buf, int wait) 5048104Syokota{ 5148104Syokota vtb->vtb_flags = 0; 5248104Syokota vtb->vtb_type = type; 5348104Syokota vtb->vtb_cols = cols; 5448104Syokota vtb->vtb_rows = rows; 5548104Syokota vtb->vtb_size = cols*rows; 56102241Sarchie vtb->vtb_buffer = 0; 5748104Syokota vtb->vtb_tail = 0; 5848104Syokota 5948104Syokota switch (type) { 6048104Syokota case VTB_MEMORY: 6148104Syokota case VTB_RINGBUFFER: 6248104Syokota if ((buf == NULL) && (cols*rows != 0)) { 6348104Syokota vtb->vtb_buffer = 6448104Syokota (vm_offset_t)malloc(cols*rows*sizeof(u_int16_t), 6548104Syokota M_DEVBUF, 66111119Simp (wait) ? M_WAITOK : M_NOWAIT); 67102241Sarchie if (vtb->vtb_buffer != 0) { 6848104Syokota bzero((void *)sc_vtb_pointer(vtb, 0), 6948104Syokota cols*rows*sizeof(u_int16_t)); 7078956Syokota vtb->vtb_flags |= VTB_ALLOCED; 7178956Syokota } 7248104Syokota } else { 7348104Syokota vtb->vtb_buffer = (vm_offset_t)buf; 7448104Syokota } 7548104Syokota vtb->vtb_flags |= VTB_VALID; 7648104Syokota break; 77146476Smarius#ifndef __sparc64__ 7848104Syokota case VTB_FRAMEBUFFER: 7948104Syokota vtb->vtb_buffer = (vm_offset_t)buf; 8048104Syokota vtb->vtb_flags |= VTB_VALID; 8148104Syokota break; 82146476Smarius#endif 8348104Syokota default: 8448104Syokota break; 8548104Syokota } 8648104Syokota} 8748104Syokota 8848104Syokotavoid 8948104Syokotasc_vtb_destroy(sc_vtb_t *vtb) 9048104Syokota{ 9148104Syokota vm_offset_t p; 9248104Syokota 9348104Syokota vtb->vtb_cols = 0; 9448104Syokota vtb->vtb_rows = 0; 9548104Syokota vtb->vtb_size = 0; 9648104Syokota vtb->vtb_tail = 0; 9748104Syokota 9848104Syokota p = vtb->vtb_buffer; 99102241Sarchie vtb->vtb_buffer = 0; 10048104Syokota switch (vtb->vtb_type) { 10148104Syokota case VTB_MEMORY: 10248104Syokota case VTB_RINGBUFFER: 103102241Sarchie if ((vtb->vtb_flags & VTB_ALLOCED) && (p != 0)) 10448104Syokota free((void *)p, M_DEVBUF); 10548104Syokota break; 10648104Syokota default: 10748104Syokota break; 10848104Syokota } 10978956Syokota vtb->vtb_flags = 0; 11048104Syokota vtb->vtb_type = VTB_INVALID; 11148104Syokota} 11248104Syokota 11348104Syokotasize_t 11448104Syokotasc_vtb_size(int cols, int rows) 11548104Syokota{ 11648104Syokota return (size_t)(cols*rows*sizeof(u_int16_t)); 11748104Syokota} 11848104Syokota 11948104Syokotaint 12048104Syokotasc_vtb_getc(sc_vtb_t *vtb, int at) 12148104Syokota{ 122146476Smarius#ifndef __sparc64__ 12348104Syokota if (vtb->vtb_type == VTB_FRAMEBUFFER) 12448104Syokota return (readw(sc_vtb_pointer(vtb, at)) & 0x00ff); 12548104Syokota else 126146476Smarius#endif 12748104Syokota return (*(u_int16_t *)sc_vtb_pointer(vtb, at) & 0x00ff); 12848104Syokota} 12948104Syokota 13048104Syokotaint 13148104Syokotasc_vtb_geta(sc_vtb_t *vtb, int at) 13248104Syokota{ 133146476Smarius#ifndef __sparc64__ 13448104Syokota if (vtb->vtb_type == VTB_FRAMEBUFFER) 13548104Syokota return (readw(sc_vtb_pointer(vtb, at)) & 0xff00); 13648104Syokota else 137146476Smarius#endif 13848104Syokota return (*(u_int16_t *)sc_vtb_pointer(vtb, at) & 0xff00); 13948104Syokota} 14048104Syokota 14148104Syokotavoid 14248104Syokotasc_vtb_putc(sc_vtb_t *vtb, int at, int c, int a) 14348104Syokota{ 144146476Smarius#ifndef __sparc64__ 14548104Syokota if (vtb->vtb_type == VTB_FRAMEBUFFER) 14648104Syokota writew(sc_vtb_pointer(vtb, at), a | c); 14748104Syokota else 148146476Smarius#endif 14948104Syokota *(u_int16_t *)sc_vtb_pointer(vtb, at) = a | c; 15048104Syokota} 15148104Syokota 15248104Syokotavm_offset_t 15348104Syokotasc_vtb_putchar(sc_vtb_t *vtb, vm_offset_t p, int c, int a) 15448104Syokota{ 155146476Smarius#ifndef __sparc64__ 15648104Syokota if (vtb->vtb_type == VTB_FRAMEBUFFER) 15748104Syokota writew(p, a | c); 15848104Syokota else 159146476Smarius#endif 16048104Syokota *(u_int16_t *)p = a | c; 16148104Syokota return (p + sizeof(u_int16_t)); 16248104Syokota} 16348104Syokota 16448104Syokotavm_offset_t 16548104Syokotasc_vtb_pointer(sc_vtb_t *vtb, int at) 16648104Syokota{ 16748104Syokota return (vtb->vtb_buffer + sizeof(u_int16_t)*(at)); 16848104Syokota} 16948104Syokota 17048104Syokotaint 17148104Syokotasc_vtb_pos(sc_vtb_t *vtb, int pos, int offset) 17248104Syokota{ 17348104Syokota return ((pos + offset + vtb->vtb_size)%vtb->vtb_size); 17448104Syokota} 17548104Syokota 17648104Syokotavoid 17748104Syokotasc_vtb_clear(sc_vtb_t *vtb, int c, int attr) 17848104Syokota{ 179146476Smarius#ifndef __sparc64__ 18048104Syokota if (vtb->vtb_type == VTB_FRAMEBUFFER) 18148104Syokota fillw_io(attr | c, sc_vtb_pointer(vtb, 0), vtb->vtb_size); 18248104Syokota else 183146476Smarius#endif 18448104Syokota fillw(attr | c, (void *)sc_vtb_pointer(vtb, 0), vtb->vtb_size); 18548104Syokota} 18648104Syokota 18748104Syokotavoid 18848104Syokotasc_vtb_copy(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int to, int count) 18948104Syokota{ 190146476Smarius#ifndef __sparc64__ 19148104Syokota /* XXX if both are VTB_VRAMEBUFFER... */ 192146476Smarius if (vtb2->vtb_type == VTB_FRAMEBUFFER) 19348104Syokota bcopy_toio(sc_vtb_pointer(vtb1, from), 19448104Syokota sc_vtb_pointer(vtb2, to), 19548104Syokota count*sizeof(u_int16_t)); 196146476Smarius else if (vtb1->vtb_type == VTB_FRAMEBUFFER) 19748104Syokota bcopy_fromio(sc_vtb_pointer(vtb1, from), 19848104Syokota sc_vtb_pointer(vtb2, to), 19948104Syokota count*sizeof(u_int16_t)); 200146476Smarius else 201146476Smarius#endif 20248104Syokota bcopy((void *)sc_vtb_pointer(vtb1, from), 20348104Syokota (void *)sc_vtb_pointer(vtb2, to), 20448104Syokota count*sizeof(u_int16_t)); 20548104Syokota} 20648104Syokota 20748104Syokotavoid 20848104Syokotasc_vtb_append(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int count) 20948104Syokota{ 21048104Syokota int len; 21148104Syokota 21248104Syokota if (vtb2->vtb_type != VTB_RINGBUFFER) 21348104Syokota return; 21448104Syokota 21548104Syokota while (count > 0) { 21648104Syokota len = imin(count, vtb2->vtb_size - vtb2->vtb_tail); 217146476Smarius#ifndef __sparc64__ 218146476Smarius if (vtb1->vtb_type == VTB_FRAMEBUFFER) 21948104Syokota bcopy_fromio(sc_vtb_pointer(vtb1, from), 22048104Syokota sc_vtb_pointer(vtb2, vtb2->vtb_tail), 22148104Syokota len*sizeof(u_int16_t)); 222146476Smarius else 223146476Smarius#endif 22448104Syokota bcopy((void *)sc_vtb_pointer(vtb1, from), 22548104Syokota (void *)sc_vtb_pointer(vtb2, vtb2->vtb_tail), 22648104Syokota len*sizeof(u_int16_t)); 22748104Syokota from += len; 22848104Syokota count -= len; 22948104Syokota vtb2->vtb_tail = vtb_wrap(vtb2, vtb2->vtb_tail, len); 23048104Syokota } 23148104Syokota} 23248104Syokota 23348104Syokotavoid 23448104Syokotasc_vtb_seek(sc_vtb_t *vtb, int pos) 23548104Syokota{ 23648104Syokota vtb->vtb_tail = pos%vtb->vtb_size; 23748104Syokota} 23848104Syokota 23948104Syokotavoid 24048104Syokotasc_vtb_erase(sc_vtb_t *vtb, int at, int count, int c, int attr) 24148104Syokota{ 24248104Syokota if (at + count > vtb->vtb_size) 24348104Syokota count = vtb->vtb_size - at; 244146476Smarius#ifndef __sparc64__ 24548104Syokota if (vtb->vtb_type == VTB_FRAMEBUFFER) 24648104Syokota fillw_io(attr | c, sc_vtb_pointer(vtb, at), count); 24748104Syokota else 248146476Smarius#endif 24948104Syokota fillw(attr | c, (void *)sc_vtb_pointer(vtb, at), count); 25048104Syokota} 25148104Syokota 25248104Syokotavoid 25348189Syokotasc_vtb_move(sc_vtb_t *vtb, int from, int to, int count) 25448189Syokota{ 25548189Syokota if (from + count > vtb->vtb_size) 25648189Syokota count = vtb->vtb_size - from; 25748189Syokota if (to + count > vtb->vtb_size) 25848189Syokota count = vtb->vtb_size - to; 25948189Syokota if (count <= 0) 26048189Syokota return; 261146476Smarius#ifndef __sparc64__ 262146476Smarius if (vtb->vtb_type == VTB_FRAMEBUFFER) 26348189Syokota bcopy_io(sc_vtb_pointer(vtb, from), 26448189Syokota sc_vtb_pointer(vtb, to), count*sizeof(u_int16_t)); 265146476Smarius else 266146476Smarius#endif 26748189Syokota bcopy((void *)sc_vtb_pointer(vtb, from), 26848189Syokota (void *)sc_vtb_pointer(vtb, to), count*sizeof(u_int16_t)); 26948189Syokota} 27048189Syokota 27148189Syokotavoid 27248104Syokotasc_vtb_delete(sc_vtb_t *vtb, int at, int count, int c, int attr) 27348104Syokota{ 27448104Syokota int len; 27548104Syokota 27648104Syokota if (at + count > vtb->vtb_size) 27748104Syokota count = vtb->vtb_size - at; 27848104Syokota len = vtb->vtb_size - at - count; 27948104Syokota if (len > 0) { 280146476Smarius#ifndef __sparc64__ 281146476Smarius if (vtb->vtb_type == VTB_FRAMEBUFFER) 28248104Syokota bcopy_io(sc_vtb_pointer(vtb, at + count), 28348104Syokota sc_vtb_pointer(vtb, at), 28448104Syokota len*sizeof(u_int16_t)); 285146476Smarius else 286146476Smarius#endif 28748104Syokota bcopy((void *)sc_vtb_pointer(vtb, at + count), 28848104Syokota (void *)sc_vtb_pointer(vtb, at), 28948104Syokota len*sizeof(u_int16_t)); 29048104Syokota } 291146476Smarius#ifndef __sparc64__ 29248104Syokota if (vtb->vtb_type == VTB_FRAMEBUFFER) 29348104Syokota fillw_io(attr | c, sc_vtb_pointer(vtb, at + len), 29448104Syokota vtb->vtb_size - at - len); 29548104Syokota else 296146476Smarius#endif 29748104Syokota fillw(attr | c, (void *)sc_vtb_pointer(vtb, at + len), 29848104Syokota vtb->vtb_size - at - len); 29948104Syokota} 30048104Syokota 30148104Syokotavoid 30248104Syokotasc_vtb_ins(sc_vtb_t *vtb, int at, int count, int c, int attr) 30348104Syokota{ 304146476Smarius if (at + count > vtb->vtb_size) 30548104Syokota count = vtb->vtb_size - at; 306146476Smarius else { 307146476Smarius#ifndef __sparc64__ 308146476Smarius if (vtb->vtb_type == VTB_FRAMEBUFFER) 30948104Syokota bcopy_io(sc_vtb_pointer(vtb, at), 31048104Syokota sc_vtb_pointer(vtb, at + count), 31148104Syokota (vtb->vtb_size - at - count)*sizeof(u_int16_t)); 312146476Smarius else 313146476Smarius#endif 31448104Syokota bcopy((void *)sc_vtb_pointer(vtb, at), 31548104Syokota (void *)sc_vtb_pointer(vtb, at + count), 31648104Syokota (vtb->vtb_size - at - count)*sizeof(u_int16_t)); 31748104Syokota } 318146476Smarius#ifndef __sparc64__ 31948104Syokota if (vtb->vtb_type == VTB_FRAMEBUFFER) 32048104Syokota fillw_io(attr | c, sc_vtb_pointer(vtb, at), count); 32148104Syokota else 322146476Smarius#endif 32348104Syokota fillw(attr | c, (void *)sc_vtb_pointer(vtb, at), count); 32448104Syokota} 325