[coreboot] r3370 - in trunk/payloads/libpayload: curses drivers include

svn at coreboot.org svn at coreboot.org
Fri Jun 20 02:01:42 CEST 2008


Author: jcrouse
Date: 2008-06-20 02:01:42 +0200 (Fri, 20 Jun 2008)
New Revision: 3370

Modified:
   trunk/payloads/libpayload/curses/keyboard.c
   trunk/payloads/libpayload/curses/tinycurses.c
   trunk/payloads/libpayload/drivers/serial.c
   trunk/payloads/libpayload/include/libpayload.h
Log:
libpayload:  Support curses for serial

Support the curses interface over serial by supporting a minimal vt100
terminal.

Signed-off-by: Jordan Crouse <jordan.crouse at amd.com>
Acked-by: Ronald G. Minnich <rminnich at gmail.com>


Modified: trunk/payloads/libpayload/curses/keyboard.c
===================================================================
--- trunk/payloads/libpayload/curses/keyboard.c	2008-06-20 00:01:14 UTC (rev 3369)
+++ trunk/payloads/libpayload/curses/keyboard.c	2008-06-20 00:01:42 UTC (rev 3370)
@@ -43,11 +43,89 @@
 
 /* ============== Serial ==================== */
 
-/* FIXME:  Cook the serial correctly */
+/* 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 */
 
+static int getkeyseq(char *buffer, int len)
+{
+	int i;
+
+	for(i = 0; i < 75; i++) {
+		if (serial_havechar())
+			break;
+		mdelay(1);
+	}
+
+	if (i == 75)
+		return len;
+
+	buffer[len++] = serial_getchar();
+	return getkeyseq(buffer, len);
+}
+
+static struct {
+	char *seq;
+	int key;
+} escape_codes[] = {
+	{ "[A", KEY_UP },
+	{ "[B", KEY_DOWN },
+	{ "[C", KEY_RIGHT },
+	{ "[D", KEY_LEFT },
+	{ "OP", KEY_F(1) },
+	{ "OQ", KEY_F(2) },
+	{ "OR", KEY_F(3) },
+	{ "OS", KEY_F(4) },
+	{ "[15~", KEY_F(5) },
+	{ "[17~", KEY_F(6) },
+	{ "[18~", KEY_F(7) },
+	{ "[19~", KEY_F(8) },
+	{ "[20~", KEY_F(9) },
+	{ "[21~", KEY_F(10) },
+	{ "[24~", KEY_F(12) },
+	{ NULL },
+};
+
+static int handle_escape(void)
+{
+	char buffer[5];
+	int len = getkeyseq(buffer, 0);
+	int i, t;
+
+	if (len == 0)
+		return 27;
+
+	for(i = 0; escape_codes[i].seq != NULL; i++) {
+		char *p = escape_codes[i].seq;
+
+		for(t = 0; t < len; t++) {
+			if (!*p || *p != buffer[t])
+				break;
+			p++;
+		}
+
+		if (t == len)
+			return escape_codes[i].key;
+	}
+
+	return 0;
+}
+
 static int cook_serial(unsigned char ch)
 {
-	return (int) ch;
+	switch(ch) {
+	case 8:
+		return KEY_BACKSPACE;
+
+	case 13:
+		return KEY_ENTER;
+
+	case 27:
+		return handle_escape();
+
+	default:
+		return ch;
+	}
 }
 
 /* ================ Keyboard ================ */

Modified: trunk/payloads/libpayload/curses/tinycurses.c
===================================================================
--- trunk/payloads/libpayload/curses/tinycurses.c	2008-06-20 00:01:14 UTC (rev 3369)
+++ trunk/payloads/libpayload/curses/tinycurses.c	2008-06-20 00:01:42 UTC (rev 3370)
@@ -218,6 +218,10 @@
 	// newterm(name, stdout, stdin);
 	// def_prog_mode();
 
+	if (curses_flags & F_ENABLE_SERIAL) {
+		serial_clear();
+	}
+
 	if (curses_flags & F_ENABLE_CONSOLE) {
 		/* Clear the screen and kill the cursor */
 
@@ -586,20 +590,48 @@
 	win->_flags |= _HASMOVED;
 	return OK;
 }
+
 int wnoutrefresh(WINDOW *win)
 {
 	// FIXME.
+	int serial_is_bold = 0;
+
 	int x, y;
 
+	serial_end_bold();
+
 	for (y = 0; y <= win->_maxy; y++) {
+
+		/* Position the serial cursor */
+
+		if (curses_flags & F_ENABLE_SERIAL)
+			serial_set_cursor(win->_begy + y, win->_begx);
+
 		for (x = 0; x <= win->_maxx; x++) {
-			if (curses_flags & F_ENABLE_SERIAL)
+			attr_t attr = win->_line[y].text[x].attr;
+
+			unsigned int c =
+				((int)color_pairs[PAIR_NUMBER(attr)]) << 8;
+
+			if (curses_flags & F_ENABLE_SERIAL) {
+
+				if (attr & A_BOLD) {
+					if (!serial_is_bold) {
+						serial_start_bold();
+						serial_is_bold = 1;
+					}
+				}
+				else {
+					if (serial_is_bold) {
+						serial_end_bold();
+						serial_is_bold = 0;
+					}
+				}
+
 				serial_putchar(win->_line[y].text[x].chars[0]);
+			}
 
 			if (curses_flags & F_ENABLE_CONSOLE) {
-				attr_t attr = win->_line[y].text[x].attr;
-				unsigned int c =
-				  ((int)color_pairs[PAIR_NUMBER(attr)]) << 8;
 
 				/* Handle some of the attributes. */
 				if (attr & A_BOLD)

Modified: trunk/payloads/libpayload/drivers/serial.c
===================================================================
--- trunk/payloads/libpayload/drivers/serial.c	2008-06-20 00:01:14 UTC (rev 3369)
+++ trunk/payloads/libpayload/drivers/serial.c	2008-06-20 00:01:42 UTC (rev 3370)
@@ -35,6 +35,25 @@
 #define DIVISOR (115200 / CONFIG_SERIAL_BAUD_RATE)
 #endif
 
+/* This is a hack - we convert the drawing characters to ASCII */
+
+static unsigned char translate_special_chars(unsigned char c)
+{
+	switch(c) {
+	case 196:
+		return '-';
+	case 179:
+		return '|';
+	case 218:
+	case 191:
+	case 192:
+	case 217:
+		return '+';
+	default:
+		return ' ';
+	}
+}
+
 void serial_init(void)
 {
 #ifdef CONFIG_SERIAL_SET_SPEED
@@ -61,6 +80,9 @@
 
 void serial_putchar(unsigned char c)
 {
+	if (c > 127)
+		c = translate_special_chars(c);
+
 	while ((inb(IOBASE + 0x05) & 0x20) == 0) ;
 	outb(c, IOBASE);
 }
@@ -75,3 +97,38 @@
 	while (!serial_havechar()) ;
 	return (int)inb(IOBASE);
 }
+
+/*  These are thinly veiled vt100 functions used by curses */
+
+#define VT100_CLEAR       "\e[H\e[J"
+#define VT100_SBOLD       "\e[7m"
+#define VT100_EBOLD       "\e[m"
+#define VT100_CURSOR_ADDR "\e[%d;%dH"
+
+static void serial_putcmd(char *str)
+{
+	while(*str)
+		serial_putchar(*(str++));
+}
+
+void serial_clear(void)
+{
+	serial_putcmd(VT100_CLEAR);
+}
+
+void serial_start_bold(void)
+{
+	serial_putcmd(VT100_SBOLD);
+}
+
+void serial_end_bold(void)
+{
+	serial_putcmd(VT100_EBOLD);
+}
+
+void serial_set_cursor(int y, int x)
+{
+	char buffer[32];
+	snprintf(buffer, sizeof(buffer), VT100_CURSOR_ADDR, y, x);
+	serial_putcmd(buffer);
+}

Modified: trunk/payloads/libpayload/include/libpayload.h
===================================================================
--- trunk/payloads/libpayload/include/libpayload.h	2008-06-20 00:01:14 UTC (rev 3369)
+++ trunk/payloads/libpayload/include/libpayload.h	2008-06-20 00:01:42 UTC (rev 3370)
@@ -107,6 +107,11 @@
 int serial_havechar(void);
 int serial_getchar(void);
 
+void serial_clear(void);
+void serial_start_bold(void);
+void serial_end_bold(void);
+void serial_set_cursor(int y, int x);
+
 /* drivers/speaker.c */
 void speaker_enable(u16 freq);
 void speaker_disable(void);





More information about the coreboot mailing list