xref: /freebsd/sys/dev/syscons/scvtb.c (revision fa50a3552d1e759e1bb65e54cb0b7e863bcf54d5)
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