From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D7594C433EF for ; Wed, 2 Mar 2022 10:54:10 +0000 (UTC) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 8A35C83CC0; Wed, 2 Mar 2022 11:53:28 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=kernel.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=kernel.org header.i=@kernel.org header.b="RuJDC2Kj"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 592F183CC6; Wed, 2 Mar 2022 11:53:19 +0100 (CET) Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 9BE1D83C98 for ; Wed, 2 Mar 2022 11:52:49 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=kernel.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=pali@kernel.org Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 69CAD6174A; Wed, 2 Mar 2022 10:52:48 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id E5A1AC004E1; Wed, 2 Mar 2022 10:52:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1646218368; bh=PQnD062QmzsfGK/+5NFpJWQkjmSPmPDLSqBo0QyTt9Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RuJDC2KjOhIr4VVTpF2cmNNeuy5vhq/epS7kD+bjS+M8+qj5LtEDYKjuiuZ7lecg+ U0wQNsPUp9xD84v0ZeHrJl2n1GmYGjKAQeDuulEL+eX5KALhiCEwraHPAaQuNE3Kkj YlSmleggq0QUDeBxbISo3fZt3fHqbFizpx2l8j849LZ5mp7SY5RcPurAb6cPuvilHv XFfHovKIuvRBVIwNuCrCoM2/vkXP8Xg7gG0uasvgwMJdsLBPoZ/vX1G//xO145rp1a iHaexEqn1DwxJL+OxKzi+NpLtaLgCsEAGlmhjzUANyZOe/PdxVwWmczV15D29ctxKT VQgAY8va06C8A== Received: by pali.im (Postfix) id 9F0B6677; Wed, 2 Mar 2022 11:52:47 +0100 (CET) From: =?UTF-8?q?Pali=20Roh=C3=A1r?= To: Stefan Roese , =?UTF-8?q?Marek=20Beh=C3=BAn?= , Tony Dinh Cc: u-boot@lists.denx.de Subject: [PATCH u-boot-marvell 06/10] tools: kwboot: Add support for backspace key in mini terminal Date: Wed, 2 Mar 2022 11:49:23 +0100 Message-Id: <20220302104927.18607-7-pali@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20220302104927.18607-1-pali@kernel.org> References: <20220302104927.18607-1-pali@kernel.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.5 at phobos.denx.de X-Virus-Status: Clean Marvell BootROM recognize only '\b' byte as backspace. Use terminfo for retrieving current backspace sequence and replace any occurrence of backspace sequence by the '\b' byte. Reading terminfo database is possible via tigetstr() function from system library libtinfo.so.*. So link kwboot with -ltinfo. Normally terminfo functions are in system header file. But this header file conflicts with U-Boot "termios_linux.h" header file. So declare terminfo functions manually. Signed-off-by: Pali Rohár --- tools/Makefile | 2 +- tools/kwboot.c | 109 +++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 97 insertions(+), 14 deletions(-) diff --git a/tools/Makefile b/tools/Makefile index c4a06dd9ba36..dca773b909b4 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -200,7 +200,7 @@ hostprogs-$(CONFIG_EXYNOS5420) += mkexynosspl HOSTCFLAGS_mkexynosspl.o := -pedantic HOSTCFLAGS_kwboot.o += -pthread -HOSTLDLIBS_kwboot += -pthread +HOSTLDLIBS_kwboot += -pthread -ltinfo ifdtool-objs := $(LIBFDT_OBJS) ifdtool.o hostprogs-$(CONFIG_X86) += ifdtool diff --git a/tools/kwboot.c b/tools/kwboot.c index 3ab49e74bb67..26cfe6dea6a7 100644 --- a/tools/kwboot.c +++ b/tools/kwboot.c @@ -36,6 +36,13 @@ #include #endif +/* + * These functions are in header file, but this header file conflicts + * with "termios_linux.h" header file. So declare these functions manually. + */ +extern int setupterm(const char *, int, int *); +extern char *tigetstr(const char *); + /* * Marvell BootROM UART Sensing */ @@ -1376,37 +1383,84 @@ kwboot_xmodem(int tty, const void *_img, size_t size, int baudrate) } static int -kwboot_term_pipe(int in, int out, const char *quit, int *s) +kwboot_term_pipe(int in, int out, const char *quit, int *s, const char *kbs, int *k) { char buf[128]; - ssize_t nin; + ssize_t nin, noff; nin = read(in, buf, sizeof(buf)); if (nin <= 0) return -1; - if (quit) { + noff = 0; + + if (quit || kbs) { int i; for (i = 0; i < nin; i++) { - if (buf[i] == quit[*s]) { + if ((quit || kbs) && + (!quit || buf[i] != quit[*s]) && + (!kbs || buf[i] != kbs[*k])) { + const char *prefix; + int plen; + + if (quit && kbs) { + prefix = (*s >= *k) ? quit : kbs; + plen = (*s >= *k) ? *s : *k; + } else if (quit) { + prefix = quit; + plen = *s; + } else { + prefix = kbs; + plen = *k; + } + + if (plen > i && kwboot_write(out, prefix, plen - i) < 0) + return -1; + } + + if (quit && buf[i] == quit[*s]) { (*s)++; if (!quit[*s]) { nin = (i > *s) ? (i - *s) : 0; break; } - } else { - if (*s > i && kwboot_write(out, quit, *s - i) < 0) - return -1; + } else if (quit) { *s = 0; } + + if (kbs && buf[i] == kbs[*k]) { + (*k)++; + if (!kbs[*k]) { + if (i > *k + noff && + kwboot_write(out, buf + noff, i - *k - noff) < 0) + return -1; + /* + * Replace backspace key by '\b' (0x08) + * byte which is the only recognized + * backspace byte by Marvell BootROM. + */ + if (write(out, "\x08", 1) < 0) + return -1; + noff = i + 1; + *k = 0; + } + } else if (kbs) { + *k = 0; + } } - if (i == nin) - nin -= (nin > *s) ? *s : nin; + if (i == nin) { + i = 0; + if (quit && i < *s) + i = *s; + if (kbs && i < *k) + i = *k; + nin -= (nin > i) ? i : nin; + } } - if (kwboot_write(out, buf, nin) < 0) + if (nin > noff && kwboot_write(out, buf + noff, nin - noff) < 0) return -1; return 0; @@ -1415,7 +1469,8 @@ kwboot_term_pipe(int in, int out, const char *quit, int *s) static int kwboot_terminal(int tty) { - int rc, in, s; + int rc, in, s, k; + const char *kbs = NULL; const char *quit = "\34c"; struct termios otio, tio; @@ -1434,6 +1489,33 @@ kwboot_terminal(int tty) goto out; } + /* + * Get sequence for backspace key used by the current + * terminal. Every occurrence of this sequence will be + * replaced by '\b' byte which is the only recognized + * backspace byte by Marvell BootROM. + * + * Note that we cannot read this sequence from termios + * c_cc[VERASE] as VERASE is valid only when ICANON is + * set in termios c_lflag, which is not case for us. + * + * Also most terminals do not set termios c_cc[VERASE] + * as c_cc[VERASE] can specify only one-byte sequence + * and instead let applications to read (possible + * multi-byte) sequence for backspace key from "kbs" + * terminfo database based on $TERM env variable. + * + * So read "kbs" from terminfo database via tigetstr() + * call after successful setupterm(). Most terminals + * use byte 0x7F for backspace key, so replacement with + * '\b' is required. + */ + if (setupterm(NULL, STDOUT_FILENO, &rc) == 0) { + kbs = tigetstr("kbs"); + if (kbs == (char *)-1) + kbs = NULL; + } + kwboot_printv("[Type Ctrl-%c + %c to quit]\r\n", quit[0] | 0100, quit[1]); } else @@ -1441,6 +1523,7 @@ kwboot_terminal(int tty) rc = 0; s = 0; + k = 0; do { fd_set rfds; @@ -1460,13 +1543,13 @@ kwboot_terminal(int tty) break; if (FD_ISSET(tty, &rfds)) { - rc = kwboot_term_pipe(tty, STDOUT_FILENO, NULL, NULL); + rc = kwboot_term_pipe(tty, STDOUT_FILENO, NULL, NULL, NULL, NULL); if (rc) break; } if (in >= 0 && FD_ISSET(in, &rfds)) { - rc = kwboot_term_pipe(in, tty, quit, &s); + rc = kwboot_term_pipe(in, tty, quit, &s, kbs, &k); if (rc) break; } -- 2.20.1