Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 5 May 2014 21:48:19 +0000 (UTC)
From:      Aleksandr Rybalko <ray@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r265397 - in head/sys/dev/vt/hw: efifb fb
Message-ID:  <201405052148.s45LmJi6086278@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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_ */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201405052148.s45LmJi6086278>