[coreboot] tinycurses enhancements

Jordan Crouse jordan.crouse at amd.com
Fri Sep 26 18:38:38 CEST 2008


On 26/09/08 01:18 +0200, Stefan Reinauer wrote:
> See patch
> 
> -- 
> coresystems GmbH • Brahmsstr. 16 • D-79104 Freiburg i. Br.
>       Tel.: +49 761 7668825 • Fax: +49 761 7664613
> Email: info at coresystems.dehttp://www.coresystems.de/
> Registergericht: Amtsgericht Freiburg • HRB 7656
> Geschäftsführer: Stefan Reinauer • Ust-IdNr.: DE245674866
> 

> * factor out serial hardware init
> * add reverse color support for serial
> * add cursor enable/disable support for serial
> * fix tinycurses compilation if serial is disabled
> * add functions to query whether serial or vga console is enabled in tinycurses
> * initialize uninitialized COLOR_PAIRS variable
> * implement has_colors(), wredrawln() functions in curses
> 
> Signed-off-by: Stefan Reinauer <stepan at coresystems.de>

There is a lot going on here - but it looks good, and I asssume
you have tested it.

Acked-by: Jordan Crouse <jordan.crouse at amd.com>

> Index: include/libpayload.h
> ===================================================================
> --- include/libpayload.h	(revision 3600)
> +++ include/libpayload.h	(working copy)
> @@ -131,15 +142,19 @@
>   * @{
>   */
>  void serial_init(void);
> +void serial_hardware_init(int port, int speed, int word_bits, int parity, int stop_bits);
>  void serial_putchar(unsigned char c);
>  int serial_havechar(void);
>  int serial_getchar(void);
>  void serial_clear(void);
>  void serial_start_bold(void);
>  void serial_end_bold(void);
> +void serial_start_reverse(void);
> +void serial_end_reverse(void);
>  void serial_start_altcharset(void);
>  void serial_end_altcharset(void);
>  void serial_set_color(short fg, short bg);
> +void serial_cursor_enable(int state);
>  void serial_set_cursor(int y, int x);
>  /** @} */
>  
> Index: include/curses.h
> ===================================================================
> --- include/curses.h	(revision 3600)
> +++ include/curses.h	(working copy)
> @@ -1673,4 +1673,7 @@
>  void curses_enable_vga(int);
>  void curses_enable_serial(int);
>  
> +int curses_vga_enabled(void);
> +int curses_serial_enabled(void);
> +
>  #endif /* _CURSES_H */
> Index: curses/keyboard.c
> ===================================================================
> --- curses/keyboard.c	(revision 3600)
> +++ curses/keyboard.c	(working copy)
> @@ -44,6 +44,7 @@
>  
>  /* ============== Serial ==================== */
>  
> +#ifdef CONFIG_SERIAL_CONSOLE
>  /* We treat serial like a vt100 terminal.  For now we
>     do the cooking in here, but we should probably eventually
>     pass it to dedicated vt100 code */
> @@ -135,6 +136,7 @@
>  		return ch;
>  	}
>  }
> +#endif
>  
>  /* ================ Keyboard ================ */
>  
> @@ -215,8 +217,14 @@
>  	else
>  		curses_flags &= ~F_ENABLE_CONSOLE;
>  }
> +
> +int curses_vga_enabled(void)
> +{
> +	return (curses_flags & F_ENABLE_CONSOLE) != 0;
> +}
>  #else
>  void curses_enable_vga(int state) { }
> +int curses_vga_enabled(void) { return 0; }
>  #endif
>  
>  #ifdef CONFIG_SERIAL_CONSOLE
> @@ -227,7 +235,14 @@
>  	else
>  		curses_flags &= ~F_ENABLE_SERIAL;
>  }
> +
> +int curses_serial_enabled(void)
> +{
> +	return (curses_flags & F_ENABLE_SERIAL) != 0;
> +}
> +
>  #else
>  void curses_enable_serial(int state) { }
> +int curses_serial_enabled(void) { return 0; }
>  #endif
>  
> Index: curses/tinycurses.c
> ===================================================================
> --- curses/tinycurses.c	(revision 3600)
> +++ curses/tinycurses.c	(working copy)
> @@ -77,7 +77,7 @@
>  
>  /* Globals */
>  int COLORS;		/* Currently unused? */
> -int COLOR_PAIRS;
> +int COLOR_PAIRS = 255;
>  WINDOW *stdscr;
>  WINDOW *curscr;
>  WINDOW *newscr;
> @@ -111,6 +111,7 @@
>  	'|',	'<',	'>',	'*',	'!',	'f',	'o',	' ',
>  	};
>  
> +#ifdef CONFIG_SERIAL_CONSOLE
>  #ifdef CONFIG_SERIAL_ACS_FALLBACK
>  chtype serial_acs_map[128];
>  #else
> @@ -135,7 +136,9 @@
>  	'x',	'y',	'z',	'{',	'|',	'}',	'~',	0,
>  	};
>  #endif
> +#endif
>  
> +#ifdef CONFIG_VIDEO_CONSOLE
>  /* See acsc of linux. */
>  chtype console_acs_map[128] =
>  	{
> @@ -156,6 +159,7 @@
>  	'\304',	'\304',	'\304',	'_',	'\303', '\264', '\301',	'\302',
>  	'\263',	'\363',	'\362',	'\343',	'\330',	'\234',	'\376',	0,
>  	};
> +#endif
>  
>  // FIXME: Ugly (and insecure!) hack!
>  char sprintf_tmp[1024];
> @@ -196,13 +200,16 @@
>  // int color_content(short color, short *r, short *g, short *b) {}
>  int curs_set(int on)
>  {
> +#ifdef CONFIG_SERIAL_CONSOLE
>  	if (curses_flags & F_ENABLE_SERIAL) {
> -		// TODO
> +		serial_cursor_enable(on);
>  	}
> -
> +#endif
> +#ifdef CONFIG_VIDEO_CONSOLE
>  	if (curses_flags & F_ENABLE_CONSOLE) {
>  		video_console_cursor_enable(on);
>  	}
> +#endif
>  
>  	return OK;
>  }
> @@ -284,7 +291,7 @@
>  // int flash(void) {}
>  int flushinp(void) { /* TODO */ return 0; }
>  // WINDOW *getwin (FILE *) {}
> -bool has_colors (void) { /* TODO */ return(*(bool *)0); }
> +bool has_colors (void) { return(TRUE); }
>  // bool has_ic (void) {}
>  // bool has_il (void) {}
>  // void idcok (WINDOW *, bool) {}
> @@ -300,21 +307,23 @@
>  
>  	for (i = 0; i < 128; i++)
>  	  acs_map[i] = (chtype) i | A_ALTCHARSET;
> -
> +#ifdef CONFIG_SERIAL_CONSOLE
>  	if (curses_flags & F_ENABLE_SERIAL) {
>  		serial_clear();
>  	}
> -
> +#endif
> +#ifdef CONFIG_VIDEO_CONSOLE
>  	if (curses_flags & F_ENABLE_CONSOLE) {
>  		/* Clear the screen and kill the cursor */
>  
>  		video_console_clear();
>  		video_console_cursor_enable(0);
>  	}
> +#endif
>  
>  	// Speaker init?
>  
> -	stdscr = newwin(SCREEN_Y, SCREEN_X, 0, 0);
> +	stdscr = newwin(SCREEN_Y, SCREEN_X + 1, 0, 0);
>  	// TODO: curscr, newscr?
>  
>  	werase(stdscr);
> @@ -693,18 +702,23 @@
>  	(((c) & 0x4400) >> 2) | ((c) & 0xAA00) | (((c) & 0x1100) << 2)
>  int wnoutrefresh(WINDOW *win)
>  {
> +#ifdef CONFIG_SERIAL_CONSOLE
>  	// FIXME.
>  	int serial_is_bold = 0;
> +	int serial_is_reverse = 0;
>  	int serial_is_altcharset = 0;
>  	int serial_cur_pair = 0;
>  
> +	int need_altcharset;
> +	short fg, bg;
> +#endif
>  	int x, y;
>  	chtype ch;
> -	int need_altcharset;
> -	short fg, bg;
>  
> +#ifdef CONFIG_SERIAL_CONSOLE
>  	serial_end_bold();
>  	serial_end_altcharset();
> +#endif
>  
>  	for (y = 0; y <= win->_maxy; y++) {
>  
> @@ -713,9 +727,11 @@
>  
>  		/* Position the serial cursor */
>  
> +#ifdef CONFIG_SERIAL_CONSOLE
>  		if (curses_flags & F_ENABLE_SERIAL)
>  			serial_set_cursor(win->_begy + y, win->_begx +
>  					win->_line[y].firstchar);
> +#endif
>  
>  		for (x = win->_line[y].firstchar; x <= win->_line[y].lastchar; x++) {
>  			attr_t attr = win->_line[y].text[x].attr;
> @@ -723,6 +739,7 @@
>  			unsigned int c =
>  				((int)color_pairs[PAIR_NUMBER(attr)]) << 8;
>  
> +#ifdef CONFIG_SERIAL_CONSOLE
>  			if (curses_flags & F_ENABLE_SERIAL) {
>  				ch = win->_line[y].text[x].chars[0];
>  
> @@ -731,15 +748,35 @@
>  						serial_start_bold();
>  						serial_is_bold = 1;
>  					}
> -				}
> -				else {
> +				} else {
>  					if (serial_is_bold) {
>  						serial_end_bold();
>  						serial_is_bold = 0;
> +						/* work around serial.c
> +						 * shortcoming:
> +						 */
> +						serial_is_reverse = 0;
>  						serial_cur_pair = 0;
>  					}
>  				}
>  
> +				if (attr & A_REVERSE) {
> +					if (!serial_is_reverse) {
> +						serial_start_reverse();
> +						serial_is_reverse = 1;
> +					}
> +				} else {
> +					if (serial_is_reverse) {
> +						serial_end_reverse();
> +						serial_is_reverse = 0;
> +						/* work around serial.c
> +						 * shortcoming:
> +						 */
> +						serial_is_bold = 0;
> +						serial_cur_pair = 0;
> +					}
> +				}
> +
>  				need_altcharset = 0;
>  				if (attr & A_ALTCHARSET) {
>  					if (serial_acs_map[ch & 0x7f]) {
> @@ -767,7 +804,8 @@
>  				serial_putchar(ch);
>  
>  			}
> -
> +#endif
> +#ifdef CONFIG_VIDEO_CONSOLE
>  			c = SWAP_RED_BLUE(c);
>  
>  			if (curses_flags & F_ENABLE_CONSOLE) {
> @@ -799,16 +837,21 @@
>  				c |= (chtype) (ch & 0xff);
>  				video_console_putc(win->_begy + y, win->_begx + x, c);
>  			}
> +#endif
>  		}
>  		win->_line[y].firstchar = _NOCHANGE;
>  		win->_line[y].lastchar = _NOCHANGE;
>  	}
>  
> +#ifdef CONFIG_SERIAL_CONSOLE
>  	if (curses_flags & F_ENABLE_SERIAL)
>  		serial_set_cursor(win->_begy + win->_cury, win->_begx + win->_curx);
> +#endif
>  
> +#ifdef CONFIG_VIDEO_CONSOLE
>  	if (curses_flags & F_ENABLE_CONSOLE)
>  		video_console_set_cursor(win->_begx + win->_curx, win->_begy + win->_cury);
> +#endif
>  
>  	return OK;
>  }
> @@ -823,7 +866,19 @@
>  
>  	return code;
>  }
> -// int wredrawln (WINDOW *,int,int) {}
> +
> +int wredrawln (WINDOW *win, int beg_line, int num_lines)
> +{
> +	int i;
> +
> +	for (i = beg_line; i < beg_line + num_lines; i++) {
> +		win->_line[i].firstchar = 0;
> +		win->_line[i].lastchar = win->_maxx;
> +	}
> +
> +	return OK;
> +}
> +
>  int wrefresh(WINDOW *win)
>  {
>  	// FIXME
> Index: drivers/serial.c
> ===================================================================
> --- drivers/serial.c	(revision 3600)
> +++ drivers/serial.c	(working copy)
> @@ -32,32 +32,36 @@
>  #include <libpayload.h>
>  
>  #define IOBASE lib_sysinfo.ser_ioport
> +#define DIVISOR(x) (115200 / x)
>  
> -#ifdef CONFIG_SERIAL_SET_SPEED
> -#define DIVISOR (115200 / CONFIG_SERIAL_BAUD_RATE)
> -#endif
> -
> -void serial_init(void)
> +void serial_hardware_init(int port, int speed, int word_bits, int parity, int stop_bits)
>  {
> -#ifdef CONFIG_SERIAL_SET_SPEED
>  	unsigned char reg;
>  
> +	/* We will assume 8n1 for now. Does anyone use anything else these days? */
> +
>  	/* Disable interrupts. */
> -	outb(0, IOBASE + 0x01);
> +	outb(0, port + 0x01);
>  
>  	/* Assert RTS and DTR. */
> -	outb(3, IOBASE + 0x04);
> +	outb(3, port + 0x04);
>  
>  	/* Set the divisor latch. */
> -	reg = inb(IOBASE + 0x03);
> -	outb(reg | 0x80, IOBASE + 0x03);
> +	reg = inb(port + 0x03);
> +	outb(reg | 0x80, port + 0x03);
>  
>  	/* Write the divisor. */
> -	outb(DIVISOR & 0xFF, IOBASE);
> -	outb(DIVISOR >> 8 & 0xFF, IOBASE + 1);
> +	outb(DIVISOR(speed) & 0xFF, port);
> +	outb(DIVISOR(speed) >> 8 & 0xFF, port + 1);
>  
>  	/* Restore the previous value of the divisor. */
> -	outb(reg &= ~0x80, IOBASE + 0x03);
> +	outb(reg &= ~0x80, port + 0x03);
> +}
> +
> +void serial_init(void)
> +{
> +#ifdef CONFIG_SERIAL_SET_SPEED
> +	serial_hardware_init(IOBASE, CONFIG_SERIAL_BAUD_RATE, 8, 0, 1);
>  #endif
>  }
>  
> @@ -81,9 +85,17 @@
>  /*  These are thinly veiled vt100 functions used by curses */
>  
>  #define VT100_CLEAR       "\e[H\e[J"
> +/* These defines will fail if you use bold and reverse at the same time.
> + * Switching off one of them will switch off both. tinycurses knows about
> + * this and does the right thing.
> + */
>  #define VT100_SBOLD       "\e[1m"
>  #define VT100_EBOLD       "\e[m"
> +#define VT100_SREVERSE    "\e[7m"
> +#define VT100_EREVERSE    "\e[m"
>  #define VT100_CURSOR_ADDR "\e[%d;%dH"
> +#define VT100_CURSOR_ON   "\e[?25l"
> +#define VT100_CURSOR_OFF  "\e[?25h"
>  /* The following smacs/rmacs are actually for xterm; a real vt100 has
>     enacs=\E(B\E)0, smacs=^N, rmacs=^O.  */
>  #define VT100_SMACS       "\e(0"
> @@ -112,6 +124,16 @@
>  	serial_putcmd(VT100_EBOLD);
>  }
>  
> +void serial_start_reverse(void)
> +{
> +	serial_putcmd(VT100_SREVERSE);
> +}
> +
> +void serial_end_reverse(void)
> +{
> +	serial_putcmd(VT100_EREVERSE);
> +}
> +
>  void serial_start_altcharset(void)
>  {
>  	serial_putcmd(VT100_SMACS);
> @@ -141,3 +163,11 @@
>  	snprintf(buffer, sizeof(buffer), VT100_CURSOR_ADDR, y + 1, x + 1);
>  	serial_putcmd(buffer);
>  }
> +
> +void serial_cursor_enable(int state)
> +{
> +	if (state)
> +		serial_putcmd(VT100_CURSOR_ON);
> +	else
> +		serial_putcmd(VT100_CURSOR_OFF);
> +}
> 

> --
> coreboot mailing list: coreboot at coreboot.org
> http://www.coreboot.org/mailman/listinfo/coreboot


-- 
Jordan Crouse
Systems Software Development Engineer 
Advanced Micro Devices, Inc.





More information about the coreboot mailing list