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

Cache object: 1a58b7ef827ac546379533e0e4506ee2


[ 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.