tools: kwboot: Calculate real used space in kwbimage header when calling kwboot_img_g...
[platform/kernel/u-boot.git] / tools / kwboot.c
1 /*
2  * Boot a Marvell SoC, with Xmodem over UART0.
3  *  supports Kirkwood, Dove, Armada 370, Armada XP, Armada 375, Armada 38x and
4  *           Armada 39x
5  *
6  * (c) 2012 Daniel Stodden <daniel.stodden@gmail.com>
7  * (c) 2021 Pali Rohár <pali@kernel.org>
8  * (c) 2021 Marek Behún <marek.behun@nic.cz>
9  *
10  * References: marvell.com, "88F6180, 88F6190, 88F6192, and 88F6281
11  *   Integrated Controller: Functional Specifications" December 2,
12  *   2008. Chapter 24.2 "BootROM Firmware".
13  */
14
15 #include "kwbimage.h"
16 #include "mkimage.h"
17 #include "version.h"
18
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <stdarg.h>
23 #include <image.h>
24 #include <libgen.h>
25 #include <fcntl.h>
26 #include <errno.h>
27 #include <unistd.h>
28 #include <stdint.h>
29 #include <time.h>
30 #include <sys/stat.h>
31
32 #ifdef __linux__
33 #include "termios_linux.h"
34 #else
35 #include <termios.h>
36 #endif
37
38 /*
39  * Marvell BootROM UART Sensing
40  */
41
42 static unsigned char kwboot_msg_boot[] = {
43         0xBB, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77
44 };
45
46 static unsigned char kwboot_msg_debug[] = {
47         0xDD, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77
48 };
49
50 /* Defines known to work on Kirkwood */
51 #define KWBOOT_MSG_REQ_DELAY    10 /* ms */
52 #define KWBOOT_MSG_RSP_TIMEO    50 /* ms */
53
54 /* Defines known to work on Armada XP */
55 #define KWBOOT_MSG_REQ_DELAY_AXP        1000 /* ms */
56 #define KWBOOT_MSG_RSP_TIMEO_AXP        1000 /* ms */
57
58 /*
59  * Xmodem Transfers
60  */
61
62 #define SOH     1       /* sender start of block header */
63 #define EOT     4       /* sender end of block transfer */
64 #define ACK     6       /* target block ack */
65 #define NAK     21      /* target block negative ack */
66 #define CAN     24      /* target/sender transfer cancellation */
67
68 #define KWBOOT_XM_BLKSZ 128 /* xmodem block size */
69
70 struct kwboot_block {
71         uint8_t soh;
72         uint8_t pnum;
73         uint8_t _pnum;
74         uint8_t data[KWBOOT_XM_BLKSZ];
75         uint8_t csum;
76 } __packed;
77
78 #define KWBOOT_BLK_RSP_TIMEO 1000 /* ms */
79 #define KWBOOT_HDR_RSP_TIMEO 10000 /* ms */
80
81 /* ARM code making baudrate changing function return to original exec address */
82 static unsigned char kwboot_pre_baud_code[] = {
83                                 /* exec_addr:                                 */
84         0x00, 0x00, 0x00, 0x00, /* .word 0                                    */
85         0x0c, 0xe0, 0x1f, 0xe5, /* ldr lr, exec_addr                          */
86 };
87
88 /* ARM code for binary header injection to change baudrate */
89 static unsigned char kwboot_baud_code[] = {
90                                 /* ; #define UART_BASE 0xd0012000             */
91                                 /* ; #define THR       0x00                   */
92                                 /* ; #define DLL       0x00                   */
93                                 /* ; #define DLH       0x04                   */
94                                 /* ; #define LCR       0x0c                   */
95                                 /* ; #define   DLAB    0x80                   */
96                                 /* ; #define LSR       0x14                   */
97                                 /* ; #define   THRE    0x20                   */
98                                 /* ; #define   TEMT    0x40                   */
99                                 /* ; #define DIV_ROUND(a, b) ((a + b/2) / b)  */
100                                 /* ;                                          */
101                                 /* ; u32 set_baudrate(u32 old_b, u32 new_b) { */
102                                 /* ;   const u8 *str = "$baudratechange";     */
103                                 /* ;   u8 c;                                  */
104                                 /* ;   do {                                   */
105                                 /* ;       c = *str++;                        */
106                                 /* ;       writel(UART_BASE + THR, c);        */
107                                 /* ;   } while (c);                           */
108                                 /* ;   while                                  */
109                                 /* ;      (!(readl(UART_BASE + LSR) & TEMT)); */
110                                 /* ;   u32 lcr = readl(UART_BASE + LCR);      */
111                                 /* ;   writel(UART_BASE + LCR, lcr | DLAB);   */
112                                 /* ;   u8 old_dll = readl(UART_BASE + DLL);   */
113                                 /* ;   u8 old_dlh = readl(UART_BASE + DLH);   */
114                                 /* ;   u16 old_dl = old_dll | (old_dlh << 8); */
115                                 /* ;   u32 clk = old_b * old_dl;              */
116                                 /* ;   u16 new_dl = DIV_ROUND(clk, new_b);    */
117                                 /* ;   u8 new_dll = new_dl & 0xff;            */
118                                 /* ;   u8 new_dlh = (new_dl >> 8) & 0xff;     */
119                                 /* ;   writel(UART_BASE + DLL, new_dll);      */
120                                 /* ;   writel(UART_BASE + DLH, new_dlh);      */
121                                 /* ;   writel(UART_BASE + LCR, lcr & ~DLAB);  */
122                                 /* ;   msleep(1);                             */
123                                 /* ;   return 0;                              */
124                                 /* ; }                                        */
125
126         0xfe, 0x5f, 0x2d, 0xe9, /* push  { r1 - r12, lr }                     */
127
128                                 /*  ; r0 = UART_BASE                          */
129         0x02, 0x0a, 0xa0, 0xe3, /* mov   r0, #0x2000                          */
130         0x01, 0x00, 0x4d, 0xe3, /* movt  r0, #0xd001                          */
131
132                                 /*  ; r2 = address of preamble string         */
133         0xd0, 0x20, 0x8f, 0xe2, /* adr   r2, preamble                         */
134
135                                 /*  ; Send preamble string over UART          */
136                                 /* .Lloop_preamble:                           */
137                                 /*                                            */
138                                 /*  ; Wait until Transmitter Holding is Empty */
139                                 /* .Lloop_thre:                               */
140                                 /*  ; r1 = UART_BASE[LSR] & THRE              */
141         0x14, 0x10, 0x90, 0xe5, /* ldr   r1, [r0, #0x14]                      */
142         0x20, 0x00, 0x11, 0xe3, /* tst   r1, #0x20                            */
143         0xfc, 0xff, 0xff, 0x0a, /* beq   .Lloop_thre                          */
144
145                                 /*  ; Put character into Transmitter FIFO     */
146                                 /*  ; r1 = *r2++                              */
147         0x01, 0x10, 0xd2, 0xe4, /* ldrb  r1, [r2], #1                         */
148                                 /*  ; UART_BASE[THR] = r1                     */
149         0x00, 0x10, 0x80, 0xe5, /* str   r1, [r0, #0x0]                       */
150
151                                 /*  ; Loop until end of preamble string       */
152         0x00, 0x00, 0x51, 0xe3, /* cmp   r1, #0                               */
153         0xf8, 0xff, 0xff, 0x1a, /* bne   .Lloop_preamble                      */
154
155                                 /*  ; Wait until Transmitter FIFO is Empty    */
156                                 /* .Lloop_txempty:                            */
157                                 /*  ; r1 = UART_BASE[LSR] & TEMT              */
158         0x14, 0x10, 0x90, 0xe5, /* ldr   r1, [r0, #0x14]                      */
159         0x40, 0x00, 0x11, 0xe3, /* tst   r1, #0x40                            */
160         0xfc, 0xff, 0xff, 0x0a, /* beq   .Lloop_txempty                       */
161
162                                 /*  ; Set Divisor Latch Access Bit            */
163                                 /*  ; UART_BASE[LCR] |= DLAB                  */
164         0x0c, 0x10, 0x90, 0xe5, /* ldr   r1, [r0, #0x0c]                      */
165         0x80, 0x10, 0x81, 0xe3, /* orr   r1, r1, #0x80                        */
166         0x0c, 0x10, 0x80, 0xe5, /* str   r1, [r0, #0x0c]                      */
167
168                                 /*  ; Read current Divisor Latch              */
169                                 /*  ; r1 = UART_BASE[DLH]<<8 | UART_BASE[DLL] */
170         0x00, 0x10, 0x90, 0xe5, /* ldr   r1, [r0, #0x00]                      */
171         0xff, 0x10, 0x01, 0xe2, /* and   r1, r1, #0xff                        */
172         0x01, 0x20, 0xa0, 0xe1, /* mov   r2, r1                               */
173         0x04, 0x10, 0x90, 0xe5, /* ldr   r1, [r0, #0x04]                      */
174         0xff, 0x10, 0x01, 0xe2, /* and   r1, r1, #0xff                        */
175         0x41, 0x14, 0xa0, 0xe1, /* asr   r1, r1, #8                           */
176         0x02, 0x10, 0x81, 0xe1, /* orr   r1, r1, r2                           */
177
178                                 /*  ; Read old baudrate value                 */
179                                 /*  ; r2 = old_baudrate                       */
180         0x8c, 0x20, 0x9f, 0xe5, /* ldr   r2, old_baudrate                     */
181
182                                 /*  ; Calculate base clock                    */
183                                 /*  ; r1 = r2 * r1                            */
184         0x92, 0x01, 0x01, 0xe0, /* mul   r1, r2, r1                           */
185
186                                 /*  ; Read new baudrate value                 */
187                                 /*  ; r2 = baudrate                           */
188         0x88, 0x20, 0x9f, 0xe5, /* ldr   r2, baudrate                         */
189
190                                 /*  ; Calculate new Divisor Latch             */
191                                 /*  ; r1 = DIV_ROUND(r1, r2) =                */
192                                 /*  ;    = (r1 + r2/2) / r2                   */
193         0xa2, 0x10, 0x81, 0xe0, /* add   r1, r1, r2, lsr #1                   */
194         0x02, 0x40, 0xa0, 0xe1, /* mov   r4, r2                               */
195         0xa1, 0x00, 0x54, 0xe1, /* cmp   r4, r1, lsr #1                       */
196                                 /* .Lloop_div1:                               */
197         0x84, 0x40, 0xa0, 0x91, /* movls r4, r4, lsl #1                       */
198         0xa1, 0x00, 0x54, 0xe1, /* cmp   r4, r1, lsr #1                       */
199         0xfc, 0xff, 0xff, 0x9a, /* bls   .Lloop_div1                          */
200         0x00, 0x30, 0xa0, 0xe3, /* mov   r3, #0                               */
201                                 /* .Lloop_div2:                               */
202         0x04, 0x00, 0x51, 0xe1, /* cmp   r1, r4                               */
203         0x04, 0x10, 0x41, 0x20, /* subhs r1, r1, r4                           */
204         0x03, 0x30, 0xa3, 0xe0, /* adc   r3, r3, r3                           */
205         0xa4, 0x40, 0xa0, 0xe1, /* mov   r4, r4, lsr #1                       */
206         0x02, 0x00, 0x54, 0xe1, /* cmp   r4, r2                               */
207         0xf9, 0xff, 0xff, 0x2a, /* bhs   .Lloop_div2                          */
208         0x03, 0x10, 0xa0, 0xe1, /* mov   r1, r3                               */
209
210                                 /*  ; Set new Divisor Latch Low               */
211                                 /*  ; UART_BASE[DLL] = r1 & 0xff              */
212         0x01, 0x20, 0xa0, 0xe1, /* mov   r2, r1                               */
213         0xff, 0x20, 0x02, 0xe2, /* and   r2, r2, #0xff                        */
214         0x00, 0x20, 0x80, 0xe5, /* str   r2, [r0, #0x00]                      */
215
216                                 /*  ; Set new Divisor Latch High              */
217                                 /*  ; UART_BASE[DLH] = r1>>8 & 0xff           */
218         0x41, 0x24, 0xa0, 0xe1, /* asr   r2, r1, #8                           */
219         0xff, 0x20, 0x02, 0xe2, /* and   r2, r2, #0xff                        */
220         0x04, 0x20, 0x80, 0xe5, /* str   r2, [r0, #0x04]                      */
221
222                                 /*  ; Clear Divisor Latch Access Bit          */
223                                 /*  ; UART_BASE[LCR] &= ~DLAB                 */
224         0x0c, 0x10, 0x90, 0xe5, /* ldr   r1, [r0, #0x0c]                      */
225         0x80, 0x10, 0xc1, 0xe3, /* bic   r1, r1, #0x80                        */
226         0x0c, 0x10, 0x80, 0xe5, /* str   r1, [r0, #0x0c]                      */
227
228                                 /*  ; Sleep 1ms ~~ 600000 cycles at 1200 MHz  */
229                                 /*  ; r1 = 600000                             */
230         0x9f, 0x1d, 0xa0, 0xe3, /* mov   r1, #0x27c0                          */
231         0x09, 0x10, 0x40, 0xe3, /* movt  r1, #0x0009                          */
232                                 /* .Lloop_sleep:                              */
233         0x01, 0x10, 0x41, 0xe2, /* sub   r1, r1, #1                           */
234         0x00, 0x00, 0x51, 0xe3, /* cmp   r1, #0                               */
235         0xfc, 0xff, 0xff, 0x1a, /* bne   .Lloop_sleep                         */
236
237                                 /*  ; Return 0 - no error                     */
238         0x00, 0x00, 0xa0, 0xe3, /* mov   r0, #0                               */
239         0xfe, 0x9f, 0xbd, 0xe8, /* pop   { r1 - r12, pc }                     */
240
241                                 /*  ; Preamble string                         */
242                                 /* preamble:                                  */
243         0x24, 0x62, 0x61, 0x75, /* .asciz "$baudratechange"                   */
244         0x64, 0x72, 0x61, 0x74,
245         0x65, 0x63, 0x68, 0x61,
246         0x6e, 0x67, 0x65, 0x00,
247
248                                 /*  ; Placeholder for old baudrate value      */
249                                 /* old_baudrate:                              */
250         0x00, 0x00, 0x00, 0x00, /* .word 0                                    */
251
252                                 /*  ; Placeholder for new baudrate value      */
253                                 /* new_baudrate:                              */
254         0x00, 0x00, 0x00, 0x00, /* .word 0                                    */
255 };
256
257 #define KWBOOT_BAUDRATE_BIN_HEADER_SZ (sizeof(kwboot_baud_code) + \
258                                        sizeof(struct opt_hdr_v1) + 8 + 16)
259
260 static const char kwb_baud_magic[16] = "$baudratechange";
261
262 static int kwboot_verbose;
263
264 static int msg_req_delay = KWBOOT_MSG_REQ_DELAY;
265 static int msg_rsp_timeo = KWBOOT_MSG_RSP_TIMEO;
266 static int blk_rsp_timeo = KWBOOT_BLK_RSP_TIMEO;
267
268 static ssize_t
269 kwboot_write(int fd, const char *buf, size_t len)
270 {
271         size_t tot = 0;
272
273         while (tot < len) {
274                 ssize_t wr = write(fd, buf + tot, len - tot);
275
276                 if (wr < 0)
277                         return -1;
278
279                 tot += wr;
280         }
281
282         return tot;
283 }
284
285 static void
286 kwboot_printv(const char *fmt, ...)
287 {
288         va_list ap;
289
290         if (kwboot_verbose) {
291                 va_start(ap, fmt);
292                 vprintf(fmt, ap);
293                 va_end(ap);
294                 fflush(stdout);
295         }
296 }
297
298 static void
299 __spinner(void)
300 {
301         const char seq[] = { '-', '\\', '|', '/' };
302         const int div = 8;
303         static int state, bs;
304
305         if (state % div == 0) {
306                 fputc(bs, stdout);
307                 fputc(seq[state / div % sizeof(seq)], stdout);
308                 fflush(stdout);
309         }
310
311         bs = '\b';
312         state++;
313 }
314
315 static void
316 kwboot_spinner(void)
317 {
318         if (kwboot_verbose)
319                 __spinner();
320 }
321
322 static void
323 __progress(int pct, char c)
324 {
325         const int width = 70;
326         static const char *nl = "";
327         static int pos;
328
329         if (pos % width == 0)
330                 printf("%s%3d %% [", nl, pct);
331
332         fputc(c, stdout);
333
334         nl = "]\n";
335         pos = (pos + 1) % width;
336
337         if (pct == 100) {
338                 while (pos && pos++ < width)
339                         fputc(' ', stdout);
340                 fputs(nl, stdout);
341                 nl = "";
342                 pos = 0;
343         }
344
345         fflush(stdout);
346
347 }
348
349 static void
350 kwboot_progress(int _pct, char c)
351 {
352         static int pct;
353
354         if (_pct != -1)
355                 pct = _pct;
356
357         if (kwboot_verbose)
358                 __progress(pct, c);
359
360         if (pct == 100)
361                 pct = 0;
362 }
363
364 static int
365 kwboot_tty_recv(int fd, void *buf, size_t len, int timeo)
366 {
367         int rc, nfds;
368         fd_set rfds;
369         struct timeval tv;
370         ssize_t n;
371
372         rc = -1;
373
374         FD_ZERO(&rfds);
375         FD_SET(fd, &rfds);
376
377         tv.tv_sec = 0;
378         tv.tv_usec = timeo * 1000;
379         if (tv.tv_usec > 1000000) {
380                 tv.tv_sec += tv.tv_usec / 1000000;
381                 tv.tv_usec %= 1000000;
382         }
383
384         do {
385                 nfds = select(fd + 1, &rfds, NULL, NULL, &tv);
386                 if (nfds < 0)
387                         goto out;
388                 if (!nfds) {
389                         errno = ETIMEDOUT;
390                         goto out;
391                 }
392
393                 n = read(fd, buf, len);
394                 if (n <= 0)
395                         goto out;
396
397                 buf = (char *)buf + n;
398                 len -= n;
399         } while (len > 0);
400
401         rc = 0;
402 out:
403         return rc;
404 }
405
406 static int
407 kwboot_tty_send(int fd, const void *buf, size_t len)
408 {
409         if (!buf)
410                 return 0;
411
412         if (kwboot_write(fd, buf, len) < 0)
413                 return -1;
414
415         return tcdrain(fd);
416 }
417
418 static int
419 kwboot_tty_send_char(int fd, unsigned char c)
420 {
421         return kwboot_tty_send(fd, &c, 1);
422 }
423
424 static speed_t
425 kwboot_tty_baudrate_to_speed(int baudrate)
426 {
427         switch (baudrate) {
428 #ifdef B4000000
429         case 4000000:
430                 return B4000000;
431 #endif
432 #ifdef B3500000
433         case 3500000:
434                 return B3500000;
435 #endif
436 #ifdef B3000000
437         case 3000000:
438                 return B3000000;
439 #endif
440 #ifdef B2500000
441         case 2500000:
442                 return B2500000;
443 #endif
444 #ifdef B2000000
445         case 2000000:
446                 return B2000000;
447 #endif
448 #ifdef B1500000
449         case 1500000:
450                 return B1500000;
451 #endif
452 #ifdef B1152000
453         case 1152000:
454                 return B1152000;
455 #endif
456 #ifdef B1000000
457         case 1000000:
458                 return B1000000;
459 #endif
460 #ifdef B921600
461         case 921600:
462                 return B921600;
463 #endif
464 #ifdef B614400
465         case 614400:
466                 return B614400;
467 #endif
468 #ifdef B576000
469         case 576000:
470                 return B576000;
471 #endif
472 #ifdef B500000
473         case 500000:
474                 return B500000;
475 #endif
476 #ifdef B460800
477         case 460800:
478                 return B460800;
479 #endif
480 #ifdef B307200
481         case 307200:
482                 return B307200;
483 #endif
484 #ifdef B230400
485         case 230400:
486                 return B230400;
487 #endif
488 #ifdef B153600
489         case 153600:
490                 return B153600;
491 #endif
492 #ifdef B115200
493         case 115200:
494                 return B115200;
495 #endif
496 #ifdef B76800
497         case 76800:
498                 return B76800;
499 #endif
500 #ifdef B57600
501         case 57600:
502                 return B57600;
503 #endif
504 #ifdef B38400
505         case 38400:
506                 return B38400;
507 #endif
508 #ifdef B19200
509         case 19200:
510                 return B19200;
511 #endif
512 #ifdef B9600
513         case 9600:
514                 return B9600;
515 #endif
516 #ifdef B4800
517         case 4800:
518                 return B4800;
519 #endif
520 #ifdef B2400
521         case 2400:
522                 return B2400;
523 #endif
524 #ifdef B1800
525         case 1800:
526                 return B1800;
527 #endif
528 #ifdef B1200
529         case 1200:
530                 return B1200;
531 #endif
532 #ifdef B600
533         case 600:
534                 return B600;
535 #endif
536 #ifdef B300
537         case 300:
538                 return B300;
539 #endif
540 #ifdef B200
541         case 200:
542                 return B200;
543 #endif
544 #ifdef B150
545         case 150:
546                 return B150;
547 #endif
548 #ifdef B134
549         case 134:
550                 return B134;
551 #endif
552 #ifdef B110
553         case 110:
554                 return B110;
555 #endif
556 #ifdef B75
557         case 75:
558                 return B75;
559 #endif
560 #ifdef B50
561         case 50:
562                 return B50;
563 #endif
564         default:
565 #ifdef BOTHER
566                 return BOTHER;
567 #else
568                 return B0;
569 #endif
570         }
571 }
572
573 static int
574 _is_within_tolerance(int value, int reference, int tolerance)
575 {
576         return 100 * value >= reference * (100 - tolerance) &&
577                100 * value <= reference * (100 + tolerance);
578 }
579
580 static int
581 kwboot_tty_change_baudrate(int fd, int baudrate)
582 {
583         struct termios tio;
584         speed_t speed;
585         int rc;
586
587         rc = tcgetattr(fd, &tio);
588         if (rc)
589                 return rc;
590
591         speed = kwboot_tty_baudrate_to_speed(baudrate);
592         if (speed == B0) {
593                 errno = EINVAL;
594                 return -1;
595         }
596
597 #ifdef BOTHER
598         if (speed == BOTHER)
599                 tio.c_ospeed = tio.c_ispeed = baudrate;
600 #endif
601
602         rc = cfsetospeed(&tio, speed);
603         if (rc)
604                 return rc;
605
606         rc = cfsetispeed(&tio, speed);
607         if (rc)
608                 return rc;
609
610         rc = tcsetattr(fd, TCSANOW, &tio);
611         if (rc)
612                 return rc;
613
614         rc = tcgetattr(fd, &tio);
615         if (rc)
616                 return rc;
617
618         if (cfgetospeed(&tio) != speed || cfgetispeed(&tio) != speed)
619                 goto baud_fail;
620
621 #ifdef BOTHER
622         /*
623          * Check whether set baudrate is within 3% tolerance.
624          * If BOTHER is defined, Linux always fills out c_ospeed / c_ispeed
625          * with real values.
626          */
627         if (!_is_within_tolerance(tio.c_ospeed, baudrate, 3))
628                 goto baud_fail;
629
630         if (!_is_within_tolerance(tio.c_ispeed, baudrate, 3))
631                 goto baud_fail;
632 #endif
633
634         return 0;
635
636 baud_fail:
637         fprintf(stderr, "Could not set baudrate to requested value\n");
638         errno = EINVAL;
639         return -1;
640 }
641
642 static int
643 kwboot_open_tty(const char *path, int baudrate)
644 {
645         int rc, fd, flags;
646         struct termios tio;
647
648         rc = -1;
649
650         fd = open(path, O_RDWR | O_NOCTTY | O_NDELAY);
651         if (fd < 0)
652                 goto out;
653
654         rc = tcgetattr(fd, &tio);
655         if (rc)
656                 goto out;
657
658         cfmakeraw(&tio);
659         tio.c_cflag |= CREAD | CLOCAL;
660         tio.c_cflag &= ~(CSTOPB | HUPCL | CRTSCTS);
661         tio.c_cc[VMIN] = 1;
662         tio.c_cc[VTIME] = 0;
663
664         rc = tcsetattr(fd, TCSANOW, &tio);
665         if (rc)
666                 goto out;
667
668         flags = fcntl(fd, F_GETFL);
669         if (flags < 0)
670                 goto out;
671
672         rc = fcntl(fd, F_SETFL, flags & ~O_NDELAY);
673         if (rc)
674                 goto out;
675
676         rc = kwboot_tty_change_baudrate(fd, baudrate);
677         if (rc)
678                 goto out;
679
680         rc = fd;
681 out:
682         if (rc < 0) {
683                 if (fd >= 0)
684                         close(fd);
685         }
686
687         return rc;
688 }
689
690 static int
691 kwboot_bootmsg(int tty, void *msg)
692 {
693         int rc;
694         char c;
695         int count;
696
697         if (msg == NULL)
698                 kwboot_printv("Please reboot the target into UART boot mode...");
699         else
700                 kwboot_printv("Sending boot message. Please reboot the target...");
701
702         do {
703                 rc = tcflush(tty, TCIOFLUSH);
704                 if (rc)
705                         break;
706
707                 for (count = 0; count < 128; count++) {
708                         rc = kwboot_tty_send(tty, msg, 8);
709                         if (rc) {
710                                 usleep(msg_req_delay * 1000);
711                                 continue;
712                         }
713                 }
714
715                 rc = kwboot_tty_recv(tty, &c, 1, msg_rsp_timeo);
716
717                 kwboot_spinner();
718
719         } while (rc || c != NAK);
720
721         kwboot_printv("\n");
722
723         return rc;
724 }
725
726 static int
727 kwboot_debugmsg(int tty, void *msg)
728 {
729         int rc;
730
731         kwboot_printv("Sending debug message. Please reboot the target...");
732
733         do {
734                 char buf[16];
735
736                 rc = tcflush(tty, TCIOFLUSH);
737                 if (rc)
738                         break;
739
740                 rc = kwboot_tty_send(tty, msg, 8);
741                 if (rc) {
742                         usleep(msg_req_delay * 1000);
743                         continue;
744                 }
745
746                 rc = kwboot_tty_recv(tty, buf, 16, msg_rsp_timeo);
747
748                 kwboot_spinner();
749
750         } while (rc);
751
752         kwboot_printv("\n");
753
754         return rc;
755 }
756
757 static size_t
758 kwboot_xm_makeblock(struct kwboot_block *block, const void *data,
759                     size_t size, int pnum)
760 {
761         size_t i, n;
762
763         block->soh = SOH;
764         block->pnum = pnum;
765         block->_pnum = ~block->pnum;
766
767         n = size < KWBOOT_XM_BLKSZ ? size : KWBOOT_XM_BLKSZ;
768         memcpy(&block->data[0], data, n);
769         memset(&block->data[n], 0, KWBOOT_XM_BLKSZ - n);
770
771         block->csum = 0;
772         for (i = 0; i < n; i++)
773                 block->csum += block->data[i];
774
775         return n;
776 }
777
778 static uint64_t
779 _now(void)
780 {
781         struct timespec ts;
782
783         if (clock_gettime(CLOCK_MONOTONIC, &ts)) {
784                 static int err_print;
785
786                 if (!err_print) {
787                         perror("clock_gettime() does not work");
788                         err_print = 1;
789                 }
790
791                 /* this will just make the timeout not work */
792                 return -1ULL;
793         }
794
795         return ts.tv_sec * 1000ULL + (ts.tv_nsec + 500000) / 1000000;
796 }
797
798 static int
799 _is_xm_reply(char c)
800 {
801         return c == ACK || c == NAK || c == CAN;
802 }
803
804 static int
805 _xm_reply_to_error(int c)
806 {
807         int rc = -1;
808
809         switch (c) {
810         case ACK:
811                 rc = 0;
812                 break;
813         case NAK:
814                 errno = EBADMSG;
815                 break;
816         case CAN:
817                 errno = ECANCELED;
818                 break;
819         default:
820                 errno = EPROTO;
821                 break;
822         }
823
824         return rc;
825 }
826
827 static int
828 kwboot_baud_magic_handle(int fd, char c, int baudrate)
829 {
830         static size_t rcv_len;
831
832         if (rcv_len < sizeof(kwb_baud_magic)) {
833                 /* try to recognize whole magic word */
834                 if (c == kwb_baud_magic[rcv_len]) {
835                         rcv_len++;
836                 } else {
837                         printf("%.*s%c", (int)rcv_len, kwb_baud_magic, c);
838                         fflush(stdout);
839                         rcv_len = 0;
840                 }
841         }
842
843         if (rcv_len == sizeof(kwb_baud_magic)) {
844                 /* magic word received */
845                 kwboot_printv("\nChanging baudrate to %d Bd\n", baudrate);
846
847                 return kwboot_tty_change_baudrate(fd, baudrate) ? : 1;
848         } else {
849                 return 0;
850         }
851 }
852
853 static int
854 kwboot_xm_recv_reply(int fd, char *c, int allow_non_xm, int *non_xm_print,
855                      int baudrate, int *baud_changed)
856 {
857         int timeout = allow_non_xm ? KWBOOT_HDR_RSP_TIMEO : blk_rsp_timeo;
858         uint64_t recv_until = _now() + timeout;
859         int rc;
860
861         if (non_xm_print)
862                 *non_xm_print = 0;
863         if (baud_changed)
864                 *baud_changed = 0;
865
866         while (1) {
867                 rc = kwboot_tty_recv(fd, c, 1, timeout);
868                 if (rc) {
869                         if (errno != ETIMEDOUT)
870                                 return rc;
871                         else if (allow_non_xm && *non_xm_print)
872                                 return -1;
873                         else
874                                 *c = NAK;
875                 }
876
877                 /* If received xmodem reply, end. */
878                 if (_is_xm_reply(*c))
879                         break;
880
881                 /*
882                  * If receiving/printing non-xmodem text output is allowed and
883                  * such a byte was received, we want to increase receiving time
884                  * and either:
885                  * - print the byte, if it is not part of baudrate change magic
886                  *   sequence while baudrate change was requested (-B option)
887                  * - change baudrate
888                  * Otherwise decrease timeout by time elapsed.
889                  */
890                 if (allow_non_xm) {
891                         recv_until = _now() + timeout;
892
893                         if (baudrate && !*baud_changed) {
894                                 rc = kwboot_baud_magic_handle(fd, *c, baudrate);
895                                 if (rc == 1)
896                                         *baud_changed = 1;
897                                 else if (!rc)
898                                         *non_xm_print = 1;
899                                 else
900                                         return rc;
901                         } else if (!baudrate || !*baud_changed) {
902                                 putchar(*c);
903                                 fflush(stdout);
904                                 *non_xm_print = 1;
905                         }
906                 } else {
907                         timeout = recv_until - _now();
908                         if (timeout < 0) {
909                                 errno = ETIMEDOUT;
910                                 return -1;
911                         }
912                 }
913         }
914
915         return 0;
916 }
917
918 static int
919 kwboot_xm_sendblock(int fd, struct kwboot_block *block, int allow_non_xm,
920                     int *done_print, int baudrate)
921 {
922         int non_xm_print, baud_changed;
923         int rc, err, retries;
924         char c;
925
926         *done_print = 0;
927
928         retries = 16;
929         do {
930                 rc = kwboot_tty_send(fd, block, sizeof(*block));
931                 if (rc)
932                         return rc;
933
934                 if (allow_non_xm && !*done_print) {
935                         kwboot_progress(100, '.');
936                         kwboot_printv("Done\n");
937                         *done_print = 1;
938                 }
939
940                 rc = kwboot_xm_recv_reply(fd, &c, allow_non_xm, &non_xm_print,
941                                           baudrate, &baud_changed);
942                 if (rc)
943                         goto can;
944
945                 if (!allow_non_xm && c != ACK)
946                         kwboot_progress(-1, '+');
947         } while (c == NAK && retries-- > 0);
948
949         if (non_xm_print)
950                 kwboot_printv("\n");
951
952         if (allow_non_xm && baudrate && !baud_changed) {
953                 fprintf(stderr, "Baudrate was not changed\n");
954                 rc = -1;
955                 errno = EPROTO;
956                 goto can;
957         }
958
959         return _xm_reply_to_error(c);
960 can:
961         err = errno;
962         kwboot_tty_send_char(fd, CAN);
963         kwboot_printv("\n");
964         errno = err;
965         return rc;
966 }
967
968 static int
969 kwboot_xm_finish(int fd)
970 {
971         int rc, retries;
972         char c;
973
974         kwboot_printv("Finishing transfer\n");
975
976         retries = 16;
977         do {
978                 rc = kwboot_tty_send_char(fd, EOT);
979                 if (rc)
980                         return rc;
981
982                 rc = kwboot_xm_recv_reply(fd, &c, 0, NULL, 0, NULL);
983                 if (rc)
984                         return rc;
985         } while (c == NAK && retries-- > 0);
986
987         return _xm_reply_to_error(c);
988 }
989
990 static int
991 kwboot_xmodem_one(int tty, int *pnum, int header, const uint8_t *data,
992                   size_t size, int baudrate)
993 {
994         int done_print = 0;
995         size_t sent, left;
996         int rc;
997
998         kwboot_printv("Sending boot image %s (%zu bytes)...\n",
999                       header ? "header" : "data", size);
1000
1001         left = size;
1002         sent = 0;
1003
1004         while (sent < size) {
1005                 struct kwboot_block block;
1006                 int last_block;
1007                 size_t blksz;
1008
1009                 blksz = kwboot_xm_makeblock(&block, data, left, (*pnum)++);
1010                 data += blksz;
1011
1012                 last_block = (left <= blksz);
1013
1014                 rc = kwboot_xm_sendblock(tty, &block, header && last_block,
1015                                          &done_print, baudrate);
1016                 if (rc)
1017                         goto out;
1018
1019                 sent += blksz;
1020                 left -= blksz;
1021
1022                 if (!done_print)
1023                         kwboot_progress(sent * 100 / size, '.');
1024         }
1025
1026         if (!done_print)
1027                 kwboot_printv("Done\n");
1028
1029         return 0;
1030 out:
1031         kwboot_printv("\n");
1032         return rc;
1033 }
1034
1035 static int
1036 kwboot_xmodem(int tty, const void *_img, size_t size, int baudrate)
1037 {
1038         const uint8_t *img = _img;
1039         int rc, pnum;
1040         size_t hdrsz;
1041
1042         hdrsz = kwbheader_size(img);
1043
1044         kwboot_printv("Waiting 2s and flushing tty\n");
1045         sleep(2); /* flush isn't effective without it */
1046         tcflush(tty, TCIOFLUSH);
1047
1048         pnum = 1;
1049
1050         rc = kwboot_xmodem_one(tty, &pnum, 1, img, hdrsz, baudrate);
1051         if (rc)
1052                 return rc;
1053
1054         img += hdrsz;
1055         size -= hdrsz;
1056
1057         rc = kwboot_xmodem_one(tty, &pnum, 0, img, size, 0);
1058         if (rc)
1059                 return rc;
1060
1061         rc = kwboot_xm_finish(tty);
1062         if (rc)
1063                 return rc;
1064
1065         if (baudrate) {
1066                 char buf[sizeof(kwb_baud_magic)];
1067
1068                 kwboot_printv("Waiting 1s for baudrate change magic\n");
1069                 rc = kwboot_tty_recv(tty, buf, sizeof(buf), 1000);
1070                 if (rc)
1071                         return rc;
1072
1073                 if (memcmp(buf, kwb_baud_magic, sizeof(buf))) {
1074                         errno = EPROTO;
1075                         return -1;
1076                 }
1077
1078                 kwboot_printv("\nChanging baudrate back to 115200 Bd\n\n");
1079                 rc = kwboot_tty_change_baudrate(tty, 115200);
1080                 if (rc)
1081                         return rc;
1082         }
1083
1084         return 0;
1085 }
1086
1087 static int
1088 kwboot_term_pipe(int in, int out, const char *quit, int *s)
1089 {
1090         ssize_t nin;
1091         char _buf[128], *buf = _buf;
1092
1093         nin = read(in, buf, sizeof(_buf));
1094         if (nin <= 0)
1095                 return -1;
1096
1097         if (quit) {
1098                 int i;
1099
1100                 for (i = 0; i < nin; i++) {
1101                         if (*buf == quit[*s]) {
1102                                 (*s)++;
1103                                 if (!quit[*s])
1104                                         return 0;
1105                                 buf++;
1106                                 nin--;
1107                         } else {
1108                                 if (kwboot_write(out, quit, *s) < 0)
1109                                         return -1;
1110                                 *s = 0;
1111                         }
1112                 }
1113         }
1114
1115         if (kwboot_write(out, buf, nin) < 0)
1116                 return -1;
1117
1118         return 0;
1119 }
1120
1121 static int
1122 kwboot_terminal(int tty)
1123 {
1124         int rc, in, s;
1125         const char *quit = "\34c";
1126         struct termios otio, tio;
1127
1128         rc = -1;
1129
1130         in = STDIN_FILENO;
1131         if (isatty(in)) {
1132                 rc = tcgetattr(in, &otio);
1133                 if (!rc) {
1134                         tio = otio;
1135                         cfmakeraw(&tio);
1136                         rc = tcsetattr(in, TCSANOW, &tio);
1137                 }
1138                 if (rc) {
1139                         perror("tcsetattr");
1140                         goto out;
1141                 }
1142
1143                 kwboot_printv("[Type Ctrl-%c + %c to quit]\r\n",
1144                               quit[0] | 0100, quit[1]);
1145         } else
1146                 in = -1;
1147
1148         rc = 0;
1149         s = 0;
1150
1151         do {
1152                 fd_set rfds;
1153                 int nfds = 0;
1154
1155                 FD_ZERO(&rfds);
1156                 FD_SET(tty, &rfds);
1157                 nfds = nfds < tty ? tty : nfds;
1158
1159                 if (in >= 0) {
1160                         FD_SET(in, &rfds);
1161                         nfds = nfds < in ? in : nfds;
1162                 }
1163
1164                 nfds = select(nfds + 1, &rfds, NULL, NULL, NULL);
1165                 if (nfds < 0)
1166                         break;
1167
1168                 if (FD_ISSET(tty, &rfds)) {
1169                         rc = kwboot_term_pipe(tty, STDOUT_FILENO, NULL, NULL);
1170                         if (rc)
1171                                 break;
1172                 }
1173
1174                 if (in >= 0 && FD_ISSET(in, &rfds)) {
1175                         rc = kwboot_term_pipe(in, tty, quit, &s);
1176                         if (rc)
1177                                 break;
1178                 }
1179         } while (quit[s] != 0);
1180
1181         if (in >= 0)
1182                 tcsetattr(in, TCSANOW, &otio);
1183         printf("\n");
1184 out:
1185         return rc;
1186 }
1187
1188 static void *
1189 kwboot_read_image(const char *path, size_t *size, size_t reserve)
1190 {
1191         int rc, fd;
1192         struct stat st;
1193         void *img;
1194         off_t tot;
1195
1196         rc = -1;
1197         img = NULL;
1198
1199         fd = open(path, O_RDONLY);
1200         if (fd < 0)
1201                 goto out;
1202
1203         rc = fstat(fd, &st);
1204         if (rc)
1205                 goto out;
1206
1207         img = malloc(st.st_size + reserve);
1208         if (!img)
1209                 goto out;
1210
1211         tot = 0;
1212         while (tot < st.st_size) {
1213                 ssize_t rd = read(fd, img + tot, st.st_size - tot);
1214
1215                 if (rd < 0)
1216                         goto out;
1217
1218                 tot += rd;
1219
1220                 if (!rd && tot < st.st_size) {
1221                         errno = EIO;
1222                         goto out;
1223                 }
1224         }
1225
1226         rc = 0;
1227         *size = st.st_size;
1228 out:
1229         if (rc && img) {
1230                 free(img);
1231                 img = NULL;
1232         }
1233         if (fd >= 0)
1234                 close(fd);
1235
1236         return img;
1237 }
1238
1239 static uint8_t
1240 kwboot_hdr_csum8(const void *hdr)
1241 {
1242         const uint8_t *data = hdr;
1243         uint8_t csum;
1244         size_t size;
1245
1246         size = kwbheader_size_for_csum(hdr);
1247
1248         for (csum = 0; size-- > 0; data++)
1249                 csum += *data;
1250
1251         return csum;
1252 }
1253
1254 static uint32_t *
1255 kwboot_img_csum32_ptr(void *img)
1256 {
1257         struct main_hdr_v1 *hdr = img;
1258         uint32_t datasz;
1259
1260         datasz = le32_to_cpu(hdr->blocksize) - sizeof(uint32_t);
1261
1262         return img + le32_to_cpu(hdr->srcaddr) + datasz;
1263 }
1264
1265 static uint32_t
1266 kwboot_img_csum32(const void *img)
1267 {
1268         const struct main_hdr_v1 *hdr = img;
1269         uint32_t datasz, csum = 0;
1270         const uint32_t *data;
1271
1272         datasz = le32_to_cpu(hdr->blocksize) - sizeof(csum);
1273         if (datasz % sizeof(uint32_t))
1274                 return 0;
1275
1276         data = img + le32_to_cpu(hdr->srcaddr);
1277         while (datasz > 0) {
1278                 csum += le32_to_cpu(*data++);
1279                 datasz -= 4;
1280         }
1281
1282         return cpu_to_le32(csum);
1283 }
1284
1285 static int
1286 kwboot_img_is_secure(void *img)
1287 {
1288         struct opt_hdr_v1 *ohdr;
1289
1290         for_each_opt_hdr_v1 (ohdr, img)
1291                 if (ohdr->headertype == OPT_HDR_V1_SECURE_TYPE)
1292                         return 1;
1293
1294         return 0;
1295 }
1296
1297 static void *
1298 kwboot_img_grow_data_right(void *img, size_t *size, size_t grow)
1299 {
1300         struct main_hdr_v1 *hdr = img;
1301         void *result;
1302
1303         /*
1304          * 32-bit checksum comes after end of image code, so we will be putting
1305          * new code there. So we get this pointer and then increase data size
1306          * (since increasing data size changes kwboot_img_csum32_ptr() return
1307          *  value).
1308          */
1309         result = kwboot_img_csum32_ptr(img);
1310         hdr->blocksize = cpu_to_le32(le32_to_cpu(hdr->blocksize) + grow);
1311         *size += grow;
1312
1313         return result;
1314 }
1315
1316 static void
1317 kwboot_img_grow_hdr(void *img, size_t *size, size_t grow)
1318 {
1319         uint32_t hdrsz, datasz, srcaddr;
1320         struct main_hdr_v1 *hdr = img;
1321         struct opt_hdr_v1 *ohdr;
1322         uint8_t *data;
1323
1324         srcaddr = le32_to_cpu(hdr->srcaddr);
1325
1326         /* calculate real used space in kwbimage header */
1327         if (kwbimage_version(img) == 0) {
1328                 hdrsz = kwbheader_size(img);
1329         } else {
1330                 hdrsz = sizeof(*hdr);
1331                 for_each_opt_hdr_v1 (ohdr, hdr)
1332                         hdrsz += opt_hdr_v1_size(ohdr);
1333         }
1334
1335         data = (uint8_t *)img + srcaddr;
1336         datasz = *size - srcaddr;
1337
1338         /* only move data if there is not enough space */
1339         if (hdrsz + grow > srcaddr) {
1340                 size_t need = hdrsz + grow - srcaddr;
1341
1342                 /* move data by enough bytes */
1343                 memmove(data + need, data, datasz);
1344
1345                 hdr->srcaddr = cpu_to_le32(srcaddr + need);
1346                 *size += need;
1347         }
1348
1349         if (kwbimage_version(img) == 1) {
1350                 hdrsz += grow;
1351                 if (hdrsz > kwbheader_size(img)) {
1352                         hdr->headersz_msb = hdrsz >> 16;
1353                         hdr->headersz_lsb = cpu_to_le16(hdrsz & 0xffff);
1354                 }
1355         }
1356 }
1357
1358 static void *
1359 kwboot_add_bin_ohdr_v1(void *img, size_t *size, uint32_t binsz)
1360 {
1361         struct main_hdr_v1 *hdr = img;
1362         struct opt_hdr_v1 *ohdr;
1363         uint32_t num_args;
1364         uint32_t offset;
1365         uint32_t ohdrsz;
1366         uint8_t *prev_ext;
1367
1368         if (hdr->ext & 0x1) {
1369                 for_each_opt_hdr_v1 (ohdr, img)
1370                         if (opt_hdr_v1_next(ohdr) == NULL)
1371                                 break;
1372
1373                 prev_ext = opt_hdr_v1_ext(ohdr);
1374                 ohdr = _opt_hdr_v1_next(ohdr);
1375         } else {
1376                 ohdr = (void *)(hdr + 1);
1377                 prev_ext = &hdr->ext;
1378         }
1379
1380         /*
1381          * ARM executable code inside the BIN header on some mvebu platforms
1382          * (e.g. A370, AXP) must always be aligned with the 128-bit boundary.
1383          * This requirement can be met by inserting dummy arguments into
1384          * BIN header, if needed.
1385          */
1386         offset = &ohdr->data[4] - (char *)img;
1387         num_args = ((16 - offset % 16) % 16) / sizeof(uint32_t);
1388
1389         ohdrsz = sizeof(*ohdr) + 4 + 4 * num_args + binsz + 4;
1390         kwboot_img_grow_hdr(hdr, size, ohdrsz);
1391
1392         *prev_ext |= 1;
1393
1394         ohdr->headertype = OPT_HDR_V1_BINARY_TYPE;
1395         ohdr->headersz_msb = ohdrsz >> 16;
1396         ohdr->headersz_lsb = cpu_to_le16(ohdrsz & 0xffff);
1397
1398         memset(&ohdr->data[0], 0, ohdrsz - sizeof(*ohdr));
1399         *(uint32_t *)&ohdr->data[0] = cpu_to_le32(num_args);
1400
1401         return &ohdr->data[4 + 4 * num_args];
1402 }
1403
1404 static void
1405 _inject_baudrate_change_code(void *img, size_t *size, int pre,
1406                              int old_baud, int new_baud)
1407 {
1408         uint32_t codesz = sizeof(kwboot_baud_code);
1409         struct main_hdr_v1 *hdr = img;
1410         uint8_t *code;
1411
1412         if (pre) {
1413                 uint32_t presz = sizeof(kwboot_pre_baud_code);
1414                 uint32_t orig_datasz;
1415
1416                 orig_datasz = le32_to_cpu(hdr->blocksize) - sizeof(uint32_t);
1417
1418                 code = kwboot_img_grow_data_right(img, size, presz + codesz);
1419
1420                 /*
1421                  * We need to prepend code that loads lr register with original
1422                  * value of hdr->execaddr. We do this by putting the original
1423                  * exec address before the code that loads it relatively from
1424                  * it's beginning.
1425                  * Afterwards we change the exec address to this code (which is
1426                  * at offset 4, because the first 4 bytes contain the original
1427                  * exec address).
1428                  */
1429                 memcpy(code, kwboot_pre_baud_code, presz);
1430                 *(uint32_t *)code = hdr->execaddr;
1431
1432                 hdr->execaddr = cpu_to_le32(le32_to_cpu(hdr->destaddr) +
1433                                             orig_datasz + 4);
1434
1435                 code += presz;
1436         } else {
1437                 code = kwboot_add_bin_ohdr_v1(img, size, codesz);
1438         }
1439
1440         memcpy(code, kwboot_baud_code, codesz - 8);
1441         *(uint32_t *)(code + codesz - 8) = cpu_to_le32(old_baud);
1442         *(uint32_t *)(code + codesz - 4) = cpu_to_le32(new_baud);
1443 }
1444
1445 static int
1446 kwboot_img_patch(void *img, size_t *size, int baudrate)
1447 {
1448         struct main_hdr_v1 *hdr;
1449         uint32_t srcaddr;
1450         uint8_t csum;
1451         size_t hdrsz;
1452         int image_ver;
1453         int is_secure;
1454
1455         hdr = img;
1456
1457         if (*size < sizeof(struct main_hdr_v1))
1458                 goto err;
1459
1460         image_ver = kwbimage_version(img);
1461         if (image_ver != 0 && image_ver != 1) {
1462                 fprintf(stderr, "Invalid image header version\n");
1463                 goto err;
1464         }
1465
1466         hdrsz = kwbheader_size(hdr);
1467
1468         if (*size < hdrsz)
1469                 goto err;
1470
1471         csum = kwboot_hdr_csum8(hdr) - hdr->checksum;
1472         if (csum != hdr->checksum)
1473                 goto err;
1474
1475         srcaddr = le32_to_cpu(hdr->srcaddr);
1476
1477         switch (hdr->blockid) {
1478         case IBR_HDR_SATA_ID:
1479                 if (srcaddr < 1)
1480                         goto err;
1481
1482                 hdr->srcaddr = cpu_to_le32((srcaddr - 1) * 512);
1483                 break;
1484
1485         case IBR_HDR_SDIO_ID:
1486                 hdr->srcaddr = cpu_to_le32(srcaddr * 512);
1487                 break;
1488
1489         case IBR_HDR_PEX_ID:
1490                 if (srcaddr == 0xFFFFFFFF)
1491                         hdr->srcaddr = cpu_to_le32(hdrsz);
1492                 break;
1493
1494         case IBR_HDR_SPI_ID:
1495                 if (hdr->destaddr == cpu_to_le32(0xFFFFFFFF)) {
1496                         kwboot_printv("Patching destination and execution addresses from SPI/NOR XIP area to DDR area 0x00800000\n");
1497                         hdr->destaddr = cpu_to_le32(0x00800000);
1498                         hdr->execaddr = cpu_to_le32(0x00800000);
1499                 }
1500                 break;
1501         }
1502
1503         if (hdrsz > le32_to_cpu(hdr->srcaddr) ||
1504             *size < le32_to_cpu(hdr->srcaddr) + le32_to_cpu(hdr->blocksize))
1505                 goto err;
1506
1507         if (kwboot_img_csum32(img) != *kwboot_img_csum32_ptr(img))
1508                 goto err;
1509
1510         is_secure = kwboot_img_is_secure(img);
1511
1512         if (hdr->blockid != IBR_HDR_UART_ID) {
1513                 if (is_secure) {
1514                         fprintf(stderr,
1515                                 "Image has secure header with signature for non-UART booting\n");
1516                         goto err;
1517                 }
1518
1519                 kwboot_printv("Patching image boot signature to UART\n");
1520                 hdr->blockid = IBR_HDR_UART_ID;
1521         }
1522
1523         if (!is_secure) {
1524                 if (image_ver == 1) {
1525                         /*
1526                          * Tell BootROM to send BootROM messages to UART port
1527                          * number 0 (used also for UART booting) with default
1528                          * baudrate (which should be 115200) and do not touch
1529                          * UART MPP configuration.
1530                          */
1531                         hdr->options &= ~0x1F;
1532                         hdr->options |= MAIN_HDR_V1_OPT_BAUD_DEFAULT;
1533                         hdr->options |= 0 << 3;
1534                 }
1535                 if (image_ver == 0)
1536                         ((struct main_hdr_v0 *)img)->nandeccmode = IBR_HDR_ECC_DISABLED;
1537                 hdr->nandpagesize = 0;
1538         }
1539
1540         if (baudrate) {
1541                 if (image_ver == 0) {
1542                         fprintf(stderr,
1543                                 "Cannot inject code for changing baudrate into v0 image header\n");
1544                         goto err;
1545                 }
1546
1547                 if (is_secure) {
1548                         fprintf(stderr,
1549                                 "Cannot inject code for changing baudrate into image with secure header\n");
1550                         goto err;
1551                 }
1552
1553                 /*
1554                  * First inject code that changes the baudrate from the default
1555                  * value of 115200 Bd to requested value. This code is inserted
1556                  * as a new opt hdr, so it is executed by BootROM after the
1557                  * header part is received.
1558                  */
1559                 kwboot_printv("Injecting binary header code for changing baudrate to %d Bd\n",
1560                               baudrate);
1561                 _inject_baudrate_change_code(img, size, 0, 115200, baudrate);
1562
1563                 /*
1564                  * Now inject code that changes the baudrate back to 115200 Bd.
1565                  * This code is appended after the data part of the image, and
1566                  * execaddr is changed so that it is executed before U-Boot
1567                  * proper.
1568                  */
1569                 kwboot_printv("Injecting code for changing baudrate back\n");
1570                 _inject_baudrate_change_code(img, size, 1, baudrate, 115200);
1571
1572                 /* Update the 32-bit data checksum */
1573                 *kwboot_img_csum32_ptr(img) = kwboot_img_csum32(img);
1574
1575                 /* recompute header size */
1576                 hdrsz = kwbheader_size(hdr);
1577         }
1578
1579         if (hdrsz % KWBOOT_XM_BLKSZ) {
1580                 size_t grow = KWBOOT_XM_BLKSZ - hdrsz % KWBOOT_XM_BLKSZ;
1581
1582                 if (is_secure) {
1583                         fprintf(stderr, "Cannot align image with secure header\n");
1584                         goto err;
1585                 }
1586
1587                 kwboot_printv("Aligning image header to Xmodem block size\n");
1588                 kwboot_img_grow_hdr(img, size, grow);
1589         }
1590
1591         hdr->checksum = kwboot_hdr_csum8(hdr) - csum;
1592
1593         *size = le32_to_cpu(hdr->srcaddr) + le32_to_cpu(hdr->blocksize);
1594         return 0;
1595 err:
1596         errno = EINVAL;
1597         return -1;
1598 }
1599
1600 static void
1601 kwboot_usage(FILE *stream, char *progname)
1602 {
1603         fprintf(stream, "kwboot version %s\n", PLAIN_VERSION);
1604         fprintf(stream,
1605                 "Usage: %s [OPTIONS] [-b <image> | -D <image> ] [-B <baud> ] <TTY>\n",
1606                 progname);
1607         fprintf(stream, "\n");
1608         fprintf(stream,
1609                 "  -b <image>: boot <image> with preamble (Kirkwood, Armada 370/XP)\n");
1610         fprintf(stream,
1611                 "  -D <image>: boot <image> without preamble (Dove)\n");
1612         fprintf(stream, "  -d: enter debug mode\n");
1613         fprintf(stream, "  -a: use timings for Armada XP\n");
1614         fprintf(stream, "  -q <req-delay>:  use specific request-delay\n");
1615         fprintf(stream, "  -s <resp-timeo>: use specific response-timeout\n");
1616         fprintf(stream,
1617                 "  -o <block-timeo>: use specific xmodem block timeout\n");
1618         fprintf(stream, "\n");
1619         fprintf(stream, "  -t: mini terminal\n");
1620         fprintf(stream, "\n");
1621         fprintf(stream, "  -B <baud>: set baud rate\n");
1622         fprintf(stream, "\n");
1623 }
1624
1625 int
1626 main(int argc, char **argv)
1627 {
1628         const char *ttypath, *imgpath;
1629         int rv, rc, tty, term;
1630         void *bootmsg;
1631         void *debugmsg;
1632         void *img;
1633         size_t size;
1634         size_t after_img_rsv;
1635         int baudrate;
1636
1637         rv = 1;
1638         tty = -1;
1639         bootmsg = NULL;
1640         debugmsg = NULL;
1641         imgpath = NULL;
1642         img = NULL;
1643         term = 0;
1644         size = 0;
1645         after_img_rsv = KWBOOT_XM_BLKSZ;
1646         baudrate = 115200;
1647
1648         kwboot_verbose = isatty(STDOUT_FILENO);
1649
1650         do {
1651                 int c = getopt(argc, argv, "hb:ptaB:dD:q:s:o:");
1652                 if (c < 0)
1653                         break;
1654
1655                 switch (c) {
1656                 case 'b':
1657                         bootmsg = kwboot_msg_boot;
1658                         imgpath = optarg;
1659                         break;
1660
1661                 case 'D':
1662                         bootmsg = NULL;
1663                         imgpath = optarg;
1664                         break;
1665
1666                 case 'd':
1667                         debugmsg = kwboot_msg_debug;
1668                         break;
1669
1670                 case 'p':
1671                         /* nop, for backward compatibility */
1672                         break;
1673
1674                 case 't':
1675                         term = 1;
1676                         break;
1677
1678                 case 'a':
1679                         msg_req_delay = KWBOOT_MSG_REQ_DELAY_AXP;
1680                         msg_rsp_timeo = KWBOOT_MSG_RSP_TIMEO_AXP;
1681                         break;
1682
1683                 case 'q':
1684                         msg_req_delay = atoi(optarg);
1685                         break;
1686
1687                 case 's':
1688                         msg_rsp_timeo = atoi(optarg);
1689                         break;
1690
1691                 case 'o':
1692                         blk_rsp_timeo = atoi(optarg);
1693                         break;
1694
1695                 case 'B':
1696                         baudrate = atoi(optarg);
1697                         break;
1698
1699                 case 'h':
1700                         rv = 0;
1701                 default:
1702                         goto usage;
1703                 }
1704         } while (1);
1705
1706         if (!bootmsg && !term && !debugmsg)
1707                 goto usage;
1708
1709         if (argc - optind < 1)
1710                 goto usage;
1711
1712         ttypath = argv[optind++];
1713
1714         tty = kwboot_open_tty(ttypath, imgpath ? 115200 : baudrate);
1715         if (tty < 0) {
1716                 perror(ttypath);
1717                 goto out;
1718         }
1719
1720         if (baudrate == 115200)
1721                 /* do not change baudrate during Xmodem to the same value */
1722                 baudrate = 0;
1723         else
1724                 /* ensure we have enough space for baudrate change code */
1725                 after_img_rsv += KWBOOT_BAUDRATE_BIN_HEADER_SZ +
1726                                  KWBOOT_XM_BLKSZ +
1727                                  sizeof(kwboot_pre_baud_code) +
1728                                  sizeof(kwboot_baud_code) +
1729                                  KWBOOT_XM_BLKSZ;
1730
1731         if (imgpath) {
1732                 img = kwboot_read_image(imgpath, &size, after_img_rsv);
1733                 if (!img) {
1734                         perror(imgpath);
1735                         goto out;
1736                 }
1737
1738                 rc = kwboot_img_patch(img, &size, baudrate);
1739                 if (rc) {
1740                         fprintf(stderr, "%s: Invalid image.\n", imgpath);
1741                         goto out;
1742                 }
1743         }
1744
1745         if (debugmsg) {
1746                 rc = kwboot_debugmsg(tty, debugmsg);
1747                 if (rc) {
1748                         perror("debugmsg");
1749                         goto out;
1750                 }
1751         } else if (bootmsg) {
1752                 rc = kwboot_bootmsg(tty, bootmsg);
1753                 if (rc) {
1754                         perror("bootmsg");
1755                         goto out;
1756                 }
1757         }
1758
1759         if (img) {
1760                 rc = kwboot_xmodem(tty, img, size, baudrate);
1761                 if (rc) {
1762                         perror("xmodem");
1763                         goto out;
1764                 }
1765         }
1766
1767         if (term) {
1768                 rc = kwboot_terminal(tty);
1769                 if (rc && !(errno == EINTR)) {
1770                         perror("terminal");
1771                         goto out;
1772                 }
1773         }
1774
1775         rv = 0;
1776 out:
1777         if (tty >= 0)
1778                 close(tty);
1779
1780         if (img)
1781                 free(img);
1782
1783         return rv;
1784
1785 usage:
1786         kwboot_usage(rv ? stderr : stdout, basename(argv[0]));
1787         goto out;
1788 }