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_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, int prot)
  455 {
  456         int error;
  457 
  458         if(offset > adp->va_window_size - PAGE_SIZE)
  459                 error = ENXIO;
  460 #ifdef __i386__
  461         error = i386_btop(adp->va_info.vi_window + offset);
  462 #elsif defined(__alpha__)
  463         error = alpha_btop(adp->va_info.vi_window + offset);
  464 #else
  465         error = ENXIO;
  466 #endif
  467         return(error);
  468 }
  469 
  470 int
  471 gfb_ioctl(video_adapter_t *adp, u_long cmd, caddr_t arg)
  472 {
  473         struct gfb_softc *sc;
  474         int error;
  475 
  476         error = 0;
  477         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
  478 
  479         switch (cmd) {
  480         case FBIOPUTCMAP:
  481                 /* FALLTHROUGH */
  482         case FBIO_GETWINORG:
  483                 /* FALLTHROUGH */
  484         case FBIO_SETWINORG:
  485                 /* FALLTHROUGH */
  486         case FBIO_SETDISPSTART:
  487                 /* FALLTHROUGH */
  488         case FBIO_SETLINEWIDTH:
  489                 /* FALLTHROUGH */
  490         case FBIO_GETPALETTE:
  491                 /* FALLTHROUGH */
  492         case FBIOGTYPE:
  493                 /* FALLTHROUGH */
  494         case FBIOGETCMAP:
  495                 /* FALLTHROUGH */
  496         default:
  497                 error = fb_commonioctl(adp, cmd, arg); 
  498         }
  499         return(error);
  500 }
  501 
  502 int
  503 gfb_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy)
  504 {
  505         int off;
  506 
  507         /*
  508            Just traverse the buffer, one pixel span at a time, setting
  509            each pixel to the block-color...
  510         */
  511         for(off = (x * y); off < ((x + cx) * (y + cy)); off++)
  512                 (*vidsw[adp->va_index]->putp)(adp, off, 0x000007ff, 0xffffffff,
  513                     sizeof(u_int32_t), 1, 0, 0);
  514 
  515         return(0);
  516 }
  517 
  518 int
  519 gfb_bitblt(video_adapter_t *adp, ...)
  520 {
  521         va_list args;
  522         vm_offset_t src, dst;
  523         int count, i;
  524         u_int32_t val;
  525 
  526         va_start(args, adp);
  527 
  528         src = (va_arg(args, vm_offset_t) + adp->va_window_orig) &
  529             0x0000000000fffff8;
  530         dst = (va_arg(args, vm_offset_t) + adp->va_window_orig) &
  531             0x0000000000fffff8;
  532         count = va_arg(args, int);
  533         for(i = 0; i < count; i++, src++, dst++) {
  534                 val = READ_GFB_BUFFER(adp, src);
  535                 WRITE_GFB_BUFFER(adp, dst, val);
  536         }
  537         va_end(args);
  538         return(0);
  539 }
  540 
  541 int
  542 /*gfb_clear(video_adapter_t *adp, int n)*/
  543 gfb_clear(video_adapter_t *adp)
  544         video_adapter_t *adp;
  545 {
  546         int off;
  547 
  548 #if 0
  549         if(n == 0)
  550                 return(0);
  551 #endif
  552 
  553         /*
  554            Just traverse the buffer, one 2K-pixel span at a time, clearing
  555            each pixel...
  556         */
  557         /* for(off = 0; off < (n * adp->va_line_width); off += (2 KB)) */
  558         for(off = 0; off < adp->va_window_size; off++)
  559                 (*vidsw[adp->va_index]->putp)(adp, off, 0x000007ff, 0xffffffff,
  560                     sizeof(u_int32_t), 1, 0, 0);
  561 
  562         return(0);
  563 }
  564 
  565 int
  566 gfb_diag(video_adapter_t *adp, int level)
  567 {
  568         video_info_t info;
  569         struct gfb_softc *sc;
  570         int error;
  571 
  572         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
  573 
  574         /* Just dump everything we know about the adapter to the screen... */
  575         fb_dump_adp_info(sc->driver_name, adp, level);
  576 
  577         /* Try to get the info on this adapter... */
  578         if(!(error = (*vidsw[adp->va_index]->get_info)(adp,
  579             adp->va_initial_mode, &info)))
  580                 /*
  581                    Just dump everything we know about the adapter's mode
  582                    to the screen...
  583                 */
  584                 fb_dump_mode_info(sc->driver_name, adp, &info, level);
  585 
  586         return(error);
  587 }
  588 
  589 int
  590 gfb_save_cursor_palette(video_adapter_t *adp, u_char *palette)
  591 {
  592         struct gfb_softc *sc;
  593         int error, i;
  594 
  595         error = 0;
  596         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
  597 
  598 #if 0
  599         /* If we have a RAMDAC-specific counterpart, use it... */
  600         if(sc->gfbc->ramdac_save_cursor_palette)
  601                 error = sc->gfbc->ramdac_save_cursor_palette(adp,
  602                     &sc->gfbc->cursor_palette);
  603 
  604         else
  605                 /* Otherwise, use the built-in functionality... */
  606                 error = sc->gfbc->builtin_save_cursor_palette(adp,
  607                     &sc->gfbc->cursor_palette);
  608 #endif
  609 
  610         for(i = 0; i < sc->gfbc->cursor_palette.count; i++) {
  611                 palette[(3 * i)] = sc->gfbc->cursor_palette.red[i];
  612                 palette[(3 * i) + 1] = sc->gfbc->cursor_palette.green[i];
  613                 palette[(3 * i) + 2] = sc->gfbc->cursor_palette.blue[i];
  614         }
  615         return(error);
  616 }
  617 
  618 int
  619 gfb_load_cursor_palette(video_adapter_t *adp, u_char *palette)
  620 {
  621         struct gfb_softc *sc;
  622         int error, i;
  623 
  624         error = 0;
  625         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
  626 
  627         for(i = 0; i < sc->gfbc->cursor_palette.count; i++) {
  628                 sc->gfbc->cursor_palette.red[i] = palette[(3 * i)];
  629                 sc->gfbc->cursor_palette.green[i] = palette[(3 * i) + 1];
  630                 sc->gfbc->cursor_palette.blue[i] = palette[(3 * i) + 2];
  631         }
  632 
  633         /* If we have a RAMDAC-specific counterpart, use it... */
  634         if(sc->gfbc->ramdac_load_cursor_palette)
  635                 error = sc->gfbc->ramdac_load_cursor_palette(adp,
  636                     &sc->gfbc->cursor_palette);
  637         else
  638                 /* Otherwise, use the built-in functionality... */
  639                 error = sc->gfbc->builtin_load_cursor_palette(adp,
  640                     &sc->gfbc->cursor_palette);
  641 
  642         return(error);
  643 }
  644 
  645 int
  646 gfb_copy(video_adapter_t *adp, vm_offset_t src, vm_offset_t dst, int n)
  647 {
  648         int error, num_pixels;
  649 
  650         if(n == 0)
  651                 return(0);
  652         num_pixels = adp->va_info.vi_cheight * adp->va_line_width;
  653         error = (*vidsw[adp->va_index]->bitblt)(adp, src * num_pixels,
  654             dst * num_pixels, n * num_pixels);
  655         return(error);
  656 }
  657 
  658 int
  659 gfb_putp(video_adapter_t *adp, vm_offset_t off, u_int32_t p, u_int32_t a,
  660     int size, int bpp, int bit_ltor, int byte_ltor)
  661 {
  662         int i, j, k, num_shifts;
  663         u_int32_t _p, val[32];
  664 
  665         if(bpp < 1)
  666                 return(-1);
  667 
  668         /*
  669             If we don't display bits right-to-left (little-bitian?),
  670             then perform a bit-swap on p...
  671         */
  672         if(bit_ltor) {
  673                 num_shifts = 8 * size;
  674                 for(i = 0, _p = 0; i < num_shifts; i++, p >>= 1) {
  675                         _p <<= 1;
  676                         _p |= (p & 0x00000001);
  677                 }
  678         } else
  679                 _p = p;
  680 
  681         switch(bpp) {
  682         /* Accelerate the simplest cases... */
  683         case 1:
  684                 if((a & 0x00000001) == 0)
  685                         val[0] = 0;
  686                 else if(size <= 0)
  687                         val[0] = 0;
  688                 else if(size == 1)
  689                         val[0] = _p & 0x000000ff;
  690                 else if(size == 2)
  691                         val[0] = _p & 0x0000ffff;
  692                 else if(size == 3)
  693                         val[0] = _p & 0x00ffffff;
  694                 else if(size == 4)
  695                         val[0] = _p & 0xffffffff;
  696                 break;
  697 
  698         /* Only do the following if we are not a simple case... */
  699         case 8:
  700                 if(size > 0) {
  701                         a &= 0x000000ff;
  702                         val[0] = 0;
  703                         if(_p & 0x00000001) val[0] |= (a);
  704                         if(_p & 0x00000002) val[0] |= (a << 8);
  705                         if(_p & 0x00000004) val[0] |= (a << 16);
  706                         if(_p & 0x00000008) val[0] |= (a << 24);
  707                         val[1] = 0;
  708                         if(_p & 0x00000010) val[1] |= (a);
  709                         if(_p & 0x00000020) val[1] |= (a << 8);
  710                         if(_p & 0x00000040) val[1] |= (a << 16);
  711                         if(_p & 0x00000080) val[1] |= (a << 24);
  712                 }
  713                 if(size > 1) {
  714                         val[2] = 0;
  715                         if(_p & 0x00000100) val[2] |= (a);
  716                         if(_p & 0x00000200) val[2] |= (a << 8);
  717                         if(_p & 0x00000400) val[2] |= (a << 16);
  718                         if(_p & 0x00000800) val[2] |= (a << 24);
  719                         val[3] = 0;
  720                         if(_p & 0x00001000) val[3] |= (a);
  721                         if(_p & 0x00002000) val[3] |= (a << 8);
  722                         if(_p & 0x00004000) val[3] |= (a << 16);
  723                         if(_p & 0x00008000) val[3] |= (a << 24);
  724                 }       
  725                 if(size > 2) {
  726                         val[4] = 0;
  727                         if(_p & 0x00010000) val[4] |= (a);
  728                         if(_p & 0x00020000) val[4] |= (a << 8);
  729                         if(_p & 0x00040000) val[4] |= (a << 16);
  730                         if(_p & 0x00080000) val[4] |= (a << 24);
  731                         val[5] = 0;
  732                         if(_p & 0x00100000) val[5] |= (a);
  733                         if(_p & 0x00200000) val[5] |= (a << 8);
  734                         if(_p & 0x00400000) val[5] |= (a << 16);
  735                         if(_p & 0x00800080) val[5] |= (a << 24);
  736                 }
  737                 if(size > 3) {
  738                         val[6] = 0;
  739                         if(_p & 0x01000000) val[6] |= (a);
  740                         if(_p & 0x02000000) val[6] |= (a << 8);
  741                         if(_p & 0x04000000) val[6] |= (a << 16);
  742                         if(_p & 0x08000000) val[6] |= (a << 24);
  743                         val[7] = 0;
  744                         if(_p & 0x10000000) val[7] |= (a);
  745                         if(_p & 0x20000000) val[7] |= (a << 8);
  746                         if(_p & 0x40000000) val[7] |= (a << 16);
  747                         if(_p & 0x80000000) val[7] |= (a << 24);
  748                 }
  749                 break;
  750         case 16:
  751                 if(size > 0) {
  752                         a &= 0x0000ffff;
  753                         if(_p & 0x00000001) val[0] |= (a);
  754                         if(_p & 0x00000002) val[0] |= (a << 16);
  755                         if(_p & 0x00000004) val[1] |= (a);
  756                         if(_p & 0x00000008) val[1] |= (a << 16);
  757                         if(_p & 0x00000010) val[2] |= (a);
  758                         if(_p & 0x00000020) val[2] |= (a << 16);
  759                         if(_p & 0x00000040) val[3] |= (a);
  760                         if(_p & 0x00000080) val[3] |= (a << 16);
  761                 }
  762                 if(size > 1) {
  763                         if(_p & 0x00000100) val[4] |= (a);
  764                         if(_p & 0x00000200) val[4] |= (a << 16);
  765                         if(_p & 0x00000400) val[5] |= (a);
  766                         if(_p & 0x00000800) val[5] |= (a << 16);
  767                         if(_p & 0x00001000) val[6] |= (a);
  768                         if(_p & 0x00002000) val[6] |= (a << 16);
  769                         if(_p & 0x00004000) val[7] |= (a);
  770                         if(_p & 0x00008000) val[7] |= (a << 16);
  771                 }
  772                 if(size > 2) {
  773                         if(_p & 0x00010000) val[8] |= (a);
  774                         if(_p & 0x00020000) val[8] |= (a << 16);
  775                         if(_p & 0x00040000) val[9] |= (a);
  776                         if(_p & 0x00080000) val[9] |= (a << 16);
  777                         if(_p & 0x00100000) val[10] |= (a);
  778                         if(_p & 0x00200000) val[10] |= (a << 16);
  779                         if(_p & 0x00400000) val[11] |= (a);
  780                         if(_p & 0x00800000) val[11] |= (a << 16);
  781                 }
  782                 if(size > 3) {
  783                         if(_p & 0x01000000) val[12] |= (a);
  784                         if(_p & 0x02000000) val[12] |= (a << 16);
  785                         if(_p & 0x04000000) val[13] |= (a);
  786                         if(_p & 0x08000000) val[13] |= (a << 16);
  787                         if(_p & 0x10000000) val[14] |= (a);
  788                         if(_p & 0x20000000) val[14] |= (a << 16);
  789                         if(_p & 0x40000000) val[15] |= (a);
  790                         if(_p & 0x80000000) val[15] |= (a << 16);
  791                 }
  792                 break;
  793         case 32:
  794                 if(size > 0) {
  795                         a &= 0xffffffff;
  796                         if(_p & 0x00000001) val[0] = (a);
  797                         if(_p & 0x00000002) val[1] = (a);
  798                         if(_p & 0x00000004) val[2] = (a);
  799                         if(_p & 0x00000008) val[3] = (a);
  800                         if(_p & 0x00000010) val[4] = (a);
  801                         if(_p & 0x00000020) val[5] = (a);
  802                         if(_p & 0x00000040) val[6] = (a);
  803                         if(_p & 0x00000080) val[7] = (a);
  804                 }
  805                 if(size > 1) {
  806                         if(_p & 0x00000100) val[8] = (a);
  807                         if(_p & 0x00000200) val[9] = (a);
  808                         if(_p & 0x00000400) val[10] = (a);
  809                         if(_p & 0x00000800) val[11] = (a);
  810                         if(_p & 0x00001000) val[12] = (a);
  811                         if(_p & 0x00002000) val[13] = (a);
  812                         if(_p & 0x00004000) val[14] = (a);
  813                         if(_p & 0x00008000) val[15] = (a);
  814                 }
  815                 if(size > 2) {
  816                         if(_p & 0x00010000) val[16] = (a);
  817                         if(_p & 0x00020000) val[17] = (a);
  818                         if(_p & 0x00040000) val[18] = (a);
  819                         if(_p & 0x00080000) val[19] = (a);
  820                         if(_p & 0x00100000) val[20] = (a);
  821                         if(_p & 0x00200000) val[21] = (a);
  822                         if(_p & 0x00400000) val[22] = (a);
  823                         if(_p & 0x00800000) val[23] = (a);
  824                 }
  825                 if(size > 3) {
  826                         if(_p & 0x01000000) val[24] = (a);
  827                         if(_p & 0x02000000) val[25] = (a);
  828                         if(_p & 0x04000000) val[26] = (a);
  829                         if(_p & 0x08000000) val[27] = (a);
  830                         if(_p & 0x10000000) val[28] = (a);
  831                         if(_p & 0x20000000) val[29] = (a);
  832                         if(_p & 0x40000000) val[30] = (a);
  833                         if(_p & 0x80000000) val[31] = (a);
  834                 }
  835                 break;
  836         default:
  837                 break;
  838         }
  839         j = (bpp == 1) ? 1 : bpp * size / sizeof(u_int32_t);
  840 
  841         /*
  842             If we don't display bytes right-to-left (little-endian),
  843             then perform a byte-swap on p (we don't have to swap if
  844             bpp == 1 and val[0] == 0)...
  845         */
  846         if((byte_ltor) && (j > 1) && (val[j] != 0)) {
  847                 for(i = 0; i < (j - i); i++) {
  848                         _p = val[j - i];
  849                         val[j - i] = val[i];
  850                         val[i] = _p;
  851                 }
  852                 for(i = 0; i < j; i++) {
  853                         _p = val[i];
  854                         for(k = 0, val[i] = 0; k < sizeof(u_int32_t);
  855                             k++, _p >>= 8) {
  856                                 val[i] <<= 8;
  857                                 val[i] |= (_p & 0xff);
  858                         }
  859                 }
  860         }
  861 
  862         for(i = 0; i < j; i++) {
  863                 /* Write the pixel-row... */
  864                 WRITE_GFB_BUFFER(adp, (off + i), val[i]);
  865         }
  866         return(0);
  867 }
  868 
  869 int
  870 gfb_putc(video_adapter_t *adp, vm_offset_t off, u_int8_t c, u_int8_t a)
  871 {
  872         vm_offset_t poff;
  873         struct gfb_softc *sc;
  874         int i, pixel_size;
  875         u_int row, col;
  876         u_int8_t *pixel;
  877 
  878         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
  879         pixel_size = adp->va_info.vi_depth / 8;
  880 
  881         /* Get the start of the array of pixels rows for this character... */
  882         pixel = sc->gfbc->font + (c * adp->va_info.vi_cheight);
  883 
  884         /* Calculate the new cursor position... */
  885         row = off / adp->va_info.vi_width;
  886         col = off % adp->va_info.vi_width;
  887 
  888         /* Iterate over all the pixel rows for this character... */
  889         for(i = 0; i < adp->va_info.vi_cheight; i++) {
  890                 /* Get the address of the character's pixel-row... */
  891                 poff = ((col * adp->va_info.vi_cwidth * pixel_size) +
  892                     (((row * adp->va_info.vi_cheight) + i) *
  893                     adp->va_line_width)) / sizeof(u_int32_t);
  894 
  895                 /* Now display the current pixel row... */
  896                 (*vidsw[adp->va_index]->putp)(adp, poff, pixel[i], a,
  897                     sizeof(u_int8_t), 1, 1, 0);
  898         }
  899         return(0);
  900 }
  901 
  902 int
  903 gfb_puts(video_adapter_t *adp, vm_offset_t off, u_int16_t *s, int len)
  904 {
  905         struct gfb_softc *sc;
  906         int i;
  907 
  908         sc = gfb_device_softcs[adp->va_model][adp->va_unit];
  909 
  910         /* If the string in empty, just return now... */
  911         if(len == 0)
  912                 return(0);
  913 
  914         for(i = 0; i < len; i++)
  915                 (*vidsw[adp->va_index]->putc)(adp, off + i, s[i] & 0x00ff,
  916                     (s[i] & 0xff00) >> 8);
  917 
  918         return(0);
  919 }
  920 
  921 int
  922 gfb_putm(video_adapter_t *adp, int x, int y, u_int8_t *pixel_image,
  923     u_int32_t pixel_mask, int size)
  924 {
  925         vm_offset_t poff;
  926         int i, pixel_size;
  927 
  928         pixel_size = adp->va_info.vi_depth / 8;
  929 
  930         /* Iterate over all the pixel rows for the mouse pointer... */
  931         for(i = 0; i < size; i++) {
  932                 /* Get the address of the mouse pointer's pixel-row... */
  933                 poff = ((x * pixel_size) + ((y + i) * adp->va_line_width)) /
  934                     sizeof(u_int32_t);
  935                 /* Now display the current pixel-row... */
  936                 (*vidsw[adp->va_index]->putp)(adp, poff, pixel_image[i],
  937                     pixel_mask, sizeof(u_int8_t), 1, 1, 0);
  938         }
  939 
  940         return(0);
  941 }
  942 
  943 int
  944 gfb_error(void)
  945 {
  946 
  947         return(0);
  948 }

Cache object: cdcafa578f31adcc21a48d72efd24c63


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