Author: ray
Date: Mon May  5 21:48:19 2014
New Revision: 265397
URL: http://svnweb.freebsd.org/changeset/base/265397

Log:
  Switch fb and efifb drivers to use names and new vt(4) driver probe method.
  
  Sponsored by: The FreeBSD Foundation

Modified:
  head/sys/dev/vt/hw/efifb/efifb.c
  head/sys/dev/vt/hw/fb/vt_early_fb.c
  head/sys/dev/vt/hw/fb/vt_fb.c
  head/sys/dev/vt/hw/fb/vt_fb.h

Modified: head/sys/dev/vt/hw/efifb/efifb.c
==============================================================================
--- head/sys/dev/vt/hw/efifb/efifb.c    Mon May  5 21:46:10 2014        
(r265396)
+++ head/sys/dev/vt/hw/efifb/efifb.c    Mon May  5 21:48:19 2014        
(r265397)
@@ -51,36 +51,58 @@ __FBSDID("$FreeBSD$");
 #include <dev/vt/hw/fb/vt_fb.h>
 #include <dev/vt/colors/vt_termcolors.h>
 
-static vd_init_t vt_efb_init;
+static vd_init_t vt_efifb_init;
+static vd_probe_t vt_efifb_probe;
 
-static struct vt_driver vt_efb_driver = {
-       .vd_init = vt_efb_init,
+static struct vt_driver vt_efifb_driver = {
+       .vd_name = "efifb",
+       .vd_probe = vt_efifb_probe,
+       .vd_init = vt_efifb_init,
        .vd_blank = vt_fb_blank,
        .vd_bitbltchr = vt_fb_bitbltchr,
+       .vd_maskbitbltchr = vt_fb_maskbitbltchr,
        /* Better than VGA, but still generic driver. */
        .vd_priority = VD_PRIORITY_GENERIC + 1,
 };
 
-static struct fb_info info;
-VT_CONSDEV_DECLARE(vt_efb_driver,
-    MAX(80, PIXEL_WIDTH(VT_FB_DEFAULT_WIDTH)),
-    MAX(25, PIXEL_HEIGHT(VT_FB_DEFAULT_HEIGHT)), &info);
+static struct fb_info local_info;
+VT_DRIVER_DECLARE(vt_efifb, vt_efifb_driver);
 
 static int
-vt_efb_init(struct vt_device *vd)
+vt_efifb_probe(struct vt_device *vd)
 {
-       int             depth, d, disable, i, len;
-       struct fb_info  *info;
+       int             disabled;
        struct efi_fb   *efifb;
        caddr_t         kmdp;
 
-       info = vd->vd_softc;
+       disabled = 0;
+       TUNABLE_INT_FETCH("hw.syscons.disable", &disabled);
+       if (disabled != 0)
+               return (CN_DEAD);
 
-       disable = 0;
-       TUNABLE_INT_FETCH("hw.syscons.disable", &disable);
-       if (disable != 0)
+       kmdp = preload_search_by_type("elf kernel");
+       if (kmdp == NULL)
+               kmdp = preload_search_by_type("elf64 kernel");
+       efifb = (struct efi_fb *)preload_search_info(kmdp,
+           MODINFO_METADATA | MODINFOMD_EFI_FB);
+       if (efifb == NULL)
                return (CN_DEAD);
 
+       return (CN_INTERNAL);
+}
+
+static int
+vt_efifb_init(struct vt_device *vd)
+{
+       int             depth, d, i, len;
+       struct fb_info  *info;
+       struct efi_fb   *efifb;
+       caddr_t         kmdp;
+
+       info = vd->vd_softc;
+       if (info == NULL)
+               info = vd->vd_softc = (void *)&local_info;
+
        kmdp = preload_search_by_type("elf kernel");
        if (kmdp == NULL)
                kmdp = preload_search_by_type("elf64 kernel");
@@ -136,7 +158,8 @@ vt_efb_init(struct vt_device *vd)
        fb_probe(info);
        vt_fb_init(vd);
 
+       /* Clear the screen. */
+       vt_fb_blank(vd, TC_BLACK);
 
        return (CN_INTERNAL);
 }
-

Modified: head/sys/dev/vt/hw/fb/vt_early_fb.c
==============================================================================
--- head/sys/dev/vt/hw/fb/vt_early_fb.c Mon May  5 21:46:10 2014        
(r265396)
+++ head/sys/dev/vt/hw/fb/vt_early_fb.c Mon May  5 21:48:19 2014        
(r265397)
@@ -52,18 +52,19 @@ __FBSDID("$FreeBSD$");
 #include <dev/vt/colors/vt_termcolors.h>
 
 static vd_init_t vt_efb_init;
+static vd_probe_t vt_efb_probe;
 
 static struct vt_driver vt_fb_early_driver = {
+       .vd_name = "efb",
+       .vd_probe = vt_efb_probe,
        .vd_init = vt_efb_init,
        .vd_blank = vt_fb_blank,
        .vd_bitbltchr = vt_fb_bitbltchr,
        .vd_priority = VD_PRIORITY_GENERIC,
 };
 
-static struct fb_info info;
-VT_CONSDEV_DECLARE(vt_fb_early_driver,
-    MAX(80, PIXEL_WIDTH(VT_FB_DEFAULT_WIDTH)),
-    MAX(25, PIXEL_HEIGHT(VT_FB_DEFAULT_HEIGHT)), &info);
+static struct fb_info local_info;
+VT_DRIVER_DECLARE(vt_efb, vt_fb_early_driver);
 
 static void
 #ifdef FDT
@@ -126,30 +127,62 @@ vt_efb_initialize(struct fb_info *info)
         }
 }
 
-static int
-vt_efb_init(struct vt_device *vd)
+static phandle_t
+vt_efb_get_fbnode()
 {
-       struct ofw_pci_register pciaddrs[8];
-       struct fb_info *info;
-       int i, len, n_pciaddrs;
        phandle_t chosen, node;
        ihandle_t stdout;
        char type[64];
 
-       info = vd->vd_softc;
-
        chosen = OF_finddevice("/chosen");
        OF_getprop(chosen, "stdout", &stdout, sizeof(stdout));
        node = OF_instance_to_package(stdout);
-       if (node == -1) {
-               /*
-                * The "/chosen/stdout" does not exist try
-                * using "screen" directly.
-                */
-               node = OF_finddevice("screen");
+       if (node != -1) {
+               /* The "/chosen/stdout" present. */
+               OF_getprop(node, "device_type", type, sizeof(type));
+               /* Check if it has "display" type. */
+               if (strcmp(type, "display") == 0)
+                       return (node);
        }
-       OF_getprop(node, "device_type", type, sizeof(type));
-       if (strcmp(type, "display") != 0)
+       /* Try device with name "screen". */
+       node = OF_finddevice("screen");
+
+       return (node);
+}
+
+static int
+vt_efb_probe(struct vt_device *vd)
+{
+       phandle_t node;
+
+       node = vt_efb_get_fbnode();
+       if (node == -1)
+               return (CN_DEAD);
+
+       if ((OF_getproplen(node, "height") <= 0) ||
+           (OF_getproplen(node, "width") <= 0) ||
+           (OF_getproplen(node, "depth") <= 0) ||
+           (OF_getproplen(node, "linebytes") <= 0))
+               return (CN_DEAD);
+
+       return (CN_INTERNAL);
+}
+
+static int
+vt_efb_init(struct vt_device *vd)
+{
+       struct ofw_pci_register pciaddrs[8];
+       struct fb_info *info;
+       int i, len, n_pciaddrs;
+       phandle_t node;
+
+       if (vd->vd_softc == NULL)
+               vd->vd_softc = (void *)&local_info;
+
+       info = vd->vd_softc;
+
+       node = vt_efb_get_fbnode();
+       if (node == -1)
                return (CN_DEAD);
 
 #define        GET(name, var)                                                  
\
@@ -249,7 +282,6 @@ vt_efb_init(struct vt_device *vd)
        #endif
         }
 
-
        /* blank full size */
        len = info->fb_size / 4;
        for (i = 0; i < len; i++) {
@@ -274,6 +306,5 @@ vt_efb_init(struct vt_device *vd)
        fb_probe(info);
        vt_fb_init(vd);
 
-
        return (CN_INTERNAL);
 }

Modified: head/sys/dev/vt/hw/fb/vt_fb.c
==============================================================================
--- head/sys/dev/vt/hw/fb/vt_fb.c       Mon May  5 21:46:10 2014        
(r265396)
+++ head/sys/dev/vt/hw/fb/vt_fb.c       Mon May  5 21:48:19 2014        
(r265397)
@@ -50,9 +50,11 @@ void vt_fb_drawrect(struct vt_device *vd
 void vt_fb_setpixel(struct vt_device *vd, int x, int y, term_color_t color);
 
 static struct vt_driver vt_fb_driver = {
+       .vd_name = "fb",
        .vd_init = vt_fb_init,
        .vd_blank = vt_fb_blank,
        .vd_bitbltchr = vt_fb_bitbltchr,
+       .vd_maskbitbltchr = vt_fb_maskbitbltchr,
        .vd_drawrect = vt_fb_drawrect,
        .vd_setpixel = vt_fb_setpixel,
        .vd_postswitch = vt_fb_postswitch,
@@ -61,6 +63,8 @@ static struct vt_driver vt_fb_driver = {
        .vd_fb_mmap = vt_fb_mmap,
 };
 
+VT_DRIVER_DECLARE(vt_fb, vt_fb_driver);
+
 static int
 vt_fb_ioctl(struct vt_device *vd, u_long cmd, caddr_t data, struct thread *td)
 {
@@ -189,6 +193,68 @@ vt_fb_bitbltchr(struct vt_device *vd, co
        uint32_t fgc, bgc, cc, o;
        int c, l, bpp;
        u_long line;
+       uint8_t b;
+       const uint8_t *ch;
+
+       info = vd->vd_softc;
+       bpp = FBTYPE_GET_BYTESPP(info);
+       fgc = info->fb_cmap[fg];
+       bgc = info->fb_cmap[bg];
+       b = 0;
+       if (bpl == 0)
+               bpl = (width + 7) >> 3; /* Bytes per sorce line. */
+
+       /* Don't try to put off screen pixels */
+       if (((left + width) > info->fb_width) || ((top + height) >
+           info->fb_height))
+               return;
+
+       line = (info->fb_stride * top) + (left * bpp);
+       for (l = 0; l < height; l++) {
+               ch = src;
+               for (c = 0; c < width; c++) {
+                       if (c % 8 == 0)
+                               b = *ch++;
+                       else
+                               b <<= 1;
+                       o = line + (c * bpp);
+                       cc = b & 0x80 ? fgc : bgc;
+
+                       switch(bpp) {
+                       case 1:
+                               info->wr1(info, o, cc);
+                               break;
+                       case 2:
+                               info->wr2(info, o, cc);
+                               break;
+                       case 3:
+                               /* Packed mode, so unaligned. Byte access. */
+                               info->wr1(info, o, (cc >> 16) & 0xff);
+                               info->wr1(info, o + 1, (cc >> 8) & 0xff);
+                               info->wr1(info, o + 2, cc & 0xff);
+                               break;
+                       case 4:
+                               info->wr4(info, o, cc);
+                               break;
+                       default:
+                               /* panic? */
+                               break;
+                       }
+               }
+               line += info->fb_stride;
+               src += bpl;
+       }
+}
+
+void
+vt_fb_maskbitbltchr(struct vt_device *vd, const uint8_t *src, const uint8_t 
*mask,
+    int bpl, vt_axis_t top, vt_axis_t left, unsigned int width,
+    unsigned int height, term_color_t fg, term_color_t bg)
+{
+       struct fb_info *info;
+       uint32_t fgc, bgc, cc, o;
+       int c, l, bpp;
+       u_long line;
        uint8_t b, m;
        const uint8_t *ch;
 

Modified: head/sys/dev/vt/hw/fb/vt_fb.h
==============================================================================
--- head/sys/dev/vt/hw/fb/vt_fb.h       Mon May  5 21:46:10 2014        
(r265396)
+++ head/sys/dev/vt/hw/fb/vt_fb.h       Mon May  5 21:48:19 2014        
(r265397)
@@ -41,7 +41,7 @@ int fb_probe(struct fb_info *info);
 vd_init_t      vt_fb_init;
 vd_blank_t     vt_fb_blank;
 vd_bitbltchr_t vt_fb_bitbltchr;
+vd_maskbitbltchr_t vt_fb_maskbitbltchr;
 vd_postswitch_t        vt_fb_postswitch;
 
-
 #endif /* _DEV_VT_HW_FB_VT_FB_H_ */
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to