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/fb.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  * SPDX-License-Identifier: BSD-3-Clause
    3  *
    4  * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer as
   12  *    the first lines of this file unmodified.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. The name of the author may not be used to endorse or promote products
   17  *    derived from this software without specific prior written permission.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
   20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   21  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   22  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   24  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   29  */
   30 
   31 #include <sys/cdefs.h>
   32 __FBSDID("$FreeBSD$");
   33 
   34 #include "opt_fb.h"
   35 
   36 #include <sys/param.h>
   37 #include <sys/systm.h>
   38 #include <sys/conf.h>
   39 #include <sys/bus.h>
   40 #include <sys/kernel.h>
   41 #include <sys/malloc.h>
   42 #include <sys/module.h>
   43 #include <sys/uio.h>
   44 #include <sys/fbio.h>
   45 #include <sys/linker_set.h>
   46 
   47 #include <vm/vm.h>
   48 #include <vm/pmap.h>
   49 
   50 #include <dev/fb/fbreg.h>
   51 
   52 SET_DECLARE(videodriver_set, const video_driver_t);
   53 
   54 /* local arrays */
   55 
   56 /*
   57  * We need at least one entry each in order to initialize a video card
   58  * for the kernel console.  The arrays will be increased dynamically
   59  * when necessary.
   60  */
   61 
   62 static int              vid_malloc;
   63 static int              adapters = 1;
   64 static video_adapter_t  *adp_ini;
   65 static video_adapter_t  **adapter = &adp_ini;
   66 static video_switch_t   *vidsw_ini;
   67        video_switch_t   **vidsw = &vidsw_ini;
   68 
   69 #define ARRAY_DELTA     4
   70 
   71 static int
   72 vid_realloc_array(void)
   73 {
   74         video_adapter_t **new_adp;
   75         video_switch_t **new_vidsw;
   76         int newsize;
   77         int s;
   78 
   79         if (!vid_malloc)
   80                 return ENOMEM;
   81 
   82         s = spltty();
   83         newsize = rounddown(adapters + ARRAY_DELTA, ARRAY_DELTA);
   84         new_adp = malloc(sizeof(*new_adp)*newsize, M_DEVBUF, M_WAITOK | M_ZERO);
   85         new_vidsw = malloc(sizeof(*new_vidsw)*newsize, M_DEVBUF,
   86             M_WAITOK | M_ZERO);
   87         bcopy(adapter, new_adp, sizeof(*adapter)*adapters);
   88         bcopy(vidsw, new_vidsw, sizeof(*vidsw)*adapters);
   89         if (adapters > 1) {
   90                 free(adapter, M_DEVBUF);
   91                 free(vidsw, M_DEVBUF);
   92         }
   93         adapter = new_adp;
   94         vidsw = new_vidsw;
   95         adapters = newsize;
   96         splx(s);
   97 
   98         if (bootverbose)
   99                 printf("fb: new array size %d\n", adapters);
  100 
  101         return 0;
  102 }
  103 
  104 static void
  105 vid_malloc_init(void *arg)
  106 {
  107         vid_malloc = TRUE;
  108 }
  109 
  110 SYSINIT(vid_mem, SI_SUB_KMEM, SI_ORDER_ANY, vid_malloc_init, NULL);
  111 
  112 /*
  113  * Low-level frame buffer driver functions
  114  * frame buffer subdrivers, such as the VGA driver, call these functions
  115  * to initialize the video_adapter structure and register it to the virtual
  116  * frame buffer driver `fb'.
  117  */
  118 
  119 /* initialize the video_adapter_t structure */
  120 void
  121 vid_init_struct(video_adapter_t *adp, char *name, int type, int unit)
  122 {
  123         adp->va_flags = 0;
  124         adp->va_name = name;
  125         adp->va_type = type;
  126         adp->va_unit = unit;
  127 }
  128 
  129 /* Register a video adapter */
  130 int
  131 vid_register(video_adapter_t *adp)
  132 {
  133         const video_driver_t **list;
  134         const video_driver_t *p;
  135         int index;
  136 
  137         for (index = 0; index < adapters; ++index) {
  138                 if (adapter[index] == NULL)
  139                         break;
  140         }
  141         if (index >= adapters) {
  142                 if (vid_realloc_array())
  143                         return -1;
  144         }
  145 
  146         adp->va_index = index;
  147         adp->va_token = NULL;
  148         SET_FOREACH(list, videodriver_set) {
  149                 p = *list;
  150                 if (strcmp(p->name, adp->va_name) == 0) {
  151                         adapter[index] = adp;
  152                         vidsw[index] = p->vidsw;
  153                         return index;
  154                 }
  155         }
  156 
  157         return -1;
  158 }
  159 
  160 int
  161 vid_unregister(video_adapter_t *adp)
  162 {
  163         if ((adp->va_index < 0) || (adp->va_index >= adapters))
  164                 return ENOENT;
  165         if (adapter[adp->va_index] != adp)
  166                 return ENOENT;
  167 
  168         adapter[adp->va_index] = NULL;
  169         vidsw[adp->va_index] = NULL;
  170         return 0;
  171 }
  172 
  173 /* Get video I/O function table */
  174 video_switch_t
  175 *vid_get_switch(char *name)
  176 {
  177         const video_driver_t **list;
  178         const video_driver_t *p;
  179 
  180         SET_FOREACH(list, videodriver_set) {
  181                 p = *list;
  182                 if (strcmp(p->name, name) == 0)
  183                         return p->vidsw;
  184         }
  185 
  186         return NULL;
  187 }
  188 
  189 /*
  190  * Video card client functions
  191  * Video card clients, such as the console driver `syscons' and the frame
  192  * buffer cdev driver, use these functions to claim and release a card for
  193  * exclusive use.
  194  */
  195 
  196 /* find the video card specified by a driver name and a unit number */
  197 int
  198 vid_find_adapter(char *driver, int unit)
  199 {
  200         int i;
  201 
  202         for (i = 0; i < adapters; ++i) {
  203                 if (adapter[i] == NULL)
  204                         continue;
  205                 if (strcmp("*", driver) && strcmp(adapter[i]->va_name, driver))
  206                         continue;
  207                 if ((unit != -1) && (adapter[i]->va_unit != unit))
  208                         continue;
  209                 return i;
  210         }
  211         return -1;
  212 }
  213 
  214 /* allocate a video card */
  215 int
  216 vid_allocate(char *driver, int unit, void *id)
  217 {
  218         int index;
  219         int s;
  220 
  221         s = spltty();
  222         index = vid_find_adapter(driver, unit);
  223         if (index >= 0) {
  224                 if (adapter[index]->va_token) {
  225                         splx(s);
  226                         return -1;
  227                 }
  228                 adapter[index]->va_token = id;
  229         }
  230         splx(s);
  231         return index;
  232 }
  233 
  234 int
  235 vid_release(video_adapter_t *adp, void *id)
  236 {
  237         int error;
  238         int s;
  239 
  240         s = spltty();
  241         if (adp->va_token == NULL) {
  242                 error = EINVAL;
  243         } else if (adp->va_token != id) {
  244                 error = EPERM;
  245         } else {
  246                 adp->va_token = NULL;
  247                 error = 0;
  248         }
  249         splx(s);
  250         return error;
  251 }
  252 
  253 /* Get a video adapter structure */
  254 video_adapter_t
  255 *vid_get_adapter(int index)
  256 {
  257         if ((index < 0) || (index >= adapters))
  258                 return NULL;
  259         return adapter[index];
  260 }
  261 
  262 /* Configure drivers: this is a backdoor for the console driver XXX */
  263 int
  264 vid_configure(int flags)
  265 {
  266         const video_driver_t **list;
  267         const video_driver_t *p;
  268 
  269         SET_FOREACH(list, videodriver_set) {
  270                 p = *list;
  271                 if (p->configure != NULL)
  272                         (*p->configure)(flags);
  273         }
  274 
  275         return 0;
  276 }
  277 
  278 #define FB_DRIVER_NAME  "fb"
  279 
  280 static char
  281 *adapter_name(int type)
  282 {
  283     static struct {
  284         int type;
  285         char *name;
  286     } names[] = {
  287         { KD_MONO,      "MDA" },
  288         { KD_HERCULES,  "Hercules" },
  289         { KD_CGA,       "CGA" },
  290         { KD_EGA,       "EGA" },
  291         { KD_VGA,       "VGA" },
  292         { KD_TGA,       "TGA" },
  293         { -1,           "Unknown" },
  294     };
  295     int i;
  296 
  297     for (i = 0; names[i].type != -1; ++i)
  298         if (names[i].type == type)
  299             break;
  300     return names[i].name;
  301 }
  302 
  303 /*
  304  * Generic low-level frame buffer functions
  305  * The low-level functions in the frame buffer subdriver may use these
  306  * functions.
  307  */
  308 
  309 void
  310 fb_dump_adp_info(char *driver, video_adapter_t *adp, int level)
  311 {
  312     if (level <= 0)
  313         return;
  314 
  315     printf("%s%d: %s%d, %s, type:%s (%d), flags:0x%x\n", 
  316            FB_DRIVER_NAME, adp->va_index, driver, adp->va_unit, adp->va_name,
  317            adapter_name(adp->va_type), adp->va_type, adp->va_flags);
  318     printf("%s%d: port:0x%lx-0x%lx, crtc:0x%lx, mem:0x%lx 0x%x\n",
  319            FB_DRIVER_NAME, adp->va_index, (u_long)adp->va_io_base, 
  320            (u_long)adp->va_io_base + adp->va_io_size - 1,
  321            (u_long)adp->va_crtc_addr, (u_long)adp->va_mem_base, 
  322            adp->va_mem_size);
  323     printf("%s%d: init mode:%d, bios mode:%d, current mode:%d\n",
  324            FB_DRIVER_NAME, adp->va_index,
  325            adp->va_initial_mode, adp->va_initial_bios_mode, adp->va_mode);
  326     printf("%s%d: window:%p size:%dk gran:%dk, buf:%p size:%dk\n",
  327            FB_DRIVER_NAME, adp->va_index, 
  328            (void *)adp->va_window, (int)adp->va_window_size/1024,
  329            (int)adp->va_window_gran/1024, (void *)adp->va_buffer,
  330            (int)adp->va_buffer_size/1024);
  331 }
  332 
  333 void
  334 fb_dump_mode_info(char *driver, video_adapter_t *adp, video_info_t *info,
  335                   int level)
  336 {
  337     if (level <= 0)
  338         return;
  339 
  340     printf("%s%d: %s, mode:%d, flags:0x%x ", 
  341            driver, adp->va_unit, adp->va_name, info->vi_mode, info->vi_flags);
  342     if (info->vi_flags & V_INFO_GRAPHICS)
  343         printf("G %dx%dx%d, %d plane(s), font:%dx%d, ",
  344                info->vi_width, info->vi_height, 
  345                info->vi_depth, info->vi_planes, 
  346                info->vi_cwidth, info->vi_cheight); 
  347     else
  348         printf("T %dx%d, font:%dx%d, ",
  349                info->vi_width, info->vi_height, 
  350                info->vi_cwidth, info->vi_cheight); 
  351     printf("win:0x%lx\n", (u_long)info->vi_window);
  352 }
  353 
  354 int
  355 fb_type(int adp_type)
  356 {
  357         static struct {
  358                 int     fb_type;
  359                 int     va_type;
  360         } types[] = {
  361                 { FBTYPE_MDA,           KD_MONO },
  362                 { FBTYPE_HERCULES,      KD_HERCULES },
  363                 { FBTYPE_CGA,           KD_CGA },
  364                 { FBTYPE_EGA,           KD_EGA },
  365                 { FBTYPE_VGA,           KD_VGA },
  366                 { FBTYPE_TGA,           KD_TGA },
  367         };
  368         int i;
  369 
  370         for (i = 0; i < nitems(types); ++i) {
  371                 if (types[i].va_type == adp_type)
  372                         return types[i].fb_type;
  373         }
  374         return -1;
  375 }
  376 
  377 int
  378 fb_commonioctl(video_adapter_t *adp, u_long cmd, caddr_t arg)
  379 {
  380         int error;
  381         int s;
  382 
  383         /* assert(adp != NULL) */
  384 
  385         error = 0;
  386         s = spltty();
  387 
  388         switch (cmd) {
  389 
  390         case FBIO_ADAPTER:      /* get video adapter index */
  391                 *(int *)arg = adp->va_index;
  392                 break;
  393 
  394         case FBIO_ADPTYPE:      /* get video adapter type */
  395                 *(int *)arg = adp->va_type;
  396                 break;
  397 
  398         case FBIO_ADPINFO:      /* get video adapter info */
  399                 ((video_adapter_info_t *)arg)->va_index = adp->va_index;
  400                 ((video_adapter_info_t *)arg)->va_type = adp->va_type;
  401                 bcopy(adp->va_name, ((video_adapter_info_t *)arg)->va_name,
  402                       imin(strlen(adp->va_name) + 1,
  403                            sizeof(((video_adapter_info_t *)arg)->va_name))); 
  404                 ((video_adapter_info_t *)arg)->va_unit = adp->va_unit;
  405                 ((video_adapter_info_t *)arg)->va_flags = adp->va_flags;
  406                 ((video_adapter_info_t *)arg)->va_io_base = adp->va_io_base;
  407                 ((video_adapter_info_t *)arg)->va_io_size = adp->va_io_size;
  408                 ((video_adapter_info_t *)arg)->va_crtc_addr = adp->va_crtc_addr;
  409                 ((video_adapter_info_t *)arg)->va_mem_base = adp->va_mem_base;
  410                 ((video_adapter_info_t *)arg)->va_mem_size = adp->va_mem_size;
  411                 ((video_adapter_info_t *)arg)->va_window
  412 #if defined(__amd64__) || defined(__i386__)
  413                         = vtophys(adp->va_window);
  414 #else
  415                         = adp->va_window;
  416 #endif
  417                 ((video_adapter_info_t *)arg)->va_window_size
  418                         = adp->va_window_size;
  419                 ((video_adapter_info_t *)arg)->va_window_gran
  420                         = adp->va_window_gran;
  421                 ((video_adapter_info_t *)arg)->va_window_orig
  422                         = adp->va_window_orig;
  423                 ((video_adapter_info_t *)arg)->va_unused0
  424 #if defined(__amd64__) || defined(__i386__)
  425                         = adp->va_buffer != 0 ? vtophys(adp->va_buffer) : 0;
  426 #else
  427                         = adp->va_buffer;
  428 #endif
  429                 ((video_adapter_info_t *)arg)->va_buffer_size
  430                         = adp->va_buffer_size;
  431                 ((video_adapter_info_t *)arg)->va_mode = adp->va_mode;
  432                 ((video_adapter_info_t *)arg)->va_initial_mode
  433                         = adp->va_initial_mode;
  434                 ((video_adapter_info_t *)arg)->va_initial_bios_mode
  435                         = adp->va_initial_bios_mode;
  436                 ((video_adapter_info_t *)arg)->va_line_width
  437                         = adp->va_line_width;
  438                 ((video_adapter_info_t *)arg)->va_disp_start.x
  439                         = adp->va_disp_start.x;
  440                 ((video_adapter_info_t *)arg)->va_disp_start.y
  441                         = adp->va_disp_start.y;
  442                 break;
  443 
  444         case FBIO_MODEINFO:     /* get mode information */
  445                 error = vidd_get_info(adp,
  446                     ((video_info_t *)arg)->vi_mode,
  447                     (video_info_t *)arg);
  448                 if (error)
  449                         error = ENODEV;
  450                 break;
  451 
  452         case FBIO_FINDMODE:     /* find a matching video mode */
  453                 error = vidd_query_mode(adp, (video_info_t *)arg);
  454                 break;
  455 
  456         case FBIO_GETMODE:      /* get video mode */
  457                 *(int *)arg = adp->va_mode;
  458                 break;
  459 
  460         case FBIO_SETMODE:      /* set video mode */
  461                 error = vidd_set_mode(adp, *(int *)arg);
  462                 if (error)
  463                         error = ENODEV; /* EINVAL? */
  464                 break;
  465 
  466         case FBIO_GETWINORG:    /* get frame buffer window origin */
  467                 *(u_int *)arg = adp->va_window_orig;
  468                 break;
  469 
  470         case FBIO_GETDISPSTART: /* get display start address */
  471                 ((video_display_start_t *)arg)->x = adp->va_disp_start.x;
  472                 ((video_display_start_t *)arg)->y = adp->va_disp_start.y;
  473                 break;
  474 
  475         case FBIO_GETLINEWIDTH: /* get scan line width in bytes */
  476                 *(u_int *)arg = adp->va_line_width;
  477                 break;
  478 
  479         case FBIO_BLANK:        /* blank display */
  480                 error = vidd_blank_display(adp, *(int *)arg);
  481                 break;
  482 
  483         case FBIO_GETPALETTE:   /* get color palette */
  484         case FBIO_SETPALETTE:   /* set color palette */
  485                 /* XXX */
  486 
  487         case FBIOPUTCMAP:
  488         case FBIOGETCMAP:
  489                 /* XXX */
  490 
  491         case FBIO_SETWINORG:    /* set frame buffer window origin */
  492         case FBIO_SETDISPSTART: /* set display start address */
  493         case FBIO_SETLINEWIDTH: /* set scan line width in pixel */
  494 
  495         case FBIOGTYPE:
  496 
  497         default:
  498                 error = ENODEV;
  499                 break;
  500         }
  501 
  502         splx(s);
  503         return error;
  504 }

Cache object: fbfa81604e1d11d64500815ae3ab4e9e


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