* factor out serial hardware init
authorStefan Reinauer <stepan@coresystems.de>
Fri, 26 Sep 2008 18:36:26 +0000 (18:36 +0000)
committerStefan Reinauer <stepan@openbios.org>
Fri, 26 Sep 2008 18:36:26 +0000 (18:36 +0000)
* 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@coresystems.de>
Acked-by: Jordan Crouse <jordan.crouse@amd.com>
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@3604 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1

payloads/libpayload/curses/keyboard.c
payloads/libpayload/curses/tinycurses.c
payloads/libpayload/drivers/serial.c
payloads/libpayload/include/curses.h
payloads/libpayload/include/libpayload.h

index cfb7b769d72be2341ecfb56c13386345bae213a6..5fc54224a0f36ec53230e5ce1d9ae50e0f0d95a5 100644 (file)
@@ -44,6 +44,7 @@ static int _halfdelay = 0;
 
 /* ============== 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 @@ static int cook_serial(unsigned char ch)
                return ch;
        }
 }
+#endif
 
 /* ================ Keyboard ================ */
 
@@ -215,8 +217,14 @@ void curses_enable_vga(int state)
        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 @@ void curses_enable_serial(int state)
        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 329c45c055d4b71fb230e5ed3f951dc005cf39ac..6e83e670645356cacaf86813b4be39a211d869cd 100644 (file)
@@ -77,7 +77,7 @@ static int linebuf_count = 0;
 
 /* Globals */
 int COLORS;            /* Currently unused? */
-int COLOR_PAIRS;
+int COLOR_PAIRS = 255;
 WINDOW *stdscr;
 WINDOW *curscr;
 WINDOW *newscr;
@@ -111,6 +111,7 @@ chtype fallback_acs_map[128] =
        '|',    '<',    '>',    '*',    '!',    'f',    'o',    ' ',
        };
 
+#ifdef CONFIG_SERIAL_CONSOLE
 #ifdef CONFIG_SERIAL_ACS_FALLBACK
 chtype serial_acs_map[128];
 #else
@@ -135,7 +136,9 @@ chtype serial_acs_map[128] =
        'x',    'y',    'z',    '{',    '|',    '}',    '~',    0,
        };
 #endif
+#endif
 
+#ifdef CONFIG_VIDEO_CONSOLE
 /* See acsc of linux. */
 chtype console_acs_map[128] =
        {
@@ -156,6 +159,7 @@ chtype console_acs_map[128] =
        '\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 cbreak(void) { /* TODO */ return 0; }
 // 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 endwin(void)
 // 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 @@ WINDOW *initscr(void)
 
        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 @@ int whline(WINDOW *win, chtype ch, int n)
        (((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 x, y;
-       chtype ch;
        int need_altcharset;
        short fg, bg;
+#endif
+       int x, y;
+       chtype ch;
 
+#ifdef CONFIG_SERIAL_CONSOLE
        serial_end_bold();
        serial_end_altcharset();
+#endif
 
        for (y = 0; y <= win->_maxy; y++) {
 
@@ -713,9 +727,11 @@ int wnoutrefresh(WINDOW *win)
 
                /* 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 @@ int wnoutrefresh(WINDOW *win)
                        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,11 +748,31 @@ int wnoutrefresh(WINDOW *win)
                                                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;
                                        }
                                }
@@ -767,7 +804,8 @@ int wnoutrefresh(WINDOW *win)
                                serial_putchar(ch);
 
                        }
-
+#endif
+#ifdef CONFIG_VIDEO_CONSOLE
                        c = SWAP_RED_BLUE(c);
 
                        if (curses_flags & F_ENABLE_CONSOLE) {
@@ -799,16 +837,21 @@ int wnoutrefresh(WINDOW *win)
                                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 @@ int wprintw(WINDOW *win, const char *fmt, ...)
 
        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 cce43ca2fe5e17b9316613cf1bfae0c4a621939a..95f5b4855e04edcc6d53f3f998eb3e7ebf2d92ce 100644 (file)
 #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 @@ int serial_getchar(void)
 /*  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 @@ void serial_end_bold(void)
        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 @@ void serial_set_cursor(int y, int x)
        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);
+}
index 993bb3c962da9b245053ae58e01ae5824e95e150..6c9307a5986cb94fd489550b2e70883b53e02db1 100644 (file)
@@ -1673,4 +1673,7 @@ extern NCURSES_EXPORT(const char *) _nc_visbuf (const char *);
 void curses_enable_vga(int);
 void curses_enable_serial(int);
 
+int curses_vga_enabled(void);
+int curses_serial_enabled(void);
+
 #endif /* _CURSES_H */
index 7af19dee06358ce0bf881210b3cd10b2ecfa385f..6a4db0e05125916fc34d4e47e7ffcdaa1028b38a 100644 (file)
@@ -131,15 +131,19 @@ int keyboard_getchar(void);
  * @{
  */
 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);
 /** @} */