ARM: amlogic: add sm efuse write support and cmd for read/write efuse
[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_cc[VMIN] = 1;
661         tio.c_cc[VTIME] = 0;
662
663         rc = tcsetattr(fd, TCSANOW, &tio);
664         if (rc)
665                 goto out;
666
667         flags = fcntl(fd, F_GETFL);
668         if (flags < 0)
669                 goto out;
670
671         rc = fcntl(fd, F_SETFL, flags & ~O_NDELAY);
672         if (rc)
673                 goto out;
674
675         rc = kwboot_tty_change_baudrate(fd, baudrate);
676         if (rc)
677                 goto out;
678
679         rc = fd;
680 out:
681         if (rc < 0) {
682                 if (fd >= 0)
683                         close(fd);
684         }
685
686         return rc;
687 }
688
689 static int
690 kwboot_bootmsg(int tty, void *msg)
691 {
692         int rc;
693         char c;
694         int count;
695
696         if (msg == NULL)
697                 kwboot_printv("Please reboot the target into UART boot mode...");
698         else
699                 kwboot_printv("Sending boot message. Please reboot the target...");
700
701         do {
702                 rc = tcflush(tty, TCIOFLUSH);
703                 if (rc)
704                         break;
705
706                 for (count = 0; count < 128; count++) {
707                         rc = kwboot_tty_send(tty, msg, 8);
708                         if (rc) {
709                                 usleep(msg_req_delay * 1000);
710                                 continue;
711                         }
712                 }
713
714                 rc = kwboot_tty_recv(tty, &c, 1, msg_rsp_timeo);
715
716                 kwboot_spinner();
717
718         } while (rc || c != NAK);
719
720         kwboot_printv("\n");
721
722         return rc;
723 }
724
725 static int
726 kwboot_debugmsg(int tty, void *msg)
727 {
728         int rc;
729
730         kwboot_printv("Sending debug message. Please reboot the target...");
731
732         do {
733                 char buf[16];
734
735                 rc = tcflush(tty, TCIOFLUSH);
736                 if (rc)
737                         break;
738
739                 rc = kwboot_tty_send(tty, msg, 8);
740                 if (rc) {
741                         usleep(msg_req_delay * 1000);
742                         continue;
743                 }
744
745                 rc = kwboot_tty_recv(tty, buf, 16, msg_rsp_timeo);
746
747                 kwboot_spinner();
748
749         } while (rc);
750
751         kwboot_printv("\n");
752
753         return rc;
754 }
755
756 static size_t
757 kwboot_xm_makeblock(struct kwboot_block *block, const void *data,
758                     size_t size, int pnum)
759 {
760         size_t i, n;
761
762         block->soh = SOH;
763         block->pnum = pnum;
764         block->_pnum = ~block->pnum;
765
766         n = size < KWBOOT_XM_BLKSZ ? size : KWBOOT_XM_BLKSZ;
767         memcpy(&block->data[0], data, n);
768         memset(&block->data[n], 0, KWBOOT_XM_BLKSZ - n);
769
770         block->csum = 0;
771         for (i = 0; i < n; i++)
772                 block->csum += block->data[i];
773
774         return n;
775 }
776
777 static uint64_t
778 _now(void)
779 {
780         struct timespec ts;
781
782         if (clock_gettime(CLOCK_MONOTONIC, &ts)) {
783                 static int err_print;
784
785                 if (!err_print) {
786                         perror("clock_gettime() does not work");
787                         err_print = 1;
788                 }
789
790                 /* this will just make the timeout not work */
791                 return -1ULL;
792         }
793
794         return ts.tv_sec * 1000ULL + (ts.tv_nsec + 500000) / 1000000;
795 }
796
797 static int
798 _is_xm_reply(char c)
799 {
800         return c == ACK || c == NAK || c == CAN;
801 }
802
803 static int
804 _xm_reply_to_error(int c)
805 {
806         int rc = -1;
807
808         switch (c) {
809         case ACK:
810                 rc = 0;
811                 break;
812         case NAK:
813                 errno = EBADMSG;
814                 break;
815         case CAN:
816                 errno = ECANCELED;
817                 break;
818         default:
819                 errno = EPROTO;
820                 break;
821         }
822
823         return rc;
824 }
825
826 static int
827 kwboot_baud_magic_handle(int fd, char c, int baudrate)
828 {
829         static size_t rcv_len;
830
831         if (rcv_len < sizeof(kwb_baud_magic)) {
832                 /* try to recognize whole magic word */
833                 if (c == kwb_baud_magic[rcv_len]) {
834                         rcv_len++;
835                 } else {
836                         printf("%.*s%c", (int)rcv_len, kwb_baud_magic, c);
837                         fflush(stdout);
838                         rcv_len = 0;
839                 }
840         }
841
842         if (rcv_len == sizeof(kwb_baud_magic)) {
843                 /* magic word received */
844                 kwboot_printv("\nChanging baudrate to %d Bd\n", baudrate);
845
846                 return kwboot_tty_change_baudrate(fd, baudrate) ? : 1;
847         } else {
848                 return 0;
849         }
850 }
851
852 static int
853 kwboot_xm_recv_reply(int fd, char *c, int allow_non_xm, int *non_xm_print,
854                      int baudrate, int *baud_changed)
855 {
856         int timeout = allow_non_xm ? KWBOOT_HDR_RSP_TIMEO : blk_rsp_timeo;
857         uint64_t recv_until = _now() + timeout;
858         int rc;
859
860         if (non_xm_print)
861                 *non_xm_print = 0;
862         if (baud_changed)
863                 *baud_changed = 0;
864
865         while (1) {
866                 rc = kwboot_tty_recv(fd, c, 1, timeout);
867                 if (rc) {
868                         if (errno != ETIMEDOUT)
869                                 return rc;
870                         else if (allow_non_xm && *non_xm_print)
871                                 return -1;
872                         else
873                                 *c = NAK;
874                 }
875
876                 /* If received xmodem reply, end. */
877                 if (_is_xm_reply(*c))
878                         break;
879
880                 /*
881                  * If receiving/printing non-xmodem text output is allowed and
882                  * such a byte was received, we want to increase receiving time
883                  * and either:
884                  * - print the byte, if it is not part of baudrate change magic
885                  *   sequence while baudrate change was requested (-B option)
886                  * - change baudrate
887                  * Otherwise decrease timeout by time elapsed.
888                  */
889                 if (allow_non_xm) {
890                         recv_until = _now() + timeout;
891
892                         if (baudrate && !*baud_changed) {
893                                 rc = kwboot_baud_magic_handle(fd, *c, baudrate);
894                                 if (rc == 1)
895                                         *baud_changed = 1;
896                                 else if (!rc)
897                                         *non_xm_print = 1;
898                                 else
899                                         return rc;
900                         } else if (!baudrate || !*baud_changed) {
901                                 putchar(*c);
902                                 fflush(stdout);
903                                 *non_xm_print = 1;
904                         }
905                 } else {
906                         timeout = recv_until - _now();
907                         if (timeout < 0) {
908                                 errno = ETIMEDOUT;
909                                 return -1;
910                         }
911                 }
912         }
913
914         return 0;
915 }
916
917 static int
918 kwboot_xm_sendblock(int fd, struct kwboot_block *block, int allow_non_xm,
919                     int *done_print, int baudrate)
920 {
921         int non_xm_print, baud_changed;
922         int rc, err, retries;
923         char c;
924
925         *done_print = 0;
926
927         retries = 16;
928         do {
929                 rc = kwboot_tty_send(fd, block, sizeof(*block));
930                 if (rc)
931                         return rc;
932
933                 if (allow_non_xm && !*done_print) {
934                         kwboot_progress(100, '.');
935                         kwboot_printv("Done\n");
936                         *done_print = 1;
937                 }
938
939                 rc = kwboot_xm_recv_reply(fd, &c, allow_non_xm, &non_xm_print,
940                                           baudrate, &baud_changed);
941                 if (rc)
942                         goto can;
943
944                 if (!allow_non_xm && c != ACK)
945                         kwboot_progress(-1, '+');
946         } while (c == NAK && retries-- > 0);
947
948         if (non_xm_print)
949                 kwboot_printv("\n");
950
951         if (allow_non_xm && baudrate && !baud_changed) {
952                 fprintf(stderr, "Baudrate was not changed\n");
953                 rc = -1;
954                 errno = EPROTO;
955                 goto can;
956         }
957
958         return _xm_reply_to_error(c);
959 can:
960         err = errno;
961         kwboot_tty_send_char(fd, CAN);
962         kwboot_printv("\n");
963         errno = err;
964         return rc;
965 }
966
967 static int
968 kwboot_xm_finish(int fd)
969 {
970         int rc, retries;
971         char c;
972
973         kwboot_printv("Finishing transfer\n");
974
975         retries = 16;
976         do {
977                 rc = kwboot_tty_send_char(fd, EOT);
978                 if (rc)
979                         return rc;
980
981                 rc = kwboot_xm_recv_reply(fd, &c, 0, NULL, 0, NULL);
982                 if (rc)
983                         return rc;
984         } while (c == NAK && retries-- > 0);
985
986         return _xm_reply_to_error(c);
987 }
988
989 static int
990 kwboot_xmodem_one(int tty, int *pnum, int header, const uint8_t *data,
991                   size_t size, int baudrate)
992 {
993         int done_print = 0;
994         size_t sent, left;
995         int rc;
996
997         kwboot_printv("Sending boot image %s (%zu bytes)...\n",
998                       header ? "header" : "data", size);
999
1000         left = size;
1001         sent = 0;
1002
1003         while (sent < size) {
1004                 struct kwboot_block block;
1005                 int last_block;
1006                 size_t blksz;
1007
1008                 blksz = kwboot_xm_makeblock(&block, data, left, (*pnum)++);
1009                 data += blksz;
1010
1011                 last_block = (left <= blksz);
1012
1013                 rc = kwboot_xm_sendblock(tty, &block, header && last_block,
1014                                          &done_print, baudrate);
1015                 if (rc)
1016                         goto out;
1017
1018                 sent += blksz;
1019                 left -= blksz;
1020
1021                 if (!done_print)
1022                         kwboot_progress(sent * 100 / size, '.');
1023         }
1024
1025         if (!done_print)
1026                 kwboot_printv("Done\n");
1027
1028         return 0;
1029 out:
1030         kwboot_printv("\n");
1031         return rc;
1032 }
1033
1034 static int
1035 kwboot_xmodem(int tty, const void *_img, size_t size, int baudrate)
1036 {
1037         const uint8_t *img = _img;
1038         int rc, pnum;
1039         size_t hdrsz;
1040
1041         hdrsz = kwbheader_size(img);
1042
1043         kwboot_printv("Waiting 2s and flushing tty\n");
1044         sleep(2); /* flush isn't effective without it */
1045         tcflush(tty, TCIOFLUSH);
1046
1047         pnum = 1;
1048
1049         rc = kwboot_xmodem_one(tty, &pnum, 1, img, hdrsz, baudrate);
1050         if (rc)
1051                 return rc;
1052
1053         img += hdrsz;
1054         size -= hdrsz;
1055
1056         rc = kwboot_xmodem_one(tty, &pnum, 0, img, size, 0);
1057         if (rc)
1058                 return rc;
1059
1060         rc = kwboot_xm_finish(tty);
1061         if (rc)
1062                 return rc;
1063
1064         if (baudrate) {
1065                 char buf[sizeof(kwb_baud_magic)];
1066
1067                 /* Wait 1s for baudrate change magic */
1068                 rc = kwboot_tty_recv(tty, buf, sizeof(buf), 1000);
1069                 if (rc)
1070                         return rc;
1071
1072                 if (memcmp(buf, kwb_baud_magic, sizeof(buf))) {
1073                         errno = EPROTO;
1074                         return -1;
1075                 }
1076
1077                 kwboot_printv("\nChanging baudrate back to 115200 Bd\n\n");
1078                 rc = kwboot_tty_change_baudrate(tty, 115200);
1079                 if (rc)
1080                         return rc;
1081         }
1082
1083         return 0;
1084 }
1085
1086 static int
1087 kwboot_term_pipe(int in, int out, const char *quit, int *s)
1088 {
1089         ssize_t nin;
1090         char _buf[128], *buf = _buf;
1091
1092         nin = read(in, buf, sizeof(_buf));
1093         if (nin <= 0)
1094                 return -1;
1095
1096         if (quit) {
1097                 int i;
1098
1099                 for (i = 0; i < nin; i++) {
1100                         if (*buf == quit[*s]) {
1101                                 (*s)++;
1102                                 if (!quit[*s])
1103                                         return 0;
1104                                 buf++;
1105                                 nin--;
1106                         } else {
1107                                 if (kwboot_write(out, quit, *s) < 0)
1108                                         return -1;
1109                                 *s = 0;
1110                         }
1111                 }
1112         }
1113
1114         if (kwboot_write(out, buf, nin) < 0)
1115                 return -1;
1116
1117         return 0;
1118 }
1119
1120 static int
1121 kwboot_terminal(int tty)
1122 {
1123         int rc, in, s;
1124         const char *quit = "\34c";
1125         struct termios otio, tio;
1126
1127         rc = -1;
1128
1129         in = STDIN_FILENO;
1130         if (isatty(in)) {
1131                 rc = tcgetattr(in, &otio);
1132                 if (!rc) {
1133                         tio = otio;
1134                         cfmakeraw(&tio);
1135                         rc = tcsetattr(in, TCSANOW, &tio);
1136                 }
1137                 if (rc) {
1138                         perror("tcsetattr");
1139                         goto out;
1140                 }
1141
1142                 kwboot_printv("[Type Ctrl-%c + %c to quit]\r\n",
1143                               quit[0] | 0100, quit[1]);
1144         } else
1145                 in = -1;
1146
1147         rc = 0;
1148         s = 0;
1149
1150         do {
1151                 fd_set rfds;
1152                 int nfds = 0;
1153
1154                 FD_SET(tty, &rfds);
1155                 nfds = nfds < tty ? tty : nfds;
1156
1157                 if (in >= 0) {
1158                         FD_SET(in, &rfds);
1159                         nfds = nfds < in ? in : nfds;
1160                 }
1161
1162                 nfds = select(nfds + 1, &rfds, NULL, NULL, NULL);
1163                 if (nfds < 0)
1164                         break;
1165
1166                 if (FD_ISSET(tty, &rfds)) {
1167                         rc = kwboot_term_pipe(tty, STDOUT_FILENO, NULL, NULL);
1168                         if (rc)
1169                                 break;
1170                 }
1171
1172                 if (in >= 0 && FD_ISSET(in, &rfds)) {
1173                         rc = kwboot_term_pipe(in, tty, quit, &s);
1174                         if (rc)
1175                                 break;
1176                 }
1177         } while (quit[s] != 0);
1178
1179         if (in >= 0)
1180                 tcsetattr(in, TCSANOW, &otio);
1181         printf("\n");
1182 out:
1183         return rc;
1184 }
1185
1186 static void *
1187 kwboot_read_image(const char *path, size_t *size, size_t reserve)
1188 {
1189         int rc, fd;
1190         struct stat st;
1191         void *img;
1192         off_t tot;
1193
1194         rc = -1;
1195         img = NULL;
1196
1197         fd = open(path, O_RDONLY);
1198         if (fd < 0)
1199                 goto out;
1200
1201         rc = fstat(fd, &st);
1202         if (rc)
1203                 goto out;
1204
1205         img = malloc(st.st_size + reserve);
1206         if (!img)
1207                 goto out;
1208
1209         tot = 0;
1210         while (tot < st.st_size) {
1211                 ssize_t rd = read(fd, img + tot, st.st_size - tot);
1212
1213                 if (rd < 0)
1214                         goto out;
1215
1216                 tot += rd;
1217
1218                 if (!rd && tot < st.st_size) {
1219                         errno = EIO;
1220                         goto out;
1221                 }
1222         }
1223
1224         rc = 0;
1225         *size = st.st_size;
1226 out:
1227         if (rc && img) {
1228                 free(img);
1229                 img = NULL;
1230         }
1231         if (fd >= 0)
1232                 close(fd);
1233
1234         return img;
1235 }
1236
1237 static uint8_t
1238 kwboot_hdr_csum8(const void *hdr)
1239 {
1240         const uint8_t *data = hdr;
1241         uint8_t csum;
1242         size_t size;
1243
1244         size = kwbheader_size_for_csum(hdr);
1245
1246         for (csum = 0; size-- > 0; data++)
1247                 csum += *data;
1248
1249         return csum;
1250 }
1251
1252 static int
1253 kwboot_img_is_secure(void *img)
1254 {
1255         struct opt_hdr_v1 *ohdr;
1256
1257         for_each_opt_hdr_v1 (ohdr, img)
1258                 if (ohdr->headertype == OPT_HDR_V1_SECURE_TYPE)
1259                         return 1;
1260
1261         return 0;
1262 }
1263
1264 static void *
1265 kwboot_img_grow_data_left(void *img, size_t *size, size_t grow)
1266 {
1267         uint32_t hdrsz, datasz, srcaddr;
1268         struct main_hdr_v1 *hdr = img;
1269         uint8_t *data;
1270
1271         srcaddr = le32_to_cpu(hdr->srcaddr);
1272
1273         hdrsz = kwbheader_size(hdr);
1274         data = (uint8_t *)img + srcaddr;
1275         datasz = *size - srcaddr;
1276
1277         /* only move data if there is not enough space */
1278         if (hdrsz + grow > srcaddr) {
1279                 size_t need = hdrsz + grow - srcaddr;
1280
1281                 /* move data by enough bytes */
1282                 memmove(data + need, data, datasz);
1283                 *size += need;
1284                 srcaddr += need;
1285         }
1286
1287         srcaddr -= grow;
1288         hdr->srcaddr = cpu_to_le32(srcaddr);
1289         hdr->destaddr = cpu_to_le32(le32_to_cpu(hdr->destaddr) - grow);
1290         hdr->blocksize = cpu_to_le32(le32_to_cpu(hdr->blocksize) + grow);
1291
1292         return (uint8_t *)img + srcaddr;
1293 }
1294
1295 static void
1296 kwboot_img_grow_hdr(void *img, size_t *size, size_t grow)
1297 {
1298         uint32_t hdrsz, datasz, srcaddr;
1299         struct main_hdr_v1 *hdr = img;
1300         uint8_t *data;
1301
1302         srcaddr = le32_to_cpu(hdr->srcaddr);
1303
1304         hdrsz = kwbheader_size(img);
1305         data = (uint8_t *)img + srcaddr;
1306         datasz = *size - srcaddr;
1307
1308         /* only move data if there is not enough space */
1309         if (hdrsz + grow > srcaddr) {
1310                 size_t need = hdrsz + grow - srcaddr;
1311
1312                 /* move data by enough bytes */
1313                 memmove(data + need, data, datasz);
1314
1315                 hdr->srcaddr = cpu_to_le32(srcaddr + need);
1316                 *size += need;
1317         }
1318
1319         if (kwbimage_version(img) == 1) {
1320                 hdrsz += grow;
1321                 hdr->headersz_msb = hdrsz >> 16;
1322                 hdr->headersz_lsb = cpu_to_le16(hdrsz & 0xffff);
1323         }
1324 }
1325
1326 static void *
1327 kwboot_add_bin_ohdr_v1(void *img, size_t *size, uint32_t binsz)
1328 {
1329         struct main_hdr_v1 *hdr = img;
1330         struct opt_hdr_v1 *ohdr;
1331         uint32_t num_args;
1332         uint32_t offset;
1333         uint32_t ohdrsz;
1334
1335         if (hdr->ext & 0x1) {
1336                 for_each_opt_hdr_v1 (ohdr, img)
1337                         if (opt_hdr_v1_next(ohdr) == NULL)
1338                                 break;
1339
1340                 *opt_hdr_v1_ext(ohdr) |= 1;
1341                 ohdr = opt_hdr_v1_next(ohdr);
1342         } else {
1343                 hdr->ext |= 1;
1344                 ohdr = (void *)(hdr + 1);
1345         }
1346
1347         /*
1348          * ARM executable code inside the BIN header on some mvebu platforms
1349          * (e.g. A370, AXP) must always be aligned with the 128-bit boundary.
1350          * This requirement can be met by inserting dummy arguments into
1351          * BIN header, if needed.
1352          */
1353         offset = &ohdr->data[4] - (char *)img;
1354         num_args = ((16 - offset % 16) % 16) / sizeof(uint32_t);
1355
1356         ohdrsz = sizeof(*ohdr) + 4 + 4 * num_args + binsz + 4;
1357         kwboot_img_grow_hdr(hdr, size, ohdrsz);
1358
1359         ohdr->headertype = OPT_HDR_V1_BINARY_TYPE;
1360         ohdr->headersz_msb = ohdrsz >> 16;
1361         ohdr->headersz_lsb = cpu_to_le16(ohdrsz & 0xffff);
1362
1363         memset(&ohdr->data[0], 0, ohdrsz - sizeof(*ohdr));
1364         *(uint32_t *)&ohdr->data[0] = cpu_to_le32(num_args);
1365
1366         return &ohdr->data[4 + 4 * num_args];
1367 }
1368
1369 static void
1370 _copy_baudrate_change_code(struct main_hdr_v1 *hdr, void *dst, int pre,
1371                            int old_baud, int new_baud)
1372 {
1373         size_t codesz = sizeof(kwboot_baud_code);
1374         uint8_t *code = dst;
1375
1376         if (pre) {
1377                 size_t presz = sizeof(kwboot_pre_baud_code);
1378
1379                 /*
1380                  * We need to prepend code that loads lr register with original
1381                  * value of hdr->execaddr. We do this by putting the original
1382                  * exec address before the code that loads it relatively from
1383                  * it's beginning.
1384                  * Afterwards we change the exec address to this code (which is
1385                  * at offset 4, because the first 4 bytes contain the original
1386                  * exec address).
1387                  */
1388                 memcpy(code, kwboot_pre_baud_code, presz);
1389                 *(uint32_t *)code = hdr->execaddr;
1390
1391                 hdr->execaddr = cpu_to_le32(le32_to_cpu(hdr->destaddr) + 4);
1392
1393                 code += presz;
1394         }
1395
1396         memcpy(code, kwboot_baud_code, codesz - 8);
1397         *(uint32_t *)(code + codesz - 8) = cpu_to_le32(old_baud);
1398         *(uint32_t *)(code + codesz - 4) = cpu_to_le32(new_baud);
1399 }
1400
1401 static int
1402 kwboot_img_patch(void *img, size_t *size, int baudrate)
1403 {
1404         struct main_hdr_v1 *hdr;
1405         uint32_t srcaddr;
1406         uint8_t csum;
1407         size_t hdrsz;
1408         int image_ver;
1409         int is_secure;
1410
1411         hdr = img;
1412
1413         if (*size < sizeof(struct main_hdr_v1))
1414                 goto err;
1415
1416         image_ver = kwbimage_version(img);
1417         if (image_ver != 0 && image_ver != 1) {
1418                 fprintf(stderr, "Invalid image header version\n");
1419                 goto err;
1420         }
1421
1422         hdrsz = kwbheader_size(hdr);
1423
1424         if (*size < hdrsz)
1425                 goto err;
1426
1427         csum = kwboot_hdr_csum8(hdr) - hdr->checksum;
1428         if (csum != hdr->checksum)
1429                 goto err;
1430
1431         srcaddr = le32_to_cpu(hdr->srcaddr);
1432
1433         switch (hdr->blockid) {
1434         case IBR_HDR_SATA_ID:
1435                 if (srcaddr < 1)
1436                         goto err;
1437
1438                 hdr->srcaddr = cpu_to_le32((srcaddr - 1) * 512);
1439                 break;
1440
1441         case IBR_HDR_SDIO_ID:
1442                 hdr->srcaddr = cpu_to_le32(srcaddr * 512);
1443                 break;
1444
1445         case IBR_HDR_PEX_ID:
1446                 if (srcaddr == 0xFFFFFFFF)
1447                         hdr->srcaddr = cpu_to_le32(hdrsz);
1448                 break;
1449
1450         case IBR_HDR_SPI_ID:
1451                 if (hdr->destaddr == cpu_to_le32(0xFFFFFFFF)) {
1452                         kwboot_printv("Patching destination and execution addresses from SPI/NOR XIP area to DDR area 0x00800000\n");
1453                         hdr->destaddr = cpu_to_le32(0x00800000);
1454                         hdr->execaddr = cpu_to_le32(0x00800000);
1455                 }
1456                 break;
1457         }
1458
1459         if (hdrsz > le32_to_cpu(hdr->srcaddr) ||
1460             *size < le32_to_cpu(hdr->srcaddr) + le32_to_cpu(hdr->blocksize))
1461                 goto err;
1462
1463         is_secure = kwboot_img_is_secure(img);
1464
1465         if (hdr->blockid != IBR_HDR_UART_ID) {
1466                 if (is_secure) {
1467                         fprintf(stderr,
1468                                 "Image has secure header with signature for non-UART booting\n");
1469                         goto err;
1470                 }
1471
1472                 kwboot_printv("Patching image boot signature to UART\n");
1473                 hdr->blockid = IBR_HDR_UART_ID;
1474         }
1475
1476         if (!is_secure) {
1477                 if (image_ver == 0)
1478                         ((struct main_hdr_v0 *)img)->nandeccmode = IBR_HDR_ECC_DISABLED;
1479                 hdr->nandpagesize = 0;
1480         }
1481
1482         if (baudrate) {
1483                 uint32_t codesz = sizeof(kwboot_baud_code);
1484                 void *code;
1485
1486                 if (image_ver == 0) {
1487                         fprintf(stderr,
1488                                 "Cannot inject code for changing baudrate into v0 image header\n");
1489                         goto err;
1490                 }
1491
1492                 if (is_secure) {
1493                         fprintf(stderr,
1494                                 "Cannot inject code for changing baudrate into image with secure header\n");
1495                         goto err;
1496                 }
1497
1498                 /*
1499                  * First inject code that changes the baudrate from the default
1500                  * value of 115200 Bd to requested value. This code is inserted
1501                  * as a new opt hdr, so it is executed by BootROM after the
1502                  * header part is received.
1503                  */
1504                 kwboot_printv("Injecting binary header code for changing baudrate to %d Bd\n",
1505                               baudrate);
1506
1507                 code = kwboot_add_bin_ohdr_v1(img, size, codesz);
1508                 _copy_baudrate_change_code(hdr, code, 0, 115200, baudrate);
1509
1510                 /*
1511                  * Now inject code that changes the baudrate back to 115200 Bd.
1512                  * This code is prepended to the data part of the image, so it
1513                  * is executed before U-Boot proper.
1514                  */
1515                 kwboot_printv("Injecting code for changing baudrate back\n");
1516
1517                 codesz += sizeof(kwboot_pre_baud_code);
1518                 code = kwboot_img_grow_data_left(img, size, codesz);
1519                 _copy_baudrate_change_code(hdr, code, 1, baudrate, 115200);
1520
1521                 /* recompute header size */
1522                 hdrsz = kwbheader_size(hdr);
1523         }
1524
1525         if (hdrsz % KWBOOT_XM_BLKSZ) {
1526                 size_t offset = (KWBOOT_XM_BLKSZ - hdrsz % KWBOOT_XM_BLKSZ) %
1527                                 KWBOOT_XM_BLKSZ;
1528
1529                 if (is_secure) {
1530                         fprintf(stderr, "Cannot align image with secure header\n");
1531                         goto err;
1532                 }
1533
1534                 kwboot_printv("Aligning image header to Xmodem block size\n");
1535                 kwboot_img_grow_hdr(img, size, offset);
1536         }
1537
1538         hdr->checksum = kwboot_hdr_csum8(hdr) - csum;
1539
1540         *size = le32_to_cpu(hdr->srcaddr) + le32_to_cpu(hdr->blocksize);
1541         return 0;
1542 err:
1543         errno = EINVAL;
1544         return -1;
1545 }
1546
1547 static void
1548 kwboot_usage(FILE *stream, char *progname)
1549 {
1550         fprintf(stream, "kwboot version %s\n", PLAIN_VERSION);
1551         fprintf(stream,
1552                 "Usage: %s [OPTIONS] [-b <image> | -D <image> ] [-B <baud> ] <TTY>\n",
1553                 progname);
1554         fprintf(stream, "\n");
1555         fprintf(stream,
1556                 "  -b <image>: boot <image> with preamble (Kirkwood, Armada 370/XP)\n");
1557         fprintf(stream,
1558                 "  -D <image>: boot <image> without preamble (Dove)\n");
1559         fprintf(stream, "  -d: enter debug mode\n");
1560         fprintf(stream, "  -a: use timings for Armada XP\n");
1561         fprintf(stream, "  -q <req-delay>:  use specific request-delay\n");
1562         fprintf(stream, "  -s <resp-timeo>: use specific response-timeout\n");
1563         fprintf(stream,
1564                 "  -o <block-timeo>: use specific xmodem block timeout\n");
1565         fprintf(stream, "\n");
1566         fprintf(stream, "  -t: mini terminal\n");
1567         fprintf(stream, "\n");
1568         fprintf(stream, "  -B <baud>: set baud rate\n");
1569         fprintf(stream, "\n");
1570 }
1571
1572 int
1573 main(int argc, char **argv)
1574 {
1575         const char *ttypath, *imgpath;
1576         int rv, rc, tty, term;
1577         void *bootmsg;
1578         void *debugmsg;
1579         void *img;
1580         size_t size;
1581         size_t after_img_rsv;
1582         int baudrate;
1583
1584         rv = 1;
1585         tty = -1;
1586         bootmsg = NULL;
1587         debugmsg = NULL;
1588         imgpath = NULL;
1589         img = NULL;
1590         term = 0;
1591         size = 0;
1592         after_img_rsv = KWBOOT_XM_BLKSZ;
1593         baudrate = 115200;
1594
1595         kwboot_verbose = isatty(STDOUT_FILENO);
1596
1597         do {
1598                 int c = getopt(argc, argv, "hb:ptaB:dD:q:s:o:");
1599                 if (c < 0)
1600                         break;
1601
1602                 switch (c) {
1603                 case 'b':
1604                         bootmsg = kwboot_msg_boot;
1605                         imgpath = optarg;
1606                         break;
1607
1608                 case 'D':
1609                         bootmsg = NULL;
1610                         imgpath = optarg;
1611                         break;
1612
1613                 case 'd':
1614                         debugmsg = kwboot_msg_debug;
1615                         break;
1616
1617                 case 'p':
1618                         /* nop, for backward compatibility */
1619                         break;
1620
1621                 case 't':
1622                         term = 1;
1623                         break;
1624
1625                 case 'a':
1626                         msg_req_delay = KWBOOT_MSG_REQ_DELAY_AXP;
1627                         msg_rsp_timeo = KWBOOT_MSG_RSP_TIMEO_AXP;
1628                         break;
1629
1630                 case 'q':
1631                         msg_req_delay = atoi(optarg);
1632                         break;
1633
1634                 case 's':
1635                         msg_rsp_timeo = atoi(optarg);
1636                         break;
1637
1638                 case 'o':
1639                         blk_rsp_timeo = atoi(optarg);
1640                         break;
1641
1642                 case 'B':
1643                         baudrate = atoi(optarg);
1644                         break;
1645
1646                 case 'h':
1647                         rv = 0;
1648                 default:
1649                         goto usage;
1650                 }
1651         } while (1);
1652
1653         if (!bootmsg && !term && !debugmsg)
1654                 goto usage;
1655
1656         if (argc - optind < 1)
1657                 goto usage;
1658
1659         ttypath = argv[optind++];
1660
1661         tty = kwboot_open_tty(ttypath, imgpath ? 115200 : baudrate);
1662         if (tty < 0) {
1663                 perror(ttypath);
1664                 goto out;
1665         }
1666
1667         if (baudrate == 115200)
1668                 /* do not change baudrate during Xmodem to the same value */
1669                 baudrate = 0;
1670         else
1671                 /* ensure we have enough space for baudrate change code */
1672                 after_img_rsv += KWBOOT_BAUDRATE_BIN_HEADER_SZ +
1673                                  sizeof(kwboot_pre_baud_code) +
1674                                  sizeof(kwboot_baud_code);
1675
1676         if (imgpath) {
1677                 img = kwboot_read_image(imgpath, &size, after_img_rsv);
1678                 if (!img) {
1679                         perror(imgpath);
1680                         goto out;
1681                 }
1682
1683                 rc = kwboot_img_patch(img, &size, baudrate);
1684                 if (rc) {
1685                         fprintf(stderr, "%s: Invalid image.\n", imgpath);
1686                         goto out;
1687                 }
1688         }
1689
1690         if (debugmsg) {
1691                 rc = kwboot_debugmsg(tty, debugmsg);
1692                 if (rc) {
1693                         perror("debugmsg");
1694                         goto out;
1695                 }
1696         } else if (bootmsg) {
1697                 rc = kwboot_bootmsg(tty, bootmsg);
1698                 if (rc) {
1699                         perror("bootmsg");
1700                         goto out;
1701                 }
1702         }
1703
1704         if (img) {
1705                 rc = kwboot_xmodem(tty, img, size, baudrate);
1706                 if (rc) {
1707                         perror("xmodem");
1708                         goto out;
1709                 }
1710         }
1711
1712         if (term) {
1713                 rc = kwboot_terminal(tty);
1714                 if (rc && !(errno == EINTR)) {
1715                         perror("terminal");
1716                         goto out;
1717                 }
1718         }
1719
1720         rv = 0;
1721 out:
1722         if (tty >= 0)
1723                 close(tty);
1724
1725         if (img)
1726                 free(img);
1727
1728         return rv;
1729
1730 usage:
1731         kwboot_usage(rv ? stderr : stdout, basename(argv[0]));
1732         goto out;
1733 }