changeset 3994:4fafdadace7c

6540669 console color regression with coherent console
author lq150181
date Sun, 08 Apr 2007 20:25:56 -0700
parents 9abc97b92b88
children 63fc894a6109
files usr/src/psm/promif/ieee1275/common/prom_fb.c usr/src/uts/common/io/tem.c usr/src/uts/common/io/tem_safe.c usr/src/uts/common/sys/consconfig_dacf.h usr/src/uts/common/sys/tem_impl.h usr/src/uts/i86pc/io/consplat.c usr/src/uts/sparc/io/consplat.c usr/src/uts/sun/sys/promif.h
diffstat 8 files changed, 142 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/psm/promif/ieee1275/common/prom_fb.c	Sun Apr 08 19:47:02 2007 -0700
+++ b/usr/src/psm/promif/ieee1275/common/prom_fb.c	Sun Apr 08 20:25:56 2007 -0700
@@ -55,6 +55,20 @@
 }
 
 /*
+ * get inverse? and inverse-screen? property,
+ * -1 is returned if true, 0 is returned if false.
+ */
+void
+prom_get_tem_inverses(int *inverse, int *inverse_screen)
+{
+	prom_interpret(
+	    "my-self >r stdout @ is my-self "
+	    "inverse? swap l! inverse-screen? swap l! "
+	    "r> is my-self",
+	    (uintptr_t)inverse, (uintptr_t)inverse_screen, 0, 0, 0);
+}
+
+/*
  * get current cursor position from the stdout handle, which
  * containing the instance handle of the OBP console output device.
  */
--- a/usr/src/uts/common/io/tem.c	Sun Apr 08 19:47:02 2007 -0700
+++ b/usr/src/uts/common/io/tem.c	Sun Apr 08 20:25:56 2007 -0700
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -67,7 +67,8 @@
 			size_t, size_t);
 static void	tem_modechange_callback(tem_t *, struct vis_devinit *);
 static void	tem_free(tem_t *);
-
+static void	tem_get_inverses(boolean_t *, boolean_t *);
+static void	tem_get_initial_color(tem_t *);
 static int	tem_adjust_row(tem_t *, int, cred_t *);
 
 /*
@@ -308,6 +309,11 @@
 	}
 
 	/*
+	 * make our kernel console keep compatibility with OBP.
+	 */
+	tem_get_initial_color(tem);
+
+	/*
 	 * On SPARC don't clear the screen if the console is the framebuffer.
 	 * Otherwise it needs to be cleared to get rid of junk that may be
 	 * in frameuffer memory, since the screen isn't cleared when
@@ -318,11 +324,11 @@
 		 * The old getting current cursor position code, which
 		 * is not needed here, has been in tem_write/tem_polled_write.
 		 */
-		tem_reset_display(tem, credp, CALLED_FROM_NORMAL, 0);
+		tem_reset_display(tem, credp, CALLED_FROM_NORMAL, 0, NULL);
 	} else if (plat_stdout_is_framebuffer()) {
 		ASSERT(devinit.mode == VIS_PIXEL);
 		plat_tem_hide_prom_cursor();
-		tem_reset_display(tem, credp, CALLED_FROM_NORMAL, 0);
+		tem_reset_display(tem, credp, CALLED_FROM_NORMAL, 0, NULL);
 
 		/*
 		 * We are getting the current cursor position in pixel
@@ -346,7 +352,7 @@
 		tem->state->a_c_cursor.col = 0;
 		tem_align_cursor(tem);
 	} else {
-		tem_reset_display(tem, credp, CALLED_FROM_NORMAL, 1);
+		tem_reset_display(tem, credp, CALLED_FROM_NORMAL, 1, NULL);
 	}
 
 #ifdef _HAVE_TEM_FIRMWARE
@@ -375,19 +381,30 @@
  * the underlying frame buffer driver to reconfigure the terminal
  * emulator to a new screen size and depth in conjunction with
  * framebuffer videomode changes.
+ * Here we keep the foreground/background color and attributes,
+ * which may be different with the initial settings, so that
+ * the color won't change while the framebuffer videomode changes.
+ * And we also reset the kernel terminal emulator and clear the
+ * whole screen.
  */
 void
 tem_modechange_callback(tem_t *tem, struct vis_devinit *devinit)
 {
+	tem_color_t tc;
+
 	mutex_enter(&tem->lock);
 
 	ASSERT(tem->hdl != NULL);
 
+	tc.fg_color = tem->state->fg_color;
+	tc.bg_color = tem->state->bg_color;
+	tc.a_flags = tem->state->a_flags;
+
 	(void) tem_setup_terminal(devinit, tem,
 	    tem->state->a_c_dimension.height,
 	    tem->state->a_c_dimension.width);
 
-	tem_reset_display(tem, kcred, CALLED_FROM_NORMAL, 1);
+	tem_reset_display(tem, kcred, CALLED_FROM_NORMAL, 1, &tc);
 
 	mutex_exit(&tem->lock);
 
@@ -704,3 +721,41 @@
 
 	return (tem_row);
 }
+
+static void
+tem_get_inverses(boolean_t *p_inverse, boolean_t *p_inverse_screen)
+{
+	int i_inverse = 0;
+	int i_inverse_screen = 0;
+
+	plat_tem_get_inverses(&i_inverse, &i_inverse_screen);
+
+	*p_inverse = (i_inverse == 0) ? B_FALSE : B_TRUE;
+	*p_inverse_screen = (i_inverse_screen == 0) ? B_FALSE : B_TRUE;
+}
+
+/*
+ * Get the foreground/background color and attributes from the initial
+ * PROM, so that our kernel console can keep the same visual behaviour.
+ */
+static void
+tem_get_initial_color(tem_t *tem)
+{
+	boolean_t inverse, inverse_screen;
+	unsigned short  flags = 0;
+
+	tem->init_color.fg_color = DEFAULT_ANSI_FOREGROUND;
+	tem->init_color.bg_color = DEFAULT_ANSI_BACKGROUND;
+
+	if (plat_stdout_is_framebuffer()) {
+		tem_get_inverses(&inverse, &inverse_screen);
+		if (inverse)
+			flags |= TEM_ATTR_REVERSE;
+		if (inverse_screen)
+			flags |= TEM_ATTR_SCREEN_REVERSE;
+		if (flags != 0)
+			flags |= TEM_ATTR_BOLD;
+	}
+
+	tem->init_color.a_flags = flags;
+}
--- a/usr/src/uts/common/io/tem_safe.c	Sun Apr 08 19:47:02 2007 -0700
+++ b/usr/src/uts/common/io/tem_safe.c	Sun Apr 08 20:25:56 2007 -0700
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -118,15 +118,6 @@
 static void	tem_pix_clear_prom_output(struct tem *tem,
 			cred_t *credp, enum called_from called_from);
 
-#ifdef _HAVE_TEM_FIRMWARE
-#define	DEFAULT_ANSI_FOREGROUND	ANSI_COLOR_BLACK
-#define	DEFAULT_ANSI_BACKGROUND	ANSI_COLOR_WHITE
-#else /* _HAVE_TEM_FIRMWARE */
-#define	DEFAULT_ANSI_FOREGROUND	ANSI_COLOR_WHITE
-#define	DEFAULT_ANSI_BACKGROUND	ANSI_COLOR_BLACK
-#endif
-
-
 /* BEGIN CSTYLED */
 /*                                      Bk  Rd  Gr  Br  Bl  Mg  Cy  Wh */
 static text_color_t fg_dim_xlate[] = {  1,  5,  3,  7,  2,  6,  4,  8 };
@@ -442,16 +433,19 @@
 			} else {
 				tems->a_flags &= ~TEM_ATTR_REVERSE;
 			}
-			tems->a_flags &= ~TEM_ATTR_BOLD;
-			tems->a_flags &= ~TEM_ATTR_BLINK;
-			tems->fg_color = DEFAULT_ANSI_FOREGROUND;
-			tems->bg_color = DEFAULT_ANSI_BACKGROUND;
+			tems->a_flags = tem->init_color.a_flags;
+			tems->fg_color = tem->init_color.fg_color;
+			tems->bg_color = tem->init_color.bg_color;
 			break;
 
 		case 1: /* Bold Intense */
 			tems->a_flags |= TEM_ATTR_BOLD;
 			break;
 
+		case 2: /* Faint Intense */
+			tems->a_flags &= ~TEM_ATTR_BOLD;
+			break;
+
 		case 5: /* Blink */
 			tems->a_flags |= TEM_ATTR_BLINK;
 			break;
@@ -1100,7 +1094,7 @@
 		tems->a_state = A_STATE_START;
 		if (ch == 'c')
 			/* ESC c resets display */
-			tem_reset_display(tem, credp, called_from, 1);
+			tem_reset_display(tem, credp, called_from, 1, NULL);
 		else if (ch == 'H')
 			/* ESC H sets a tab */
 			tem_set_tab(tem);
@@ -1667,7 +1661,8 @@
 /* ARGSUSED */
 void
 tem_reset_emulator(struct tem *tem,
-    cred_t *credp, enum called_from called_from)
+    cred_t *credp, enum called_from called_from,
+    tem_color_t *pcolor)
 {
 	struct tem_state *tems = tem->state;
 	int j;
@@ -1686,10 +1681,19 @@
 	tems->a_gotparam = B_FALSE;
 	tems->a_curparam = 0;
 	tems->a_paramval = 0;
-	tems->a_flags = 0;
 	tems->a_nscroll = 1;
-	tems->fg_color = DEFAULT_ANSI_FOREGROUND;
-	tems->bg_color = DEFAULT_ANSI_BACKGROUND;
+
+	if (pcolor != NULL) {
+		/* use customized settings */
+		tems->fg_color = pcolor->fg_color;
+		tems->bg_color = pcolor->bg_color;
+		tems->a_flags = pcolor->a_flags;
+	} else {
+		/* use initial settings */
+		tems->fg_color = tem->init_color.fg_color;
+		tems->bg_color = tem->init_color.bg_color;
+		tems->a_flags = tem->init_color.a_flags;
+	}
 
 	/*
 	 * set up the initial tab stops
@@ -1704,14 +1708,15 @@
 
 void
 tem_reset_display(struct tem *tem,
-    cred_t *credp, enum called_from called_from, int clear_txt)
+    cred_t *credp, enum called_from called_from, int clear_txt,
+    tem_color_t *pcolor)
 {
 	struct tem_state *tems = tem->state;
 
 	ASSERT((called_from == CALLED_FROM_STANDALONE) ||
 	    MUTEX_HELD(&tem->lock));
 
-	tem_reset_emulator(tem, credp, called_from);
+	tem_reset_emulator(tem, credp, called_from, pcolor);
 	tem_reset_colormap(tem, credp, called_from);
 
 	if (clear_txt) {
--- a/usr/src/uts/common/sys/consconfig_dacf.h	Sun Apr 08 19:47:02 2007 -0700
+++ b/usr/src/uts/common/sys/consconfig_dacf.h	Sun Apr 08 20:25:56 2007 -0700
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -124,6 +124,7 @@
 extern int	plat_stdout_is_framebuffer(void);
 extern int	plat_stdin_is_keyboard(void);
 
+extern void	plat_tem_get_inverses(int *, int *);
 extern void	plat_tem_get_prom_font_size(int *, int *);
 extern void	plat_tem_get_prom_size(size_t *, size_t *);
 extern void	plat_tem_hide_prom_cursor(void);
--- a/usr/src/uts/common/sys/tem_impl.h	Sun Apr 08 19:47:02 2007 -0700
+++ b/usr/src/uts/common/sys/tem_impl.h	Sun Apr 08 20:25:56 2007 -0700
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -90,10 +90,27 @@
 #define	TEM_DEFAULT_ROWS	34
 #define	TEM_DEFAULT_COLS	80
 
+/*
+ * Default foreground/background color
+ */
+#ifdef _HAVE_TEM_FIRMWARE
+#define	DEFAULT_ANSI_FOREGROUND	ANSI_COLOR_BLACK
+#define	DEFAULT_ANSI_BACKGROUND	ANSI_COLOR_WHITE
+#else /* _HAVE_TEM_FIRMWARE */
+#define	DEFAULT_ANSI_FOREGROUND	ANSI_COLOR_WHITE
+#define	DEFAULT_ANSI_BACKGROUND	ANSI_COLOR_BLACK
+#endif
+
 #define	BUF_LEN		160 /* Two lines of data can be processed at a time */
 
 typedef uint8_t text_color_t;
 
+typedef struct tem_color {
+	text_color_t	fg_color;
+	text_color_t	bg_color;
+	unsigned short	a_flags;
+} tem_color_t;
+
 struct tem_pix_pos {
 	screen_pos_t	x;
 	screen_pos_t	y;
@@ -186,13 +203,15 @@
 	tem_state_t		*state;
 	tem_modechg_cb_t	modechg_cb;
 	tem_modechg_cb_arg_t	modechg_arg;
+	tem_color_t		init_color; /* initial color and attributes */
 } tem_t;
 
 void	tem_check_first_time(tem_t *tem, cred_t *, enum called_from);
 void	tem_reset_colormap(tem_t *, cred_t *, enum called_from);
 void	tem_align_cursor(tem_t *);
-void	tem_reset_emulator(tem_t *, cred_t *, enum called_from);
-void	tem_reset_display(tem_t *, cred_t *, enum called_from, int);
+void	tem_reset_emulator(tem_t *, cred_t *, enum called_from, tem_color_t *);
+void	tem_reset_display(tem_t *, cred_t *, enum called_from, int,
+			tem_color_t *);
 void	tem_display_layered(tem_t *, struct vis_consdisplay *, cred_t *);
 void	tem_copy_layered(tem_t *, struct vis_conscopy *, cred_t *);
 void	tem_cursor_layered(tem_t *, struct vis_conscursor *, cred_t *);
--- a/usr/src/uts/i86pc/io/consplat.c	Sun Apr 08 19:47:02 2007 -0700
+++ b/usr/src/uts/i86pc/io/consplat.c	Sun Apr 08 20:25:56 2007 -0700
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -246,6 +246,13 @@
  * unused on x86.
  */
 void
+plat_tem_get_inverses(int *inverse, int *inverse_screen)
+{
+	*inverse = 0;
+	*inverse_screen = 0;
+}
+
+void
 plat_tem_get_prom_font_size(int *charheight, int *windowtop)
 {
 	*charheight = 0;
--- a/usr/src/uts/sparc/io/consplat.c	Sun Apr 08 19:47:02 2007 -0700
+++ b/usr/src/uts/sparc/io/consplat.c	Sun Apr 08 20:25:56 2007 -0700
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -215,6 +215,12 @@
 }
 
 void
+plat_tem_get_inverses(int *inverse, int *inverse_screen)
+{
+	prom_get_tem_inverses(inverse, inverse_screen);
+}
+
+void
 plat_tem_get_prom_font_size(int *charheight, int *windowtop)
 {
 	prom_get_term_font_size(charheight, windowtop);
--- a/usr/src/uts/sun/sys/promif.h	Sun Apr 08 19:47:02 2007 -0700
+++ b/usr/src/uts/sun/sys/promif.h	Sun Apr 08 20:25:56 2007 -0700
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -158,6 +158,7 @@
 extern	int		prom_stdout_is_framebuffer(void);
 extern	int		prom_stdin_stdout_equivalence(void);
 
+extern void		prom_get_tem_inverses(int *, int *);
 extern void		prom_get_tem_size(size_t *, size_t *);
 extern void		prom_get_tem_pos(uint32_t *, uint32_t *);
 extern void		prom_get_term_font_size(int *, int *);