From owner-svn-src-head@freebsd.org Thu Sep 5 22:15:53 2019 Return-Path: Delivered-To: svn-src-head@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 102E9D53C7; Thu, 5 Sep 2019 22:15:53 +0000 (UTC) (envelope-from tsoome@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 46PZlF0Llrz4RPn; Thu, 5 Sep 2019 22:15:53 +0000 (UTC) (envelope-from tsoome@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id E3419AF58; Thu, 5 Sep 2019 22:15:52 +0000 (UTC) (envelope-from tsoome@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id x85MFqR9098399; Thu, 5 Sep 2019 22:15:52 GMT (envelope-from tsoome@FreeBSD.org) Received: (from tsoome@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x85MFoZN098388; Thu, 5 Sep 2019 22:15:50 GMT (envelope-from tsoome@FreeBSD.org) Message-Id: <201909052215.x85MFoZN098388@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: tsoome set sender to tsoome@FreeBSD.org using -f From: Toomas Soome Date: Thu, 5 Sep 2019 22:15:50 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r351900 - in head/stand: . efi/include efi/libefi efi/loader efi/loader/arch/amd64 efi/loader/arch/i386 forth i386/libi386 lua X-SVN-Group: head X-SVN-Commit-Author: tsoome X-SVN-Commit-Paths: in head/stand: . efi/include efi/libefi efi/loader efi/loader/arch/amd64 efi/loader/arch/i386 forth i386/libi386 lua X-SVN-Commit-Revision: 351900 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 05 Sep 2019 22:15:53 -0000 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 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 #include +#include #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 #include #include +#include +#include +#include + +#include + #include "libi386.h" #if KEYBOARD_PROBE -#include - 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 ***