xref: /dragonfly/sys/dev/misc/syscons/scvtb.c (revision 6bd457ed)
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  * $FreeBSD: src/sys/dev/syscons/scvtb.c,v 1.5.2.1 2001/07/16 05:21:23 yokota Exp $
27  * $DragonFly: src/sys/dev/misc/syscons/scvtb.c,v 1.6 2005/05/26 16:24:33 swildner Exp $
28  */
29 
30 #include "opt_syscons.h"
31 
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 
35 #include <machine/console.h>
36 #include <machine/md_var.h>
37 
38 #include <dev/video/fb/fbreg.h>
39 #include "syscons.h"
40 
41 #define vtb_wrap(vtb, at, offset)				\
42     (((at) + (offset) + (vtb)->vtb_size)%(vtb)->vtb_size)
43 
44 void
45 sc_vtb_init(sc_vtb_t *vtb, int type, int cols, int rows, void *buf, int wait)
46 {
47 	vtb->vtb_flags = 0;
48 	vtb->vtb_type = type;
49 	vtb->vtb_cols = cols;
50 	vtb->vtb_rows = rows;
51 	vtb->vtb_size = cols*rows;
52 	vtb->vtb_buffer = NULL;
53 	vtb->vtb_tail = 0;
54 
55 	switch (type) {
56 	case VTB_MEMORY:
57 	case VTB_RINGBUFFER:
58 		if ((buf == NULL) && (cols*rows != 0)) {
59 			vtb->vtb_buffer = malloc(cols*rows*sizeof(uint16_t),
60 				    M_SYSCONS,
61 				    M_ZERO | ((wait) ? M_WAITOK : M_NOWAIT));
62 			if (vtb->vtb_buffer != NULL) {
63 				vtb->vtb_flags |= VTB_VALID;
64 				vtb->vtb_flags |= VTB_ALLOCED;
65 			}
66 		} else {
67 			vtb->vtb_buffer = buf;
68 			vtb->vtb_flags |= VTB_VALID;
69 		}
70 		break;
71 	case VTB_FRAMEBUFFER:
72 		vtb->vtb_buffer = buf;
73 		vtb->vtb_flags |= VTB_VALID;
74 		break;
75 	default:
76 		break;
77 	}
78 }
79 
80 void
81 sc_vtb_destroy(sc_vtb_t *vtb)
82 {
83 	vtb->vtb_cols = 0;
84 	vtb->vtb_rows = 0;
85 	vtb->vtb_size = 0;
86 	vtb->vtb_tail = 0;
87 	vtb->vtb_buffer = NULL;
88 	switch (vtb->vtb_type) {
89 	case VTB_MEMORY:
90 	case VTB_RINGBUFFER:
91 		if ((vtb->vtb_flags & VTB_ALLOCED) && (vtb->vtb_buffer != NULL))
92 			free(vtb->vtb_buffer, M_SYSCONS);
93 		break;
94 	default:
95 		break;
96 	}
97 	vtb->vtb_flags = 0;
98 	vtb->vtb_type = VTB_INVALID;
99 }
100 
101 size_t
102 sc_vtb_size(int cols, int rows)
103 {
104 	return (size_t)(cols*rows*sizeof(uint16_t));
105 }
106 
107 int
108 sc_vtb_getc(sc_vtb_t *vtb, int at)
109 {
110 	if (vtb->vtb_type == VTB_FRAMEBUFFER)
111 		return (readw(vtb->vtb_buffer + at) & 0x00ff);
112 	else
113 		return (*(vtb->vtb_buffer + at) & 0x00ff);
114 }
115 
116 int
117 sc_vtb_geta(sc_vtb_t *vtb, int at)
118 {
119 	if (vtb->vtb_type == VTB_FRAMEBUFFER)
120 		return (readw(vtb->vtb_buffer + at) & 0xff00);
121 	else
122 		return (*(vtb->vtb_buffer + at) & 0xff00);
123 }
124 
125 void
126 sc_vtb_putc(sc_vtb_t *vtb, int at, int c, int a)
127 {
128 	if (vtb->vtb_type == VTB_FRAMEBUFFER)
129 		writew(vtb->vtb_buffer + at, a | c);
130 	else
131 		*(vtb->vtb_buffer + at) = a | c;
132 }
133 
134 uint16_t *
135 sc_vtb_putchar(sc_vtb_t *vtb, uint16_t *p, int c, int a)
136 {
137 	if (vtb->vtb_type == VTB_FRAMEBUFFER)
138 		writew(p, a | c);
139 	else
140 		*p = a | c;
141 	return (p + 1);
142 }
143 
144 int
145 sc_vtb_pos(sc_vtb_t *vtb, int pos, int offset)
146 {
147 	return ((pos + offset + vtb->vtb_size)%vtb->vtb_size);
148 }
149 
150 void
151 sc_vtb_clear(sc_vtb_t *vtb, int c, int attr)
152 {
153 	if (vtb->vtb_type == VTB_FRAMEBUFFER)
154 		fillw_io(attr | c, vtb->vtb_buffer, vtb->vtb_size);
155 	else
156 		fillw(attr | c, vtb->vtb_buffer, vtb->vtb_size);
157 }
158 
159 void
160 sc_vtb_copy(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int to, int count)
161 {
162 	/* XXX if both are VTB_VRAMEBUFFER... */
163 	if (vtb2->vtb_type == VTB_FRAMEBUFFER) {
164 		bcopy_toio(vtb1->vtb_buffer + from, vtb2->vtb_buffer + to,
165 			   count*sizeof(uint16_t));
166 	} else if (vtb1->vtb_type == VTB_FRAMEBUFFER) {
167 		bcopy_fromio(vtb1->vtb_buffer + from, vtb2->vtb_buffer + to,
168 			     count*sizeof(uint16_t));
169 	} else {
170 		bcopy(vtb1->vtb_buffer + from, vtb2->vtb_buffer + to,
171 		      count*sizeof(uint16_t));
172 	}
173 }
174 
175 void
176 sc_vtb_append(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int count)
177 {
178 	int len;
179 
180 	if (vtb2->vtb_type != VTB_RINGBUFFER)
181 		return;
182 
183 	while (count > 0) {
184 		len = imin(count, vtb2->vtb_size - vtb2->vtb_tail);
185 		if (vtb1->vtb_type == VTB_FRAMEBUFFER) {
186 			bcopy_fromio(vtb1->vtb_buffer + from,
187 				     vtb2->vtb_buffer + vtb2->vtb_tail,
188 				     len*sizeof(uint16_t));
189 		} else {
190 			bcopy(vtb1->vtb_buffer + from,
191 			      vtb2->vtb_buffer + vtb2->vtb_tail,
192 			      len*sizeof(uint16_t));
193 		}
194 		from += len;
195 		count -= len;
196 		vtb2->vtb_tail = vtb_wrap(vtb2, vtb2->vtb_tail, len);
197 	}
198 }
199 
200 void
201 sc_vtb_seek(sc_vtb_t *vtb, int pos)
202 {
203 	vtb->vtb_tail = pos%vtb->vtb_size;
204 }
205 
206 void
207 sc_vtb_erase(sc_vtb_t *vtb, int at, int count, int c, int attr)
208 {
209 	if (at + count > vtb->vtb_size)
210 		count = vtb->vtb_size - at;
211 	if (vtb->vtb_type == VTB_FRAMEBUFFER)
212 		fillw_io(attr | c, vtb->vtb_buffer + at, count);
213 	else
214 		fillw(attr | c, vtb->vtb_buffer + at, count);
215 }
216 
217 void
218 sc_vtb_move(sc_vtb_t *vtb, int from, int to, int count)
219 {
220 	if (from + count > vtb->vtb_size)
221 		count = vtb->vtb_size - from;
222 	if (to + count > vtb->vtb_size)
223 		count = vtb->vtb_size - to;
224 	if (count <= 0)
225 		return;
226 	if (vtb->vtb_type == VTB_FRAMEBUFFER) {
227 		bcopy_io(vtb->vtb_buffer + from, vtb->vtb_buffer + to,
228 			 count*sizeof(uint16_t));
229 	} else {
230 		bcopy(vtb->vtb_buffer + from, vtb->vtb_buffer + to,
231 		      count*sizeof(uint16_t));
232 	}
233 }
234 
235 void
236 sc_vtb_delete(sc_vtb_t *vtb, int at, int count, int c, int attr)
237 {
238 	int len;
239 
240 	if (at + count > vtb->vtb_size)
241 		count = vtb->vtb_size - at;
242 	len = vtb->vtb_size - at - count;
243 	if (len > 0) {
244 		if (vtb->vtb_type == VTB_FRAMEBUFFER) {
245 			bcopy_io(vtb->vtb_buffer + at + count,
246 				 vtb->vtb_buffer + at,
247 				 len*sizeof(uint16_t));
248 		} else {
249 			bcopy(vtb->vtb_buffer + at + count,
250 			      vtb->vtb_buffer + at,
251 			      len*sizeof(uint16_t));
252 		}
253 	}
254 	if (vtb->vtb_type == VTB_FRAMEBUFFER)
255 		fillw_io(attr | c, vtb->vtb_buffer + at + len,
256 			 vtb->vtb_size - at - len);
257 	else
258 		fillw(attr | c, vtb->vtb_buffer + at + len,
259 		      vtb->vtb_size - at - len);
260 }
261 
262 void
263 sc_vtb_ins(sc_vtb_t *vtb, int at, int count, int c, int attr)
264 {
265 	if (at + count > vtb->vtb_size) {
266 		count = vtb->vtb_size - at;
267 	} else {
268 		if (vtb->vtb_type == VTB_FRAMEBUFFER) {
269 			bcopy_io(vtb->vtb_buffer + at,
270 				 vtb->vtb_buffer + at + count,
271 				 (vtb->vtb_size - at - count)*sizeof(uint16_t));
272 		} else {
273 			bcopy(vtb->vtb_buffer + at,
274 			      vtb->vtb_buffer + at + count,
275 			      (vtb->vtb_size - at - count)*sizeof(uint16_t));
276 		}
277 	}
278 	if (vtb->vtb_type == VTB_FRAMEBUFFER)
279 		fillw_io(attr | c, vtb->vtb_buffer + at, count);
280 	else
281 		fillw(attr | c, vtb->vtb_buffer + at, count);
282 }
283