[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