* 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@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
This commit is contained in:
Stefan Reinauer
2008-09-26 18:36:26 +00:00
committed by Stefan Reinauer
parent 96bcc53071
commit e75c3d85a3
5 changed files with 141 additions and 34 deletions

View File

@ -44,6 +44,7 @@ static int _halfdelay = 0;
/* ============== Serial ==================== */ /* ============== Serial ==================== */
#ifdef CONFIG_SERIAL_CONSOLE
/* We treat serial like a vt100 terminal. For now we /* We treat serial like a vt100 terminal. For now we
do the cooking in here, but we should probably eventually do the cooking in here, but we should probably eventually
pass it to dedicated vt100 code */ pass it to dedicated vt100 code */
@ -135,6 +136,7 @@ static int cook_serial(unsigned char ch)
return ch; return ch;
} }
} }
#endif
/* ================ Keyboard ================ */ /* ================ Keyboard ================ */
@ -215,8 +217,14 @@ void curses_enable_vga(int state)
else else
curses_flags &= ~F_ENABLE_CONSOLE; curses_flags &= ~F_ENABLE_CONSOLE;
} }
int curses_vga_enabled(void)
{
return (curses_flags & F_ENABLE_CONSOLE) != 0;
}
#else #else
void curses_enable_vga(int state) { } void curses_enable_vga(int state) { }
int curses_vga_enabled(void) { return 0; }
#endif #endif
#ifdef CONFIG_SERIAL_CONSOLE #ifdef CONFIG_SERIAL_CONSOLE
@ -227,7 +235,14 @@ void curses_enable_serial(int state)
else else
curses_flags &= ~F_ENABLE_SERIAL; curses_flags &= ~F_ENABLE_SERIAL;
} }
int curses_serial_enabled(void)
{
return (curses_flags & F_ENABLE_SERIAL) != 0;
}
#else #else
void curses_enable_serial(int state) { } void curses_enable_serial(int state) { }
int curses_serial_enabled(void) { return 0; }
#endif #endif

View File

@ -77,7 +77,7 @@ static int linebuf_count = 0;
/* Globals */ /* Globals */
int COLORS; /* Currently unused? */ int COLORS; /* Currently unused? */
int COLOR_PAIRS; int COLOR_PAIRS = 255;
WINDOW *stdscr; WINDOW *stdscr;
WINDOW *curscr; WINDOW *curscr;
WINDOW *newscr; WINDOW *newscr;
@ -111,6 +111,7 @@ chtype fallback_acs_map[128] =
'|', '<', '>', '*', '!', 'f', 'o', ' ', '|', '<', '>', '*', '!', 'f', 'o', ' ',
}; };
#ifdef CONFIG_SERIAL_CONSOLE
#ifdef CONFIG_SERIAL_ACS_FALLBACK #ifdef CONFIG_SERIAL_ACS_FALLBACK
chtype serial_acs_map[128]; chtype serial_acs_map[128];
#else #else
@ -135,7 +136,9 @@ chtype serial_acs_map[128] =
'x', 'y', 'z', '{', '|', '}', '~', 0, 'x', 'y', 'z', '{', '|', '}', '~', 0,
}; };
#endif #endif
#endif
#ifdef CONFIG_VIDEO_CONSOLE
/* See acsc of linux. */ /* See acsc of linux. */
chtype console_acs_map[128] = chtype console_acs_map[128] =
{ {
@ -156,6 +159,7 @@ chtype console_acs_map[128] =
'\304', '\304', '\304', '_', '\303', '\264', '\301', '\302', '\304', '\304', '\304', '_', '\303', '\264', '\301', '\302',
'\263', '\363', '\362', '\343', '\330', '\234', '\376', 0, '\263', '\363', '\362', '\343', '\330', '\234', '\376', 0,
}; };
#endif
// FIXME: Ugly (and insecure!) hack! // FIXME: Ugly (and insecure!) hack!
char sprintf_tmp[1024]; 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 color_content(short color, short *r, short *g, short *b) {}
int curs_set(int on) int curs_set(int on)
{ {
#ifdef CONFIG_SERIAL_CONSOLE
if (curses_flags & F_ENABLE_SERIAL) { if (curses_flags & F_ENABLE_SERIAL) {
// TODO serial_cursor_enable(on);
} }
#endif
#ifdef CONFIG_VIDEO_CONSOLE
if (curses_flags & F_ENABLE_CONSOLE) { if (curses_flags & F_ENABLE_CONSOLE) {
video_console_cursor_enable(on); video_console_cursor_enable(on);
} }
#endif
return OK; return OK;
} }
@ -284,7 +291,7 @@ int endwin(void)
// int flash(void) {} // int flash(void) {}
int flushinp(void) { /* TODO */ return 0; } int flushinp(void) { /* TODO */ return 0; }
// WINDOW *getwin (FILE *) {} // WINDOW *getwin (FILE *) {}
bool has_colors (void) { /* TODO */ return(*(bool *)0); } bool has_colors (void) { return(TRUE); }
// bool has_ic (void) {} // bool has_ic (void) {}
// bool has_il (void) {} // bool has_il (void) {}
// void idcok (WINDOW *, bool) {} // void idcok (WINDOW *, bool) {}
@ -300,21 +307,23 @@ WINDOW *initscr(void)
for (i = 0; i < 128; i++) for (i = 0; i < 128; i++)
acs_map[i] = (chtype) i | A_ALTCHARSET; acs_map[i] = (chtype) i | A_ALTCHARSET;
#ifdef CONFIG_SERIAL_CONSOLE
if (curses_flags & F_ENABLE_SERIAL) { if (curses_flags & F_ENABLE_SERIAL) {
serial_clear(); serial_clear();
} }
#endif
#ifdef CONFIG_VIDEO_CONSOLE
if (curses_flags & F_ENABLE_CONSOLE) { if (curses_flags & F_ENABLE_CONSOLE) {
/* Clear the screen and kill the cursor */ /* Clear the screen and kill the cursor */
video_console_clear(); video_console_clear();
video_console_cursor_enable(0); video_console_cursor_enable(0);
} }
#endif
// Speaker init? // Speaker init?
stdscr = newwin(SCREEN_Y, SCREEN_X, 0, 0); stdscr = newwin(SCREEN_Y, SCREEN_X + 1, 0, 0);
// TODO: curscr, newscr? // TODO: curscr, newscr?
werase(stdscr); werase(stdscr);
@ -693,18 +702,23 @@ int whline(WINDOW *win, chtype ch, int n)
(((c) & 0x4400) >> 2) | ((c) & 0xAA00) | (((c) & 0x1100) << 2) (((c) & 0x4400) >> 2) | ((c) & 0xAA00) | (((c) & 0x1100) << 2)
int wnoutrefresh(WINDOW *win) int wnoutrefresh(WINDOW *win)
{ {
#ifdef CONFIG_SERIAL_CONSOLE
// FIXME. // FIXME.
int serial_is_bold = 0; int serial_is_bold = 0;
int serial_is_reverse = 0;
int serial_is_altcharset = 0; int serial_is_altcharset = 0;
int serial_cur_pair = 0; int serial_cur_pair = 0;
int x, y;
chtype ch;
int need_altcharset; int need_altcharset;
short fg, bg; short fg, bg;
#endif
int x, y;
chtype ch;
#ifdef CONFIG_SERIAL_CONSOLE
serial_end_bold(); serial_end_bold();
serial_end_altcharset(); serial_end_altcharset();
#endif
for (y = 0; y <= win->_maxy; y++) { for (y = 0; y <= win->_maxy; y++) {
@ -713,9 +727,11 @@ int wnoutrefresh(WINDOW *win)
/* Position the serial cursor */ /* Position the serial cursor */
#ifdef CONFIG_SERIAL_CONSOLE
if (curses_flags & F_ENABLE_SERIAL) if (curses_flags & F_ENABLE_SERIAL)
serial_set_cursor(win->_begy + y, win->_begx + serial_set_cursor(win->_begy + y, win->_begx +
win->_line[y].firstchar); win->_line[y].firstchar);
#endif
for (x = win->_line[y].firstchar; x <= win->_line[y].lastchar; x++) { for (x = win->_line[y].firstchar; x <= win->_line[y].lastchar; x++) {
attr_t attr = win->_line[y].text[x].attr; attr_t attr = win->_line[y].text[x].attr;
@ -723,6 +739,7 @@ int wnoutrefresh(WINDOW *win)
unsigned int c = unsigned int c =
((int)color_pairs[PAIR_NUMBER(attr)]) << 8; ((int)color_pairs[PAIR_NUMBER(attr)]) << 8;
#ifdef CONFIG_SERIAL_CONSOLE
if (curses_flags & F_ENABLE_SERIAL) { if (curses_flags & F_ENABLE_SERIAL) {
ch = win->_line[y].text[x].chars[0]; ch = win->_line[y].text[x].chars[0];
@ -731,11 +748,31 @@ int wnoutrefresh(WINDOW *win)
serial_start_bold(); serial_start_bold();
serial_is_bold = 1; serial_is_bold = 1;
} }
} } else {
else {
if (serial_is_bold) { if (serial_is_bold) {
serial_end_bold(); serial_end_bold();
serial_is_bold = 0; 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; serial_cur_pair = 0;
} }
} }
@ -767,7 +804,8 @@ int wnoutrefresh(WINDOW *win)
serial_putchar(ch); serial_putchar(ch);
} }
#endif
#ifdef CONFIG_VIDEO_CONSOLE
c = SWAP_RED_BLUE(c); c = SWAP_RED_BLUE(c);
if (curses_flags & F_ENABLE_CONSOLE) { if (curses_flags & F_ENABLE_CONSOLE) {
@ -799,16 +837,21 @@ int wnoutrefresh(WINDOW *win)
c |= (chtype) (ch & 0xff); c |= (chtype) (ch & 0xff);
video_console_putc(win->_begy + y, win->_begx + x, c); video_console_putc(win->_begy + y, win->_begx + x, c);
} }
#endif
} }
win->_line[y].firstchar = _NOCHANGE; win->_line[y].firstchar = _NOCHANGE;
win->_line[y].lastchar = _NOCHANGE; win->_line[y].lastchar = _NOCHANGE;
} }
#ifdef CONFIG_SERIAL_CONSOLE
if (curses_flags & F_ENABLE_SERIAL) if (curses_flags & F_ENABLE_SERIAL)
serial_set_cursor(win->_begy + win->_cury, win->_begx + win->_curx); serial_set_cursor(win->_begy + win->_cury, win->_begx + win->_curx);
#endif
#ifdef CONFIG_VIDEO_CONSOLE
if (curses_flags & F_ENABLE_CONSOLE) if (curses_flags & F_ENABLE_CONSOLE)
video_console_set_cursor(win->_begx + win->_curx, win->_begy + win->_cury); video_console_set_cursor(win->_begx + win->_curx, win->_begy + win->_cury);
#endif
return OK; return OK;
} }
@ -823,7 +866,19 @@ int wprintw(WINDOW *win, const char *fmt, ...)
return code; 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) int wrefresh(WINDOW *win)
{ {
// FIXME // FIXME

View File

@ -32,32 +32,36 @@
#include <libpayload.h> #include <libpayload.h>
#define IOBASE lib_sysinfo.ser_ioport #define IOBASE lib_sysinfo.ser_ioport
#define DIVISOR(x) (115200 / x)
#ifdef CONFIG_SERIAL_SET_SPEED void serial_hardware_init(int port, int speed, int word_bits, int parity, int stop_bits)
#define DIVISOR (115200 / CONFIG_SERIAL_BAUD_RATE) {
#endif unsigned char reg;
/* We will assume 8n1 for now. Does anyone use anything else these days? */
/* Disable interrupts. */
outb(0, port + 0x01);
/* Assert RTS and DTR. */
outb(3, port + 0x04);
/* Set the divisor latch. */
reg = inb(port + 0x03);
outb(reg | 0x80, port + 0x03);
/* Write the divisor. */
outb(DIVISOR(speed) & 0xFF, port);
outb(DIVISOR(speed) >> 8 & 0xFF, port + 1);
/* Restore the previous value of the divisor. */
outb(reg &= ~0x80, port + 0x03);
}
void serial_init(void) void serial_init(void)
{ {
#ifdef CONFIG_SERIAL_SET_SPEED #ifdef CONFIG_SERIAL_SET_SPEED
unsigned char reg; serial_hardware_init(IOBASE, CONFIG_SERIAL_BAUD_RATE, 8, 0, 1);
/* Disable interrupts. */
outb(0, IOBASE + 0x01);
/* Assert RTS and DTR. */
outb(3, IOBASE + 0x04);
/* Set the divisor latch. */
reg = inb(IOBASE + 0x03);
outb(reg | 0x80, IOBASE + 0x03);
/* Write the divisor. */
outb(DIVISOR & 0xFF, IOBASE);
outb(DIVISOR >> 8 & 0xFF, IOBASE + 1);
/* Restore the previous value of the divisor. */
outb(reg &= ~0x80, IOBASE + 0x03);
#endif #endif
} }
@ -81,9 +85,17 @@ int serial_getchar(void)
/* These are thinly veiled vt100 functions used by curses */ /* These are thinly veiled vt100 functions used by curses */
#define VT100_CLEAR "\e[H\e[J" #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_SBOLD "\e[1m"
#define VT100_EBOLD "\e[m" #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_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 /* The following smacs/rmacs are actually for xterm; a real vt100 has
enacs=\E(B\E)0, smacs=^N, rmacs=^O. */ enacs=\E(B\E)0, smacs=^N, rmacs=^O. */
#define VT100_SMACS "\e(0" #define VT100_SMACS "\e(0"
@ -112,6 +124,16 @@ void serial_end_bold(void)
serial_putcmd(VT100_EBOLD); 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) void serial_start_altcharset(void)
{ {
serial_putcmd(VT100_SMACS); 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); snprintf(buffer, sizeof(buffer), VT100_CURSOR_ADDR, y + 1, x + 1);
serial_putcmd(buffer); serial_putcmd(buffer);
} }
void serial_cursor_enable(int state)
{
if (state)
serial_putcmd(VT100_CURSOR_ON);
else
serial_putcmd(VT100_CURSOR_OFF);
}

View File

@ -1673,4 +1673,7 @@ extern NCURSES_EXPORT(const char *) _nc_visbuf (const char *);
void curses_enable_vga(int); void curses_enable_vga(int);
void curses_enable_serial(int); void curses_enable_serial(int);
int curses_vga_enabled(void);
int curses_serial_enabled(void);
#endif /* _CURSES_H */ #endif /* _CURSES_H */

View File

@ -131,15 +131,19 @@ int keyboard_getchar(void);
* @{ * @{
*/ */
void serial_init(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); void serial_putchar(unsigned char c);
int serial_havechar(void); int serial_havechar(void);
int serial_getchar(void); int serial_getchar(void);
void serial_clear(void); void serial_clear(void);
void serial_start_bold(void); void serial_start_bold(void);
void serial_end_bold(void); void serial_end_bold(void);
void serial_start_reverse(void);
void serial_end_reverse(void);
void serial_start_altcharset(void); void serial_start_altcharset(void);
void serial_end_altcharset(void); void serial_end_altcharset(void);
void serial_set_color(short fg, short bg); void serial_set_color(short fg, short bg);
void serial_cursor_enable(int state);
void serial_set_cursor(int y, int x); void serial_set_cursor(int y, int x);
/** @} */ /** @} */