Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 16 Jun 2014 11:26:30 +0000 (UTC)
From:      Aleksandr Rybalko <ray@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r267538 - in stable/10/sys/dev/vt: . hw/efifb hw/fb hw/ofwfb hw/vga hw/xboxfb
Message-ID:  <201406161126.s5GBQUxv048470@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ray
Date: Mon Jun 16 11:26:30 2014
New Revision: 267538
URL: http://svnweb.freebsd.org/changeset/base/267538

Log:
  MFC 262785 263183 264182 264999 265391 265392 265395 265397 265398 265402 265403
      265442 265546 265680 265681 265719 265862 265864 265867 265927 266010 266495
      266540 266835 266856 266861 266862 267007 267310.
  
  265391
    Define a new method for probing vt(4) driver before attach it at early stage.
  265392
    Create dataset for vt(4) drivers.
  265395
    Set of updates to vt(4) core part.
    o Declare vt(4) drivers dataset.
    o Create single static structures for all early drivers.
    o Add vt(4) to be by default in the kernel consoles list.
    o Create one more sysinit point, to be able to initialize memory and lock
    	requirement of early drivers.
    o Implement early drivers select. (Only best available will be selected).
    o Fix one missed "return (0)" for VTYLOCK.
    o Improve locking for cases when one driver replace another.
    o Make driver replacement notification less debug-look-like.
    o Minor spell fixes.
  265397
    Switch fb and efifb drivers to use names and new vt(4) driver probe method.
  265398
    Add vt(4) driver name for ofwfb driver.
  265402
    Revert r264997 and r265026. It is not required anymore.
  265403
    Switch vga drivers to use names and new vt(4) driver probe method.
  265442
    Implement KDMKTONE ioctl.
  265546
    Fix possible divide by zero.
  265680
    No need to assign fields required and checked on probe.
  265681
    Fix scrollback.
  265719
    Hide debug messages under VT_DEBUG.
  265927
    Update terminal sizes in any case when new vt(4) driver arrive.
    (Plus remove one unused newline)
  266010
    Remove extra newlines.
    No functional changes.
  266495
    Fix tty locking.
    o Correct expected values for VT_LOCKSWITCH ioctl.
    o Check current window for locked state.
  266540
    Proper fix of VT_LOCKSWITCH ioctl.
  266835
    Remove driver as unused.
  267007
    Fix case when vt(4) started w/o driver assigned.
    o Always init locks and cv ASAP.
    o Initialize driver-independent parts even if driver probing fail.
    o Allow to call vt_upgrade anytime, for later loaded drivers.
    o New window flag VWF_READY, to track if window already initialized.
    Other updates:
    o Pass vd as a cookie for kbd_allocate.
    o Do not blank window on driver replacement.
  
  Sponsored by:	The FreeBSD Foundation

Added:
  stable/10/sys/dev/vt/hw/efifb/
     - copied from r262785, head/sys/dev/vt/hw/efifb/
Deleted:
  stable/10/sys/dev/vt/hw/xboxfb/
Modified:
  stable/10/sys/dev/vt/hw/efifb/efifb.c
  stable/10/sys/dev/vt/hw/fb/vt_early_fb.c
  stable/10/sys/dev/vt/hw/fb/vt_fb.c
  stable/10/sys/dev/vt/hw/fb/vt_fb.h
  stable/10/sys/dev/vt/hw/ofwfb/ofwfb.c
  stable/10/sys/dev/vt/hw/vga/vga.c
  stable/10/sys/dev/vt/vt.h
  stable/10/sys/dev/vt/vt_buf.c
  stable/10/sys/dev/vt/vt_consolectl.c
  stable/10/sys/dev/vt/vt_core.c
  stable/10/sys/dev/vt/vt_sysmouse.c

Modified: stable/10/sys/dev/vt/hw/efifb/efifb.c
==============================================================================
--- head/sys/dev/vt/hw/efifb/efifb.c	Wed Mar  5 14:37:45 2014	(r262785)
+++ stable/10/sys/dev/vt/hw/efifb/efifb.c	Mon Jun 16 11:26:30 2014	(r267538)
@@ -52,42 +52,64 @@ __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");
         efifb = (struct efi_fb *)preload_search_info(kmdp,
             MODINFO_METADATA | MODINFOMD_EFI_FB);
-        if (!efifb->fb_present)
+	if (efifb == NULL)
 		return (CN_DEAD);
 
 	info->fb_height = efifb->fb_height;
@@ -137,7 +159,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: stable/10/sys/dev/vt/hw/fb/vt_early_fb.c
==============================================================================
--- stable/10/sys/dev/vt/hw/fb/vt_early_fb.c	Mon Jun 16 11:00:14 2014	(r267537)
+++ stable/10/sys/dev/vt/hw/fb/vt_early_fb.c	Mon Jun 16 11:26:30 2014	(r267538)
@@ -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++) {
@@ -259,13 +291,6 @@ vt_efb_init(struct vt_device *vd)
 	/* Get pixel storage size. */
 	info->fb_bpp = info->fb_stride / info->fb_width * 8;
 
-	/*
-	 * Early FB driver work with static window buffer 80x25, so reduce
-	 * size to 640x480.
-	 */
-	info->fb_width = VT_FB_DEFAULT_WIDTH;
-	info->fb_height = VT_FB_DEFAULT_HEIGHT;
-
 #ifdef	FDT
 	vt_efb_initialize(info, node);
 #else
@@ -274,6 +299,5 @@ vt_efb_init(struct vt_device *vd)
 	fb_probe(info);
 	vt_fb_init(vd);
 
-
 	return (CN_INTERNAL);
 }

Modified: stable/10/sys/dev/vt/hw/fb/vt_fb.c
==============================================================================
--- stable/10/sys/dev/vt/hw/fb/vt_fb.c	Mon Jun 16 11:00:14 2014	(r267537)
+++ stable/10/sys/dev/vt/hw/fb/vt_fb.c	Mon Jun 16 11:26:30 2014	(r267538)
@@ -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: stable/10/sys/dev/vt/hw/fb/vt_fb.h
==============================================================================
--- stable/10/sys/dev/vt/hw/fb/vt_fb.h	Mon Jun 16 11:00:14 2014	(r267537)
+++ stable/10/sys/dev/vt/hw/fb/vt_fb.h	Mon Jun 16 11:26:30 2014	(r267538)
@@ -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_ */

Modified: stable/10/sys/dev/vt/hw/ofwfb/ofwfb.c
==============================================================================
--- stable/10/sys/dev/vt/hw/ofwfb/ofwfb.c	Mon Jun 16 11:00:14 2014	(r267537)
+++ stable/10/sys/dev/vt/hw/ofwfb/ofwfb.c	Mon Jun 16 11:26:30 2014	(r267538)
@@ -49,6 +49,10 @@ __FBSDID("$FreeBSD$");
 struct ofwfb_softc {
 	phandle_t	sc_node;
 
+	struct ofw_pci_register sc_pciaddrs[8];
+	int		sc_num_pciaddrs;
+
+
 	intptr_t	sc_addr;
 	int		sc_depth;
 	int		sc_stride;
@@ -58,21 +62,50 @@ struct ofwfb_softc {
 	uint32_t	sc_colormap[16];
 };
 
+static vd_probe_t	ofwfb_probe;
 static vd_init_t	ofwfb_init;
 static vd_blank_t	ofwfb_blank;
 static vd_bitbltchr_t	ofwfb_bitbltchr;
+static vd_fb_mmap_t	ofwfb_mmap;
 
 static const struct vt_driver vt_ofwfb_driver = {
+	.vd_name	= "ofwfb",
+	.vd_probe	= ofwfb_probe,
 	.vd_init	= ofwfb_init,
 	.vd_blank	= ofwfb_blank,
 	.vd_bitbltchr	= ofwfb_bitbltchr,
+	.vd_maskbitbltchr = ofwfb_bitbltchr,
+	.vd_fb_mmap	= ofwfb_mmap,
 	.vd_priority	= VD_PRIORITY_GENERIC+1,
 };
 
 static struct ofwfb_softc ofwfb_conssoftc;
-VT_CONSDEV_DECLARE(vt_ofwfb_driver, PIXEL_WIDTH(1920), PIXEL_HEIGHT(1200),
-    &ofwfb_conssoftc);
-/* XXX: hardcoded max size */
+VT_DRIVER_DECLARE(vt_ofwfb, vt_ofwfb_driver);
+
+static int
+ofwfb_probe(struct vt_device *vd)
+{
+	phandle_t chosen, node;
+	ihandle_t stdout;
+	char type[64];
+
+	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");
+	}
+	OF_getprop(node, "device_type", type, sizeof(type));
+	if (strcmp(type, "display") != 0)
+		return (CN_DEAD);
+
+	/* Looks OK... */
+	return (CN_INTERNAL);
+}
 
 static void
 ofwfb_blank(struct vt_device *vd, term_color_t color)
@@ -109,6 +142,10 @@ ofwfb_bitbltchr(struct vt_device *vd, co
 	uint32_t fgc, bgc;
 	int c;
 	uint8_t b, m;
+	union {
+		uint32_t l;
+		uint8_t	 c[4];
+	} ch1, ch2;
 
 	fgc = sc->sc_colormap[fg];
 	bgc = sc->sc_colormap[bg];
@@ -120,36 +157,70 @@ ofwfb_bitbltchr(struct vt_device *vd, co
 		return;
 
 	line = (sc->sc_stride * top) + left * sc->sc_depth/8;
-	for (; height > 0; height--) {
-		for (c = 0; c < width; c++) {
-			if (c % 8 == 0)
+	if (mask == NULL && sc->sc_depth == 8 && (width % 8 == 0)) {
+		for (; height > 0; height--) {
+			for (c = 0; c < width; c += 8) {
 				b = *src++;
-			else
-				b <<= 1;
-			if (mask != NULL) {
+
+				/*
+				 * Assume that there is more background than
+				 * foreground in characters and init accordingly
+				 */
+				ch1.l = ch2.l = (bg << 24) | (bg << 16) |
+				    (bg << 8) | bg;
+
+				/*
+				 * Calculate 2 x 4-chars at a time, and then
+				 * write these out.
+				 */
+				if (b & 0x80) ch1.c[0] = fg;
+				if (b & 0x40) ch1.c[1] = fg;
+				if (b & 0x20) ch1.c[2] = fg;
+				if (b & 0x10) ch1.c[3] = fg;
+
+				if (b & 0x08) ch2.c[0] = fg;
+				if (b & 0x04) ch2.c[1] = fg;
+				if (b & 0x02) ch2.c[2] = fg;
+				if (b & 0x01) ch2.c[3] = fg;
+
+				*(uint32_t *)(sc->sc_addr + line + c) = ch1.l;
+				*(uint32_t *)(sc->sc_addr + line + c + 4) =
+				    ch2.l;
+			}
+			line += sc->sc_stride;
+		}
+	} else {
+		for (; height > 0; height--) {
+			for (c = 0; c < width; c++) {
 				if (c % 8 == 0)
-					m = *mask++;
+					b = *src++;
 				else
-					m <<= 1;
-				/* Skip pixel write, if mask has no bit set. */
-				if ((m & 0x80) == 0)
-					continue;
-			}
-			switch(sc->sc_depth) {
-			case 8:
-				*(uint8_t *)(sc->sc_addr + line + c) =
-				    b & 0x80 ? fg : bg;
-				break;
-			case 32:
-				*(uint32_t *)(sc->sc_addr + line + 4*c) = 
-				    (b & 0x80) ? fgc : bgc;
-				break;
-			default:
-				/* panic? */
-				break;
+					b <<= 1;
+				if (mask != NULL) {
+					if (c % 8 == 0)
+						m = *mask++;
+					else
+						m <<= 1;
+					/* Skip pixel write, if mask not set. */
+					if ((m & 0x80) == 0)
+						continue;
+				}
+				switch(sc->sc_depth) {
+				case 8:
+					*(uint8_t *)(sc->sc_addr + line + c) =
+					    b & 0x80 ? fg : bg;
+					break;
+				case 32:
+					*(uint32_t *)(sc->sc_addr + line + 4*c)
+					    = (b & 0x80) ? fgc : bgc;
+					break;
+				default:
+					/* panic? */
+					break;
+				}
 			}
+			line += sc->sc_stride;
 		}
-		line += sc->sc_stride;
 	}
 }
 
@@ -217,14 +288,12 @@ ofwfb_initialize(struct vt_device *vd)
 static int
 ofwfb_init(struct vt_device *vd)
 {
-	struct ofwfb_softc *sc = vd->vd_softc;
+	struct ofwfb_softc *sc;
 	char type[64];
 	phandle_t chosen;
 	ihandle_t stdout;
 	phandle_t node;
 	uint32_t depth, height, width;
-	struct ofw_pci_register pciaddrs[8];
-	int n_pciaddrs;
 	uint32_t fb_phys;
 	int i, len;
 #ifdef __sparc64__
@@ -233,6 +302,9 @@ ofwfb_init(struct vt_device *vd)
 	int space;
 #endif
 
+	/* Initialize softc */
+	vd->vd_softc = sc = &ofwfb_conssoftc;
+
 	chosen = OF_finddevice("/chosen");
 	OF_getprop(chosen, "stdout", &stdout, sizeof(stdout));
 	node = OF_instance_to_package(stdout);
@@ -275,15 +347,15 @@ ofwfb_init(struct vt_device *vd)
 	 * child of the PCI device: in that case, try the parent for
 	 * the assigned-addresses property.
 	 */
-	len = OF_getprop(node, "assigned-addresses", pciaddrs,
-	    sizeof(pciaddrs));
+	len = OF_getprop(node, "assigned-addresses", sc->sc_pciaddrs,
+	    sizeof(sc->sc_pciaddrs));
 	if (len == -1) {
 		len = OF_getprop(OF_parent(node), "assigned-addresses",
-		    pciaddrs, sizeof(pciaddrs));
+		    sc->sc_pciaddrs, sizeof(sc->sc_pciaddrs));
         }
         if (len == -1)
                 len = 0;
-	n_pciaddrs = len / sizeof(struct ofw_pci_register);
+	sc->sc_num_pciaddrs = len / sizeof(struct ofw_pci_register);
 
 	/*
 	 * Grab the physical address of the framebuffer, and then map it
@@ -313,13 +385,13 @@ ofwfb_init(struct vt_device *vd)
 		 * Linux does the same thing.
 		 */
 
-		fb_phys = n_pciaddrs;
-		for (i = 0; i < n_pciaddrs; i++) {
+		fb_phys = sc->sc_num_pciaddrs;
+		for (i = 0; i < sc->sc_num_pciaddrs; i++) {
 			/* If it is too small, not the framebuffer */
-			if (pciaddrs[i].size_lo < sc->sc_stride*height)
+			if (sc->sc_pciaddrs[i].size_lo < sc->sc_stride*height)
 				continue;
 			/* If it is not memory, it isn't either */
-			if (!(pciaddrs[i].phys_hi &
+			if (!(sc->sc_pciaddrs[i].phys_hi &
 			    OFW_PCI_PHYS_HI_SPACE_MEM32))
 				continue;
 
@@ -327,11 +399,12 @@ ofwfb_init(struct vt_device *vd)
 			fb_phys = i;
 
 			/* If it is prefetchable, it certainly is */
-			if (pciaddrs[i].phys_hi & OFW_PCI_PHYS_HI_PREFETCHABLE)
+			if (sc->sc_pciaddrs[i].phys_hi &
+			    OFW_PCI_PHYS_HI_PREFETCHABLE)
 				break;
 		}
 
-		if (fb_phys == n_pciaddrs) /* No candidates found */
+		if (fb_phys == sc->sc_num_pciaddrs) /* No candidates found */
 			return (CN_DEAD);
 
 	#if defined(__powerpc__)
@@ -348,3 +421,37 @@ ofwfb_init(struct vt_device *vd)
 	return (CN_INTERNAL);
 }
 
+static int
+ofwfb_mmap(struct vt_device *vd, vm_ooffset_t offset, vm_paddr_t *paddr,
+    int prot, vm_memattr_t *memattr)
+{
+	struct ofwfb_softc *sc = vd->vd_softc;
+        int i;
+
+	/*
+	 * Make sure the requested address lies within the PCI device's
+	 * assigned addrs
+	 */
+	for (i = 0; i < sc->sc_num_pciaddrs; i++)
+	  if (offset >= sc->sc_pciaddrs[i].phys_lo &&
+	    offset < (sc->sc_pciaddrs[i].phys_lo + sc->sc_pciaddrs[i].size_lo))
+		{
+			/*
+			 * If this is a prefetchable BAR, we can (and should)
+			 * enable write-combining.
+			 */
+			if (sc->sc_pciaddrs[i].phys_hi &
+			    OFW_PCI_PHYS_HI_PREFETCHABLE)
+				*memattr = VM_MEMATTR_WRITE_COMBINING;
+
+			*paddr = offset;
+			return (0);
+		}
+
+        /*
+         * Hack for Radeon...
+         */
+	*paddr = offset;
+	return (0);
+}
+

Modified: stable/10/sys/dev/vt/hw/vga/vga.c
==============================================================================
--- stable/10/sys/dev/vt/hw/vga/vga.c	Mon Jun 16 11:00:14 2014	(r267537)
+++ stable/10/sys/dev/vt/hw/vga/vga.c	Mon Jun 16 11:26:30 2014	(r267538)
@@ -71,6 +71,7 @@ struct vga_softc {
 #define	VT_VGA_HEIGHT	480
 #define	VT_VGA_MEMSIZE	(VT_VGA_WIDTH * VT_VGA_HEIGHT / 8)
 
+static vd_probe_t	vga_probe;
 static vd_init_t	vga_init;
 static vd_blank_t	vga_blank;
 static vd_bitbltchr_t	vga_bitbltchr;
@@ -81,6 +82,8 @@ static vd_putchar_t	vga_putchar;
 static vd_postswitch_t	vga_postswitch;
 
 static const struct vt_driver vt_vga_driver = {
+	.vd_name	= "vga",
+	.vd_probe	= vga_probe,
 	.vd_init	= vga_init,
 	.vd_blank	= vga_blank,
 	.vd_bitbltchr	= vga_bitbltchr,
@@ -97,8 +100,7 @@ static const struct vt_driver vt_vga_dri
  * buffer is always big enough to support both.
  */
 static struct vga_softc vga_conssoftc;
-VT_CONSDEV_DECLARE(vt_vga_driver, MAX(80, PIXEL_WIDTH(VT_VGA_WIDTH)),
-    MAX(25, PIXEL_HEIGHT(VT_VGA_HEIGHT)), &vga_conssoftc);
+VT_DRIVER_DECLARE(vt_vga, vt_vga_driver);
 
 static inline void
 vga_setcolor(struct vt_device *vd, term_color_t color)
@@ -349,7 +351,8 @@ static const struct unicp437 cp437table[
 	{ 0x263a, 0x01, 0x01 }, { 0x263c, 0x0f, 0x00 },
 	{ 0x2640, 0x0c, 0x00 }, { 0x2642, 0x0b, 0x00 },
 	{ 0x2660, 0x06, 0x00 }, { 0x2663, 0x05, 0x00 },
-	{ 0x2665, 0x03, 0x01 }, { 0x266a, 0x0d, 0x01 },
+	{ 0x2665, 0x03, 0x01 }, { 0x266a, 0x0d, 0x00 },
+	{ 0x266c, 0x0e, 0x00 },
 };
 
 static uint8_t
@@ -631,10 +634,22 @@ vga_initialize(struct vt_device *vd, int
 }
 
 static int
+vga_probe(struct vt_device *vd)
+{
+
+	return (CN_INTERNAL);
+}
+
+static int
 vga_init(struct vt_device *vd)
 {
-	struct vga_softc *sc = vd->vd_softc;
-	int textmode = 0;
+	struct vga_softc *sc;
+	int textmode;
+
+	if (vd->vd_softc == NULL)
+		vd->vd_softc = (void *)&vga_conssoftc;
+	sc = vd->vd_softc;
+	textmode = 0;
 
 #if defined(__amd64__) || defined(__i386__)
 	sc->vga_fb_tag = X86_BUS_SPACE_MEM;

Modified: stable/10/sys/dev/vt/vt.h
==============================================================================
--- stable/10/sys/dev/vt/vt.h	Mon Jun 16 11:00:14 2014	(r267537)
+++ stable/10/sys/dev/vt/vt.h	Mon Jun 16 11:26:30 2014	(r267538)
@@ -78,7 +78,13 @@ one 'device sc' or 'device vt'"
 #endif /* defined(SC_TWOBUTTON_MOUSE) || defined(VT_TWOBUTTON_MOUSE) */
 
 #define	SC_DRIVER_NAME	"vt"
+#ifdef VT_DEBUG
 #define	DPRINTF(_l, ...)	if (vt_debug > (_l)) printf( __VA_ARGS__ )
+#define VT_CONSOLECTL_DEBUG
+#define VT_SYSMOUSE_DEBUG
+#else
+#define	DPRINTF(_l, ...)	do {} while (0)
+#endif
 #define	ISSIGVALID(sig)	((sig) > 0 && (sig) < NSIG)
 
 #define	VT_SYSCTL_INT(_name, _default, _descr)				\
@@ -253,6 +259,7 @@ struct vt_window {
 #define	VWF_CONSOLE	0x8	/* Kernel message console window. */
 #define	VWF_VTYLOCK	0x10	/* Prevent window switch. */
 #define	VWF_MOUSE_HIDE	0x20	/* Disable mouse events processing. */
+#define	VWF_READY	0x40	/* Window fully initialized. */
 #define	VWF_SWWAIT_REL	0x10000	/* Program wait for VT acquire is done. */
 #define	VWF_SWWAIT_ACQ	0x20000	/* Program wait for VT release is done. */
 	pid_t			 vw_pid;	/* Terminal holding process */
@@ -277,6 +284,7 @@ struct vt_window {
  */
 
 typedef int vd_init_t(struct vt_device *vd);
+typedef int vd_probe_t(struct vt_device *vd);
 typedef void vd_postswitch_t(struct vt_device *vd);
 typedef void vd_blank_t(struct vt_device *vd, term_color_t color);
 typedef void vd_bitbltchr_t(struct vt_device *vd, const uint8_t *src,
@@ -295,7 +303,9 @@ typedef void vd_drawrect_t(struct vt_dev
 typedef void vd_setpixel_t(struct vt_device *, int, int, term_color_t);
 
 struct vt_driver {
+	char		 vd_name[16];
 	/* Console attachment. */
+	vd_probe_t	*vd_probe;
 	vd_init_t	*vd_init;
 
 	/* Drawing. */
@@ -337,10 +347,10 @@ void vt_upgrade(struct vt_device *vd);
 #define	PIXEL_HEIGHT(h)	((h) / 16)
 
 #ifndef VT_FB_DEFAULT_WIDTH
-#define	VT_FB_DEFAULT_WIDTH	640
+#define	VT_FB_DEFAULT_WIDTH	2048
 #endif
 #ifndef VT_FB_DEFAULT_HEIGHT
-#define	VT_FB_DEFAULT_HEIGHT	480
+#define	VT_FB_DEFAULT_HEIGHT	1200
 #endif
 
 #define	VT_CONSDEV_DECLARE(driver, width, height, softc)		\
@@ -391,6 +401,9 @@ TERMINAL_DECLARE_EARLY(driver ## _conste
 SYSINIT(vt_early_cons, SI_SUB_INT_CONFIG_HOOKS, SI_ORDER_ANY,		\
     vt_upgrade, &driver ## _consdev)
 
+/* name argument is not used yet. */
+#define VT_DRIVER_DECLARE(name, drv) DATA_SET(vt_drv_set, drv)
+
 /*
  * Fonts.
  *

Modified: stable/10/sys/dev/vt/vt_buf.c
==============================================================================
--- stable/10/sys/dev/vt/vt_buf.c	Mon Jun 16 11:00:14 2014	(r267537)
+++ stable/10/sys/dev/vt/vt_buf.c	Mon Jun 16 11:26:30 2014	(r267538)
@@ -357,17 +357,17 @@ void
 vtbuf_fill_locked(struct vt_buf *vb, const term_rect_t *r, term_char_t c)
 {
 	KASSERT(r->tr_begin.tp_row < vb->vb_scr_size.tp_row,
-	    ("vtbuf_fill_locked begin.tp_row %d must be < screen width %d",
+	    ("vtbuf_fill_locked begin.tp_row %d must be < screen height %d",
 		r->tr_begin.tp_row, vb->vb_scr_size.tp_row));
 	KASSERT(r->tr_begin.tp_col < vb->vb_scr_size.tp_col,
-	    ("vtbuf_fill_locked begin.tp_col %d must be < screen height %d",
+	    ("vtbuf_fill_locked begin.tp_col %d must be < screen width %d",
 		r->tr_begin.tp_col, vb->vb_scr_size.tp_col));
 
 	KASSERT(r->tr_end.tp_row <= vb->vb_scr_size.tp_row,
-	    ("vtbuf_fill_locked end.tp_row %d must be <= screen width %d",
+	    ("vtbuf_fill_locked end.tp_row %d must be <= screen height %d",
 		r->tr_end.tp_row, vb->vb_scr_size.tp_row));
 	KASSERT(r->tr_end.tp_col <= vb->vb_scr_size.tp_col,
-	    ("vtbuf_fill_locked end.tp_col %d must be <= screen height %d",
+	    ("vtbuf_fill_locked end.tp_col %d must be <= screen width %d",
 		r->tr_end.tp_col, vb->vb_scr_size.tp_col));
 
 	VTBUF_LOCK(vb);
@@ -448,8 +448,9 @@ vtbuf_grow(struct vt_buf *vb, const term
 
 	history_size = MAX(history_size, p->tp_row);
 
-	if (history_size > vb->vb_history_size || p->tp_col >
-	    vb->vb_scr_size.tp_col) {
+	/* If new screen/history size bigger or buffer is VBF_STATIC. */
+	if ((history_size > vb->vb_history_size) || (p->tp_col >
+	    vb->vb_scr_size.tp_col) || (vb->vb_flags & VBF_STATIC)) {
 		/* Allocate new buffer. */
 		bufsize = history_size * p->tp_col * sizeof(term_char_t);
 		new = malloc(bufsize, M_VTBUF, M_WAITOK | M_ZERO);
@@ -495,6 +496,9 @@ vtbuf_grow(struct vt_buf *vb, const term
 		/* Deallocate old buffer. */
 		free(old, M_VTBUF);
 		free(oldrows, M_VTBUF);
+	} else {
+		/* Just update the size. */
+		vb->vb_scr_size = *p;
 	}
 }
 

Modified: stable/10/sys/dev/vt/vt_consolectl.c
==============================================================================
--- stable/10/sys/dev/vt/vt_consolectl.c	Mon Jun 16 11:00:14 2014	(r267537)
+++ stable/10/sys/dev/vt/vt_consolectl.c	Mon Jun 16 11:26:30 2014	(r267538)
@@ -61,8 +61,10 @@ consolectl_ioctl(struct cdev *dev, u_lon
 		return (0);
 	}
 	default:
+#ifdef VT_CONSOLECTL_DEBUG
 		printf("consolectl: unknown ioctl: %c:%lx\n",
 		    (char)IOCGROUP(cmd), IOCBASECMD(cmd));
+#endif
 		return (ENOIOCTL);
 	}
 }

Modified: stable/10/sys/dev/vt/vt_core.c
==============================================================================
--- stable/10/sys/dev/vt/vt_core.c	Mon Jun 16 11:00:14 2014	(r267537)
+++ stable/10/sys/dev/vt/vt_core.c	Mon Jun 16 11:26:30 2014	(r267538)
@@ -120,9 +120,10 @@ VT_SYSCTL_INT(debug, 0, "vt(9) debug lev
 VT_SYSCTL_INT(deadtimer, 15, "Time to wait busy process in VT_PROCESS mode");
 VT_SYSCTL_INT(suspendswitch, 1, "Switch to VT0 before suspend");
 
+static struct vt_device	vt_consdev;
 static unsigned int vt_unit = 0;
 static MALLOC_DEFINE(M_VT, "vt", "vt device");
-struct vt_device *main_vd = NULL;
+struct vt_device *main_vd = &vt_consdev;
 
 /* Boot logo. */
 extern unsigned int vt_logo_width;
@@ -144,6 +145,85 @@ static int vt_window_switch(struct vt_wi
 static int vt_late_window_switch(struct vt_window *);
 static int vt_proc_alive(struct vt_window *);
 static void vt_resize(struct vt_device *);
+static void vt_update_static(void *);
+
+SET_DECLARE(vt_drv_set, struct vt_driver);
+
+#define _VTDEFH MAX(100, PIXEL_HEIGHT(VT_FB_DEFAULT_HEIGHT))
+#define _VTDEFW MAX(200, PIXEL_WIDTH(VT_FB_DEFAULT_WIDTH))
+
+static struct terminal	vt_consterm;
+static struct vt_window	vt_conswindow;
+static struct vt_device	vt_consdev = {
+	.vd_driver = NULL,
+	.vd_softc = NULL,
+	.vd_flags = VDF_INVALID,
+	.vd_windows = { [VT_CONSWINDOW] =  &vt_conswindow, },
+	.vd_curwindow = &vt_conswindow,
+	.vd_markedwin = NULL,
+	.vd_kbstate = 0,
+};
+static term_char_t vt_constextbuf[(_VTDEFW) * (VBF_DEFAULT_HISTORY_SIZE)];
+static term_char_t *vt_constextbufrows[VBF_DEFAULT_HISTORY_SIZE];
+static struct vt_window	vt_conswindow = {
+	.vw_number = VT_CONSWINDOW,
+	.vw_flags = VWF_CONSOLE,
+	.vw_buf = {
+		.vb_buffer = vt_constextbuf,
+		.vb_rows = vt_constextbufrows,
+		.vb_history_size = VBF_DEFAULT_HISTORY_SIZE,
+		.vb_curroffset = 0,
+		.vb_roffset = 0,
+		.vb_flags = VBF_STATIC,
+		.vb_mark_start = {.tp_row = 0, .tp_col = 0,},
+		.vb_mark_end = {.tp_row = 0, .tp_col = 0,},
+		.vb_scr_size = {
+			.tp_row = _VTDEFH,
+			.tp_col = _VTDEFW,
+		},
+	},
+	.vw_device = &vt_consdev,
+	.vw_terminal = &vt_consterm,
+	.vw_kbdmode = K_XLATE,
+};
+static struct terminal vt_consterm = {
+	.tm_class = &vt_termclass,
+	.tm_softc = &vt_conswindow,
+	.tm_flags = TF_CONS,
+};
+static struct consdev vt_consterm_consdev = {
+	.cn_ops = &termcn_cnops,
+	.cn_arg = &vt_consterm,
+	.cn_name = "ttyv0",
+};
+
+/* Add to set of consoles. */
+DATA_SET(cons_set, vt_consterm_consdev);
+
+/*
+ * Right after kmem is done to allow early drivers to use locking and allocate
+ * memory.
+ */
+SYSINIT(vt_update_static, SI_SUB_KMEM, SI_ORDER_ANY, vt_update_static,
+    &vt_consdev);
+/* Delay until all devices attached, to not waste time. */
+SYSINIT(vt_early_cons, SI_SUB_INT_CONFIG_HOOKS, SI_ORDER_ANY, vt_upgrade,
+    &vt_consdev);
+
+/* Initialize locks/mem depended members. */
+static void
+vt_update_static(void *dummy)
+{
+
+	if (main_vd->vd_driver != NULL)
+		printf("VT: running with driver \"%s\".\n",
+		    main_vd->vd_driver->vd_name);
+	else
+		printf("VT: init without driver.\n");
+
+	mtx_init(&main_vd->vd_lock, "vtdev", NULL, MTX_DEF);
+	cv_init(&main_vd->vd_winswitch, "vtwswt");
+}
 
 static void
 vt_switch_timer(void *arg)
@@ -203,12 +283,12 @@ vt_proc_window_switch(struct vt_window *
 	struct vt_device *vd;
 	int ret;
 
-	if (vw->vw_flags & VWF_VTYLOCK)
-		return (EBUSY);
-
 	vd = vw->vw_device;
 	curvw = vd->vd_curwindow;
 
+	if (curvw->vw_flags & VWF_VTYLOCK)
+		return (EBUSY);
+
 	/* Ask current process permitions to switch away. */
 	if (curvw->vw_smode.mode == VT_PROCESS) {
 		DPRINTF(30, "%s: VT_PROCESS ", __func__);
@@ -556,11 +636,9 @@ vt_allocate_keyboard(struct vt_device *v
 	keyboard_t	*k0, *k;
 	keyboard_info_t	 ki;
 
-	idx0 = kbd_allocate("kbdmux", -1, (void *)&vd->vd_keyboard,
-	    vt_kbdevent, vd);
-	/* XXX: kb_token lost */
+	idx0 = kbd_allocate("kbdmux", -1, vd, vt_kbdevent, vd);
 	vd->vd_keyboard = idx0;
-	if (idx0 != -1) {
+	if (idx0 >= 0) {
 		DPRINTF(20, "%s: kbdmux allocated, idx = %d\n", __func__, idx0);
 		k0 = kbd_get_keyboard(idx0);
 
@@ -580,8 +658,11 @@ vt_allocate_keyboard(struct vt_device *v
 		}
 	} else {
 		DPRINTF(20, "%s: no kbdmux allocated\n", __func__);
-		idx0 = kbd_allocate("*", -1, (void *)&vd->vd_keyboard,
-		    vt_kbdevent, vd);
+		idx0 = kbd_allocate("*", -1, vd, vt_kbdevent, vd);
+		if (idx0 < 0) {
+			DPRINTF(10, "%s: No keyboard found.\n", __func__);
+			return (-1);
+		}
 	}
 	DPRINTF(20, "%s: vd_keyboard = %d\n", __func__, vd->vd_keyboard);
 
@@ -601,6 +682,22 @@ vtterm_bell(struct terminal *tm)
 }
 
 static void
+vtterm_beep(struct terminal *tm, u_int param)
+{
+	u_int freq, period;
+
+	if ((param == 0) || ((param & 0xffff) == 0)) {
+		vtterm_bell(tm);
+		return;
+	}
+
+	period = ((param >> 16) & 0xffff) * hz / 1000;
+	freq = 1193182 / (param & 0xffff);
+
+	sysbeep(freq, period);
+}
+
+static void
 vtterm_cursor(struct terminal *tm, const term_pos_t *p)
 {
 	struct vt_window *vw = tm->tm_softc;
@@ -775,7 +872,7 @@ vt_flush(struct vt_device *vd)
 	if ((vd->vd_flags & (VDF_MOUSECURSOR|VDF_TEXTMODE)) ==
 	    VDF_MOUSECURSOR) {
 		m = &vt_default_mouse_pointer;
-		bpl = (m->w + 7) >> 3; /* Bytes per sorce line. */
+		bpl = (m->w + 7) >> 3; /* Bytes per source line. */
 		w = m->w;
 		h = m->h;
 
@@ -851,9 +948,11 @@ vtterm_splash(struct vt_device *vd)
 }
 #endif
 
+
 static void
 vtterm_cnprobe(struct terminal *tm, struct consdev *cp)
 {
+	struct vt_driver *vtd, **vtdlist, *vtdbest = NULL;
 	struct vt_window *vw = tm->tm_softc;
 	struct vt_device *vd = vw->vw_device;
 	struct winsize wsz;
@@ -862,10 +961,27 @@ vtterm_cnprobe(struct terminal *tm, stru
 		/* Initialization already done. */
 		return;
 
-	cp->cn_pri = vd->vd_driver->vd_init(vd);

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



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