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$");
   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


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