[PATCH u-boot-marvell] tools: kwboot: Do not send magic seq when changing baudrate back to 115200
Stefan Roese
sr at denx.de
Wed Nov 3 06:39:31 CET 2021
On 01.11.21 14:00, Marek Behún wrote:
> From: Pali Rohár <pali at kernel.org>
>
> After successful transfer of whole image only two things can happen:
> - BootROM starts execution of data block, which changes UART baudrate
> back to 115200 Bd,
> - board crashes and causes CPU reset
>
> In both cases UART baudrate is reset to the default speed. So there is
> no need to send special magic sequence to inform kwboot that baudrate is
> going to be reset and kwboot does not need to wait for this event and
> can do it immediately after BootROM acknowledges end of xmodem transfer.
>
> Move ARM code for sending magic sequence from main baudrate change
> section to binhdr_pre section which is executed only before changing
> baudrate from the default value of 115200 Bd to some new value. Remove
> kwboot code waiting for magic sequence after successful xmodem transfer.
>
> Rationale: sometimes when using very high UART speeds, magic sequence is
> damaged and kwboot fails at this last stage. Removal of this magic
> sequence makes booting more stable.
>
> Data transfer protocol (xmodem) is using checksums and retransmit, so it
> already deals with possible errors on transfer line.
>
> Signed-off-by: Pali Rohár <pali at kernel.org>
> Signed-off-by: Marek Behún <marek.behun at nic.cz>
Reviewed-by: Stefan Roese <sr at denx.de>
Thanks,
Stefan
> ---
> tools/kwboot.c | 115 ++++++++++++++++++++++++++-----------------------
> 1 file changed, 60 insertions(+), 55 deletions(-)
>
> diff --git a/tools/kwboot.c b/tools/kwboot.c
> index 359b43c0d8..bacca15301 100644
> --- a/tools/kwboot.c
> +++ b/tools/kwboot.c
> @@ -81,23 +81,15 @@ struct kwboot_block {
> /* ARM code to change baudrate */
> static unsigned char kwboot_baud_code[] = {
> /* ; #define UART_BASE 0xd0012000 */
> - /* ; #define THR 0x00 */
> /* ; #define DLL 0x00 */
> /* ; #define DLH 0x04 */
> /* ; #define LCR 0x0c */
> /* ; #define DLAB 0x80 */
> /* ; #define LSR 0x14 */
> - /* ; #define THRE 0x20 */
> /* ; #define TEMT 0x40 */
> /* ; #define DIV_ROUND(a, b) ((a + b/2) / b) */
> /* ; */
> /* ; u32 set_baudrate(u32 old_b, u32 new_b) { */
> - /* ; const u8 *str = "$baudratechange"; */
> - /* ; u8 c; */
> - /* ; do { */
> - /* ; c = *str++; */
> - /* ; writel(UART_BASE + THR, c); */
> - /* ; } while (c); */
> /* ; while */
> /* ; (!(readl(UART_BASE + LSR) & TEMT)); */
> /* ; u32 lcr = readl(UART_BASE + LCR); */
> @@ -120,29 +112,6 @@ static unsigned char kwboot_baud_code[] = {
> 0x0d, 0x02, 0xa0, 0xe3, /* mov r0, #0xd0000000 */
> 0x12, 0x0a, 0x80, 0xe3, /* orr r0, r0, #0x12000 */
>
> - /* ; r2 = address of preamble string */
> - 0xc8, 0x20, 0x8f, 0xe2, /* adr r2, preamble */
> -
> - /* ; Send preamble string over UART */
> - /* .Lloop_preamble: */
> - /* */
> - /* ; Wait until Transmitter Holding is Empty */
> - /* .Lloop_thre: */
> - /* ; r1 = UART_BASE[LSR] & THRE */
> - 0x14, 0x10, 0x90, 0xe5, /* ldr r1, [r0, #0x14] */
> - 0x20, 0x00, 0x11, 0xe3, /* tst r1, #0x20 */
> - 0xfc, 0xff, 0xff, 0x0a, /* beq .Lloop_thre */
> -
> - /* ; Put character into Transmitter FIFO */
> - /* ; r1 = *r2++ */
> - 0x01, 0x10, 0xd2, 0xe4, /* ldrb r1, [r2], #1 */
> - /* ; UART_BASE[THR] = r1 */
> - 0x00, 0x10, 0x80, 0xe5, /* str r1, [r0, #0x0] */
> -
> - /* ; Loop until end of preamble string */
> - 0x00, 0x00, 0x51, 0xe3, /* cmp r1, #0 */
> - 0xf8, 0xff, 0xff, 0x1a, /* bne .Lloop_preamble */
> -
> /* ; Wait until Transmitter FIFO is Empty */
> /* .Lloop_txempty: */
> /* ; r1 = UART_BASE[LSR] & TEMT */
> @@ -168,7 +137,7 @@ static unsigned char kwboot_baud_code[] = {
>
> /* ; Read old baudrate value */
> /* ; r2 = old_baudrate */
> - 0x84, 0x20, 0x9f, 0xe5, /* ldr r2, old_baudrate */
> + 0x74, 0x20, 0x9f, 0xe5, /* ldr r2, old_baudrate */
>
> /* ; Calculate base clock */
> /* ; r1 = r2 * r1 */
> @@ -176,7 +145,7 @@ static unsigned char kwboot_baud_code[] = {
>
> /* ; Read new baudrate value */
> /* ; r2 = new_baudrate */
> - 0x80, 0x20, 0x9f, 0xe5, /* ldr r2, new_baudrate */
> + 0x70, 0x20, 0x9f, 0xe5, /* ldr r2, new_baudrate */
>
> /* ; Calculate new Divisor Latch */
> /* ; r1 = DIV_ROUND(r1, r2) = */
> @@ -225,14 +194,8 @@ static unsigned char kwboot_baud_code[] = {
> 0x00, 0x00, 0x51, 0xe3, /* cmp r1, #0 */
> 0xfc, 0xff, 0xff, 0x1a, /* bne .Lloop_sleep */
>
> - 0x05, 0x00, 0x00, 0xea, /* b end */
> -
> - /* ; Preamble string */
> - /* preamble: */
> - 0x24, 0x62, 0x61, 0x75, /* .asciz "$baudratechange" */
> - 0x64, 0x72, 0x61, 0x74,
> - 0x65, 0x63, 0x68, 0x61,
> - 0x6e, 0x67, 0x65, 0x00,
> + /* ; Jump to the end of execution */
> + 0x01, 0x00, 0x00, 0xea, /* b end */
>
> /* ; Placeholder for old baudrate value */
> /* old_baudrate: */
> @@ -245,12 +208,66 @@ static unsigned char kwboot_baud_code[] = {
> /* end: */
> };
>
> -/* ARM code for storing registers for future returning back to the bootrom */
> +/* ARM code from binary header executed by BootROM before changing baudrate */
> static unsigned char kwboot_baud_code_binhdr_pre[] = {
> + /* ; #define UART_BASE 0xd0012000 */
> + /* ; #define THR 0x00 */
> + /* ; #define LSR 0x14 */
> + /* ; #define THRE 0x20 */
> + /* ; */
> + /* ; void send_preamble(void) { */
> + /* ; const u8 *str = "$baudratechange"; */
> + /* ; u8 c; */
> + /* ; do { */
> + /* ; while */
> + /* ; ((readl(UART_BASE + LSR) & THRE)); */
> + /* ; c = *str++; */
> + /* ; writel(UART_BASE + THR, c); */
> + /* ; } while (c); */
> + /* ; } */
> +
> + /* ; Preserve registers for BootROM */
> 0xfe, 0x5f, 0x2d, 0xe9, /* push { r1 - r12, lr } */
> +
> + /* ; r0 = UART_BASE */
> + 0x0d, 0x02, 0xa0, 0xe3, /* mov r0, #0xd0000000 */
> + 0x12, 0x0a, 0x80, 0xe3, /* orr r0, r0, #0x12000 */
> +
> + /* ; r2 = address of preamble string */
> + 0x00, 0x20, 0x8f, 0xe2, /* adr r2, .Lstr_preamble */
> +
> + /* ; Skip preamble data section */
> + 0x03, 0x00, 0x00, 0xea, /* b .Lloop_preamble */
> +
> + /* ; Preamble string */
> + /* .Lstr_preamble: */
> + 0x24, 0x62, 0x61, 0x75, /* .asciz "$baudratechange" */
> + 0x64, 0x72, 0x61, 0x74,
> + 0x65, 0x63, 0x68, 0x61,
> + 0x6e, 0x67, 0x65, 0x00,
> +
> + /* ; Send preamble string over UART */
> + /* .Lloop_preamble: */
> + /* */
> + /* ; Wait until Transmitter Holding is Empty */
> + /* .Lloop_thre: */
> + /* ; r1 = UART_BASE[LSR] & THRE */
> + 0x14, 0x10, 0x90, 0xe5, /* ldr r1, [r0, #0x14] */
> + 0x20, 0x00, 0x11, 0xe3, /* tst r1, #0x20 */
> + 0xfc, 0xff, 0xff, 0x0a, /* beq .Lloop_thre */
> +
> + /* ; Put character into Transmitter FIFO */
> + /* ; r1 = *r2++ */
> + 0x01, 0x10, 0xd2, 0xe4, /* ldrb r1, [r2], #1 */
> + /* ; UART_BASE[THR] = r1 */
> + 0x00, 0x10, 0x80, 0xe5, /* str r1, [r0, #0x0] */
> +
> + /* ; Loop until end of preamble string */
> + 0x00, 0x00, 0x51, 0xe3, /* cmp r1, #0 */
> + 0xf8, 0xff, 0xff, 0x1a, /* bne .Lloop_preamble */
> };
>
> -/* ARM code for returning back to the bootrom */
> +/* ARM code for returning from binary header back to BootROM */
> static unsigned char kwboot_baud_code_binhdr_post[] = {
> /* ; Return 0 - no error */
> 0x00, 0x00, 0xa0, 0xe3, /* mov r0, #0 */
> @@ -1078,18 +1095,6 @@ kwboot_xmodem(int tty, const void *_img, size_t size, int baudrate)
> return rc;
>
> if (baudrate) {
> - char buf[sizeof(kwb_baud_magic)];
> -
> - kwboot_printv("Waiting 1s for baudrate change magic\n");
> - rc = kwboot_tty_recv(tty, buf, sizeof(buf), 1000);
> - if (rc)
> - return rc;
> -
> - if (memcmp(buf, kwb_baud_magic, sizeof(buf))) {
> - errno = EPROTO;
> - return -1;
> - }
> -
> kwboot_printv("\nChanging baudrate back to 115200 Bd\n\n");
> rc = kwboot_tty_change_baudrate(tty, 115200);
> if (rc)
>
Viele Grüße,
Stefan
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-51 Fax: (+49)-8142-66989-80 Email: sr at denx.de
More information about the U-Boot
mailing list