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/powerpc/ofw/ofw_syscons.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) 2003 Peter Grehan
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  */
   26 
   27 #include <sys/cdefs.h>
   28 __FBSDID("$FreeBSD$");
   29 
   30 #include <sys/param.h>
   31 #include <sys/systm.h>
   32 #include <sys/module.h>
   33 #include <sys/bus.h>
   34 #include <sys/kernel.h>
   35 #include <sys/sysctl.h>
   36 #include <sys/limits.h>
   37 #include <sys/conf.h>
   38 #include <sys/cons.h>
   39 #include <sys/proc.h>
   40 #include <sys/fcntl.h>
   41 #include <sys/malloc.h>
   42 #include <sys/fbio.h>
   43 #include <sys/consio.h>
   44 
   45 #include <machine/bus.h>
   46 #include <machine/sc_machdep.h>
   47 
   48 #include <sys/rman.h>
   49 
   50 #include <dev/fb/fbreg.h>
   51 #include <dev/syscons/syscons.h>
   52 
   53 #include <dev/ofw/openfirm.h>
   54 #include <dev/ofw/ofw_bus.h>
   55 #include <dev/ofw/ofw_pci.h>
   56 #include <powerpc/ofw/ofw_syscons.h>
   57 
   58 static int ofwfb_ignore_mmap_checks;
   59 SYSCTL_NODE(_hw, OID_AUTO, ofwfb, CTLFLAG_RD, 0, "ofwfb");
   60 SYSCTL_INT(_hw_ofwfb, OID_AUTO, relax_mmap, CTLFLAG_RW,
   61     &ofwfb_ignore_mmap_checks, 0, "relax mmap bounds checking");
   62 
   63 extern u_char dflt_font_16[];
   64 extern u_char dflt_font_14[];
   65 extern u_char dflt_font_8[];
   66 
   67 static int ofwfb_configure(int flags);
   68 
   69 static vi_probe_t ofwfb_probe;
   70 static vi_init_t ofwfb_init;
   71 static vi_get_info_t ofwfb_get_info;
   72 static vi_query_mode_t ofwfb_query_mode;
   73 static vi_set_mode_t ofwfb_set_mode;
   74 static vi_save_font_t ofwfb_save_font;
   75 static vi_load_font_t ofwfb_load_font;
   76 static vi_show_font_t ofwfb_show_font;
   77 static vi_save_palette_t ofwfb_save_palette;
   78 static vi_load_palette_t ofwfb_load_palette;
   79 static vi_set_border_t ofwfb_set_border;
   80 static vi_save_state_t ofwfb_save_state;
   81 static vi_load_state_t ofwfb_load_state;
   82 static vi_set_win_org_t ofwfb_set_win_org;
   83 static vi_read_hw_cursor_t ofwfb_read_hw_cursor;
   84 static vi_set_hw_cursor_t ofwfb_set_hw_cursor;
   85 static vi_set_hw_cursor_shape_t ofwfb_set_hw_cursor_shape;
   86 static vi_blank_display_t ofwfb_blank_display;
   87 static vi_mmap_t ofwfb_mmap;
   88 static vi_ioctl_t ofwfb_ioctl;
   89 static vi_clear_t ofwfb_clear;
   90 static vi_fill_rect_t ofwfb_fill_rect;
   91 static vi_bitblt_t ofwfb_bitblt;
   92 static vi_diag_t ofwfb_diag;
   93 static vi_save_cursor_palette_t ofwfb_save_cursor_palette;
   94 static vi_load_cursor_palette_t ofwfb_load_cursor_palette;
   95 static vi_copy_t ofwfb_copy;
   96 static vi_putp_t ofwfb_putp;
   97 static vi_putc_t ofwfb_putc;
   98 static vi_puts_t ofwfb_puts;
   99 static vi_putm_t ofwfb_putm;
  100 
  101 static video_switch_t ofwfbvidsw = {
  102         .probe                  = ofwfb_probe,
  103         .init                   = ofwfb_init,
  104         .get_info               = ofwfb_get_info,
  105         .query_mode             = ofwfb_query_mode,
  106         .set_mode               = ofwfb_set_mode,
  107         .save_font              = ofwfb_save_font,
  108         .load_font              = ofwfb_load_font,
  109         .show_font              = ofwfb_show_font,
  110         .save_palette           = ofwfb_save_palette,
  111         .load_palette           = ofwfb_load_palette,
  112         .set_border             = ofwfb_set_border,
  113         .save_state             = ofwfb_save_state,
  114         .load_state             = ofwfb_load_state,
  115         .set_win_org            = ofwfb_set_win_org,
  116         .read_hw_cursor         = ofwfb_read_hw_cursor,
  117         .set_hw_cursor          = ofwfb_set_hw_cursor,
  118         .set_hw_cursor_shape    = ofwfb_set_hw_cursor_shape,
  119         .blank_display          = ofwfb_blank_display,
  120         .mmap                   = ofwfb_mmap,
  121         .ioctl                  = ofwfb_ioctl,
  122         .clear                  = ofwfb_clear,
  123         .fill_rect              = ofwfb_fill_rect,
  124         .bitblt                 = ofwfb_bitblt,
  125         .diag                   = ofwfb_diag,
  126         .save_cursor_palette    = ofwfb_save_cursor_palette,
  127         .load_cursor_palette    = ofwfb_load_cursor_palette,
  128         .copy                   = ofwfb_copy,
  129         .putp                   = ofwfb_putp,
  130         .putc                   = ofwfb_putc,
  131         .puts                   = ofwfb_puts,
  132         .putm                   = ofwfb_putm,
  133 };
  134 
  135 /*
  136  * bitmap depth-specific routines
  137  */
  138 static vi_blank_display_t ofwfb_blank_display8;
  139 static vi_putc_t ofwfb_putc8;
  140 static vi_putm_t ofwfb_putm8;
  141 static vi_set_border_t ofwfb_set_border8;
  142 
  143 static vi_blank_display_t ofwfb_blank_display32;
  144 static vi_putc_t ofwfb_putc32;
  145 static vi_putm_t ofwfb_putm32;
  146 static vi_set_border_t ofwfb_set_border32;
  147 
  148 VIDEO_DRIVER(ofwfb, ofwfbvidsw, ofwfb_configure);
  149 
  150 extern sc_rndr_sw_t txtrndrsw;
  151 RENDERER(ofwfb, 0, txtrndrsw, gfb_set);
  152 
  153 RENDERER_MODULE(ofwfb, gfb_set);
  154 
  155 /*
  156  * Define the iso6429-1983 colormap
  157  */
  158 static struct {
  159         uint8_t red;
  160         uint8_t green;
  161         uint8_t blue;
  162 } ofwfb_cmap[16] = {            /*  #     R    G    B   Color */
  163                                 /*  -     -    -    -   ----- */
  164         { 0x00, 0x00, 0x00 },   /*  0     0    0    0   Black */
  165         { 0x00, 0x00, 0xaa },   /*  1     0    0  2/3   Blue  */
  166         { 0x00, 0xaa, 0x00 },   /*  2     0  2/3    0   Green */
  167         { 0x00, 0xaa, 0xaa },   /*  3     0  2/3  2/3   Cyan  */
  168         { 0xaa, 0x00, 0x00 },   /*  4   2/3    0    0   Red   */
  169         { 0xaa, 0x00, 0xaa },   /*  5   2/3    0  2/3   Magenta */
  170         { 0xaa, 0x55, 0x00 },   /*  6   2/3  1/3    0   Brown */
  171         { 0xaa, 0xaa, 0xaa },   /*  7   2/3  2/3  2/3   White */
  172         { 0x55, 0x55, 0x55 },   /*  8   1/3  1/3  1/3   Gray  */
  173         { 0x55, 0x55, 0xff },   /*  9   1/3  1/3    1   Bright Blue  */
  174         { 0x55, 0xff, 0x55 },   /* 10   1/3    1  1/3   Bright Green */
  175         { 0x55, 0xff, 0xff },   /* 11   1/3    1    1   Bright Cyan  */
  176         { 0xff, 0x55, 0x55 },   /* 12     1  1/3  1/3   Bright Red   */
  177         { 0xff, 0x55, 0xff },   /* 13     1  1/3    1   Bright Magenta */
  178         { 0xff, 0xff, 0x80 },   /* 14     1    1  1/3   Bright Yellow */
  179         { 0xff, 0xff, 0xff }    /* 15     1    1    1   Bright White */
  180 };
  181 
  182 #define TODO    printf("%s: unimplemented\n", __func__)
  183 
  184 static u_int16_t ofwfb_static_window[ROW*COL];
  185 
  186 static struct ofwfb_softc ofwfb_softc;
  187 
  188 static __inline int
  189 ofwfb_background(uint8_t attr)
  190 {
  191         return (attr >> 4);
  192 }
  193 
  194 static __inline int
  195 ofwfb_foreground(uint8_t attr)
  196 {
  197         return (attr & 0x0f);
  198 }
  199 
  200 static u_int
  201 ofwfb_pix32(int attr)
  202 {
  203         u_int retval;
  204 
  205         retval = (ofwfb_cmap[attr].blue  << 16) |
  206                 (ofwfb_cmap[attr].green << 8) |
  207                 ofwfb_cmap[attr].red;
  208 
  209         return (retval);
  210 }
  211 
  212 static int
  213 ofwfb_configure(int flags)
  214 {
  215         struct ofwfb_softc *sc;
  216         phandle_t chosen;
  217         ihandle_t stdout;
  218         phandle_t node;
  219         bus_addr_t fb_phys;
  220         int depth;
  221         int disable;
  222         int len;
  223         char type[16];
  224         static int done = 0;
  225 
  226         disable = 0;
  227         TUNABLE_INT_FETCH("hw.syscons.disable", &disable);
  228         if (disable != 0)
  229                 return (0);
  230 
  231         if (done != 0)
  232                 return (0);
  233         done = 1;
  234 
  235         sc = &ofwfb_softc;
  236 
  237         chosen = OF_finddevice("/chosen");
  238         OF_getprop(chosen, "stdout", &stdout, sizeof(stdout));
  239         node = OF_instance_to_package(stdout);
  240         if (node == -1) {
  241                 /*
  242                  * The "/chosen/stdout" does not exist try
  243                  * using "screen" directly.
  244                  */
  245                 node = OF_finddevice("screen");
  246         }
  247         OF_getprop(node, "device_type", type, sizeof(type));
  248         if (strcmp(type, "display") != 0)
  249                 return (0);
  250 
  251         /* Only support 8 and 32-bit framebuffers */
  252         OF_getprop(node, "depth", &depth, sizeof(depth));
  253         if (depth == 8) {
  254                 sc->sc_blank = ofwfb_blank_display8;
  255                 sc->sc_putc = ofwfb_putc8;
  256                 sc->sc_putm = ofwfb_putm8;
  257                 sc->sc_set_border = ofwfb_set_border8;
  258         } else if (depth == 32) {
  259                 sc->sc_blank = ofwfb_blank_display32;
  260                 sc->sc_putc = ofwfb_putc32;
  261                 sc->sc_putm = ofwfb_putm32;
  262                 sc->sc_set_border = ofwfb_set_border32;
  263         } else
  264                 return (0);
  265 
  266         sc->sc_depth = depth;
  267         sc->sc_node = node;
  268         sc->sc_console = 1;
  269         OF_getprop(node, "height", &sc->sc_height, sizeof(sc->sc_height));
  270         OF_getprop(node, "width", &sc->sc_width, sizeof(sc->sc_width));
  271         OF_getprop(node, "linebytes", &sc->sc_stride, sizeof(sc->sc_stride));
  272 
  273         /*
  274          * Grab the physical address of the framebuffer, and then map it
  275          * into our memory space. If the MMU is not yet up, it will be
  276          * remapped for us when relocation turns on.
  277          *
  278          * XXX We assume #address-cells is 1 at this point.
  279          */
  280         OF_getprop(node, "address", &fb_phys, sizeof(fb_phys));
  281 
  282         bus_space_map(&bs_be_tag, fb_phys, sc->sc_height * sc->sc_stride,
  283             0, &sc->sc_addr);
  284 
  285         /*
  286          * Get the PCI addresses of the adapter. The node may be the
  287          * child of the PCI device: in that case, try the parent for
  288          * the assigned-addresses property.
  289          */
  290         len = OF_getprop(node, "assigned-addresses", sc->sc_pciaddrs,
  291                   sizeof(sc->sc_pciaddrs));
  292         if (len == -1) {
  293                 len = OF_getprop(OF_parent(node), "assigned-addresses",
  294                     sc->sc_pciaddrs, sizeof(sc->sc_pciaddrs));
  295         }
  296 
  297         if (len != -1) {
  298                 sc->sc_num_pciaddrs = len / sizeof(struct ofw_pci_register);
  299         }
  300 
  301         ofwfb_init(0, &sc->sc_va, 0);
  302 
  303         return (0);
  304 }
  305 
  306 static int
  307 ofwfb_probe(int unit, video_adapter_t **adp, void *arg, int flags)
  308 {
  309         TODO;
  310         return (0);
  311 }
  312 
  313 static int
  314 ofwfb_init(int unit, video_adapter_t *adp, int flags)
  315 {
  316         struct ofwfb_softc *sc;
  317         video_info_t *vi;
  318         int cborder;
  319         int font_height;
  320 
  321         sc = (struct ofwfb_softc *)adp;
  322         vi = &adp->va_info;
  323 
  324         vid_init_struct(adp, "ofwfb", -1, unit);
  325 
  326         /* The default font size can be overridden by loader */
  327         font_height = 16;
  328         TUNABLE_INT_FETCH("hw.syscons.fsize", &font_height);
  329         if (font_height == 8) {
  330                 sc->sc_font = dflt_font_8;
  331                 sc->sc_font_height = 8;
  332         } else if (font_height == 14) {
  333                 sc->sc_font = dflt_font_14;
  334                 sc->sc_font_height = 14;
  335         } else {
  336                 /* default is 8x16 */
  337                 sc->sc_font = dflt_font_16;
  338                 sc->sc_font_height = 16;
  339         }
  340 
  341         /* The user can set a border in chars - default is 1 char width */
  342         cborder = 1;
  343         TUNABLE_INT_FETCH("hw.syscons.border", &cborder);
  344 
  345         vi->vi_cheight = sc->sc_font_height;
  346         vi->vi_width = sc->sc_width/8 - 2*cborder;
  347         vi->vi_height = sc->sc_height/sc->sc_font_height - 2*cborder;
  348         vi->vi_cwidth = 8;
  349 
  350         /*
  351          * Clamp width/height to syscons maximums
  352          */
  353         if (vi->vi_width > COL)
  354                 vi->vi_width = COL;
  355         if (vi->vi_height > ROW)
  356                 vi->vi_height = ROW;
  357 
  358         sc->sc_xmargin = (sc->sc_width - (vi->vi_width * vi->vi_cwidth)) / 2;
  359         sc->sc_ymargin = (sc->sc_height - (vi->vi_height * vi->vi_cheight))/2;
  360 
  361         /*
  362          * Avoid huge amounts of conditional code in syscons by
  363          * defining a dummy h/w text display buffer.
  364          */
  365         adp->va_window = (vm_offset_t) ofwfb_static_window;
  366 
  367         /*
  368          * Enable future font-loading and flag color support, as well as 
  369          * adding V_ADP_MODECHANGE so that we ofwfb_set_mode() gets called
  370          * when the X server shuts down. This enables us to get the console
  371          * back when X disappears.
  372          */
  373         adp->va_flags |= V_ADP_FONT | V_ADP_COLOR | V_ADP_MODECHANGE;
  374 
  375         ofwfb_set_mode(&sc->sc_va, 0);
  376 
  377         vid_register(&sc->sc_va);
  378 
  379         return (0);
  380 }
  381 
  382 static int
  383 ofwfb_get_info(video_adapter_t *adp, int mode, video_info_t *info)
  384 {
  385         bcopy(&adp->va_info, info, sizeof(*info));
  386         return (0);
  387 }
  388 
  389 static int
  390 ofwfb_query_mode(video_adapter_t *adp, video_info_t *info)
  391 {
  392         TODO;
  393         return (0);
  394 }
  395 
  396 static int
  397 ofwfb_set_mode(video_adapter_t *adp, int mode)
  398 {
  399         struct ofwfb_softc *sc;
  400         char name[64];
  401         ihandle_t ih;
  402         int i, retval;
  403 
  404         sc = (struct ofwfb_softc *)adp;
  405 
  406         /*
  407          * Open the display device, which will initialize it.
  408          */
  409 
  410         memset(name, 0, sizeof(name));
  411         OF_package_to_path(sc->sc_node, name, sizeof(name));
  412         ih = OF_open(name);
  413 
  414         if (sc->sc_depth == 8) {
  415                 /*
  416                  * Install the ISO6429 colormap - older OFW systems
  417                  * don't do this by default
  418                  */
  419                 for (i = 0; i < 16; i++) {
  420                         OF_call_method("color!", ih, 4, 1,
  421                                        ofwfb_cmap[i].red,
  422                                        ofwfb_cmap[i].green,
  423                                        ofwfb_cmap[i].blue,
  424                                        i,
  425                                        &retval);
  426                 }
  427         }
  428 
  429         ofwfb_blank_display(&sc->sc_va, V_DISPLAY_ON);
  430 
  431         return (0);
  432 }
  433 
  434 static int
  435 ofwfb_save_font(video_adapter_t *adp, int page, int size, int width,
  436     u_char *data, int c, int count)
  437 {
  438         TODO;
  439         return (0);
  440 }
  441 
  442 static int
  443 ofwfb_load_font(video_adapter_t *adp, int page, int size, int width,
  444     u_char *data, int c, int count)
  445 {
  446         struct ofwfb_softc *sc;
  447 
  448         sc = (struct ofwfb_softc *)adp;
  449 
  450         /*
  451          * syscons code has already determined that current width/height
  452          * are unchanged for this new font
  453          */
  454         sc->sc_font = data;
  455         return (0);
  456 }
  457 
  458 static int
  459 ofwfb_show_font(video_adapter_t *adp, int page)
  460 {
  461 
  462         return (0);
  463 }
  464 
  465 static int
  466 ofwfb_save_palette(video_adapter_t *adp, u_char *palette)
  467 {
  468         /* TODO; */
  469         return (0);
  470 }
  471 
  472 static int
  473 ofwfb_load_palette(video_adapter_t *adp, u_char *palette)
  474 {
  475         /* TODO; */
  476         return (0);
  477 }
  478 
  479 static int
  480 ofwfb_set_border8(video_adapter_t *adp, int border)
  481 {
  482         struct ofwfb_softc *sc;
  483         int i, j;
  484         uint8_t *addr;
  485         uint8_t bground;
  486 
  487         sc = (struct ofwfb_softc *)adp;
  488 
  489         bground = ofwfb_background(border);
  490 
  491         /* Set top margin */
  492         addr = (uint8_t *) sc->sc_addr;
  493         for (i = 0; i < sc->sc_ymargin; i++) {
  494                 for (j = 0; j < sc->sc_width; j++) {
  495                         *(addr + j) = bground;
  496                 }
  497                 addr += sc->sc_stride;
  498         }
  499 
  500         /* bottom margin */
  501         addr = (uint8_t *) sc->sc_addr + (sc->sc_height - sc->sc_ymargin)*sc->sc_stride;
  502         for (i = 0; i < sc->sc_ymargin; i++) {
  503                 for (j = 0; j < sc->sc_width; j++) {
  504                         *(addr + j) = bground;
  505                 }
  506                 addr += sc->sc_stride;
  507         }
  508 
  509         /* remaining left and right borders */
  510         addr = (uint8_t *) sc->sc_addr + sc->sc_ymargin*sc->sc_stride;
  511         for (i = 0; i < sc->sc_height - 2*sc->sc_xmargin; i++) {
  512                 for (j = 0; j < sc->sc_xmargin; j++) {
  513                         *(addr + j) = bground;
  514                         *(addr + j + sc->sc_width - sc->sc_xmargin) = bground;
  515                 }
  516                 addr += sc->sc_stride;
  517         }
  518 
  519         return (0);
  520 }
  521 
  522 static int
  523 ofwfb_set_border32(video_adapter_t *adp, int border)
  524 {
  525         /* XXX Be lazy for now and blank entire screen */
  526         return (ofwfb_blank_display32(adp, border));
  527 }
  528 
  529 static int
  530 ofwfb_set_border(video_adapter_t *adp, int border)
  531 {
  532         struct ofwfb_softc *sc;
  533 
  534         sc = (struct ofwfb_softc *)adp;
  535 
  536         return ((*sc->sc_set_border)(adp, border));
  537 }
  538 
  539 static int
  540 ofwfb_save_state(video_adapter_t *adp, void *p, size_t size)
  541 {
  542         TODO;
  543         return (0);
  544 }
  545 
  546 static int
  547 ofwfb_load_state(video_adapter_t *adp, void *p)
  548 {
  549         TODO;
  550         return (0);
  551 }
  552 
  553 static int
  554 ofwfb_set_win_org(video_adapter_t *adp, off_t offset)
  555 {
  556         TODO;
  557         return (0);
  558 }
  559 
  560 static int
  561 ofwfb_read_hw_cursor(video_adapter_t *adp, int *col, int *row)
  562 {
  563         *col = 0;
  564         *row = 0;
  565 
  566         return (0);
  567 }
  568 
  569 static int
  570 ofwfb_set_hw_cursor(video_adapter_t *adp, int col, int row)
  571 {
  572 
  573         return (0);
  574 }
  575 
  576 static int
  577 ofwfb_set_hw_cursor_shape(video_adapter_t *adp, int base, int height,
  578     int celsize, int blink)
  579 {
  580         return (0);
  581 }
  582 
  583 static int
  584 ofwfb_blank_display8(video_adapter_t *adp, int mode)
  585 {
  586         struct ofwfb_softc *sc;
  587         int i;
  588         uint8_t *addr;
  589 
  590         sc = (struct ofwfb_softc *)adp;
  591         addr = (uint8_t *) sc->sc_addr;
  592 
  593         /* Could be done a lot faster e.g. 32-bits, or Altivec'd */
  594         for (i = 0; i < sc->sc_stride*sc->sc_height; i++)
  595                 *(addr + i) = ofwfb_background(SC_NORM_ATTR);
  596 
  597         return (0);
  598 }
  599 
  600 static int
  601 ofwfb_blank_display32(video_adapter_t *adp, int mode)
  602 {
  603         struct ofwfb_softc *sc;
  604         int i;
  605         uint32_t *addr;
  606 
  607         sc = (struct ofwfb_softc *)adp;
  608         addr = (uint32_t *) sc->sc_addr;
  609 
  610         for (i = 0; i < (sc->sc_stride/4)*sc->sc_height; i++)
  611                 *(addr + i) = ofwfb_pix32(ofwfb_background(SC_NORM_ATTR));
  612 
  613         return (0);
  614 }
  615 
  616 static int
  617 ofwfb_blank_display(video_adapter_t *adp, int mode)
  618 {
  619         struct ofwfb_softc *sc;
  620 
  621         sc = (struct ofwfb_softc *)adp;
  622 
  623         return ((*sc->sc_blank)(adp, mode));
  624 }
  625 
  626 static int
  627 ofwfb_mmap(video_adapter_t *adp, vm_offset_t offset, vm_paddr_t *paddr,
  628     int prot)
  629 {
  630         struct ofwfb_softc *sc;
  631         int i;
  632 
  633         sc = (struct ofwfb_softc *)adp;
  634 
  635         if (sc->sc_num_pciaddrs == 0)
  636                 return (ENOMEM);
  637 
  638         /*
  639          * Hack for Radeon...
  640          */
  641         if (ofwfb_ignore_mmap_checks) {
  642                 *paddr = offset;
  643                 return (0);
  644         }
  645 
  646         /*
  647          * Make sure the requested address lies within the PCI device's assigned addrs
  648          */
  649         for (i = 0; i < sc->sc_num_pciaddrs; i++)
  650                 if (offset >= sc->sc_pciaddrs[i].phys_lo &&
  651                     offset < (sc->sc_pciaddrs[i].phys_lo + sc->sc_pciaddrs[i].size_lo)) {
  652                         *paddr = offset;
  653                         return (0);
  654                 }
  655 
  656         /*
  657          * This might be a legacy VGA mem request: if so, just point it at the
  658          * framebuffer, since it shouldn't be touched
  659          */
  660         if (offset < sc->sc_stride*sc->sc_height) {
  661                 *paddr = sc->sc_addr + offset;
  662                 return (0);
  663         }
  664 
  665         return (EINVAL);
  666 }
  667 
  668 static int
  669 ofwfb_ioctl(video_adapter_t *adp, u_long cmd, caddr_t data)
  670 {
  671 
  672         return (0);
  673 }
  674 
  675 static int
  676 ofwfb_clear(video_adapter_t *adp)
  677 {
  678         TODO;
  679         return (0);
  680 }
  681 
  682 static int
  683 ofwfb_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy)
  684 {
  685         TODO;
  686         return (0);
  687 }
  688 
  689 static int
  690 ofwfb_bitblt(video_adapter_t *adp, ...)
  691 {
  692         TODO;
  693         return (0);
  694 }
  695 
  696 static int
  697 ofwfb_diag(video_adapter_t *adp, int level)
  698 {
  699         TODO;
  700         return (0);
  701 }
  702 
  703 static int
  704 ofwfb_save_cursor_palette(video_adapter_t *adp, u_char *palette)
  705 {
  706         TODO;
  707         return (0);
  708 }
  709 
  710 static int
  711 ofwfb_load_cursor_palette(video_adapter_t *adp, u_char *palette)
  712 {
  713         TODO;
  714         return (0);
  715 }
  716 
  717 static int
  718 ofwfb_copy(video_adapter_t *adp, vm_offset_t src, vm_offset_t dst, int n)
  719 {
  720         TODO;
  721         return (0);
  722 }
  723 
  724 static int
  725 ofwfb_putp(video_adapter_t *adp, vm_offset_t off, uint32_t p, uint32_t a,
  726     int size, int bpp, int bit_ltor, int byte_ltor)
  727 {
  728         TODO;
  729         return (0);
  730 }
  731 
  732 static int
  733 ofwfb_putc8(video_adapter_t *adp, vm_offset_t off, uint8_t c, uint8_t a)
  734 {
  735         struct ofwfb_softc *sc;
  736         int row;
  737         int col;
  738         int i;
  739         uint32_t *addr;
  740         u_char *p, fg, bg;
  741         union {
  742                 uint32_t l;
  743                 uint8_t  c[4];
  744         } ch1, ch2;
  745 
  746 
  747         sc = (struct ofwfb_softc *)adp;
  748         row = (off / adp->va_info.vi_width) * adp->va_info.vi_cheight;
  749         col = (off % adp->va_info.vi_width) * adp->va_info.vi_cwidth;
  750         p = sc->sc_font + c*sc->sc_font_height;
  751         addr = (u_int32_t *)((int)sc->sc_addr
  752                 + (row + sc->sc_ymargin)*sc->sc_stride
  753                 + col + sc->sc_xmargin);
  754 
  755         fg = ofwfb_foreground(a);
  756         bg = ofwfb_background(a);
  757 
  758         for (i = 0; i < sc->sc_font_height; i++) {
  759                 u_char fline = p[i];
  760 
  761                 /*
  762                  * Assume that there is more background than foreground
  763                  * in characters and init accordingly
  764                  */
  765                 ch1.l = ch2.l = (bg << 24) | (bg << 16) | (bg << 8) | bg;
  766 
  767                 /*
  768                  * Calculate 2 x 4-chars at a time, and then
  769                  * write these out.
  770                  */
  771                 if (fline & 0x80) ch1.c[0] = fg;
  772                 if (fline & 0x40) ch1.c[1] = fg;
  773                 if (fline & 0x20) ch1.c[2] = fg;
  774                 if (fline & 0x10) ch1.c[3] = fg;
  775 
  776                 if (fline & 0x08) ch2.c[0] = fg;
  777                 if (fline & 0x04) ch2.c[1] = fg;
  778                 if (fline & 0x02) ch2.c[2] = fg;
  779                 if (fline & 0x01) ch2.c[3] = fg;
  780 
  781                 addr[0] = ch1.l;
  782                 addr[1] = ch2.l;
  783                 addr += (sc->sc_stride / sizeof(u_int32_t));
  784         }
  785 
  786         return (0);
  787 }
  788 
  789 static int
  790 ofwfb_putc32(video_adapter_t *adp, vm_offset_t off, uint8_t c, uint8_t a)
  791 {
  792         struct ofwfb_softc *sc;
  793         int row;
  794         int col;
  795         int i, j, k;
  796         uint32_t *addr;
  797         u_char *p;
  798 
  799         sc = (struct ofwfb_softc *)adp;
  800         row = (off / adp->va_info.vi_width) * adp->va_info.vi_cheight;
  801         col = (off % adp->va_info.vi_width) * adp->va_info.vi_cwidth;
  802         p = sc->sc_font + c*sc->sc_font_height;
  803         addr = (uint32_t *)sc->sc_addr
  804                 + (row + sc->sc_ymargin)*(sc->sc_stride/4)
  805                 + col + sc->sc_xmargin;
  806 
  807         for (i = 0; i < sc->sc_font_height; i++) {
  808                 for (j = 0, k = 7; j < 8; j++, k--) {
  809                         if ((p[i] & (1 << k)) == 0)
  810                                 *(addr + j) = ofwfb_pix32(ofwfb_background(a));
  811                         else
  812                                 *(addr + j) = ofwfb_pix32(ofwfb_foreground(a));
  813                 }
  814                 addr += (sc->sc_stride/4);
  815         }
  816 
  817         return (0);
  818 }
  819 
  820 static int
  821 ofwfb_putc(video_adapter_t *adp, vm_offset_t off, uint8_t c, uint8_t a)
  822 {
  823         struct ofwfb_softc *sc;
  824 
  825         sc = (struct ofwfb_softc *)adp;
  826 
  827         return ((*sc->sc_putc)(adp, off, c, a));
  828 }
  829 
  830 static int
  831 ofwfb_puts(video_adapter_t *adp, vm_offset_t off, u_int16_t *s, int len)
  832 {
  833         int i;
  834 
  835         for (i = 0; i < len; i++) {
  836                 ofwfb_putc(adp, off + i, s[i] & 0xff, (s[i] & 0xff00) >> 8);
  837         }
  838         return (0);
  839 }
  840 
  841 static int
  842 ofwfb_putm(video_adapter_t *adp, int x, int y, uint8_t *pixel_image,
  843     uint32_t pixel_mask, int size, int width)
  844 {
  845         struct ofwfb_softc *sc;
  846 
  847         sc = (struct ofwfb_softc *)adp;
  848 
  849         return ((*sc->sc_putm)(adp, x, y, pixel_image, pixel_mask, size,
  850             width));
  851 }
  852 
  853 static int
  854 ofwfb_putm8(video_adapter_t *adp, int x, int y, uint8_t *pixel_image,
  855     uint32_t pixel_mask, int size, int width)
  856 {
  857         struct ofwfb_softc *sc;
  858         int i, j, k;
  859         uint8_t *addr;
  860         u_char fg, bg;
  861 
  862         sc = (struct ofwfb_softc *)adp;
  863         addr = (u_int8_t *)((int)sc->sc_addr
  864                 + (y + sc->sc_ymargin)*sc->sc_stride
  865                 + x + sc->sc_xmargin);
  866 
  867         fg = ofwfb_foreground(SC_NORM_ATTR);
  868         bg = ofwfb_background(SC_NORM_ATTR);
  869 
  870         for (i = 0; i < size && i+y < sc->sc_height - 2*sc->sc_ymargin; i++) {
  871                 /*
  872                  * Calculate 2 x 4-chars at a time, and then
  873                  * write these out.
  874                  */
  875                 for (j = 0, k = width; j < 8; j++, k--) {
  876                         if (x + j >= sc->sc_width - 2*sc->sc_xmargin)
  877                                 continue;
  878 
  879                         if (pixel_image[i] & (1 << k))
  880                                 addr[j] = (addr[j] == fg) ? bg : fg;
  881                 }
  882 
  883                 addr += (sc->sc_stride / sizeof(u_int8_t));
  884         }
  885 
  886         return (0);
  887 }
  888 
  889 static int
  890 ofwfb_putm32(video_adapter_t *adp, int x, int y, uint8_t *pixel_image,
  891     uint32_t pixel_mask, int size, int width)
  892 {
  893         struct ofwfb_softc *sc;
  894         int i, j, k;
  895         uint32_t fg, bg;
  896         uint32_t *addr;
  897 
  898         sc = (struct ofwfb_softc *)adp;
  899         addr = (uint32_t *)sc->sc_addr
  900                 + (y + sc->sc_ymargin)*(sc->sc_stride/4)
  901                 + x + sc->sc_xmargin;
  902 
  903         fg = ofwfb_pix32(ofwfb_foreground(SC_NORM_ATTR));
  904         bg = ofwfb_pix32(ofwfb_background(SC_NORM_ATTR));
  905 
  906         for (i = 0; i < size && i+y < sc->sc_height - 2*sc->sc_ymargin; i++) {
  907                 for (j = 0, k = width; j < 8; j++, k--) {
  908                         if (x + j >= sc->sc_width - 2*sc->sc_xmargin)
  909                                 continue;
  910 
  911                         if (pixel_image[i] & (1 << k))
  912                                 *(addr + j) = (*(addr + j) == fg) ? bg : fg;
  913                 }
  914                 addr += (sc->sc_stride/4);
  915         }
  916 
  917         return (0);
  918 }
  919 
  920 /*
  921  * Define the syscons nexus device attachment
  922  */
  923 static void
  924 ofwfb_scidentify(driver_t *driver, device_t parent)
  925 {
  926         device_t child;
  927 
  928         /*
  929          * Add with a priority guaranteed to make it last on
  930          * the device list
  931          */
  932         child = BUS_ADD_CHILD(parent, INT_MAX, SC_DRIVER_NAME, 0);
  933 }
  934 
  935 static int
  936 ofwfb_scprobe(device_t dev)
  937 {
  938         int error;
  939 
  940         device_set_desc(dev, "System console");
  941 
  942         error = sc_probe_unit(device_get_unit(dev), 
  943             device_get_flags(dev) | SC_AUTODETECT_KBD);
  944         if (error != 0)
  945                 return (error);
  946 
  947         /* This is a fake device, so make sure we added it ourselves */
  948         return (BUS_PROBE_NOWILDCARD);
  949 }
  950 
  951 static int
  952 ofwfb_scattach(device_t dev)
  953 {
  954         return (sc_attach_unit(device_get_unit(dev),
  955             device_get_flags(dev) | SC_AUTODETECT_KBD));
  956 }
  957 
  958 static device_method_t ofwfb_sc_methods[] = {
  959         DEVMETHOD(device_identify,      ofwfb_scidentify),
  960         DEVMETHOD(device_probe,         ofwfb_scprobe),
  961         DEVMETHOD(device_attach,        ofwfb_scattach),
  962         { 0, 0 }
  963 };
  964 
  965 static driver_t ofwfb_sc_driver = {
  966         SC_DRIVER_NAME,
  967         ofwfb_sc_methods,
  968         sizeof(sc_softc_t),
  969 };
  970 
  971 static devclass_t       sc_devclass;
  972 
  973 DRIVER_MODULE(sc, nexus, ofwfb_sc_driver, sc_devclass, 0, 0);
  974 
  975 /*
  976  * Define a stub keyboard driver in case one hasn't been
  977  * compiled into the kernel
  978  */
  979 #include <sys/kbio.h>
  980 #include <dev/kbd/kbdreg.h>
  981 
  982 static int dummy_kbd_configure(int flags);
  983 
  984 keyboard_switch_t dummysw;
  985 
  986 static int
  987 dummy_kbd_configure(int flags)
  988 {
  989 
  990         return (0);
  991 }
  992 KEYBOARD_DRIVER(dummy, dummysw, dummy_kbd_configure);
  993 
  994 /*
  995  * Utility routines from <dev/fb/fbreg.h>
  996  */
  997 void
  998 ofwfb_bcopy(const void *s, void *d, size_t c)
  999 {
 1000         bcopy(s, d, c);
 1001 }
 1002 
 1003 void
 1004 ofwfb_bzero(void *d, size_t c)
 1005 {
 1006         bzero(d, c);
 1007 }
 1008 
 1009 void
 1010 ofwfb_fillw(int pat, void *base, size_t cnt)
 1011 {
 1012         u_int16_t *bptr = base;
 1013 
 1014         while (cnt--)
 1015                 *bptr++ = pat;
 1016 }
 1017 
 1018 u_int16_t
 1019 ofwfb_readw(u_int16_t *addr)
 1020 {
 1021         return (*addr);
 1022 }
 1023 
 1024 void
 1025 ofwfb_writew(u_int16_t *addr, u_int16_t val)
 1026 {
 1027         *addr = val;
 1028 }

Cache object: 1df181c3f455a5d802b90b6f5af09909


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