svn commit: r351900 - in head/stand: . efi/include efi/libefi efi/loader efi/loader/arch/amd64 efi/loader/arch/i386 forth i386/libi386 lua

Toomas Soome tsoome at FreeBSD.org
Thu Sep 5 22:15:53 UTC 2019


Author: tsoome
Date: Thu Sep  5 22:15:50 2019
New Revision: 351900
URL: https://svnweb.freebsd.org/changeset/base/351900

Log:
  loader: use teken teminal emulator for x86 and uefi
  
  Replace mini cons25 emulator with teken, this does enable us proper console
  terminal for loader and will make it possible to implement different
  back end callbacks to draw to screen.
  
  At this time we still only "draw" in text mode.

Modified:
  head/stand/defs.mk
  head/stand/efi/include/efilib.h
  head/stand/efi/libefi/Makefile
  head/stand/efi/libefi/efi_console.c
  head/stand/efi/loader/arch/amd64/Makefile.inc
  head/stand/efi/loader/arch/i386/Makefile.inc
  head/stand/efi/loader/main.c
  head/stand/forth/frames.4th
  head/stand/i386/libi386/Makefile
  head/stand/i386/libi386/vidconsole.c
  head/stand/lua/drawer.lua

Modified: head/stand/defs.mk
==============================================================================
--- head/stand/defs.mk	Thu Sep  5 21:43:33 2019	(r351899)
+++ head/stand/defs.mk	Thu Sep  5 22:15:50 2019	(r351900)
@@ -180,6 +180,13 @@ CFLAGS+=-I.
 
 all: ${PROG}
 
+CLEANFILES+= teken_state.h
+teken.c: teken_state.h
+
+teken_state.h: ${SYSDIR}/teken/sequences
+	awk -f ${SYSDIR}/teken/gensequences \
+		${SYSDIR}/teken/sequences > teken_state.h
+
 .if !defined(NO_OBJ)
 _ILINKS=machine
 .if ${MACHINE} != ${MACHINE_CPUARCH} && ${MACHINE} != "arm64"

Modified: head/stand/efi/include/efilib.h
==============================================================================
--- head/stand/efi/include/efilib.h	Thu Sep  5 21:43:33 2019	(r351899)
+++ head/stand/efi/include/efilib.h	Thu Sep  5 22:15:50 2019	(r351900)
@@ -106,6 +106,7 @@ EFI_STATUS errno_to_efi_status(int errno);
 void efi_time_init(void);
 void efi_time_fini(void);
 
+bool efi_cons_update_mode(void);
 EFI_STATUS efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE* Xsystab);
 
 EFI_STATUS main(int argc, CHAR16 *argv[]);

Modified: head/stand/efi/libefi/Makefile
==============================================================================
--- head/stand/efi/libefi/Makefile	Thu Sep  5 21:43:33 2019	(r351899)
+++ head/stand/efi/libefi/Makefile	Thu Sep  5 22:15:50 2019	(r351900)
@@ -22,6 +22,9 @@ SRCS=	delay.c \
 	libefi.c \
 	wchar.c
 
+.PATH:  ${SYSDIR}/teken
+SRCS+=  teken.c
+
 .if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386"
 SRCS+=	time.c
 .elif ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "arm"
@@ -45,6 +48,8 @@ CFLAGS+= -fPIC -mno-red-zone
 .endif
 CFLAGS+= -I${EFIINC}
 CFLAGS+= -I${EFIINCMD}
+CFLAGS.efi_console.c+= -I${SRCTOP}/sys/teken
+CFLAGS.teken.c+= -I${SRCTOP}/sys/teken
 .if ${MK_LOADER_ZFS} != "no"
 CFLAGS+=	-I${ZFSSRC}
 CFLAGS+=	-DEFI_ZFS_BOOT
@@ -55,10 +60,5 @@ CFLAGS+= -I${LDRSRC}
 
 # Handle FreeBSD specific %b and %D printf format specifiers
 CFLAGS+= ${FORMAT_EXTENSIONS}
-
-# Do not use TERM_EMU on arm and arm64 as it doesn't behave well with serial console
-.if ${MACHINE_CPUARCH} != "arm" && ${MACHINE_CPUARCH} != "aarch64"
-CFLAGS+= -DTERM_EMU
-.endif
 
 .include <bsd.lib.mk>

Modified: head/stand/efi/libefi/efi_console.c
==============================================================================
--- head/stand/efi/libefi/efi_console.c	Thu Sep  5 21:43:33 2019	(r351899)
+++ head/stand/efi/libefi/efi_console.c	Thu Sep  5 22:15:50 2019	(r351900)
@@ -29,6 +29,7 @@ __FBSDID("$FreeBSD$");
 
 #include <efi.h>
 #include <efilib.h>
+#include <teken.h>
 
 #include "bootstrap.h"
 
@@ -37,26 +38,57 @@ static SIMPLE_TEXT_OUTPUT_INTERFACE	*conout;
 static SIMPLE_INPUT_INTERFACE		*conin;
 static EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *coninex;
 
-#ifdef TERM_EMU
-#define	DEFAULT_FGCOLOR	EFI_LIGHTGRAY
-#define	DEFAULT_BGCOLOR	EFI_BLACK
+static tf_bell_t	efi_cons_bell;
+static tf_cursor_t	efi_text_cursor;
+static tf_putchar_t	efi_text_putchar;
+static tf_fill_t	efi_text_fill;
+static tf_copy_t	efi_text_copy;
+static tf_param_t	efi_text_param;
+static tf_respond_t	efi_cons_respond;
 
-#define	MAXARGS	8
-static int args[MAXARGS], argc;
-static int fg_c, bg_c, curx, cury;
-static int esc;
+static teken_funcs_t tf = {
+	.tf_bell	= efi_cons_bell,
+	.tf_cursor	= efi_text_cursor,
+	.tf_putchar	= efi_text_putchar,
+	.tf_fill	= efi_text_fill,
+	.tf_copy	= efi_text_copy,
+	.tf_param	= efi_text_param,
+	.tf_respond	= efi_cons_respond,
+};
 
-void get_pos(int *x, int *y);
-void curs_move(int *_x, int *_y, int x, int y);
-static void CL(int);
-void HO(void);
-void end_term(void);
-#endif
+teken_t teken;
+teken_pos_t tp;
 
+struct text_pixel {
+	teken_char_t c;
+	teken_attr_t a;
+};
+
+static struct text_pixel *buffer;
+
 #define	KEYBUFSZ 10
 static unsigned keybuf[KEYBUFSZ];	/* keybuf for extended codes */
 static int key_pending;
 
+static const unsigned char teken_color_to_efi_color[16] = {
+	EFI_BLACK,
+	EFI_RED,
+	EFI_GREEN,
+	EFI_BROWN,
+	EFI_BLUE,
+	EFI_MAGENTA,
+	EFI_CYAN,
+	EFI_LIGHTGRAY,
+	EFI_DARKGRAY,
+	EFI_LIGHTRED,
+	EFI_LIGHTGREEN,
+	EFI_YELLOW,
+	EFI_LIGHTBLUE,
+	EFI_LIGHTMAGENTA,
+	EFI_LIGHTCYAN,
+	EFI_WHITE
+};
+
 static void efi_cons_probe(struct console *);
 static int efi_cons_init(int);
 void efi_cons_putchar(int);
@@ -75,378 +107,319 @@ struct console efi_console = {
 	efi_cons_poll
 };
 
-#ifdef TERM_EMU
-
-/* Get cursor position. */
-void
-get_pos(int *x, int *y)
+/*
+ * Not implemented.
+ */
+static void
+efi_cons_bell(void *s __unused)
 {
-	*x = conout->Mode->CursorColumn;
-	*y = conout->Mode->CursorRow;
 }
 
-/* Move cursor to x rows and y cols (0-based). */
-void
-curs_move(int *_x, int *_y, int x, int y)
+static void
+efi_text_cursor(void *s __unused, const teken_pos_t *p)
 {
-	conout->SetCursorPosition(conout, x, y);
-	if (_x != NULL)
-		*_x = conout->Mode->CursorColumn;
-	if (_y != NULL)
-		*_y = conout->Mode->CursorRow;
+	UINTN row, col;
+
+	(void) conout->QueryMode(conout, conout->Mode->Mode, &col, &row);
+
+	if (p->tp_col == col)
+		col = p->tp_col - 1;
+	else
+		col = p->tp_col;
+
+	if (p->tp_row == row)
+		row = p->tp_row - 1;
+	else
+		row = p->tp_row;
+
+	conout->SetCursorPosition(conout, col, row);
 }
 
-/* Clear internal state of the terminal emulation code. */
-void
-end_term(void)
+static void
+efi_text_printchar(const teken_pos_t *p)
 {
-	esc = 0;
-	argc = -1;
-}
+	UINTN a, attr;
+	struct text_pixel *px;
+	teken_color_t fg, bg, tmp;
 
-#endif
+	px = buffer + p->tp_col + p->tp_row * tp.tp_col;
+	a = conout->Mode->Attribute;
 
+	fg = teken_256to16(px->a.ta_fgcolor);
+	bg = teken_256to16(px->a.ta_bgcolor);
+	if (px->a.ta_format & TF_BOLD)
+		fg |= TC_LIGHT;
+	if (px->a.ta_format & TF_BLINK)
+		bg |= TC_LIGHT;
+
+	if (px->a.ta_format & TF_REVERSE) {
+		tmp = fg;
+		fg = bg;
+		bg = tmp;
+	}
+
+	attr = EFI_TEXT_ATTR(teken_color_to_efi_color[fg],
+	    teken_color_to_efi_color[bg]);
+
+	conout->SetCursorPosition(conout, p->tp_col, p->tp_row);
+
+	/* to prvent autoscroll, skip print of lower right char */
+	if (p->tp_row == tp.tp_row - 1 &&
+	    p->tp_col == tp.tp_col - 1)
+		return;
+
+	(void) conout->SetAttribute(conout, attr);
+	efi_cons_efiputchar(px->c);
+	(void) conout->SetAttribute(conout, a);
+}
+
 static void
-efi_cons_probe(struct console *cp)
+efi_text_putchar(void *s __unused, const teken_pos_t *p, teken_char_t c,
+    const teken_attr_t *a)
 {
-	conout = ST->ConOut;
-	conin = ST->ConIn;
-	cp->c_flags |= C_PRESENTIN | C_PRESENTOUT;
+	EFI_STATUS status;
+	int idx;
+
+	idx = p->tp_col + p->tp_row * tp.tp_col;
+	buffer[idx].c = c;
+	buffer[idx].a = *a;
+	efi_text_printchar(p);
 }
 
-static int
-efi_cons_init(int arg)
+static void
+efi_text_fill(void *s, const teken_rect_t *r, teken_char_t c,
+    const teken_attr_t *a)
 {
-	EFI_STATUS status;
+	teken_pos_t p;
+	UINTN row, col;
 
-#ifdef TERM_EMU
-	conout->SetAttribute(conout, EFI_TEXT_ATTR(DEFAULT_FGCOLOR,
-	    DEFAULT_BGCOLOR));
-	end_term();
-	get_pos(&curx, &cury);
-	curs_move(&curx, &cury, curx, cury);
-	fg_c = DEFAULT_FGCOLOR;
-	bg_c = DEFAULT_BGCOLOR;
-#endif
+	(void) conout->QueryMode(conout, conout->Mode->Mode, &col, &row);
+
+	conout->EnableCursor(conout, FALSE);
+	for (p.tp_row = r->tr_begin.tp_row; p.tp_row < r->tr_end.tp_row;
+	    p.tp_row++)
+		for (p.tp_col = r->tr_begin.tp_col;
+		    p.tp_col < r->tr_end.tp_col; p.tp_col++)
+			efi_text_putchar(s, &p, c, a);
 	conout->EnableCursor(conout, TRUE);
-	status = BS->OpenProtocol(ST->ConsoleInHandle, &simple_input_ex_guid,
-	    (void **)&coninex, IH, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
-	if (status != EFI_SUCCESS)
-		coninex = NULL;
-	return (0);
 }
 
+static bool
+efi_same_pixel(struct text_pixel *px1, struct text_pixel *px2)
+{
+	if (px1->c != px2->c)
+		return (false);
+
+	if (px1->a.ta_format != px2->a.ta_format)
+		return (false);
+	if (px1->a.ta_fgcolor != px2->a.ta_fgcolor)
+		return (false);
+	if (px1->a.ta_bgcolor != px2->a.ta_bgcolor)
+		return (false);
+
+	return (true);
+}
+
 static void
-efi_cons_rawputchar(int c)
+efi_text_copy(void *ptr __unused, const teken_rect_t *r, const teken_pos_t *p)
 {
-	int i;
-	UINTN x, y;
-	conout->QueryMode(conout, conout->Mode->Mode, &x, &y);
+	int srow, drow;
+	int nrow, ncol, x, y; /* Has to be signed - >= 0 comparison */
+	teken_pos_t d, s;
 
-	if (c == '\t') {
-		int n;
+	/*
+	 * Copying is a little tricky. We must make sure we do it in
+	 * correct order, to make sure we don't overwrite our own data.
+	 */
 
-		n = 8 - ((conout->Mode->CursorColumn + 8) % 8);
-		for (i = 0; i < n; i++)
-			efi_cons_rawputchar(' ');
+	nrow = r->tr_end.tp_row - r->tr_begin.tp_row;
+	ncol = r->tr_end.tp_col - r->tr_begin.tp_col;
+
+	conout->EnableCursor(conout, FALSE);
+	if (p->tp_row < r->tr_begin.tp_row) {
+		/* Copy from bottom to top. */
+		for (y = 0; y < nrow; y++) {
+			d.tp_row = p->tp_row + y;
+			s.tp_row = r->tr_begin.tp_row + y;
+			drow = d.tp_row * tp.tp_col;
+			srow = s.tp_row * tp.tp_col;
+			for (x = 0; x < ncol; x++) {
+				d.tp_col = p->tp_col + x;
+				s.tp_col = r->tr_begin.tp_col + x;
+
+				if (!efi_same_pixel(
+				    &buffer[d.tp_col + drow],
+				    &buffer[s.tp_col + srow])) {
+					buffer[d.tp_col + drow] =
+					    buffer[s.tp_col + srow];
+					efi_text_printchar(&d);
+				}
+			}
+		}
 	} else {
-#ifndef	TERM_EMU
-		if (c == '\n')
-			efi_cons_efiputchar('\r');
-		efi_cons_efiputchar(c);
-#else
-		switch (c) {
-		case '\r':
-			curx = 0;
-			efi_cons_efiputchar('\r');
-			return;
-		case '\n':
-			efi_cons_efiputchar('\n');
-			efi_cons_efiputchar('\r');
-			cury++;
-			if (cury >= y)
-				cury--;
-			curx = 0;
-			return;
-		case '\b':
-			if (curx > 0) {
-				efi_cons_efiputchar('\b');
-				curx--;
+		/* Copy from top to bottom. */
+		if (p->tp_col < r->tr_begin.tp_col) {
+			/* Copy from right to left. */
+			for (y = nrow - 1; y >= 0; y--) {
+				d.tp_row = p->tp_row + y;
+				s.tp_row = r->tr_begin.tp_row + y;
+				drow = d.tp_row * tp.tp_col;
+				srow = s.tp_row * tp.tp_col;
+				for (x = 0; x < ncol; x++) {
+					d.tp_col = p->tp_col + x;
+					s.tp_col = r->tr_begin.tp_col + x;
+
+					if (!efi_same_pixel(
+					    &buffer[d.tp_col + drow],
+					    &buffer[s.tp_col + srow])) {
+						buffer[d.tp_col + drow] =
+						    buffer[s.tp_col + srow];
+						efi_text_printchar(&d);
+					}
+				}
 			}
-			return;
-		default:
-			efi_cons_efiputchar(c);
-			curx++;
-			if (curx > x-1) {
-				curx = 0;
-				cury++;
+		} else {
+			/* Copy from left to right. */
+			for (y = nrow - 1; y >= 0; y--) {
+				d.tp_row = p->tp_row + y;
+				s.tp_row = r->tr_begin.tp_row + y;
+				drow = d.tp_row * tp.tp_col;
+				srow = s.tp_row * tp.tp_col;
+				for (x = ncol - 1; x >= 0; x--) {
+					d.tp_col = p->tp_col + x;
+					s.tp_col = r->tr_begin.tp_col + x;
+
+					if (!efi_same_pixel(
+					    &buffer[d.tp_col + drow],
+					    &buffer[s.tp_col + srow])) {
+						buffer[d.tp_col + drow] =
+						    buffer[s.tp_col + srow];
+						efi_text_printchar(&d);
+					}
+				}
 			}
-			if (cury > y-1) {
-				curx = 0;
-				cury--;
-			}
 		}
-#endif
 	}
+	conout->EnableCursor(conout, TRUE);
 }
 
-#ifdef TERM_EMU
-/* Gracefully exit ESC-sequence processing in case of misunderstanding. */
 static void
-bail_out(int c)
+efi_text_param(void *s __unused, int cmd, unsigned int value)
 {
-	char buf[16], *ch;
-	int i;
-
-	if (esc) {
-		efi_cons_rawputchar('\033');
-		if (esc != '\033')
-			efi_cons_rawputchar(esc);
-		for (i = 0; i <= argc; ++i) {
-			sprintf(buf, "%d", args[i]);
-			ch = buf;
-			while (*ch)
-				efi_cons_rawputchar(*ch++);
-		}
+	switch (cmd) {
+	case TP_SETLOCALCURSOR:
+		/*
+		 * 0 means normal (usually block), 1 means hidden, and
+		 * 2 means blinking (always block) for compatibility with
+		 * syscons.  We don't support any changes except hiding,
+		 * so must map 2 to 0.
+		 */
+		value = (value == 1) ? 0 : 1;
+		/* FALLTHROUGH */
+	case TP_SHOWCURSOR:
+		if (value == 1)
+			conout->EnableCursor(conout, TRUE);
+		else
+			conout->EnableCursor(conout, FALSE);
+		break;
+	default:
+		/* Not yet implemented */
+		break;
 	}
-	efi_cons_rawputchar(c);
-	end_term();
 }
 
-/* Clear display from current position to end of screen. */
-static void
-CD(void) {
-	int i;
-	UINTN x, y;
-
-	get_pos(&curx, &cury);
-	if (curx == 0 && cury == 0) {
-		conout->ClearScreen(conout);
-		end_term();
-		return;
-	}
-
-	conout->QueryMode(conout, conout->Mode->Mode, &x, &y);
-	CL(0);  /* clear current line from cursor to end */
-	for (i = cury + 1; i < y-1; i++) {
-		curs_move(NULL, NULL, 0, i);
-		CL(0);
-	}
-	curs_move(NULL, NULL, curx, cury);
-	end_term();
-}
-
 /*
- * Absolute cursor move to args[0] rows and args[1] columns
- * (the coordinates are 1-based).
+ * Not implemented.
  */
 static void
-CM(void)
+efi_cons_respond(void *s __unused, const void *buf __unused,
+    size_t len __unused)
 {
-	if (args[0] > 0)
-		args[0]--;
-	if (args[1] > 0)
-		args[1]--;
-	curs_move(&curx, &cury, args[1], args[0]);
-	end_term();
 }
 
-/* Home cursor (left top corner), also called from mode command. */
-void
-HO(void)
+static void
+efi_cons_probe(struct console *cp)
 {
-	argc = 1;
-	args[0] = args[1] = 1;
-	CM();
+	cp->c_flags |= C_PRESENTIN | C_PRESENTOUT;
 }
 
-/* Clear line from current position to end of line */
-static void
-CL(int direction)
+bool
+efi_cons_update_mode(void)
 {
-	int i, len;
-	UINTN x, y;
-	CHAR16 *line;
+	UINTN cols, rows;
+	const teken_attr_t *a;
+	EFI_STATUS status;
+	char env[8];
 
-	conout->QueryMode(conout, conout->Mode->Mode, &x, &y);
-	switch (direction) {
-	case 0:         /* from cursor to end */
-		len = x - curx + 1;
-		break;
-	case 1:         /* from beginning to cursor */
-		len = curx;
-		break;
-	case 2:         /* entire line */
-		len = x;
-		break;
-	default:	/* NOTREACHED */
-		__unreachable();
+	status = conout->QueryMode(conout, conout->Mode->Mode, &cols, &rows);
+	if (EFI_ERROR(status)) {
+		cols = 80;
+		rows = 24;
 	}
 
-	if (cury == y - 1)
-		len--;
-
-	line = malloc(len * sizeof (CHAR16));
-	if (line == NULL) {
-		printf("out of memory\n");
-		return;
+	if (buffer != NULL) {
+		if (tp.tp_row == rows && tp.tp_col == cols)
+			return (true);
+		free(buffer);
+	} else {
+		teken_init(&teken, &tf, NULL);
 	}
-	for (i = 0; i < len; i++)
-		line[i] = ' ';
-	line[len-1] = 0;
 
-	if (direction != 0)
-		curs_move(NULL, NULL, 0, cury);
+	tp.tp_row = rows;
+	tp.tp_col = cols;
+	buffer = malloc(rows * cols * sizeof(*buffer));
+	if (buffer == NULL)
+		return (false);
 
-	conout->OutputString(conout, line);
-	/* restore cursor position */
-	curs_move(NULL, NULL, curx, cury);
-	free(line);
-	end_term();
-}
+	teken_set_winsize(&teken, &tp);
+	a = teken_get_defattr(&teken);
 
-static void
-get_arg(int c)
-{
-	if (argc < 0)
-		argc = 0;
-	args[argc] *= 10;
-	args[argc] += c - '0';
+	for (int row = 0; row < rows; row++)
+		for (int col = 0; col < cols; col++) {
+			buffer[col + row * tp.tp_col].c = ' ';
+			buffer[col + row * tp.tp_col].a = *a;
+		}
+
+	snprintf(env, sizeof (env), "%u", (unsigned)rows);
+	setenv("LINES", env, 1);
+	snprintf(env, sizeof (env), "%u", (unsigned)cols);
+	setenv("COLUMNS", env, 1);
+
+	return (true);
 }
 
-/* Emulate basic capabilities of cons25 terminal */
-static void
-efi_term_emu(int c)
+static int
+efi_cons_init(int arg)
 {
-	static int ansi_col[] = {
-		0, 4, 2, 6, 1, 5, 3, 7
-	};
-	int t, i;
+	EFI_STATUS status;
 
-	switch (esc) {
-	case 0:
-		switch (c) {
-		case '\033':
-			esc = c;
-			break;
-		default:
-			efi_cons_rawputchar(c);
-			break;
-		}
-		break;
-	case '\033':
-		switch (c) {
-		case '[':
-			esc = c;
-			args[0] = 0;
-			argc = -1;
-			break;
-		default:
-			bail_out(c);
-			break;
-		}
-		break;
-	case '[':
-		switch (c) {
-		case ';':
-			if (argc < 0)
-				argc = 0;
-			else if (argc + 1 >= MAXARGS)
-				bail_out(c);
-			else
-				args[++argc] = 0;
-			break;
-		case 'H':               /* ho = \E[H */
-			if (argc < 0)
-				HO();
-			else if (argc == 1)
-				CM();
-			else
-				bail_out(c);
-			break;
-		case 'J':               /* cd = \E[J */
-			if (argc < 0)
-				CD();
-			else
-				bail_out(c);
-			break;
-		case 'm':
-			if (argc < 0) {
-				fg_c = DEFAULT_FGCOLOR;
-				bg_c = DEFAULT_BGCOLOR;
-			}
-			for (i = 0; i <= argc; ++i) {
-				switch (args[i]) {
-				case 0:         /* back to normal */
-					fg_c = DEFAULT_FGCOLOR;
-					bg_c = DEFAULT_BGCOLOR;
-					break;
-				case 1:         /* bold */
-					fg_c |= 0x8;
-					break;
-				case 4:         /* underline */
-				case 5:         /* blink */
-					bg_c |= 0x8;
-					break;
-				case 7:         /* reverse */
-					t = fg_c;
-					fg_c = bg_c;
-					bg_c = t;
-					break;
-				case 22:	/* normal intensity */
-					fg_c &= ~0x8;
-					break;
-				case 24:	/* not underline */
-				case 25:	/* not blinking */
-					bg_c &= ~0x8;
-					break;
-				case 30: case 31: case 32: case 33:
-				case 34: case 35: case 36: case 37:
-					fg_c = ansi_col[args[i] - 30];
-					break;
-				case 39:        /* normal */
-					fg_c = DEFAULT_FGCOLOR;
-					break;
-				case 40: case 41: case 42: case 43:
-				case 44: case 45: case 46: case 47:
-					bg_c = ansi_col[args[i] - 40];
-					break;
-				case 49:        /* normal */
-					bg_c = DEFAULT_BGCOLOR;
-					break;
-				}
-			}
-			conout->SetAttribute(conout, EFI_TEXT_ATTR(fg_c, bg_c));
-			end_term();
-			break;
-		default:
-			if (isdigit(c))
-				get_arg(c);
-			else
-				bail_out(c);
-			break;
-		}
-		break;
-	default:
-		bail_out(c);
-		break;
-	}
+	if (conin != NULL)
+		return (0);
+
+	conout = ST->ConOut;
+	conin = ST->ConIn;
+
+	conout->EnableCursor(conout, TRUE);
+	status = BS->OpenProtocol(ST->ConsoleInHandle, &simple_input_ex_guid,
+	    (void **)&coninex, IH, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+	if (status != EFI_SUCCESS)
+		coninex = NULL;
+
+	if (efi_cons_update_mode())
+		return (0);
+
+	return (1);
 }
-#else
-void
-HO(void)
-{
-}
-#endif
 
 void
 efi_cons_putchar(int c)
 {
-#ifdef TERM_EMU
-	efi_term_emu(c);
-#else
-	efi_cons_rawputchar(c);
-#endif
+	unsigned char ch = c;
+
+	if (buffer != NULL)
+		teken_input(&teken, &ch, sizeof (ch));
+	else
+		efi_cons_efiputchar(c);
 }
 
 static int
@@ -624,31 +597,13 @@ void
 efi_cons_efiputchar(int c)
 {
 	CHAR16 buf[2];
+	EFI_STATUS status;
 
-	/*
-	 * translate box chars to unicode
-	 */
-	switch (c) {
-	/* single frame */
-	case 0xb3: buf[0] = BOXDRAW_VERTICAL; break;
-	case 0xbf: buf[0] = BOXDRAW_DOWN_LEFT; break;
-	case 0xc0: buf[0] = BOXDRAW_UP_RIGHT; break;
-	case 0xc4: buf[0] = BOXDRAW_HORIZONTAL; break;
-	case 0xda: buf[0] = BOXDRAW_DOWN_RIGHT; break;
-	case 0xd9: buf[0] = BOXDRAW_UP_LEFT; break;
-
-	/* double frame */
-	case 0xba: buf[0] = BOXDRAW_DOUBLE_VERTICAL; break;
-	case 0xbb: buf[0] = BOXDRAW_DOUBLE_DOWN_LEFT; break;
-	case 0xbc: buf[0] = BOXDRAW_DOUBLE_UP_LEFT; break;
-	case 0xc8: buf[0] = BOXDRAW_DOUBLE_UP_RIGHT; break;
-	case 0xc9: buf[0] = BOXDRAW_DOUBLE_DOWN_RIGHT; break;
-	case 0xcd: buf[0] = BOXDRAW_DOUBLE_HORIZONTAL; break;
-
-	default:
-		buf[0] = c;
-	}
+	buf[0] = c;
         buf[1] = 0;     /* terminate string */
 
+	status = conout->TestString(conout, buf);
+	if (EFI_ERROR(status))
+		buf[0] = '?';
 	conout->OutputString(conout, buf);
 }

Modified: head/stand/efi/loader/arch/amd64/Makefile.inc
==============================================================================
--- head/stand/efi/loader/arch/amd64/Makefile.inc	Thu Sep  5 21:43:33 2019	(r351899)
+++ head/stand/efi/loader/arch/amd64/Makefile.inc	Thu Sep  5 22:15:50 2019	(r351900)
@@ -11,5 +11,5 @@ SRCS+=	nullconsole.c \
 	comconsole.c \
 	spinconsole.c
 
-CFLAGS+=	-fPIC -DTERM_EMU
+CFLAGS+=	-fPIC
 LDFLAGS+=	-Wl,-znocombreloc

Modified: head/stand/efi/loader/arch/i386/Makefile.inc
==============================================================================
--- head/stand/efi/loader/arch/i386/Makefile.inc	Thu Sep  5 21:43:33 2019	(r351899)
+++ head/stand/efi/loader/arch/i386/Makefile.inc	Thu Sep  5 22:15:50 2019	(r351900)
@@ -9,5 +9,5 @@ SRCS+=	nullconsole.c \
 	comconsole.c \
 	spinconsole.c
 
-CFLAGS+=	-fPIC -DTERM_EMU
+CFLAGS+=	-fPIC
 LDFLAGS+=	-Wl,-znocombreloc

Modified: head/stand/efi/loader/main.c
==============================================================================
--- head/stand/efi/loader/main.c	Thu Sep  5 21:43:33 2019	(r351899)
+++ head/stand/efi/loader/main.c	Thu Sep  5 22:15:50 2019	(r351900)
@@ -1280,10 +1280,8 @@ command_mode(int argc, char *argv[])
 	unsigned int mode;
 	int i;
 	char *cp;
-	char rowenv[8];
 	EFI_STATUS status;
 	SIMPLE_TEXT_OUTPUT_INTERFACE *conout;
-	extern void HO(void);
 
 	conout = ST->ConOut;
 
@@ -1303,9 +1301,7 @@ command_mode(int argc, char *argv[])
 			printf("couldn't set mode %d\n", mode);
 			return (CMD_ERROR);
 		}
-		sprintf(rowenv, "%u", (unsigned)rows);
-		setenv("LINES", rowenv, 1);
-		HO();		/* set cursor */
+		(void) efi_cons_update_mode();
 		return (CMD_OK);
 	}
 

Modified: head/stand/forth/frames.4th
==============================================================================
--- head/stand/forth/frames.4th	Thu Sep  5 21:43:33 2019	(r351899)
+++ head/stand/forth/frames.4th	Thu Sep  5 22:15:50 2019	(r351900)
@@ -47,32 +47,32 @@ variable fill
  43 constant ascii_plus
 
 \ Single frames
-196 constant sh_el
-179 constant sv_el
-218 constant slt_el
-192 constant slb_el
-191 constant srt_el
-217 constant srb_el
+0x2500 constant sh_el
+0x2502 constant sv_el
+0x250c constant slt_el
+0x2514 constant slb_el
+0x2510 constant srt_el
+0x2518 constant srb_el
 \ Double frames
-205 constant dh_el
-186 constant dv_el
-201 constant dlt_el
-200 constant dlb_el
-187 constant drt_el
-188 constant drb_el
+0x2550 constant dh_el
+0x2551 constant dv_el
+0x2554 constant dlt_el
+0x255a constant dlb_el
+0x2557 constant drt_el
+0x255d constant drb_el
 \ Fillings
 0 constant fill_none
 32 constant fill_blank
-176 constant fill_dark
-177 constant fill_med
-178 constant fill_bright
+0x2591 constant fill_dark
+0x2592 constant fill_med
+0x2593 constant fill_bright
 
 only forth definitions also frame-drawing
 
 : hline	( len x y -- )	\ Draw horizontal single line
 	at-xy		\ move cursor
 	0 do
-		h_el @ emit
+		h_el @ xemit
 	loop
 ;
 
@@ -113,7 +113,7 @@ only forth definitions also frame-drawing
 	2dup 4 pick
 	0 do
 		at-xy
-		v_el @ emit
+		v_el @ xemit
 		1+
 		2dup
 	loop
@@ -129,10 +129,10 @@ only forth definitions also frame-drawing
 	hline		\ Draw top horiz line
 	2dup swap 1+ swap 4 pick + 5 pick 1- -rot
 	hline		\ Draw bottom horiz line
-	2dup at-xy lt_el @ emit	\ Draw left-top corner
-	2dup 4 pick + at-xy lb_el @ emit	\ Draw left bottom corner
-	2dup swap 5 pick + swap at-xy rt_el @ emit	\ Draw right top corner
-	2 pick + swap 3 pick + swap at-xy rb_el @ emit
+	2dup at-xy lt_el @ xemit	\ Draw left-top corner
+	2dup 4 pick + at-xy lb_el @ xemit	\ Draw left bottom corner
+	2dup swap 5 pick + swap at-xy rt_el @ xemit	\ Draw right top corner
+	2 pick + swap 3 pick + swap at-xy rb_el @ xemit
 	2drop
 ;
 

Modified: head/stand/i386/libi386/Makefile
==============================================================================
--- head/stand/i386/libi386/Makefile	Thu Sep  5 21:43:33 2019	(r351899)
+++ head/stand/i386/libi386/Makefile	Thu Sep  5 22:15:50 2019	(r351900)
@@ -14,6 +14,9 @@ SRCS=	bio.c biosacpi.c biosdisk.c biosmem.c biospnp.c 
 SRCS+=  devicename_stubs.c
 CFLAGS+= -I${ZFSSRC}
 
+.PATH:	${SYSDIR}/teken
+SRCS+=	teken.c
+
 BOOT_COMCONSOLE_PORT?= 0x3f8
 CFLAGS+=	-DCOMPORT=${BOOT_COMCONSOLE_PORT}
 
@@ -37,8 +40,9 @@ CFLAGS+= -DSMBIOS_NETWORK_ENDIAN_UUID
 .endif
 .endif
 
-# Include simple terminal emulation (cons25-compatible)
-CFLAGS+= -DTERM_EMU
+# terminal emulation
+CFLAGS.vidconsole.c+= -I${SRCTOP}/sys/teken
+CFLAGS.teken.c+= -I${SRCTOP}/sys/teken
 
 # XXX: make alloca() useable
 CFLAGS+= -Dalloca=__builtin_alloca

Modified: head/stand/i386/libi386/vidconsole.c
==============================================================================
--- head/stand/i386/libi386/vidconsole.c	Thu Sep  5 21:43:33 2019	(r351899)
+++ head/stand/i386/libi386/vidconsole.c	Thu Sep  5 22:15:50 2019	(r351900)
@@ -34,11 +34,15 @@ __FBSDID("$FreeBSD$");
 #include <bootstrap.h>
 #include <btxv86.h>
 #include <machine/psl.h>
+#include <machine/cpufunc.h>
+#include <teken.h>
+#include <stdbool.h>
+
+#include <dev/vt/hw/vga/vt_vga_reg.h>
+
 #include "libi386.h"
 
 #if KEYBOARD_PROBE
-#include <machine/cpufunc.h>
-
 static int	probe_keyboard(void);
 #endif
 static void	vidc_probe(struct console *cp);
@@ -48,490 +52,658 @@ static int	vidc_getchar(void);
 static int	vidc_ischar(void);
 
 static int	vidc_started;
+static uint16_t	*vgatext;
 
-void		get_pos(int *x, int *y);
+static tf_bell_t	vidc_cons_bell;
+static tf_cursor_t	vidc_text_cursor;
+static tf_putchar_t	vidc_text_putchar;
+static tf_fill_t	vidc_text_fill;
+static tf_copy_t	vidc_text_copy;
+static tf_param_t	vidc_text_param;
+static tf_respond_t	vidc_cons_respond;
+ 
+static teken_funcs_t tf = {
+	.tf_bell	= vidc_cons_bell,
+	.tf_cursor	= vidc_text_cursor,
+	.tf_putchar	= vidc_text_putchar,
+	.tf_fill	= vidc_text_fill,
+	.tf_copy	= vidc_text_copy,
+	.tf_param	= vidc_text_param,
+	.tf_respond	= vidc_cons_respond,
+};
 
-#ifdef TERM_EMU
-#define MAXARGS		8
-#define DEFAULT_FGCOLOR	7
-#define DEFAULT_BGCOLOR	0
+teken_t		teken;
+teken_pos_t	tp;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-head mailing list