[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.de • http://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