The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/fb/gfb.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: a43ba61b73647ccf245e1c2b49bffc67


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.