FreeBSD/Linux Kernel Cross Reference
sys/dev/fb/gfb.c
1 /*-
2 * Copyright (c) 2001 Andrew Miklic
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.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26 /*-
27 * Copyright (c) 1995, 1996 Carnegie-Mellon University.
28 * All rights reserved.
29 *
30 * Author: Chris G. Demetriou
31 *
32 * Permission to use, copy, modify and distribute this software and
33 * its documentation is hereby granted, provided that both the copyright
34 * notice and this permission notice appear in all copies of the
35 * software, derivative works or modified versions, and any portions
36 * thereof, and that both notices appear in supporting documentation.
37 *
38 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
39 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
40 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
41 *
42 * Carnegie Mellon requests users of this software to return to
43 *
44 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
45 * School of Computer Science
46 * Carnegie Mellon University
47 * Pittsburgh PA 15213-3890
48 *
49 * any improvements or extensions that they make and grant Carnegie the
50 * rights to redistribute these changes.
51 */
52
53 #include <sys/cdefs.h>
54 __FBSDID("$FreeBSD$");
55
56 #include <machine/stdarg.h>
57
58 #include <sys/param.h>
59 #include <sys/systm.h>
60 #include <sys/kernel.h>
61 #include <sys/conf.h>
62 #include <sys/proc.h>
63 #include <sys/fcntl.h>
64 #include <sys/malloc.h>
65 #include <sys/fbio.h>
66
67 #include <vm/vm.h>
68 #include <vm/vm_param.h>
69 #include <vm/pmap.h>
70
71 #include <machine/md_var.h>
72 #include <machine/pc/bios.h>
73 #include <machine/clock.h>
74 #include <machine/bus.h>
75 #include <machine/pc/vesa.h>
76 #include <machine/resource.h>
77 #include <machine/rpb.h>
78
79 #include <sys/bus.h>
80 #include <sys/rman.h>
81
82 #include <dev/pci/pcireg.h>
83 #include <dev/pci/pcivar.h>
84
85 #include <dev/fb/fbreg.h>
86 #include <dev/fb/gfb.h>
87 #include <dev/gfb/gfb_pci.h>
88
89 #include "opt_gfb.h"
90
91 struct gfb_softc *gfb_device_softcs[2][MAX_NUM_GFB_CARDS] = {
92 {
93 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
94 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
95 },
96 {
97 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
98 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
99 },
100 };
101
102 /*
103 The following 9 variables exist only because we need statically
104 allocated structures very early in boot to support gfb_configure()...
105 */
106 struct gfb_softc console;
107 video_adapter_t console_adp;
108 struct gfb_conf console_gfbc;
109 u_char console_palette_red[256];
110 u_char console_palette_green[256];
111 u_char console_palette_blue[256];
112 u_char console_cursor_palette_red[3];
113 u_char console_cursor_palette_green[3];
114 u_char console_cursor_palette_blue[3];
115
116 extern struct gfb_font bold8x16;
117
118 /*****************************************************************************
119 *
120 * FB-generic functions
121 *
122 ****************************************************************************/
123
124 int
125 gfb_probe(int unit, video_adapter_t **adpp, void *arg, int flags)
126 {
127 int error;
128
129 /* Assume the best... */
130 error = 0;
131
132 if((*adpp = vid_get_adapter(vid_find_adapter((char *)arg, unit))) == NULL)
133 error = ENODEV;
134 else
135 (*adpp)->va_flags |= V_ADP_PROBED;
136
137 return(error);
138 }
139
140 int
141 gfb_init(int unit, video_adapter_t *adp, int flags)
142 {
143 struct gfb_softc *sc;
144 struct gfb_conf *gfbc;
145 int error;
146
147 /* Assume the best... */
148 error = 0;
149
150 if(!init_done(adp)) {
151 sc = gfb_device_softcs[adp->va_model][unit];
152 gfbc = sc->gfbc;
153
154 /* Initialize the RAMDAC... */
155 (*gfbc->ramdac_init)(sc);
156
157 /* Initialize the palettes... */
158 (*gfbc->ramdac_load_palette)(sc->adp, &sc->gfbc->palette);
159 (*gfbc->ramdac_load_cursor_palette)(sc->adp,
160 &sc->gfbc->cursor_palette);
161
162 /* Prepare the default font... */
163 (*vidsw[adp->va_index]->load_font)(adp, 0, bold8x16.height,
164 bold8x16.width, bold8x16.data, 0, 256);
165 adp->va_info.vi_cwidth = gfbc->fonts[0].width;
166 adp->va_info.vi_cheight = gfbc->fonts[0].height;
167
168 /*
169 Normalize vi_width and vi_height to be in terms of
170 on-screen characters, rather than pixels (*_init()
171 leaves them in terms of pixels...
172 */
173 adp->va_info.vi_width /= adp->va_info.vi_cwidth;
174 adp->va_info.vi_height /= adp->va_info.vi_cheight;
175
176 /* Enable the default font... */
177 (*vidsw[adp->va_index]->show_font)(adp, 0);
178
179 /* Enable future font-loading... */
180 adp->va_flags |= V_ADP_FONT;
181
182 /* Flag this initialization for this adapter... */
183 adp->va_flags |= V_ADP_INITIALIZED;
184 }
185 return(error);
186 }
187
188 int
189 gfb_get_info(video_adapter_t *adp, int mode, video_info_t *info)
190 {
191 int error;
192
193 /* Assume the best... */
194 error = 0;
195
196 /*
197 The info for GFB adapters does not depend on its mode,
198 so just copy it indiscriminantly (actually, we originally
199 checked the mode, but the current fb framework is somewhat
200 sloppily done in places, and assumes VGA in several places,
201 which makes such checks always fail for such GFBs as TGA)...
202 */
203 bcopy(&adp->va_info, info, sizeof(video_info_t));
204 return(error);
205 }
206
207 int
208 gfb_set_mode(video_adapter_t *adp, int mode)
209 {
210
211 adp->va_mode = mode;
212 return(0);
213 }
214
215 int
216 gfb_save_font(video_adapter_t *adp, int page, int fontsize, int fontwidth,
217 u_char *data, int ch, int count)
218 {
219 struct gfb_softc *sc;
220 int error;
221 int i;
222
223 error = 0;
224 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
225
226 /* Check the font information... */
227 if((sc->gfbc->fonts[page].height != fontsize) ||
228 (sc->gfbc->fonts[page].width != fontwidth))
229 error = EINVAL;
230 else
231
232 /*
233 Copy the character pixel array from our
234 very own private cache...
235 */
236 for(i = ch; i < count * fontsize; i++)
237 data[i] = adp->va_little_bitian ?
238 BIT_REVERSE(sc->gfbc->fonts[page].data[i]) :
239 sc->gfbc->fonts[page].data[i];
240
241 return(error);
242 }
243
244 int
245 gfb_load_font(video_adapter_t *adp, int page, int fontsize, int fontwidth,
246 u_char *data, int ch, int count)
247 {
248 struct gfb_softc *sc;
249 int error;
250 int i;
251
252 error = 0;
253 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
254
255 /* Copy the character pixel array into our very own private cache... */
256 for(i = ch; i < count * fontsize; i++)
257 sc->gfbc->fonts[page].data[i] = adp->va_little_bitian ?
258 BIT_REVERSE(data[i]) : data[i];
259
260 /* Save the font information... */
261 sc->gfbc->fonts[page].height = fontsize;
262 sc->gfbc->fonts[page].width = fontwidth;
263
264 return(error);
265 }
266
267 int
268 gfb_show_font(video_adapter_t *adp, int page)
269 {
270 struct gfb_softc *sc;
271 int error;
272
273 error = 0;
274 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
275
276 /* Normalize adapter values... */
277 adp->va_info.vi_height *= adp->va_info.vi_cheight;
278 adp->va_info.vi_width *= adp->va_info.vi_cwidth;
279
280 /* Set the current font pixels... */
281 sc->gfbc->font = sc->gfbc->fonts[page].data;
282
283 /* Set the current font width... */
284 adp->va_info.vi_cwidth = sc->gfbc->fonts[page].width;
285
286 /* Set the current font height... */
287 adp->va_info.vi_cheight = sc->gfbc->fonts[page].height;
288
289 /* Recompute adapter values... */
290 adp->va_info.vi_height /= adp->va_info.vi_cheight;
291 adp->va_info.vi_width /= adp->va_info.vi_cwidth;
292
293 return(error);
294 }
295
296 int
297 gfb_save_palette(video_adapter_t *adp, u_char *palette)
298 {
299 struct gfb_softc *sc;
300 int error;
301 int i;
302
303 error = 0;
304 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
305
306 #if 0
307 /* If we have a RAMDAC-specific counterpart, use it... */
308 if(sc->gfbc->ramdac_save_palette)
309 error = sc->gfbc->ramdac_save_palette(adp, &sc->gfbc->palette);
310
311 else
312 /* Otherwise, use the built-in functionality... */
313 error = sc->gfbc->builtin_save_palette(adp, &sc->gfbc->palette);
314 #endif
315
316 for(i = 0; i < sc->gfbc->palette.count; i++) {
317 palette[(3 * i)] = sc->gfbc->palette.red[i];
318 palette[(3 * i) + 1] = sc->gfbc->palette.green[i];
319 palette[(3 * i) + 2] = sc->gfbc->palette.blue[i];
320 }
321 return(error);
322 }
323
324 int
325 gfb_load_palette(video_adapter_t *adp, u_char *palette)
326 {
327 struct gfb_softc *sc;
328 int error;
329 int i;
330
331 error = 0;
332 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
333
334 for(i = 0; i < sc->gfbc->palette.count; i++) {
335 sc->gfbc->palette.red[i] = palette[(3 * i)];
336 sc->gfbc->palette.green[i] = palette[(3 * i) + 1];
337 sc->gfbc->palette.blue[i] = palette[(3 * i) + 2];
338 }
339
340 /* If we have a RAMDAC-specific counterpart, use it... */
341 if(sc->gfbc->ramdac_load_palette)
342 error = sc->gfbc->ramdac_load_palette(adp, &sc->gfbc->palette);
343 else
344 /* Otherwise, use the built-in functionality... */
345 error = sc->gfbc->builtin_load_palette(adp, &sc->gfbc->palette);
346
347 return(error);
348 }
349
350 int
351 gfb_set_border(video_adapter_t *adp, int color)
352 {
353
354 return(ENODEV);
355 }
356
357 int
358 gfb_save_state(video_adapter_t *adp, void *p, size_t size)
359 {
360 int i;
361 u_int32_t *regs;
362
363 regs = (u_int32_t *)p;
364 regs[0] = size;
365 for(i = 1; i <= size; i++)
366 regs[i] = READ_GFB_REGISTER(adp, i);
367 return(0);
368 }
369
370 int
371 gfb_load_state(video_adapter_t *adp, void *p)
372 {
373 size_t size;
374 int i;
375 u_int32_t *regs;
376
377 regs = (u_int32_t *)p;
378 size = regs[0];
379 for(i = 1; i <= size; i++)
380 WRITE_GFB_REGISTER(adp, i, regs[i]);
381 return(0);
382 }
383
384 int
385 gfb_set_win_org(video_adapter_t *adp, off_t offset)
386 {
387
388 adp->va_window_orig = offset;
389 return(0);
390 }
391
392 int
393 gfb_read_hw_cursor(video_adapter_t *adp, int *col, int *row)
394 {
395 struct gfb_softc *sc;
396 int error;
397
398 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
399
400 /* If we have a RAMDAC-specific counterpart, use it... */
401 if(sc->gfbc->ramdac_read_hw_cursor)
402 error = sc->gfbc->ramdac_read_hw_cursor(adp, col, row);
403 else
404 /* Otherwise, use the built-in functionality... */
405 error = sc->gfbc->builtin_read_hw_cursor(adp, col, row);
406
407 return(error);
408 }
409
410 int
411 gfb_set_hw_cursor(adp, col, row)
412 video_adapter_t *adp;
413 int col;
414 int row;
415 {
416 int error;
417 struct gfb_softc *sc;
418
419 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
420
421 /* If we have a RAMDAC-specific counterpart, use it... */
422 if(sc->gfbc->ramdac_set_hw_cursor)
423 error = sc->gfbc->ramdac_set_hw_cursor(adp, col, row);
424
425 /* Otherwise, use the built-in functionality... */
426 else
427 error = sc->gfbc->builtin_set_hw_cursor(adp, col, row);
428 return(error);
429 }
430
431 int
432 gfb_set_hw_cursor_shape(video_adapter_t *adp, int base, int height,
433 int cellsize, int blink)
434 {
435 struct gfb_softc *sc;
436 int error;
437
438 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
439
440 /* If we have a RAMDAC-specific counterpart, use it... */
441 if(sc->gfbc->ramdac_set_hw_cursor_shape)
442 error = sc->gfbc->ramdac_set_hw_cursor_shape(adp, base, height,
443 cellsize, blink);
444 else
445 /* Otherwise, use the built-in functionality... */
446 error = sc->gfbc->builtin_set_hw_cursor_shape(adp, base,
447 height, cellsize, blink);
448
449 return(error);
450 }
451
452 int
453 gfb_mmap(video_adapter_t *adp, vm_offset_t offset, vm_offset_t *paddr, int prot)
454 {
455
456 /* XXX */
457 if(offset > adp->va_window_size - PAGE_SIZE)
458 return(ENXIO);
459 *paddr = adp->va_info.vi_window + offset;
460 return(0);
461 }
462
463 int
464 gfb_ioctl(video_adapter_t *adp, u_long cmd, caddr_t arg)
465 {
466 struct gfb_softc *sc;
467 int error;
468
469 error = 0;
470 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
471
472 switch (cmd) {
473 case FBIOPUTCMAP:
474 /* FALLTHROUGH */
475 case FBIO_GETWINORG:
476 /* FALLTHROUGH */
477 case FBIO_SETWINORG:
478 /* FALLTHROUGH */
479 case FBIO_SETDISPSTART:
480 /* FALLTHROUGH */
481 case FBIO_SETLINEWIDTH:
482 /* FALLTHROUGH */
483 case FBIO_GETPALETTE:
484 /* FALLTHROUGH */
485 case FBIOGTYPE:
486 /* FALLTHROUGH */
487 case FBIOGETCMAP:
488 /* FALLTHROUGH */
489 default:
490 error = fb_commonioctl(adp, cmd, arg);
491 }
492 return(error);
493 }
494
495 int
496 gfb_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy)
497 {
498 int off;
499
500 /*
501 Just traverse the buffer, one pixel span at a time, setting
502 each pixel to the block-color...
503 */
504 for(off = (x * y); off < ((x + cx) * (y + cy)); off++)
505 (*vidsw[adp->va_index]->putp)(adp, off, 0x000007ff, 0xffffffff,
506 sizeof(u_int32_t), 1, 0, 0);
507
508 return(0);
509 }
510
511 int
512 gfb_bitblt(video_adapter_t *adp, ...)
513 {
514 va_list args;
515 vm_offset_t src, dst;
516 int count, i;
517 u_int32_t val;
518
519 va_start(args, adp);
520
521 src = (va_arg(args, vm_offset_t) + adp->va_window_orig) &
522 0x0000000000fffff8;
523 dst = (va_arg(args, vm_offset_t) + adp->va_window_orig) &
524 0x0000000000fffff8;
525 count = va_arg(args, int);
526 for(i = 0; i < count; i++, src++, dst++) {
527 val = READ_GFB_BUFFER(adp, src);
528 WRITE_GFB_BUFFER(adp, dst, val);
529 }
530 va_end(args);
531 return(0);
532 }
533
534 int
535 /*gfb_clear(video_adapter_t *adp, int n)*/
536 gfb_clear(video_adapter_t *adp)
537 {
538 int off;
539
540 #if 0
541 if(n == 0)
542 return(0);
543 #endif
544
545 /*
546 Just traverse the buffer, one 2K-pixel span at a time, clearing
547 each pixel...
548 */
549 /* for(off = 0; off < (n * adp->va_line_width); off += (2 KB)) */
550 for(off = 0; off < adp->va_window_size; off++)
551 (*vidsw[adp->va_index]->putp)(adp, off, 0x000007ff, 0xffffffff,
552 sizeof(u_int32_t), 1, 0, 0);
553
554 return(0);
555 }
556
557 int
558 gfb_diag(video_adapter_t *adp, int level)
559 {
560 video_info_t info;
561 struct gfb_softc *sc;
562 int error;
563
564 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
565
566 /* Just dump everything we know about the adapter to the screen... */
567 fb_dump_adp_info(sc->driver_name, adp, level);
568
569 /* Try to get the info on this adapter... */
570 if(!(error = (*vidsw[adp->va_index]->get_info)(adp,
571 adp->va_initial_mode, &info)))
572 /*
573 Just dump everything we know about the adapter's mode
574 to the screen...
575 */
576 fb_dump_mode_info(sc->driver_name, adp, &info, level);
577
578 return(error);
579 }
580
581 int
582 gfb_save_cursor_palette(video_adapter_t *adp, u_char *palette)
583 {
584 struct gfb_softc *sc;
585 int error, i;
586
587 error = 0;
588 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
589
590 #if 0
591 /* If we have a RAMDAC-specific counterpart, use it... */
592 if(sc->gfbc->ramdac_save_cursor_palette)
593 error = sc->gfbc->ramdac_save_cursor_palette(adp,
594 &sc->gfbc->cursor_palette);
595
596 else
597 /* Otherwise, use the built-in functionality... */
598 error = sc->gfbc->builtin_save_cursor_palette(adp,
599 &sc->gfbc->cursor_palette);
600 #endif
601
602 for(i = 0; i < sc->gfbc->cursor_palette.count; i++) {
603 palette[(3 * i)] = sc->gfbc->cursor_palette.red[i];
604 palette[(3 * i) + 1] = sc->gfbc->cursor_palette.green[i];
605 palette[(3 * i) + 2] = sc->gfbc->cursor_palette.blue[i];
606 }
607 return(error);
608 }
609
610 int
611 gfb_load_cursor_palette(video_adapter_t *adp, u_char *palette)
612 {
613 struct gfb_softc *sc;
614 int error, i;
615
616 error = 0;
617 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
618
619 for(i = 0; i < sc->gfbc->cursor_palette.count; i++) {
620 sc->gfbc->cursor_palette.red[i] = palette[(3 * i)];
621 sc->gfbc->cursor_palette.green[i] = palette[(3 * i) + 1];
622 sc->gfbc->cursor_palette.blue[i] = palette[(3 * i) + 2];
623 }
624
625 /* If we have a RAMDAC-specific counterpart, use it... */
626 if(sc->gfbc->ramdac_load_cursor_palette)
627 error = sc->gfbc->ramdac_load_cursor_palette(adp,
628 &sc->gfbc->cursor_palette);
629 else
630 /* Otherwise, use the built-in functionality... */
631 error = sc->gfbc->builtin_load_cursor_palette(adp,
632 &sc->gfbc->cursor_palette);
633
634 return(error);
635 }
636
637 int
638 gfb_copy(video_adapter_t *adp, vm_offset_t src, vm_offset_t dst, int n)
639 {
640 int error, num_pixels;
641
642 if(n == 0)
643 return(0);
644 num_pixels = adp->va_info.vi_cheight * adp->va_line_width;
645 error = (*vidsw[adp->va_index]->bitblt)(adp, src * num_pixels,
646 dst * num_pixels, n * num_pixels);
647 return(error);
648 }
649
650 int
651 gfb_putp(video_adapter_t *adp, vm_offset_t off, u_int32_t p, u_int32_t a,
652 int size, int bpp, int bit_ltor, int byte_ltor)
653 {
654 int i, j, k, num_shifts;
655 u_int32_t _p, val[32];
656
657 if(bpp < 1)
658 return(-1);
659
660 /*
661 If we don't display bits right-to-left (little-bitian?),
662 then perform a bit-swap on p...
663 */
664 if(bit_ltor) {
665 num_shifts = 8 * size;
666 for(i = 0, _p = 0; i < num_shifts; i++, p >>= 1) {
667 _p <<= 1;
668 _p |= (p & 0x00000001);
669 }
670 } else
671 _p = p;
672
673 switch(bpp) {
674 /* Accelerate the simplest cases... */
675 case 1:
676 if((a & 0x00000001) == 0)
677 val[0] = 0;
678 else if(size <= 0)
679 val[0] = 0;
680 else if(size == 1)
681 val[0] = _p & 0x000000ff;
682 else if(size == 2)
683 val[0] = _p & 0x0000ffff;
684 else if(size == 3)
685 val[0] = _p & 0x00ffffff;
686 else if(size == 4)
687 val[0] = _p & 0xffffffff;
688 break;
689
690 /* Only do the following if we are not a simple case... */
691 case 8:
692 if(size > 0) {
693 a &= 0x000000ff;
694 val[0] = 0;
695 if(_p & 0x00000001) val[0] |= (a);
696 if(_p & 0x00000002) val[0] |= (a << 8);
697 if(_p & 0x00000004) val[0] |= (a << 16);
698 if(_p & 0x00000008) val[0] |= (a << 24);
699 val[1] = 0;
700 if(_p & 0x00000010) val[1] |= (a);
701 if(_p & 0x00000020) val[1] |= (a << 8);
702 if(_p & 0x00000040) val[1] |= (a << 16);
703 if(_p & 0x00000080) val[1] |= (a << 24);
704 }
705 if(size > 1) {
706 val[2] = 0;
707 if(_p & 0x00000100) val[2] |= (a);
708 if(_p & 0x00000200) val[2] |= (a << 8);
709 if(_p & 0x00000400) val[2] |= (a << 16);
710 if(_p & 0x00000800) val[2] |= (a << 24);
711 val[3] = 0;
712 if(_p & 0x00001000) val[3] |= (a);
713 if(_p & 0x00002000) val[3] |= (a << 8);
714 if(_p & 0x00004000) val[3] |= (a << 16);
715 if(_p & 0x00008000) val[3] |= (a << 24);
716 }
717 if(size > 2) {
718 val[4] = 0;
719 if(_p & 0x00010000) val[4] |= (a);
720 if(_p & 0x00020000) val[4] |= (a << 8);
721 if(_p & 0x00040000) val[4] |= (a << 16);
722 if(_p & 0x00080000) val[4] |= (a << 24);
723 val[5] = 0;
724 if(_p & 0x00100000) val[5] |= (a);
725 if(_p & 0x00200000) val[5] |= (a << 8);
726 if(_p & 0x00400000) val[5] |= (a << 16);
727 if(_p & 0x00800080) val[5] |= (a << 24);
728 }
729 if(size > 3) {
730 val[6] = 0;
731 if(_p & 0x01000000) val[6] |= (a);
732 if(_p & 0x02000000) val[6] |= (a << 8);
733 if(_p & 0x04000000) val[6] |= (a << 16);
734 if(_p & 0x08000000) val[6] |= (a << 24);
735 val[7] = 0;
736 if(_p & 0x10000000) val[7] |= (a);
737 if(_p & 0x20000000) val[7] |= (a << 8);
738 if(_p & 0x40000000) val[7] |= (a << 16);
739 if(_p & 0x80000000) val[7] |= (a << 24);
740 }
741 break;
742 case 16:
743 if(size > 0) {
744 a &= 0x0000ffff;
745 if(_p & 0x00000001) val[0] |= (a);
746 if(_p & 0x00000002) val[0] |= (a << 16);
747 if(_p & 0x00000004) val[1] |= (a);
748 if(_p & 0x00000008) val[1] |= (a << 16);
749 if(_p & 0x00000010) val[2] |= (a);
750 if(_p & 0x00000020) val[2] |= (a << 16);
751 if(_p & 0x00000040) val[3] |= (a);
752 if(_p & 0x00000080) val[3] |= (a << 16);
753 }
754 if(size > 1) {
755 if(_p & 0x00000100) val[4] |= (a);
756 if(_p & 0x00000200) val[4] |= (a << 16);
757 if(_p & 0x00000400) val[5] |= (a);
758 if(_p & 0x00000800) val[5] |= (a << 16);
759 if(_p & 0x00001000) val[6] |= (a);
760 if(_p & 0x00002000) val[6] |= (a << 16);
761 if(_p & 0x00004000) val[7] |= (a);
762 if(_p & 0x00008000) val[7] |= (a << 16);
763 }
764 if(size > 2) {
765 if(_p & 0x00010000) val[8] |= (a);
766 if(_p & 0x00020000) val[8] |= (a << 16);
767 if(_p & 0x00040000) val[9] |= (a);
768 if(_p & 0x00080000) val[9] |= (a << 16);
769 if(_p & 0x00100000) val[10] |= (a);
770 if(_p & 0x00200000) val[10] |= (a << 16);
771 if(_p & 0x00400000) val[11] |= (a);
772 if(_p & 0x00800000) val[11] |= (a << 16);
773 }
774 if(size > 3) {
775 if(_p & 0x01000000) val[12] |= (a);
776 if(_p & 0x02000000) val[12] |= (a << 16);
777 if(_p & 0x04000000) val[13] |= (a);
778 if(_p & 0x08000000) val[13] |= (a << 16);
779 if(_p & 0x10000000) val[14] |= (a);
780 if(_p & 0x20000000) val[14] |= (a << 16);
781 if(_p & 0x40000000) val[15] |= (a);
782 if(_p & 0x80000000) val[15] |= (a << 16);
783 }
784 break;
785 case 32:
786 if(size > 0) {
787 a &= 0xffffffff;
788 if(_p & 0x00000001) val[0] = (a);
789 if(_p & 0x00000002) val[1] = (a);
790 if(_p & 0x00000004) val[2] = (a);
791 if(_p & 0x00000008) val[3] = (a);
792 if(_p & 0x00000010) val[4] = (a);
793 if(_p & 0x00000020) val[5] = (a);
794 if(_p & 0x00000040) val[6] = (a);
795 if(_p & 0x00000080) val[7] = (a);
796 }
797 if(size > 1) {
798 if(_p & 0x00000100) val[8] = (a);
799 if(_p & 0x00000200) val[9] = (a);
800 if(_p & 0x00000400) val[10] = (a);
801 if(_p & 0x00000800) val[11] = (a);
802 if(_p & 0x00001000) val[12] = (a);
803 if(_p & 0x00002000) val[13] = (a);
804 if(_p & 0x00004000) val[14] = (a);
805 if(_p & 0x00008000) val[15] = (a);
806 }
807 if(size > 2) {
808 if(_p & 0x00010000) val[16] = (a);
809 if(_p & 0x00020000) val[17] = (a);
810 if(_p & 0x00040000) val[18] = (a);
811 if(_p & 0x00080000) val[19] = (a);
812 if(_p & 0x00100000) val[20] = (a);
813 if(_p & 0x00200000) val[21] = (a);
814 if(_p & 0x00400000) val[22] = (a);
815 if(_p & 0x00800000) val[23] = (a);
816 }
817 if(size > 3) {
818 if(_p & 0x01000000) val[24] = (a);
819 if(_p & 0x02000000) val[25] = (a);
820 if(_p & 0x04000000) val[26] = (a);
821 if(_p & 0x08000000) val[27] = (a);
822 if(_p & 0x10000000) val[28] = (a);
823 if(_p & 0x20000000) val[29] = (a);
824 if(_p & 0x40000000) val[30] = (a);
825 if(_p & 0x80000000) val[31] = (a);
826 }
827 break;
828 default:
829 break;
830 }
831 j = (bpp == 1) ? 1 : bpp * size / sizeof(u_int32_t);
832
833 /*
834 If we don't display bytes right-to-left (little-endian),
835 then perform a byte-swap on p (we don't have to swap if
836 bpp == 1 and val[0] == 0)...
837 */
838 if((byte_ltor) && (j > 1) && (val[j] != 0)) {
839 for(i = 0; i < (j - i); i++) {
840 _p = val[j - i];
841 val[j - i] = val[i];
842 val[i] = _p;
843 }
844 for(i = 0; i < j; i++) {
845 _p = val[i];
846 for(k = 0, val[i] = 0; k < sizeof(u_int32_t);
847 k++, _p >>= 8) {
848 val[i] <<= 8;
849 val[i] |= (_p & 0xff);
850 }
851 }
852 }
853
854 for(i = 0; i < j; i++) {
855 /* Write the pixel-row... */
856 WRITE_GFB_BUFFER(adp, (off + i), val[i]);
857 }
858 return(0);
859 }
860
861 int
862 gfb_putc(video_adapter_t *adp, vm_offset_t off, u_int8_t c, u_int8_t a)
863 {
864 vm_offset_t poff;
865 struct gfb_softc *sc;
866 int i, pixel_size;
867 u_int row, col;
868 u_int8_t *pixel;
869
870 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
871 pixel_size = adp->va_info.vi_depth / 8;
872
873 /* Get the start of the array of pixels rows for this character... */
874 pixel = sc->gfbc->font + (c * adp->va_info.vi_cheight);
875
876 /* Calculate the new cursor position... */
877 row = off / adp->va_info.vi_width;
878 col = off % adp->va_info.vi_width;
879
880 /* Iterate over all the pixel rows for this character... */
881 for(i = 0; i < adp->va_info.vi_cheight; i++) {
882 /* Get the address of the character's pixel-row... */
883 poff = ((col * adp->va_info.vi_cwidth * pixel_size) +
884 (((row * adp->va_info.vi_cheight) + i) *
885 adp->va_line_width)) / sizeof(u_int32_t);
886
887 /* Now display the current pixel row... */
888 (*vidsw[adp->va_index]->putp)(adp, poff, pixel[i], a,
889 sizeof(u_int8_t), 1, 1, 0);
890 }
891 return(0);
892 }
893
894 int
895 gfb_puts(video_adapter_t *adp, vm_offset_t off, u_int16_t *s, int len)
896 {
897 struct gfb_softc *sc;
898 int i;
899
900 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
901
902 /* If the string in empty, just return now... */
903 if(len == 0)
904 return(0);
905
906 for(i = 0; i < len; i++)
907 (*vidsw[adp->va_index]->putc)(adp, off + i, s[i] & 0x00ff,
908 (s[i] & 0xff00) >> 8);
909
910 return(0);
911 }
912
913 int
914 gfb_putm(video_adapter_t *adp, int x, int y, u_int8_t *pixel_image,
915 u_int32_t pixel_mask, int size, int width)
916 {
917 vm_offset_t poff;
918 int i, pixel_size;
919
920 pixel_size = adp->va_info.vi_depth / 8;
921
922 /* Iterate over all the pixel rows for the mouse pointer... */
923 for(i = 0; i < size; i++) {
924 /* Get the address of the mouse pointer's pixel-row... */
925 poff = ((x * pixel_size) + ((y + i) * adp->va_line_width)) /
926 sizeof(u_int32_t);
927 /* Now display the current pixel-row... */
928 (*vidsw[adp->va_index]->putp)(adp, poff, pixel_image[i],
929 pixel_mask, sizeof(u_int8_t), 1, 1, 0);
930 }
931
932 return(0);
933 }
934
935 int
936 gfb_error(void)
937 {
938
939 return(0);
940 }
Cache object: a58e119c97f6ac5a4fb60e9d3247711c
|