diff mbox series

[u-boot-marvell,v3,13/39] tools: kwboot: Allow non-xmodem text output from BootROM only in a specific case

Message ID 20210924210716.29752-14-kabel@kernel.org
State Accepted
Commit 48b3ea66cae97a06c35f117be8613c597aa2fca8
Delegated to: Stefan Roese
Headers show
Series kwboot higher baudrate | expand

Commit Message

Marek Behún Sept. 24, 2021, 9:06 p.m. UTC
From: Pali Rohár <pali@kernel.org>

When sending image header / image data, BootROM does not send any
non-xmodem text output. We should therefore interpret unknown bytes in
the xmodem protocol as errors and resend current packet. This should
improve the transfer in case there are errors on the UART line.

Text output from BootROM may only happen after whole image header is
sent and before ACK for the last packet of image header is received.
In this case BootROM may execute code from the image, which may interact
with UART (U-Boot SPL, for example, prints stuff on UART).

Print received non-xmodem output from BootROM only in this case.

Signed-off-by: Pali Rohár <pali@kernel.org>
[ refactored & simplified ]
Signed-off-by: Marek Behún <marek.behun@nic.cz>
---
 tools/kwboot.c | 70 ++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 53 insertions(+), 17 deletions(-)

Comments

Stefan Roese Oct. 1, 2021, 6:19 a.m. UTC | #1
On 24.09.21 23:06, Marek Behún wrote:
> From: Pali Rohár <pali@kernel.org>
> 
> When sending image header / image data, BootROM does not send any
> non-xmodem text output. We should therefore interpret unknown bytes in
> the xmodem protocol as errors and resend current packet. This should
> improve the transfer in case there are errors on the UART line.
> 
> Text output from BootROM may only happen after whole image header is
> sent and before ACK for the last packet of image header is received.
> In this case BootROM may execute code from the image, which may interact
> with UART (U-Boot SPL, for example, prints stuff on UART).
> 
> Print received non-xmodem output from BootROM only in this case.
> 
> Signed-off-by: Pali Rohár <pali@kernel.org>
> [ refactored & simplified ]
> Signed-off-by: Marek Behún <marek.behun@nic.cz>

Reviewed-by: Stefan Roese <sr@denx.de>

Thanks,
Stefan

> ---
>   tools/kwboot.c | 70 ++++++++++++++++++++++++++++++++++++++------------
>   1 file changed, 53 insertions(+), 17 deletions(-)
> 
> diff --git a/tools/kwboot.c b/tools/kwboot.c
> index 2e5684b91c..4636622a6c 100644
> --- a/tools/kwboot.c
> +++ b/tools/kwboot.c
> @@ -382,33 +382,62 @@ _is_xm_reply(char c)
>   }
>   
>   static int
> -kwboot_xm_sendblock(int fd, struct kwboot_block *block)
> +kwboot_xm_recv_reply(int fd, char *c, int allow_non_xm)
> +{
> +	int rc;
> +
> +	while (1) {
> +		rc = kwboot_tty_recv(fd, c, 1, blk_rsp_timeo);
> +		if (rc) {
> +			if (errno != ETIMEDOUT)
> +				return rc;
> +			*c = NAK;
> +		}
> +
> +		/* If received xmodem reply, end. */
> +		if (_is_xm_reply(*c))
> +			break;
> +
> +		/*
> +		 * If printing non-xmodem text output is allowed and such a byte
> +		 * was received, print it.
> +		 */
> +		if (allow_non_xm) {
> +			putchar(*c);
> +			fflush(stdout);
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +static int
> +kwboot_xm_sendblock(int fd, struct kwboot_block *block, int allow_non_xm,
> +		    int *done_print)
>   {
>   	int rc, retries;
>   	char c;
>   
> +	*done_print = 0;
> +
>   	retries = 16;
>   	do {
>   		rc = kwboot_tty_send(fd, block, sizeof(*block));
>   		if (rc)
>   			return rc;
>   
> -		do {
> -			rc = kwboot_tty_recv(fd, &c, 1, blk_rsp_timeo);
> -			if (rc) {
> -				if (errno != ETIMEDOUT)
> -					return rc;
> -				c = NAK;
> -			}
> -
> -			if (!_is_xm_reply(c))
> -				printf("%c", c);
> +		if (allow_non_xm && !*done_print) {
> +			kwboot_progress(100, '.');
> +			kwboot_printv("Done\n");
> +			*done_print = 1;
> +		}
>   
> -		} while (!_is_xm_reply(c));
> +		rc = kwboot_xm_recv_reply(fd, &c, allow_non_xm);
> +		if (rc)
> +			return rc;
>   
> -		if (c != ACK)
> +		if (!allow_non_xm && c != ACK)
>   			kwboot_progress(-1, '+');
> -
>   	} while (c == NAK && retries-- > 0);
>   
>   	rc = -1;
> @@ -435,6 +464,7 @@ static int
>   kwboot_xmodem_one(int tty, int *pnum, int header, const uint8_t *data,
>   		  size_t size)
>   {
> +	int done_print = 0;
>   	size_t sent, left;
>   	int rc;
>   
> @@ -446,22 +476,28 @@ kwboot_xmodem_one(int tty, int *pnum, int header, const uint8_t *data,
>   
>   	while (sent < size) {
>   		struct kwboot_block block;
> +		int last_block;
>   		size_t blksz;
>   
>   		blksz = kwboot_xm_makeblock(&block, data, left, (*pnum)++);
>   		data += blksz;
>   
> -		rc = kwboot_xm_sendblock(tty, &block);
> +		last_block = (left <= blksz);
> +
> +		rc = kwboot_xm_sendblock(tty, &block, header && last_block,
> +					 &done_print);
>   		if (rc)
>   			goto out;
>   
>   		sent += blksz;
>   		left -= blksz;
>   
> -		kwboot_progress(sent * 100 / size, '.');
> +		if (!done_print)
> +			kwboot_progress(sent * 100 / size, '.');
>   	}
>   
> -	kwboot_printv("Done\n");
> +	if (!done_print)
> +		kwboot_printv("Done\n");
>   
>   	return 0;
>   out:
> 


Viele Grüße,
Stefan
diff mbox series

Patch

diff --git a/tools/kwboot.c b/tools/kwboot.c
index 2e5684b91c..4636622a6c 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -382,33 +382,62 @@  _is_xm_reply(char c)
 }
 
 static int
-kwboot_xm_sendblock(int fd, struct kwboot_block *block)
+kwboot_xm_recv_reply(int fd, char *c, int allow_non_xm)
+{
+	int rc;
+
+	while (1) {
+		rc = kwboot_tty_recv(fd, c, 1, blk_rsp_timeo);
+		if (rc) {
+			if (errno != ETIMEDOUT)
+				return rc;
+			*c = NAK;
+		}
+
+		/* If received xmodem reply, end. */
+		if (_is_xm_reply(*c))
+			break;
+
+		/*
+		 * If printing non-xmodem text output is allowed and such a byte
+		 * was received, print it.
+		 */
+		if (allow_non_xm) {
+			putchar(*c);
+			fflush(stdout);
+		}
+	}
+
+	return 0;
+}
+
+static int
+kwboot_xm_sendblock(int fd, struct kwboot_block *block, int allow_non_xm,
+		    int *done_print)
 {
 	int rc, retries;
 	char c;
 
+	*done_print = 0;
+
 	retries = 16;
 	do {
 		rc = kwboot_tty_send(fd, block, sizeof(*block));
 		if (rc)
 			return rc;
 
-		do {
-			rc = kwboot_tty_recv(fd, &c, 1, blk_rsp_timeo);
-			if (rc) {
-				if (errno != ETIMEDOUT)
-					return rc;
-				c = NAK;
-			}
-
-			if (!_is_xm_reply(c))
-				printf("%c", c);
+		if (allow_non_xm && !*done_print) {
+			kwboot_progress(100, '.');
+			kwboot_printv("Done\n");
+			*done_print = 1;
+		}
 
-		} while (!_is_xm_reply(c));
+		rc = kwboot_xm_recv_reply(fd, &c, allow_non_xm);
+		if (rc)
+			return rc;
 
-		if (c != ACK)
+		if (!allow_non_xm && c != ACK)
 			kwboot_progress(-1, '+');
-
 	} while (c == NAK && retries-- > 0);
 
 	rc = -1;
@@ -435,6 +464,7 @@  static int
 kwboot_xmodem_one(int tty, int *pnum, int header, const uint8_t *data,
 		  size_t size)
 {
+	int done_print = 0;
 	size_t sent, left;
 	int rc;
 
@@ -446,22 +476,28 @@  kwboot_xmodem_one(int tty, int *pnum, int header, const uint8_t *data,
 
 	while (sent < size) {
 		struct kwboot_block block;
+		int last_block;
 		size_t blksz;
 
 		blksz = kwboot_xm_makeblock(&block, data, left, (*pnum)++);
 		data += blksz;
 
-		rc = kwboot_xm_sendblock(tty, &block);
+		last_block = (left <= blksz);
+
+		rc = kwboot_xm_sendblock(tty, &block, header && last_block,
+					 &done_print);
 		if (rc)
 			goto out;
 
 		sent += blksz;
 		left -= blksz;
 
-		kwboot_progress(sent * 100 / size, '.');
+		if (!done_print)
+			kwboot_progress(sent * 100 / size, '.');
 	}
 
-	kwboot_printv("Done\n");
+	if (!done_print)
+		kwboot_printv("Done\n");
 
 	return 0;
 out: