svn commit: r204281 - head/sys/dev/syscons

Jung-uk Kim jkim at FreeBSD.org
Wed Feb 24 20:13:34 UTC 2010


Author: jkim
Date: Wed Feb 24 20:13:34 2010
New Revision: 204281
URL: http://svn.freebsd.org/changeset/base/204281

Log:
  Improve VESA mode switching via loader tunable `hint.sc.0.vesa_mode'.
  The most notable change is history buffer is fully saved/restored now.

Modified:
  head/sys/dev/syscons/scvidctl.c
  head/sys/dev/syscons/syscons.c
  head/sys/dev/syscons/syscons.h

Modified: head/sys/dev/syscons/scvidctl.c
==============================================================================
--- head/sys/dev/syscons/scvidctl.c	Wed Feb 24 19:28:15 2010	(r204280)
+++ head/sys/dev/syscons/scvidctl.c	Wed Feb 24 20:13:34 2010	(r204281)
@@ -369,34 +369,7 @@ sc_set_pixel_mode(scr_stat *scp, struct 
     if ((info.vi_width < xsize*8) || (info.vi_height < ysize*fontsize))
 	return EINVAL;
 
-    /*
-     * We currently support the following graphic modes:
-     *
-     * - 4 bpp planar modes whose memory size does not exceed 64K
-     * - 15, 16, 24 and 32 bpp linear modes
-     */
-
-    if (info.vi_mem_model == V_INFO_MM_PLANAR) {
-	if (info.vi_planes != 4)
-	    return ENODEV;
-
-	/*
-	 * A memory size >64K requires bank switching to access the entire
-	 * screen. XXX
-	 */
-
-	if (info.vi_width * info.vi_height / 8 > info.vi_window_size)
-	    return ENODEV;
-    } else if (info.vi_mem_model == V_INFO_MM_DIRECT) {
-	if (!(info.vi_flags & V_INFO_LINEAR) &&
-	    (info.vi_depth != 15) && (info.vi_depth != 16) &&
-	    (info.vi_depth != 24) && (info.vi_depth != 32))
-	    return ENODEV;
-    } else if (info.vi_mem_model == V_INFO_MM_PACKED) {
-	if (!(info.vi_flags & V_INFO_LINEAR) &&
-	    (info.vi_depth != 8))
-	    return ENODEV;
-    } else
+    if (!sc_support_pixel_mode(&info))
 	return ENODEV;
 
     /* stop screen saver, etc */
@@ -472,6 +445,48 @@ sc_set_pixel_mode(scr_stat *scp, struct 
 #endif /* SC_PIXEL_MODE */
 }
 
+int
+sc_support_pixel_mode(void *arg)
+{
+#ifdef SC_PIXEL_MODE
+	video_info_t *info = arg;
+
+	if ((info->vi_flags & V_INFO_GRAPHICS) == 0)
+		return (0);
+
+	/*
+	 * We currently support the following graphic modes:
+	 *
+	 * - 4 bpp planar modes whose memory size does not exceed 64K
+	 * - 15, 16, 24 and 32 bpp linear modes
+	 */
+	switch (info->vi_mem_model) {
+	case V_INFO_MM_PLANAR:
+		if (info->vi_planes != 4)
+			break;
+		/*
+		 * A memory size >64K requires bank switching to access
+		 * the entire screen. XXX
+		 */
+		if (info->vi_width * info->vi_height / 8 > info->vi_window_size)
+			break;
+		return (1);
+	case V_INFO_MM_DIRECT:
+		if ((info->vi_flags & V_INFO_LINEAR) == 0 &&
+		    info->vi_depth != 15 && info->vi_depth != 16 &&
+		    info->vi_depth != 24 && info->vi_depth != 32)
+			break;
+		return (1);
+	case V_INFO_MM_PACKED:
+		if ((info->vi_flags & V_INFO_LINEAR) == 0 &&
+		    info->vi_depth != 8)
+			break;
+		return (1);
+	}
+#endif
+	return (0);
+}
+
 #define fb_ioctl(a, c, d)		\
 	(((a) == NULL) ? ENODEV : 	\
 			 vidd_ioctl((a), (c), (caddr_t)(d)))

Modified: head/sys/dev/syscons/syscons.c
==============================================================================
--- head/sys/dev/syscons/syscons.c	Wed Feb 24 19:28:15 2010	(r204280)
+++ head/sys/dev/syscons/syscons.c	Wed Feb 24 20:13:34 2010	(r204281)
@@ -344,35 +344,94 @@ sc_alloc_tty(int index, int devnum)
 }
 
 #ifdef SC_PIXEL_MODE
-static int
-sc_initial_mode(video_adapter_t *adp, int unit)
+static void
+sc_set_vesa_mode(scr_stat *scp, sc_softc_t *sc, int unit)
 {
 	video_info_t info;
-	int depth, vmode;
+	int depth;
 	int i;
+	int vmode;
 
 	vmode = 0;
 	(void)resource_int_value("sc", unit, "vesa_mode", &vmode);
-	if (vmode < M_VESA_BASE || vmode > M_VESA_MODE_MAX)
-	    vmode = 0;
+	if (vmode < M_VESA_BASE || vmode > M_VESA_MODE_MAX ||
+	    vidd_get_info(sc->adp, vmode, &info) != 0 ||
+	    !sc_support_pixel_mode(&info))
+		vmode = 0;
 
 	/*
-	 * If the default mode is not supported, search for an available
+	 * If the mode is unset or unsupported, search for an available
 	 * 800x600 graphics mode with the highest color depth.
 	 */
-	if (vmode == 0 || vidd_get_info(adp, vmode, &info) != 0) {
-	    depth = vmode = 0;
-	    for (i = M_VESA_BASE; i <= M_VESA_MODE_MAX; i++)
-		if (vidd_get_info(adp, i, &info) == 0 &&
-		    (info.vi_flags & V_INFO_GRAPHICS) != 0 &&
-		    info.vi_width == 800 && info.vi_height == 600 &&
-		    info.vi_depth > depth) {
-			vmode = i;
-			depth = info.vi_depth;
-		}
+	if (vmode == 0) {
+		for (depth = 0, i = M_VESA_BASE; i <= M_VESA_MODE_MAX; i++)
+			if (vidd_get_info(sc->adp, i, &info) == 0 &&
+			    info.vi_width == 800 && info.vi_height == 600 &&
+			    sc_support_pixel_mode(&info) &&
+			    info.vi_depth > depth) {
+				vmode = i;
+				depth = info.vi_depth;
+			}
+		if (vmode == 0)
+			return;
+		vidd_get_info(sc->adp, vmode, &info);
 	}
 
-	return (vmode);
+#ifndef SC_NO_FONT_LOADING
+	if ((sc->fonts_loaded & FONT_16) == 0)
+		return;
+#endif
+#ifdef DEV_SPLASH
+	if ((sc->flags & SC_SPLASH_SCRN) != 0)
+		splash_term(sc->adp);
+#endif
+#ifndef SC_NO_HISTORY
+	if (scp->history != NULL) {
+		sc_vtb_append(&scp->vtb, 0, scp->history,
+		    scp->ypos * scp->xsize + scp->xpos);
+		scp->history_pos = sc_vtb_tail(scp->history);
+	}
+#endif
+	vidd_set_mode(sc->adp, vmode);
+	scp->status |= (UNKNOWN_MODE | PIXEL_MODE | MOUSE_HIDDEN);
+	scp->status &= ~(GRAPHICS_MODE | MOUSE_VISIBLE);
+	scp->xpixel = info.vi_width;
+	scp->ypixel = info.vi_height;
+	scp->xsize = scp->xpixel / 8;
+	scp->ysize = scp->ypixel / 16;
+	scp->xpos = 0;
+	scp->ypos = scp->ysize - 1;
+	scp->xoff = scp->yoff = 0;
+#ifndef SC_NO_FONT_LOADING
+	scp->font = sc->font_16;
+#else
+	scp->font = NULL;
+#endif
+	scp->font_size = 16;
+	scp->font_width = 8;
+	scp->start = scp->xsize * scp->ysize - 1;
+	scp->end = 0;
+	scp->cursor_pos = scp->cursor_oldpos = scp->xsize * scp->xsize;
+	scp->mode = sc->initial_mode = vmode;
+#ifndef __sparc64__
+	sc_vtb_init(&scp->scr, VTB_FRAMEBUFFER, scp->xsize, scp->ysize,
+	    (void *)sc->adp->va_window, FALSE);
+#endif
+	sc_alloc_scr_buffer(scp, FALSE, FALSE);
+	sc_init_emulator(scp, NULL);
+#ifndef SC_NO_CUTPASTE
+	sc_alloc_cut_buffer(scp, FALSE);
+#endif
+#ifndef SC_NO_HISTORY
+	sc_alloc_history_buffer(scp, 0, 0, FALSE);
+#endif
+	sc_set_border(scp, scp->border);
+	sc_set_cursor_image(scp);
+	scp->status &= ~UNKNOWN_MODE;
+#ifdef DEV_SPLASH
+	if ((sc->flags & SC_SPLASH_SCRN) != 0)
+		splash_init(sc->adp, scsplash_callback, sc);
+#endif
 }
 #endif
 
@@ -381,8 +440,8 @@ sc_attach_unit(int unit, int flags)
 {
     sc_softc_t *sc;
     scr_stat *scp;
-    int vc;
     struct cdev *dev;
+    int vc;
 
     flags &= ~SC_KERNEL_CONSOLE;
 
@@ -404,24 +463,8 @@ sc_attach_unit(int unit, int flags)
 	sc_console = scp;
 
 #ifdef SC_PIXEL_MODE
-    if ((sc->config & SC_VESAMODE) != 0) {
-	int vmode;
-	vmode = sc_initial_mode(sc->adp, unit);
-	if (vmode >= M_VESA_BASE) {
-#ifdef DEV_SPLASH
-	    if (sc->flags & SC_SPLASH_SCRN)
-		splash_term(sc->adp);
-#endif
-	    sc_set_graphics_mode(scp, NULL, vmode);
-	    sc_set_pixel_mode(scp, NULL, 0, 0, 16, 8);
-	    sc->initial_mode = vmode;
-#ifdef DEV_SPLASH
-	    /* put up the splash again! */
-	    if (sc->flags & SC_SPLASH_SCRN)
-		splash_init(sc->adp, scsplash_callback, sc);
-#endif
-	}
-    }
+    if ((sc->config & SC_VESAMODE) != 0)
+	sc_set_vesa_mode(scp, sc, unit);
 #endif /* SC_PIXEL_MODE */
 
     /* initialize cursor */

Modified: head/sys/dev/syscons/syscons.h
==============================================================================
--- head/sys/dev/syscons/syscons.h	Wed Feb 24 19:28:15 2010	(r204280)
+++ head/sys/dev/syscons/syscons.h	Wed Feb 24 20:13:34 2010	(r204281)
@@ -623,6 +623,7 @@ int		sc_set_text_mode(scr_stat *scp, str
 int		sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode);
 int		sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize,
 				  int ysize, int fontsize, int font_width);
+int		sc_support_pixel_mode(void *arg);
 int		sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data,
 			     struct thread *td);
 


More information about the svn-src-all mailing list