scvtb.c revision 78956
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 *
2650477Speter * $FreeBSD: head/sys/dev/syscons/scvtb.c 78956 2001-06-29 08:24:56Z yokota $
2748104Syokota */
2848104Syokota
2948104Syokota#include "opt_syscons.h"
3048104Syokota
3148104Syokota#include <sys/param.h>
3248104Syokota#include <sys/systm.h>
3348104Syokota#include <sys/malloc.h>
3466834Sphk#include <sys/fbio.h>
3566834Sphk#include <sys/consio.h>
3648104Syokota
3748104Syokota#include <machine/md_var.h>
3865176Sdfr#include <machine/bus.h>
3948104Syokota
4048104Syokota#include <dev/fb/fbreg.h>
4148104Syokota#include <dev/syscons/syscons.h>
4248104Syokota
4348104Syokota#define vtb_wrap(vtb, at, offset)				\
4448104Syokota    (((at) + (offset) + (vtb)->vtb_size)%(vtb)->vtb_size)
4548104Syokota
4648104Syokotavoid
4748104Syokotasc_vtb_init(sc_vtb_t *vtb, int type, int cols, int rows, void *buf, int wait)
4848104Syokota{
4948104Syokota	vtb->vtb_flags = 0;
5048104Syokota	vtb->vtb_type = type;
5148104Syokota	vtb->vtb_cols = cols;
5248104Syokota	vtb->vtb_rows = rows;
5348104Syokota	vtb->vtb_size = cols*rows;
5448104Syokota	vtb->vtb_buffer = NULL;
5548104Syokota	vtb->vtb_tail = 0;
5648104Syokota
5748104Syokota	switch (type) {
5848104Syokota	case VTB_MEMORY:
5948104Syokota	case VTB_RINGBUFFER:
6048104Syokota		if ((buf == NULL) && (cols*rows != 0)) {
6148104Syokota			vtb->vtb_buffer =
6248104Syokota				(vm_offset_t)malloc(cols*rows*sizeof(u_int16_t),
6348104Syokota						    M_DEVBUF,
6448104Syokota						    (wait) ? M_WAITOK : M_NOWAIT);
6578956Syokota			if (vtb->vtb_buffer != NULL) {
6648104Syokota				bzero((void *)sc_vtb_pointer(vtb, 0),
6748104Syokota				      cols*rows*sizeof(u_int16_t));
6878956Syokota				vtb->vtb_flags |= VTB_ALLOCED;
6978956Syokota			}
7048104Syokota		} else {
7148104Syokota			vtb->vtb_buffer = (vm_offset_t)buf;
7248104Syokota		}
7348104Syokota		vtb->vtb_flags |= VTB_VALID;
7448104Syokota		break;
7548104Syokota	case VTB_FRAMEBUFFER:
7648104Syokota		vtb->vtb_buffer = (vm_offset_t)buf;
7748104Syokota		vtb->vtb_flags |= VTB_VALID;
7848104Syokota		break;
7948104Syokota	default:
8048104Syokota		break;
8148104Syokota	}
8248104Syokota}
8348104Syokota
8448104Syokotavoid
8548104Syokotasc_vtb_destroy(sc_vtb_t *vtb)
8648104Syokota{
8748104Syokota	vm_offset_t p;
8848104Syokota
8948104Syokota	vtb->vtb_cols = 0;
9048104Syokota	vtb->vtb_rows = 0;
9148104Syokota	vtb->vtb_size = 0;
9248104Syokota	vtb->vtb_tail = 0;
9348104Syokota
9448104Syokota	p = vtb->vtb_buffer;
9548104Syokota	vtb->vtb_buffer = NULL;
9648104Syokota	switch (vtb->vtb_type) {
9748104Syokota	case VTB_MEMORY:
9848104Syokota	case VTB_RINGBUFFER:
9978956Syokota		if ((vtb->vtb_flags & VTB_ALLOCED) && (p != NULL))
10048104Syokota			free((void *)p, M_DEVBUF);
10148104Syokota		break;
10248104Syokota	default:
10348104Syokota		break;
10448104Syokota	}
10578956Syokota	vtb->vtb_flags = 0;
10648104Syokota	vtb->vtb_type = VTB_INVALID;
10748104Syokota}
10848104Syokota
10948104Syokotasize_t
11048104Syokotasc_vtb_size(int cols, int rows)
11148104Syokota{
11248104Syokota	return (size_t)(cols*rows*sizeof(u_int16_t));
11348104Syokota}
11448104Syokota
11548104Syokotaint
11648104Syokotasc_vtb_getc(sc_vtb_t *vtb, int at)
11748104Syokota{
11848104Syokota	if (vtb->vtb_type == VTB_FRAMEBUFFER)
11948104Syokota		return (readw(sc_vtb_pointer(vtb, at)) & 0x00ff);
12048104Syokota	else
12148104Syokota		return (*(u_int16_t *)sc_vtb_pointer(vtb, at) & 0x00ff);
12248104Syokota}
12348104Syokota
12448104Syokotaint
12548104Syokotasc_vtb_geta(sc_vtb_t *vtb, int at)
12648104Syokota{
12748104Syokota	if (vtb->vtb_type == VTB_FRAMEBUFFER)
12848104Syokota		return (readw(sc_vtb_pointer(vtb, at)) & 0xff00);
12948104Syokota	else
13048104Syokota		return (*(u_int16_t *)sc_vtb_pointer(vtb, at) & 0xff00);
13148104Syokota}
13248104Syokota
13348104Syokotavoid
13448104Syokotasc_vtb_putc(sc_vtb_t *vtb, int at, int c, int a)
13548104Syokota{
13648104Syokota	if (vtb->vtb_type == VTB_FRAMEBUFFER)
13748104Syokota		writew(sc_vtb_pointer(vtb, at), a | c);
13848104Syokota	else
13948104Syokota		*(u_int16_t *)sc_vtb_pointer(vtb, at) = a | c;
14048104Syokota}
14148104Syokota
14248104Syokotavm_offset_t
14348104Syokotasc_vtb_putchar(sc_vtb_t *vtb, vm_offset_t p, int c, int a)
14448104Syokota{
14548104Syokota	if (vtb->vtb_type == VTB_FRAMEBUFFER)
14648104Syokota		writew(p, a | c);
14748104Syokota	else
14848104Syokota		*(u_int16_t *)p = a | c;
14948104Syokota	return (p + sizeof(u_int16_t));
15048104Syokota}
15148104Syokota
15248104Syokotavm_offset_t
15348104Syokotasc_vtb_pointer(sc_vtb_t *vtb, int at)
15448104Syokota{
15548104Syokota	return (vtb->vtb_buffer + sizeof(u_int16_t)*(at));
15648104Syokota}
15748104Syokota
15848104Syokotaint
15948104Syokotasc_vtb_pos(sc_vtb_t *vtb, int pos, int offset)
16048104Syokota{
16148104Syokota	return ((pos + offset + vtb->vtb_size)%vtb->vtb_size);
16248104Syokota}
16348104Syokota
16448104Syokotavoid
16548104Syokotasc_vtb_clear(sc_vtb_t *vtb, int c, int attr)
16648104Syokota{
16748104Syokota	if (vtb->vtb_type == VTB_FRAMEBUFFER)
16848104Syokota		fillw_io(attr | c, sc_vtb_pointer(vtb, 0), vtb->vtb_size);
16948104Syokota	else
17048104Syokota		fillw(attr | c, (void *)sc_vtb_pointer(vtb, 0), vtb->vtb_size);
17148104Syokota}
17248104Syokota
17348104Syokotavoid
17448104Syokotasc_vtb_copy(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int to, int count)
17548104Syokota{
17648104Syokota	/* XXX if both are VTB_VRAMEBUFFER... */
17748104Syokota	if (vtb2->vtb_type == VTB_FRAMEBUFFER) {
17848104Syokota		bcopy_toio(sc_vtb_pointer(vtb1, from),
17948104Syokota			   sc_vtb_pointer(vtb2, to),
18048104Syokota			   count*sizeof(u_int16_t));
18148104Syokota	} else if (vtb1->vtb_type == VTB_FRAMEBUFFER) {
18248104Syokota		bcopy_fromio(sc_vtb_pointer(vtb1, from),
18348104Syokota			     sc_vtb_pointer(vtb2, to),
18448104Syokota			     count*sizeof(u_int16_t));
18548104Syokota	} else {
18648104Syokota		bcopy((void *)sc_vtb_pointer(vtb1, from),
18748104Syokota		      (void *)sc_vtb_pointer(vtb2, to),
18848104Syokota		      count*sizeof(u_int16_t));
18948104Syokota	}
19048104Syokota}
19148104Syokota
19248104Syokotavoid
19348104Syokotasc_vtb_append(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int count)
19448104Syokota{
19548104Syokota	int len;
19648104Syokota
19748104Syokota	if (vtb2->vtb_type != VTB_RINGBUFFER)
19848104Syokota		return;
19948104Syokota
20048104Syokota	while (count > 0) {
20148104Syokota		len = imin(count, vtb2->vtb_size - vtb2->vtb_tail);
20248104Syokota		if (vtb1->vtb_type == VTB_FRAMEBUFFER) {
20348104Syokota			bcopy_fromio(sc_vtb_pointer(vtb1, from),
20448104Syokota				     sc_vtb_pointer(vtb2, vtb2->vtb_tail),
20548104Syokota				     len*sizeof(u_int16_t));
20648104Syokota		} else {
20748104Syokota			bcopy((void *)sc_vtb_pointer(vtb1, from),
20848104Syokota			      (void *)sc_vtb_pointer(vtb2, vtb2->vtb_tail),
20948104Syokota			      len*sizeof(u_int16_t));
21048104Syokota		}
21148104Syokota		from += len;
21248104Syokota		count -= len;
21348104Syokota		vtb2->vtb_tail = vtb_wrap(vtb2, vtb2->vtb_tail, len);
21448104Syokota	}
21548104Syokota}
21648104Syokota
21748104Syokotavoid
21848104Syokotasc_vtb_seek(sc_vtb_t *vtb, int pos)
21948104Syokota{
22048104Syokota	vtb->vtb_tail = pos%vtb->vtb_size;
22148104Syokota}
22248104Syokota
22348104Syokotavoid
22448104Syokotasc_vtb_erase(sc_vtb_t *vtb, int at, int count, int c, int attr)
22548104Syokota{
22648104Syokota	if (at + count > vtb->vtb_size)
22748104Syokota		count = vtb->vtb_size - at;
22848104Syokota	if (vtb->vtb_type == VTB_FRAMEBUFFER)
22948104Syokota		fillw_io(attr | c, sc_vtb_pointer(vtb, at), count);
23048104Syokota	else
23148104Syokota		fillw(attr | c, (void *)sc_vtb_pointer(vtb, at), count);
23248104Syokota}
23348104Syokota
23448104Syokotavoid
23548189Syokotasc_vtb_move(sc_vtb_t *vtb, int from, int to, int count)
23648189Syokota{
23748189Syokota	if (from + count > vtb->vtb_size)
23848189Syokota		count = vtb->vtb_size - from;
23948189Syokota	if (to + count > vtb->vtb_size)
24048189Syokota		count = vtb->vtb_size - to;
24148189Syokota	if (count <= 0)
24248189Syokota		return;
24348189Syokota	if (vtb->vtb_type == VTB_FRAMEBUFFER) {
24448189Syokota		bcopy_io(sc_vtb_pointer(vtb, from),
24548189Syokota			 sc_vtb_pointer(vtb, to), count*sizeof(u_int16_t));
24648189Syokota	} else {
24748189Syokota		bcopy((void *)sc_vtb_pointer(vtb, from),
24848189Syokota		      (void *)sc_vtb_pointer(vtb, to), count*sizeof(u_int16_t));
24948189Syokota	}
25048189Syokota}
25148189Syokota
25248189Syokotavoid
25348104Syokotasc_vtb_delete(sc_vtb_t *vtb, int at, int count, int c, int attr)
25448104Syokota{
25548104Syokota	int len;
25648104Syokota
25748104Syokota	if (at + count > vtb->vtb_size)
25848104Syokota		count = vtb->vtb_size - at;
25948104Syokota	len = vtb->vtb_size - at - count;
26048104Syokota	if (len > 0) {
26148104Syokota		if (vtb->vtb_type == VTB_FRAMEBUFFER) {
26248104Syokota			bcopy_io(sc_vtb_pointer(vtb, at + count),
26348104Syokota				 sc_vtb_pointer(vtb, at),
26448104Syokota				 len*sizeof(u_int16_t));
26548104Syokota		} else {
26648104Syokota			bcopy((void *)sc_vtb_pointer(vtb, at + count),
26748104Syokota			      (void *)sc_vtb_pointer(vtb, at),
26848104Syokota			      len*sizeof(u_int16_t));
26948104Syokota		}
27048104Syokota	}
27148104Syokota	if (vtb->vtb_type == VTB_FRAMEBUFFER)
27248104Syokota		fillw_io(attr | c, sc_vtb_pointer(vtb, at + len),
27348104Syokota			 vtb->vtb_size - at - len);
27448104Syokota	else
27548104Syokota		fillw(attr | c, (void *)sc_vtb_pointer(vtb, at + len),
27648104Syokota		      vtb->vtb_size - at - len);
27748104Syokota}
27848104Syokota
27948104Syokotavoid
28048104Syokotasc_vtb_ins(sc_vtb_t *vtb, int at, int count, int c, int attr)
28148104Syokota{
28248104Syokota	if (at + count > vtb->vtb_size) {
28348104Syokota		count = vtb->vtb_size - at;
28448104Syokota	} else {
28548104Syokota		if (vtb->vtb_type == VTB_FRAMEBUFFER) {
28648104Syokota			bcopy_io(sc_vtb_pointer(vtb, at),
28748104Syokota				 sc_vtb_pointer(vtb, at + count),
28848104Syokota				 (vtb->vtb_size - at - count)*sizeof(u_int16_t));
28948104Syokota		} else {
29048104Syokota			bcopy((void *)sc_vtb_pointer(vtb, at),
29148104Syokota			      (void *)sc_vtb_pointer(vtb, at + count),
29248104Syokota			      (vtb->vtb_size - at - count)*sizeof(u_int16_t));
29348104Syokota		}
29448104Syokota	}
29548104Syokota	if (vtb->vtb_type == VTB_FRAMEBUFFER)
29648104Syokota		fillw_io(attr | c, sc_vtb_pointer(vtb, at), count);
29748104Syokota	else
29848104Syokota		fillw(attr | c, (void *)sc_vtb_pointer(vtb, at), count);
29948104Syokota}
300