tools: kwboot: Add support for backspace key in mini terminal
[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 #include <pthread.h>
32
33 #ifdef __linux__
34 #include "termios_linux.h"
35 #else
36 #include <termios.h>
37 #endif
38
39 /*
40  * These functions are in <term.h> header file, but this header file conflicts
41  * with "termios_linux.h" header file. So declare these functions manually.
42  */
43 extern int setupterm(const char *, int, int *);
44 extern char *tigetstr(const char *);
45
46 /*
47  * Marvell BootROM UART Sensing
48  */
49
50 static unsigned char kwboot_msg_boot[] = {
51         0xBB, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77
52 };
53
54 static unsigned char kwboot_msg_debug[] = {
55         0xDD, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77
56 };
57
58 /* Defines known to work on Kirkwood */
59 #define KWBOOT_MSG_RSP_TIMEO    50 /* ms */
60
61 /* Defines known to work on Armada XP */
62 #define KWBOOT_MSG_RSP_TIMEO_AXP        1000 /* ms */
63
64 /*
65  * Xmodem Transfers
66  */
67
68 #define SOH     1       /* sender start of block header */
69 #define EOT     4       /* sender end of block transfer */
70 #define ACK     6       /* target block ack */
71 #define NAK     21      /* target block negative ack */
72
73 #define KWBOOT_XM_BLKSZ 128 /* xmodem block size */
74
75 struct kwboot_block {
76         uint8_t soh;
77         uint8_t pnum;
78         uint8_t _pnum;
79         uint8_t data[KWBOOT_XM_BLKSZ];
80         uint8_t csum;
81 } __packed;
82
83 #define KWBOOT_BLK_RSP_TIMEO 2000 /* ms */
84 #define KWBOOT_HDR_RSP_TIMEO 10000 /* ms */
85
86 /* ARM code to change baudrate */
87 static unsigned char kwboot_baud_code[] = {
88                                 /* ; #define UART_BASE 0xd0012000             */
89                                 /* ; #define DLL       0x00                   */
90                                 /* ; #define DLH       0x04                   */
91                                 /* ; #define LCR       0x0c                   */
92                                 /* ; #define   DLAB    0x80                   */
93                                 /* ; #define LSR       0x14                   */
94                                 /* ; #define   TEMT    0x40                   */
95                                 /* ; #define DIV_ROUND(a, b) ((a + b/2) / b)  */
96                                 /* ;                                          */
97                                 /* ; u32 set_baudrate(u32 old_b, u32 new_b) { */
98                                 /* ;   while                                  */
99                                 /* ;      (!(readl(UART_BASE + LSR) & TEMT)); */
100                                 /* ;   u32 lcr = readl(UART_BASE + LCR);      */
101                                 /* ;   writel(UART_BASE + LCR, lcr | DLAB);   */
102                                 /* ;   u8 old_dll = readl(UART_BASE + DLL);   */
103                                 /* ;   u8 old_dlh = readl(UART_BASE + DLH);   */
104                                 /* ;   u16 old_dl = old_dll | (old_dlh << 8); */
105                                 /* ;   u32 clk = old_b * old_dl;              */
106                                 /* ;   u16 new_dl = DIV_ROUND(clk, new_b);    */
107                                 /* ;   u8 new_dll = new_dl & 0xff;            */
108                                 /* ;   u8 new_dlh = (new_dl >> 8) & 0xff;     */
109                                 /* ;   writel(UART_BASE + DLL, new_dll);      */
110                                 /* ;   writel(UART_BASE + DLH, new_dlh);      */
111                                 /* ;   writel(UART_BASE + LCR, lcr & ~DLAB);  */
112                                 /* ;   msleep(5);                             */
113                                 /* ;   return 0;                              */
114                                 /* ; }                                        */
115
116                                 /*  ; r0 = UART_BASE                          */
117         0x0d, 0x02, 0xa0, 0xe3, /* mov   r0, #0xd0000000                      */
118         0x12, 0x0a, 0x80, 0xe3, /* orr   r0, r0, #0x12000                     */
119
120                                 /*  ; Wait until Transmitter FIFO is Empty    */
121                                 /* .Lloop_txempty:                            */
122                                 /*  ; r1 = UART_BASE[LSR] & TEMT              */
123         0x14, 0x10, 0x90, 0xe5, /* ldr   r1, [r0, #0x14]                      */
124         0x40, 0x00, 0x11, 0xe3, /* tst   r1, #0x40                            */
125         0xfc, 0xff, 0xff, 0x0a, /* beq   .Lloop_txempty                       */
126
127                                 /*  ; Set Divisor Latch Access Bit            */
128                                 /*  ; UART_BASE[LCR] |= DLAB                  */
129         0x0c, 0x10, 0x90, 0xe5, /* ldr   r1, [r0, #0x0c]                      */
130         0x80, 0x10, 0x81, 0xe3, /* orr   r1, r1, #0x80                        */
131         0x0c, 0x10, 0x80, 0xe5, /* str   r1, [r0, #0x0c]                      */
132
133                                 /*  ; Read current Divisor Latch              */
134                                 /*  ; r1 = UART_BASE[DLH]<<8 | UART_BASE[DLL] */
135         0x00, 0x10, 0x90, 0xe5, /* ldr   r1, [r0, #0x00]                      */
136         0xff, 0x10, 0x01, 0xe2, /* and   r1, r1, #0xff                        */
137         0x01, 0x20, 0xa0, 0xe1, /* mov   r2, r1                               */
138         0x04, 0x10, 0x90, 0xe5, /* ldr   r1, [r0, #0x04]                      */
139         0xff, 0x10, 0x01, 0xe2, /* and   r1, r1, #0xff                        */
140         0x41, 0x14, 0xa0, 0xe1, /* asr   r1, r1, #8                           */
141         0x02, 0x10, 0x81, 0xe1, /* orr   r1, r1, r2                           */
142
143                                 /*  ; Read old baudrate value                 */
144                                 /*  ; r2 = old_baudrate                       */
145         0x74, 0x20, 0x9f, 0xe5, /* ldr   r2, old_baudrate                     */
146
147                                 /*  ; Calculate base clock                    */
148                                 /*  ; r1 = r2 * r1                            */
149         0x92, 0x01, 0x01, 0xe0, /* mul   r1, r2, r1                           */
150
151                                 /*  ; Read new baudrate value                 */
152                                 /*  ; r2 = new_baudrate                       */
153         0x70, 0x20, 0x9f, 0xe5, /* ldr   r2, new_baudrate                     */
154
155                                 /*  ; Calculate new Divisor Latch             */
156                                 /*  ; r1 = DIV_ROUND(r1, r2) =                */
157                                 /*  ;    = (r1 + r2/2) / r2                   */
158         0xa2, 0x10, 0x81, 0xe0, /* add   r1, r1, r2, lsr #1                   */
159         0x02, 0x40, 0xa0, 0xe1, /* mov   r4, r2                               */
160         0xa1, 0x00, 0x54, 0xe1, /* cmp   r4, r1, lsr #1                       */
161                                 /* .Lloop_div1:                               */
162         0x84, 0x40, 0xa0, 0x91, /* movls r4, r4, lsl #1                       */
163         0xa1, 0x00, 0x54, 0xe1, /* cmp   r4, r1, lsr #1                       */
164         0xfc, 0xff, 0xff, 0x9a, /* bls   .Lloop_div1                          */
165         0x00, 0x30, 0xa0, 0xe3, /* mov   r3, #0                               */
166                                 /* .Lloop_div2:                               */
167         0x04, 0x00, 0x51, 0xe1, /* cmp   r1, r4                               */
168         0x04, 0x10, 0x41, 0x20, /* subhs r1, r1, r4                           */
169         0x03, 0x30, 0xa3, 0xe0, /* adc   r3, r3, r3                           */
170         0xa4, 0x40, 0xa0, 0xe1, /* mov   r4, r4, lsr #1                       */
171         0x02, 0x00, 0x54, 0xe1, /* cmp   r4, r2                               */
172         0xf9, 0xff, 0xff, 0x2a, /* bhs   .Lloop_div2                          */
173         0x03, 0x10, 0xa0, 0xe1, /* mov   r1, r3                               */
174
175                                 /*  ; Set new Divisor Latch Low               */
176                                 /*  ; UART_BASE[DLL] = r1 & 0xff              */
177         0x01, 0x20, 0xa0, 0xe1, /* mov   r2, r1                               */
178         0xff, 0x20, 0x02, 0xe2, /* and   r2, r2, #0xff                        */
179         0x00, 0x20, 0x80, 0xe5, /* str   r2, [r0, #0x00]                      */
180
181                                 /*  ; Set new Divisor Latch High              */
182                                 /*  ; UART_BASE[DLH] = r1>>8 & 0xff           */
183         0x41, 0x24, 0xa0, 0xe1, /* asr   r2, r1, #8                           */
184         0xff, 0x20, 0x02, 0xe2, /* and   r2, r2, #0xff                        */
185         0x04, 0x20, 0x80, 0xe5, /* str   r2, [r0, #0x04]                      */
186
187                                 /*  ; Clear Divisor Latch Access Bit          */
188                                 /*  ; UART_BASE[LCR] &= ~DLAB                 */
189         0x0c, 0x10, 0x90, 0xe5, /* ldr   r1, [r0, #0x0c]                      */
190         0x80, 0x10, 0xc1, 0xe3, /* bic   r1, r1, #0x80                        */
191         0x0c, 0x10, 0x80, 0xe5, /* str   r1, [r0, #0x0c]                      */
192
193                                 /*  ; Loop 0x2dc000 (2998272) cycles          */
194                                 /*  ; which is about 5ms on 1200 MHz CPU      */
195                                 /*  ; r1 = 0x2dc000                           */
196         0xb7, 0x19, 0xa0, 0xe3, /* mov   r1, #0x2dc000                        */
197                                 /* .Lloop_sleep:                              */
198         0x01, 0x10, 0x41, 0xe2, /* sub   r1, r1, #1                           */
199         0x00, 0x00, 0x51, 0xe3, /* cmp   r1, #0                               */
200         0xfc, 0xff, 0xff, 0x1a, /* bne   .Lloop_sleep                         */
201
202                                 /*  ; Jump to the end of execution            */
203         0x01, 0x00, 0x00, 0xea, /* b     end                                  */
204
205                                 /*  ; Placeholder for old baudrate value      */
206                                 /* old_baudrate:                              */
207         0x00, 0x00, 0x00, 0x00, /* .word 0                                    */
208
209                                 /*  ; Placeholder for new baudrate value      */
210                                 /* new_baudrate:                              */
211         0x00, 0x00, 0x00, 0x00, /* .word 0                                    */
212
213                                 /* end:                                       */
214 };
215
216 /* ARM code from binary header executed by BootROM before changing baudrate */
217 static unsigned char kwboot_baud_code_binhdr_pre[] = {
218                                 /* ; #define UART_BASE 0xd0012000             */
219                                 /* ; #define THR       0x00                   */
220                                 /* ; #define LSR       0x14                   */
221                                 /* ; #define   THRE    0x20                   */
222                                 /* ;                                          */
223                                 /* ; void send_preamble(void) {               */
224                                 /* ;   const u8 *str = "$baudratechange";     */
225                                 /* ;   u8 c;                                  */
226                                 /* ;   do {                                   */
227                                 /* ;       while                              */
228                                 /* ;       ((readl(UART_BASE + LSR) & THRE)); */
229                                 /* ;       c = *str++;                        */
230                                 /* ;       writel(UART_BASE + THR, c);        */
231                                 /* ;   } while (c);                           */
232                                 /* ; }                                        */
233
234                                 /*  ; Preserve registers for BootROM          */
235         0xfe, 0x5f, 0x2d, 0xe9, /* push  { r1 - r12, lr }                     */
236
237                                 /*  ; r0 = UART_BASE                          */
238         0x0d, 0x02, 0xa0, 0xe3, /* mov   r0, #0xd0000000                      */
239         0x12, 0x0a, 0x80, 0xe3, /* orr   r0, r0, #0x12000                     */
240
241                                 /*  ; r2 = address of preamble string         */
242         0x00, 0x20, 0x8f, 0xe2, /* adr   r2, .Lstr_preamble                   */
243
244                                 /*  ; Skip preamble data section              */
245         0x03, 0x00, 0x00, 0xea, /* b     .Lloop_preamble                      */
246
247                                 /*  ; Preamble string                         */
248                                 /* .Lstr_preamble:                            */
249         0x24, 0x62, 0x61, 0x75, /* .asciz "$baudratechange"                   */
250         0x64, 0x72, 0x61, 0x74,
251         0x65, 0x63, 0x68, 0x61,
252         0x6e, 0x67, 0x65, 0x00,
253
254                                 /*  ; Send preamble string over UART          */
255                                 /* .Lloop_preamble:                           */
256                                 /*                                            */
257                                 /*  ; Wait until Transmitter Holding is Empty */
258                                 /* .Lloop_thre:                               */
259                                 /*  ; r1 = UART_BASE[LSR] & THRE              */
260         0x14, 0x10, 0x90, 0xe5, /* ldr   r1, [r0, #0x14]                      */
261         0x20, 0x00, 0x11, 0xe3, /* tst   r1, #0x20                            */
262         0xfc, 0xff, 0xff, 0x0a, /* beq   .Lloop_thre                          */
263
264                                 /*  ; Put character into Transmitter FIFO     */
265                                 /*  ; r1 = *r2++                              */
266         0x01, 0x10, 0xd2, 0xe4, /* ldrb  r1, [r2], #1                         */
267                                 /*  ; UART_BASE[THR] = r1                     */
268         0x00, 0x10, 0x80, 0xe5, /* str   r1, [r0, #0x0]                       */
269
270                                 /*  ; Loop until end of preamble string       */
271         0x00, 0x00, 0x51, 0xe3, /* cmp   r1, #0                               */
272         0xf8, 0xff, 0xff, 0x1a, /* bne   .Lloop_preamble                      */
273 };
274
275 /* ARM code for returning from binary header back to BootROM */
276 static unsigned char kwboot_baud_code_binhdr_post[] = {
277                                 /*  ; Return 0 - no error                     */
278         0x00, 0x00, 0xa0, 0xe3, /* mov   r0, #0                               */
279         0xfe, 0x9f, 0xbd, 0xe8, /* pop   { r1 - r12, pc }                     */
280 };
281
282 /* ARM code for jumping to the original image exec_addr */
283 static unsigned char kwboot_baud_code_data_jump[] = {
284         0x04, 0xf0, 0x1f, 0xe5, /* ldr   pc, exec_addr                        */
285                                 /*  ; Placeholder for exec_addr               */
286                                 /* exec_addr:                                 */
287         0x00, 0x00, 0x00, 0x00, /* .word 0                                    */
288 };
289
290 static const char kwb_baud_magic[16] = "$baudratechange";
291
292 static int kwboot_verbose;
293
294 static int msg_rsp_timeo = KWBOOT_MSG_RSP_TIMEO;
295 static int blk_rsp_timeo = KWBOOT_BLK_RSP_TIMEO;
296
297 static ssize_t
298 kwboot_write(int fd, const char *buf, size_t len)
299 {
300         ssize_t tot = 0;
301
302         while (tot < len) {
303                 ssize_t wr = write(fd, buf + tot, len - tot);
304
305                 if (wr < 0 && errno == EINTR)
306                         continue;
307                 else if (wr < 0)
308                         return wr;
309
310                 tot += wr;
311         }
312
313         return tot;
314 }
315
316 static void
317 kwboot_printv(const char *fmt, ...)
318 {
319         va_list ap;
320
321         if (kwboot_verbose) {
322                 va_start(ap, fmt);
323                 vprintf(fmt, ap);
324                 va_end(ap);
325                 fflush(stdout);
326         }
327 }
328
329 static void
330 __spinner(void)
331 {
332         const char seq[] = { '-', '\\', '|', '/' };
333         const int div = 8;
334         static int state, bs;
335
336         if (state % div == 0) {
337                 fputc(bs, stdout);
338                 fputc(seq[state / div % sizeof(seq)], stdout);
339                 fflush(stdout);
340         }
341
342         bs = '\b';
343         state++;
344 }
345
346 static void
347 kwboot_spinner(void)
348 {
349         if (kwboot_verbose)
350                 __spinner();
351 }
352
353 static void
354 __progress(int pct, char c)
355 {
356         const int width = 70;
357         static const char *nl = "";
358         static int pos;
359
360         if (pos % width == 0)
361                 printf("%s%3d %% [", nl, pct);
362
363         fputc(c, stdout);
364
365         nl = "]\n";
366         pos = (pos + 1) % width;
367
368         if (pct == 100) {
369                 while (pos && pos++ < width)
370                         fputc(' ', stdout);
371                 fputs(nl, stdout);
372                 nl = "";
373                 pos = 0;
374         }
375
376         fflush(stdout);
377
378 }
379
380 static void
381 kwboot_progress(int _pct, char c)
382 {
383         static int pct;
384
385         if (_pct != -1)
386                 pct = _pct;
387
388         if (kwboot_verbose)
389                 __progress(pct, c);
390
391         if (pct == 100)
392                 pct = 0;
393 }
394
395 static int
396 kwboot_tty_recv(int fd, void *buf, size_t len, int timeo)
397 {
398         int rc, nfds;
399         fd_set rfds;
400         struct timeval tv;
401         ssize_t n;
402
403         rc = -1;
404
405         FD_ZERO(&rfds);
406         FD_SET(fd, &rfds);
407
408         tv.tv_sec = 0;
409         tv.tv_usec = timeo * 1000;
410         if (tv.tv_usec > 1000000) {
411                 tv.tv_sec += tv.tv_usec / 1000000;
412                 tv.tv_usec %= 1000000;
413         }
414
415         do {
416                 nfds = select(fd + 1, &rfds, NULL, NULL, &tv);
417                 if (nfds < 0 && errno == EINTR)
418                         continue;
419                 else if (nfds < 0)
420                         goto out;
421                 else if (!nfds) {
422                         errno = ETIMEDOUT;
423                         goto out;
424                 }
425
426                 n = read(fd, buf, len);
427                 if (n < 0 && errno == EINTR)
428                         continue;
429                 else if (n <= 0)
430                         goto out;
431
432                 buf = (char *)buf + n;
433                 len -= n;
434         } while (len > 0);
435
436         rc = 0;
437 out:
438         return rc;
439 }
440
441 static int
442 kwboot_tty_send(int fd, const void *buf, size_t len, int nodrain)
443 {
444         if (!buf)
445                 return 0;
446
447         if (kwboot_write(fd, buf, len) < 0)
448                 return -1;
449
450         if (nodrain)
451                 return 0;
452
453         return tcdrain(fd);
454 }
455
456 static int
457 kwboot_tty_send_char(int fd, unsigned char c)
458 {
459         return kwboot_tty_send(fd, &c, 1, 0);
460 }
461
462 static speed_t
463 kwboot_tty_baudrate_to_speed(int baudrate)
464 {
465         switch (baudrate) {
466 #ifdef B4000000
467         case 4000000:
468                 return B4000000;
469 #endif
470 #ifdef B3500000
471         case 3500000:
472                 return B3500000;
473 #endif
474 #ifdef B3000000
475         case 3000000:
476                 return B3000000;
477 #endif
478 #ifdef B2500000
479         case 2500000:
480                 return B2500000;
481 #endif
482 #ifdef B2000000
483         case 2000000:
484                 return B2000000;
485 #endif
486 #ifdef B1500000
487         case 1500000:
488                 return B1500000;
489 #endif
490 #ifdef B1152000
491         case 1152000:
492                 return B1152000;
493 #endif
494 #ifdef B1000000
495         case 1000000:
496                 return B1000000;
497 #endif
498 #ifdef B921600
499         case 921600:
500                 return B921600;
501 #endif
502 #ifdef B614400
503         case 614400:
504                 return B614400;
505 #endif
506 #ifdef B576000
507         case 576000:
508                 return B576000;
509 #endif
510 #ifdef B500000
511         case 500000:
512                 return B500000;
513 #endif
514 #ifdef B460800
515         case 460800:
516                 return B460800;
517 #endif
518 #ifdef B307200
519         case 307200:
520                 return B307200;
521 #endif
522 #ifdef B230400
523         case 230400:
524                 return B230400;
525 #endif
526 #ifdef B153600
527         case 153600:
528                 return B153600;
529 #endif
530 #ifdef B115200
531         case 115200:
532                 return B115200;
533 #endif
534 #ifdef B76800
535         case 76800:
536                 return B76800;
537 #endif
538 #ifdef B57600
539         case 57600:
540                 return B57600;
541 #endif
542 #ifdef B38400
543         case 38400:
544                 return B38400;
545 #endif
546 #ifdef B19200
547         case 19200:
548                 return B19200;
549 #endif
550 #ifdef B9600
551         case 9600:
552                 return B9600;
553 #endif
554 #ifdef B4800
555         case 4800:
556                 return B4800;
557 #endif
558 #ifdef B2400
559         case 2400:
560                 return B2400;
561 #endif
562 #ifdef B1800
563         case 1800:
564                 return B1800;
565 #endif
566 #ifdef B1200
567         case 1200:
568                 return B1200;
569 #endif
570 #ifdef B600
571         case 600:
572                 return B600;
573 #endif
574 #ifdef B300
575         case 300:
576                 return B300;
577 #endif
578 #ifdef B200
579         case 200:
580                 return B200;
581 #endif
582 #ifdef B150
583         case 150:
584                 return B150;
585 #endif
586 #ifdef B134
587         case 134:
588                 return B134;
589 #endif
590 #ifdef B110
591         case 110:
592                 return B110;
593 #endif
594 #ifdef B75
595         case 75:
596                 return B75;
597 #endif
598 #ifdef B50
599         case 50:
600                 return B50;
601 #endif
602         default:
603 #ifdef BOTHER
604                 return BOTHER;
605 #else
606                 return B0;
607 #endif
608         }
609 }
610
611 static int
612 _is_within_tolerance(int value, int reference, int tolerance)
613 {
614         return 100 * value >= reference * (100 - tolerance) &&
615                100 * value <= reference * (100 + tolerance);
616 }
617
618 static int
619 kwboot_tty_change_baudrate(int fd, int baudrate)
620 {
621         struct termios tio;
622         speed_t speed;
623         int rc;
624
625         rc = tcgetattr(fd, &tio);
626         if (rc)
627                 return rc;
628
629         speed = kwboot_tty_baudrate_to_speed(baudrate);
630         if (speed == B0) {
631                 errno = EINVAL;
632                 return -1;
633         }
634
635 #ifdef BOTHER
636         if (speed == BOTHER)
637                 tio.c_ospeed = tio.c_ispeed = baudrate;
638 #endif
639
640         rc = cfsetospeed(&tio, speed);
641         if (rc)
642                 return rc;
643
644         rc = cfsetispeed(&tio, speed);
645         if (rc)
646                 return rc;
647
648         rc = tcsetattr(fd, TCSANOW, &tio);
649         if (rc)
650                 return rc;
651
652         rc = tcgetattr(fd, &tio);
653         if (rc)
654                 return rc;
655
656         if (cfgetospeed(&tio) != speed || cfgetispeed(&tio) != speed)
657                 goto baud_fail;
658
659 #ifdef BOTHER
660         /*
661          * Check whether set baudrate is within 3% tolerance.
662          * If BOTHER is defined, Linux always fills out c_ospeed / c_ispeed
663          * with real values.
664          */
665         if (!_is_within_tolerance(tio.c_ospeed, baudrate, 3))
666                 goto baud_fail;
667
668         if (!_is_within_tolerance(tio.c_ispeed, baudrate, 3))
669                 goto baud_fail;
670 #endif
671
672         return 0;
673
674 baud_fail:
675         fprintf(stderr, "Could not set baudrate to requested value\n");
676         errno = EINVAL;
677         return -1;
678 }
679
680 static int
681 kwboot_open_tty(const char *path, int baudrate)
682 {
683         int rc, fd, flags;
684         struct termios tio;
685
686         rc = -1;
687
688         fd = open(path, O_RDWR | O_NOCTTY | O_NDELAY);
689         if (fd < 0)
690                 goto out;
691
692         rc = tcgetattr(fd, &tio);
693         if (rc)
694                 goto out;
695
696         cfmakeraw(&tio);
697         tio.c_cflag |= CREAD | CLOCAL;
698         tio.c_cflag &= ~(CSTOPB | HUPCL | CRTSCTS);
699         tio.c_cc[VMIN] = 1;
700         tio.c_cc[VTIME] = 0;
701
702         rc = tcsetattr(fd, TCSANOW, &tio);
703         if (rc)
704                 goto out;
705
706         flags = fcntl(fd, F_GETFL);
707         if (flags < 0)
708                 goto out;
709
710         rc = fcntl(fd, F_SETFL, flags & ~O_NDELAY);
711         if (rc)
712                 goto out;
713
714         rc = kwboot_tty_change_baudrate(fd, baudrate);
715         if (rc)
716                 goto out;
717
718         rc = fd;
719 out:
720         if (rc < 0) {
721                 if (fd >= 0)
722                         close(fd);
723         }
724
725         return rc;
726 }
727
728 static void *
729 kwboot_msg_write_handler(void *arg)
730 {
731         int tty = *(int *)((void **)arg)[0];
732         const void *msg = ((void **)arg)[1];
733         int rsp_timeo = msg_rsp_timeo;
734         int i, dummy_oldtype;
735
736         /* allow to cancel this thread at any time */
737         pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &dummy_oldtype);
738
739         while (1) {
740                 /* write 128 samples of message pattern into the output queue without waiting */
741                 for (i = 0; i < 128; i++) {
742                         if (kwboot_tty_send(tty, msg, 8, 1) < 0) {
743                                 perror("\nFailed to send message pattern");
744                                 exit(1);
745                         }
746                 }
747                 /* wait until output queue is transmitted and then make pause */
748                 if (tcdrain(tty) < 0) {
749                         perror("\nFailed to send message pattern");
750                         exit(1);
751                 }
752                 /* BootROM requires pause on UART after it detects message pattern */
753                 usleep(rsp_timeo * 1000);
754         }
755 }
756
757 static int
758 kwboot_msg_start_thread(pthread_t *thread, int *tty, void *msg)
759 {
760         void *arg[2];
761         int rc;
762
763         arg[0] = tty;
764         arg[1] = msg;
765         rc = pthread_create(thread, NULL, kwboot_msg_write_handler, arg);
766         if (rc) {
767                 errno = rc;
768                 return -1;
769         }
770
771         return 0;
772 }
773
774 static int
775 kwboot_msg_stop_thread(pthread_t thread)
776 {
777         int rc;
778
779         rc = pthread_cancel(thread);
780         if (rc) {
781                 errno = rc;
782                 return -1;
783         }
784
785         rc = pthread_join(thread, NULL);
786         if (rc) {
787                 errno = rc;
788                 return -1;
789         }
790
791         return 0;
792 }
793
794 static int
795 kwboot_bootmsg(int tty)
796 {
797         struct kwboot_block block;
798         pthread_t write_thread;
799         int rc, err;
800         char c;
801
802         /* flush input and output queue */
803         tcflush(tty, TCIOFLUSH);
804
805         rc = kwboot_msg_start_thread(&write_thread, &tty, kwboot_msg_boot);
806         if (rc) {
807                 perror("Failed to start write thread");
808                 return rc;
809         }
810
811         kwboot_printv("Sending boot message. Please reboot the target...");
812
813         err = 0;
814         while (1) {
815                 kwboot_spinner();
816
817                 rc = kwboot_tty_recv(tty, &c, 1, msg_rsp_timeo);
818                 if (rc && errno == ETIMEDOUT) {
819                         continue;
820                 } else if (rc) {
821                         err = errno;
822                         break;
823                 }
824
825                 if (c == NAK)
826                         break;
827         }
828
829         kwboot_printv("\n");
830
831         rc = kwboot_msg_stop_thread(write_thread);
832         if (rc) {
833                 perror("Failed to stop write thread");
834                 return rc;
835         }
836
837         if (err) {
838                 errno = err;
839                 perror("Failed to read response for boot message pattern");
840                 return -1;
841         }
842
843         /*
844          * At this stage we have sent more boot message patterns and BootROM
845          * (at least on Armada XP and 385) started interpreting sent bytes as
846          * part of xmodem packets. If BootROM is expecting SOH byte as start of
847          * a xmodem packet and it receives byte 0xff, then it throws it away and
848          * sends a NAK reply to host. If BootROM does not receive any byte for
849          * 2s when expecting some continuation of the xmodem packet, it throws
850          * away the partially received xmodem data and sends NAK reply to host.
851          *
852          * Therefore for starting xmodem transfer we have two options: Either
853          * wait 2s or send 132 0xff bytes (which is the size of xmodem packet)
854          * to ensure that BootROM throws away any partially received data.
855          */
856
857         /* flush output queue with remaining boot message patterns */
858         rc = tcflush(tty, TCOFLUSH);
859         if (rc) {
860                 perror("Failed to flush output queue");
861                 return rc;
862         }
863
864         /* send one xmodem packet with 0xff bytes to force BootROM to re-sync */
865         memset(&block, 0xff, sizeof(block));
866         rc = kwboot_tty_send(tty, &block, sizeof(block), 0);
867         if (rc) {
868                 perror("Failed to send sync sequence");
869                 return rc;
870         }
871
872         /*
873          * Sending 132 bytes via 115200B/8-N-1 takes 11.45 ms, reading 132 bytes
874          * takes 11.45 ms, so waiting for 30 ms should be enough.
875          */
876         usleep(30 * 1000);
877
878         /* flush remaining NAK replies from input queue */
879         rc = tcflush(tty, TCIFLUSH);
880         if (rc) {
881                 perror("Failed to flush input queue");
882                 return rc;
883         }
884
885         return 0;
886 }
887
888 static int
889 kwboot_debugmsg(int tty)
890 {
891         unsigned char buf[8192];
892         pthread_t write_thread;
893         int rc, err, i, pos;
894         size_t off;
895
896         /* flush input and output queue */
897         tcflush(tty, TCIOFLUSH);
898
899         rc = kwboot_msg_start_thread(&write_thread, &tty, kwboot_msg_debug);
900         if (rc) {
901                 perror("Failed to start write thread");
902                 return rc;
903         }
904
905         kwboot_printv("Sending debug message. Please reboot the target...");
906         kwboot_spinner();
907
908         err = 0;
909         off = 0;
910         while (1) {
911                 /* Read immediately all bytes in queue without waiting */
912                 rc = read(tty, buf + off, sizeof(buf) - off);
913                 if ((rc < 0 && errno == EINTR) || rc == 0) {
914                         continue;
915                 } else if (rc < 0) {
916                         err = errno;
917                         break;
918                 }
919                 off += rc - 1;
920
921                 kwboot_spinner();
922
923                 /*
924                  * Check if we received at least 4 debug message patterns
925                  * (console echo from BootROM) in cyclic buffer
926                  */
927
928                 for (pos = 0; pos < sizeof(kwboot_msg_debug); pos++)
929                         if (buf[off] == kwboot_msg_debug[(pos + off) % sizeof(kwboot_msg_debug)])
930                                 break;
931
932                 for (i = off; i >= 0; i--)
933                         if (buf[i] != kwboot_msg_debug[(pos + i) % sizeof(kwboot_msg_debug)])
934                                 break;
935
936                 off -= i;
937
938                 if (off >= 4 * sizeof(kwboot_msg_debug))
939                         break;
940
941                 /* If not move valid suffix from end of the buffer to the beginning of buffer */
942                 memmove(buf, buf + i + 1, off);
943         }
944
945         kwboot_printv("\n");
946
947         rc = kwboot_msg_stop_thread(write_thread);
948         if (rc) {
949                 perror("Failed to stop write thread");
950                 return rc;
951         }
952
953         if (err) {
954                 errno = err;
955                 perror("Failed to read response for debug message pattern");
956                 return -1;
957         }
958
959         /* flush output queue with remaining debug message patterns */
960         rc = tcflush(tty, TCOFLUSH);
961         if (rc) {
962                 perror("Failed to flush output queue");
963                 return rc;
964         }
965
966         kwboot_printv("Clearing input buffer...\n");
967
968         /*
969          * Wait until BootROM transmit all remaining echo characters.
970          * Experimentally it was measured that for Armada 385 BootROM
971          * it is required to wait at least 0.415s. So wait 0.5s.
972          */
973         usleep(500 * 1000);
974
975         /*
976          * In off variable is stored number of characters received after the
977          * successful detection of echo reply. So these characters are console
978          * echo for other following debug message patterns. BootROM may have in
979          * its output queue other echo characters which were being transmitting
980          * before above sleep call. So read remaining number of echo characters
981          * sent by the BootROM now.
982          */
983         while ((rc = kwboot_tty_recv(tty, &buf[0], 1, 0)) == 0)
984                 off++;
985         if (errno != ETIMEDOUT) {
986                 perror("Failed to read response");
987                 return rc;
988         }
989
990         /*
991          * Clear every echo character set by the BootROM by backspace byte.
992          * This is required prior writing any command to the BootROM debug
993          * because BootROM command line buffer has limited size. If length
994          * of the command is larger than buffer size then it looks like
995          * that Armada 385 BootROM crashes after sending ENTER. So erase it.
996          * Experimentally it was measured that for Armada 385 BootROM it is
997          * required to send at least 3 backspace bytes for one echo character.
998          * This is unknown why. But lets do it.
999          */
1000         off *= 3;
1001         memset(buf, '\x08', sizeof(buf));
1002         while (off > sizeof(buf)) {
1003                 rc = kwboot_tty_send(tty, buf, sizeof(buf), 1);
1004                 if (rc) {
1005                         perror("Failed to send clear sequence");
1006                         return rc;
1007                 }
1008                 off -= sizeof(buf);
1009         }
1010         rc = kwboot_tty_send(tty, buf, off, 0);
1011         if (rc) {
1012                 perror("Failed to send clear sequence");
1013                 return rc;
1014         }
1015
1016         usleep(msg_rsp_timeo * 1000);
1017         rc = tcflush(tty, TCIFLUSH);
1018         if (rc) {
1019                 perror("Failed to flush input queue");
1020                 return rc;
1021         }
1022
1023         return 0;
1024 }
1025
1026 static size_t
1027 kwboot_xm_makeblock(struct kwboot_block *block, const void *data,
1028                     size_t size, int pnum)
1029 {
1030         size_t i, n;
1031
1032         block->soh = SOH;
1033         block->pnum = pnum;
1034         block->_pnum = ~block->pnum;
1035
1036         n = size < KWBOOT_XM_BLKSZ ? size : KWBOOT_XM_BLKSZ;
1037         memcpy(&block->data[0], data, n);
1038         memset(&block->data[n], 0, KWBOOT_XM_BLKSZ - n);
1039
1040         block->csum = 0;
1041         for (i = 0; i < n; i++)
1042                 block->csum += block->data[i];
1043
1044         return n;
1045 }
1046
1047 static uint64_t
1048 _now(void)
1049 {
1050         struct timespec ts;
1051
1052         if (clock_gettime(CLOCK_MONOTONIC, &ts)) {
1053                 static int err_print;
1054
1055                 if (!err_print) {
1056                         perror("clock_gettime() does not work");
1057                         err_print = 1;
1058                 }
1059
1060                 /* this will just make the timeout not work */
1061                 return -1ULL;
1062         }
1063
1064         return ts.tv_sec * 1000ULL + (ts.tv_nsec + 500000) / 1000000;
1065 }
1066
1067 static int
1068 _is_xm_reply(char c)
1069 {
1070         return c == ACK || c == NAK;
1071 }
1072
1073 static int
1074 _xm_reply_to_error(int c)
1075 {
1076         int rc = -1;
1077
1078         switch (c) {
1079         case ACK:
1080                 rc = 0;
1081                 break;
1082         case NAK:
1083                 errno = EBADMSG;
1084                 break;
1085         default:
1086                 errno = EPROTO;
1087                 break;
1088         }
1089
1090         return rc;
1091 }
1092
1093 static int
1094 kwboot_baud_magic_handle(int fd, char c, int baudrate)
1095 {
1096         static size_t rcv_len;
1097
1098         if (rcv_len < sizeof(kwb_baud_magic)) {
1099                 /* try to recognize whole magic word */
1100                 if (c == kwb_baud_magic[rcv_len]) {
1101                         rcv_len++;
1102                 } else {
1103                         printf("%.*s%c", (int)rcv_len, kwb_baud_magic, c);
1104                         fflush(stdout);
1105                         rcv_len = 0;
1106                 }
1107         }
1108
1109         if (rcv_len == sizeof(kwb_baud_magic)) {
1110                 /* magic word received */
1111                 kwboot_printv("\nChanging baudrate to %d Bd\n", baudrate);
1112
1113                 return kwboot_tty_change_baudrate(fd, baudrate) ? : 1;
1114         } else {
1115                 return 0;
1116         }
1117 }
1118
1119 static int
1120 kwboot_xm_recv_reply(int fd, char *c, int stop_on_non_xm,
1121                      int ignore_nak_reply,
1122                      int allow_non_xm, int *non_xm_print,
1123                      int baudrate, int *baud_changed)
1124 {
1125         int timeout = allow_non_xm ? KWBOOT_HDR_RSP_TIMEO : blk_rsp_timeo;
1126         uint64_t recv_until = _now() + timeout;
1127         int rc;
1128
1129         while (1) {
1130                 rc = kwboot_tty_recv(fd, c, 1, timeout);
1131                 if (rc) {
1132                         if (errno != ETIMEDOUT)
1133                                 return rc;
1134                         else if (allow_non_xm && *non_xm_print)
1135                                 return -1;
1136                         else
1137                                 *c = NAK;
1138                 }
1139
1140                 /* If received xmodem reply, end. */
1141                 if (_is_xm_reply(*c)) {
1142                         if (*c == NAK && ignore_nak_reply) {
1143                                 timeout = recv_until - _now();
1144                                 if (timeout >= 0)
1145                                         continue;
1146                         }
1147                         break;
1148                 }
1149
1150                 /*
1151                  * If receiving/printing non-xmodem text output is allowed and
1152                  * such a byte was received, we want to increase receiving time
1153                  * and either:
1154                  * - print the byte, if it is not part of baudrate change magic
1155                  *   sequence while baudrate change was requested (-B option)
1156                  * - change baudrate
1157                  * Otherwise decrease timeout by time elapsed.
1158                  */
1159                 if (allow_non_xm) {
1160                         recv_until = _now() + timeout;
1161
1162                         if (baudrate && !*baud_changed) {
1163                                 rc = kwboot_baud_magic_handle(fd, *c, baudrate);
1164                                 if (rc == 1)
1165                                         *baud_changed = 1;
1166                                 else if (!rc)
1167                                         *non_xm_print = 1;
1168                                 else
1169                                         return rc;
1170                         } else if (!baudrate || !*baud_changed) {
1171                                 putchar(*c);
1172                                 fflush(stdout);
1173                                 *non_xm_print = 1;
1174                         }
1175                 } else {
1176                         if (stop_on_non_xm)
1177                                 break;
1178                         timeout = recv_until - _now();
1179                         if (timeout < 0) {
1180                                 errno = ETIMEDOUT;
1181                                 return -1;
1182                         }
1183                 }
1184         }
1185
1186         return 0;
1187 }
1188
1189 static int
1190 kwboot_xm_sendblock(int fd, struct kwboot_block *block, int allow_non_xm,
1191                     int *done_print, int baudrate, int allow_retries)
1192 {
1193         int non_xm_print, baud_changed;
1194         int rc, err, retries;
1195         char c;
1196
1197         *done_print = 0;
1198         non_xm_print = 0;
1199         baud_changed = 0;
1200
1201         retries = 0;
1202         do {
1203                 rc = kwboot_tty_send(fd, block, sizeof(*block), 1);
1204                 if (rc)
1205                         goto err;
1206
1207                 if (allow_non_xm && !*done_print) {
1208                         kwboot_progress(100, '.');
1209                         kwboot_printv("Done\n");
1210                         *done_print = 1;
1211                 }
1212
1213                 rc = kwboot_xm_recv_reply(fd, &c, retries < 3,
1214                                           retries > 8,
1215                                           allow_non_xm, &non_xm_print,
1216                                           baudrate, &baud_changed);
1217                 if (rc)
1218                         goto err;
1219
1220                 if (!allow_non_xm && c != ACK) {
1221                         if (c == NAK && allow_retries && retries + 1 < 16)
1222                                 kwboot_progress(-1, '+');
1223                         else
1224                                 kwboot_progress(-1, 'E');
1225                 }
1226         } while (c == NAK && allow_retries && retries++ < 16);
1227
1228         if (non_xm_print)
1229                 kwboot_printv("\n");
1230
1231         if (allow_non_xm && baudrate && !baud_changed) {
1232                 fprintf(stderr, "Baudrate was not changed\n");
1233                 errno = EPROTO;
1234                 return -1;
1235         }
1236
1237         return _xm_reply_to_error(c);
1238 err:
1239         err = errno;
1240         kwboot_printv("\n");
1241         errno = err;
1242         return rc;
1243 }
1244
1245 static int
1246 kwboot_xm_finish(int fd)
1247 {
1248         int rc, retries;
1249         char c;
1250
1251         kwboot_printv("Finishing transfer\n");
1252
1253         retries = 0;
1254         do {
1255                 rc = kwboot_tty_send_char(fd, EOT);
1256                 if (rc)
1257                         return rc;
1258
1259                 rc = kwboot_xm_recv_reply(fd, &c, retries < 3,
1260                                           retries > 8,
1261                                           0, NULL, 0, NULL);
1262                 if (rc)
1263                         return rc;
1264         } while (c == NAK && retries++ < 16);
1265
1266         return _xm_reply_to_error(c);
1267 }
1268
1269 static int
1270 kwboot_xmodem_one(int tty, int *pnum, int header, const uint8_t *data,
1271                   size_t size, int baudrate)
1272 {
1273         int done_print = 0;
1274         size_t sent, left;
1275         int rc;
1276
1277         kwboot_printv("Sending boot image %s (%zu bytes)...\n",
1278                       header ? "header" : "data", size);
1279
1280         left = size;
1281         sent = 0;
1282
1283         while (sent < size) {
1284                 struct kwboot_block block;
1285                 int last_block;
1286                 size_t blksz;
1287
1288                 blksz = kwboot_xm_makeblock(&block, data, left, (*pnum)++);
1289                 data += blksz;
1290
1291                 last_block = (left <= blksz);
1292
1293                 /*
1294                  * Handling of repeated xmodem packets is completely broken in
1295                  * Armada 385 BootROM - it completely ignores xmodem packet
1296                  * numbers, they are only used for checksum verification.
1297                  * BootROM can handle a retry of the xmodem packet only during
1298                  * the transmission of kwbimage header and only if BootROM
1299                  * itself sent NAK response to previous attempt (it does it on
1300                  * checksum failure). During the transmission of kwbimage data
1301                  * part, BootROM always expects next xmodem packet, even if it
1302                  * sent NAK to previous attempt - there is absolutely no way to
1303                  * repair incorrectly transmitted xmodem packet during kwbimage
1304                  * data part upload. Also, if kwboot receives non-ACK/NAK
1305                  * response (meaning that original BootROM response was damaged
1306                  * on UART) there is no way to detect if BootROM accepted xmodem
1307                  * packet or not and no way to check if kwboot could repeat the
1308                  * packet or not.
1309                  *
1310                  * Stop transfer and return failure if kwboot receives unknown
1311                  * reply if non-xmodem reply is not allowed (for all xmodem
1312                  * packets except the last header packet) or when non-ACK reply
1313                  * is received during data part transfer.
1314                  */
1315                 rc = kwboot_xm_sendblock(tty, &block, header && last_block,
1316                                          &done_print, baudrate, header);
1317                 if (rc)
1318                         goto out;
1319
1320                 sent += blksz;
1321                 left -= blksz;
1322
1323                 if (!done_print)
1324                         kwboot_progress(sent * 100 / size, '.');
1325         }
1326
1327         if (!done_print)
1328                 kwboot_printv("Done\n");
1329
1330         return 0;
1331 out:
1332         kwboot_printv("\n");
1333         return rc;
1334 }
1335
1336 static int
1337 kwboot_xmodem(int tty, const void *_img, size_t size, int baudrate)
1338 {
1339         const uint8_t *img = _img;
1340         int rc, pnum;
1341         size_t hdrsz;
1342
1343         hdrsz = kwbheader_size(img);
1344
1345         /*
1346          * If header size is not aligned to xmodem block size (which applies
1347          * for all images in kwbimage v0 format) then we have to ensure that
1348          * the last xmodem block of header contains beginning of the data
1349          * followed by the header. So align header size to xmodem block size.
1350          */
1351         hdrsz += (KWBOOT_XM_BLKSZ - hdrsz % KWBOOT_XM_BLKSZ) % KWBOOT_XM_BLKSZ;
1352
1353         pnum = 1;
1354
1355         rc = kwboot_xmodem_one(tty, &pnum, 1, img, hdrsz, baudrate);
1356         if (rc)
1357                 return rc;
1358
1359         /*
1360          * If we have already sent image data as a part of the last
1361          * xmodem header block then we have nothing more to send.
1362          */
1363         if (hdrsz < size) {
1364                 img += hdrsz;
1365                 size -= hdrsz;
1366                 rc = kwboot_xmodem_one(tty, &pnum, 0, img, size, 0);
1367                 if (rc)
1368                         return rc;
1369         }
1370
1371         rc = kwboot_xm_finish(tty);
1372         if (rc)
1373                 return rc;
1374
1375         if (baudrate) {
1376                 kwboot_printv("\nChanging baudrate back to 115200 Bd\n\n");
1377                 rc = kwboot_tty_change_baudrate(tty, 115200);
1378                 if (rc)
1379                         return rc;
1380         }
1381
1382         return 0;
1383 }
1384
1385 static int
1386 kwboot_term_pipe(int in, int out, const char *quit, int *s, const char *kbs, int *k)
1387 {
1388         char buf[128];
1389         ssize_t nin, noff;
1390
1391         nin = read(in, buf, sizeof(buf));
1392         if (nin <= 0)
1393                 return -1;
1394
1395         noff = 0;
1396
1397         if (quit || kbs) {
1398                 int i;
1399
1400                 for (i = 0; i < nin; i++) {
1401                         if ((quit || kbs) &&
1402                             (!quit || buf[i] != quit[*s]) &&
1403                             (!kbs || buf[i] != kbs[*k])) {
1404                                 const char *prefix;
1405                                 int plen;
1406
1407                                 if (quit && kbs) {
1408                                         prefix = (*s >= *k) ? quit : kbs;
1409                                         plen = (*s >= *k) ? *s : *k;
1410                                 } else if (quit) {
1411                                         prefix = quit;
1412                                         plen = *s;
1413                                 } else {
1414                                         prefix = kbs;
1415                                         plen = *k;
1416                                 }
1417
1418                                 if (plen > i && kwboot_write(out, prefix, plen - i) < 0)
1419                                         return -1;
1420                         }
1421
1422                         if (quit && buf[i] == quit[*s]) {
1423                                 (*s)++;
1424                                 if (!quit[*s]) {
1425                                         nin = (i > *s) ? (i - *s) : 0;
1426                                         break;
1427                                 }
1428                         } else if (quit) {
1429                                 *s = 0;
1430                         }
1431
1432                         if (kbs && buf[i] == kbs[*k]) {
1433                                 (*k)++;
1434                                 if (!kbs[*k]) {
1435                                         if (i > *k + noff &&
1436                                             kwboot_write(out, buf + noff, i - *k - noff) < 0)
1437                                                 return -1;
1438                                         /*
1439                                          * Replace backspace key by '\b' (0x08)
1440                                          * byte which is the only recognized
1441                                          * backspace byte by Marvell BootROM.
1442                                          */
1443                                         if (write(out, "\x08", 1) < 0)
1444                                                 return -1;
1445                                         noff = i + 1;
1446                                         *k = 0;
1447                                 }
1448                         } else if (kbs) {
1449                                 *k = 0;
1450                         }
1451                 }
1452
1453                 if (i == nin) {
1454                         i = 0;
1455                         if (quit && i < *s)
1456                                 i = *s;
1457                         if (kbs && i < *k)
1458                                 i = *k;
1459                         nin -= (nin > i) ? i : nin;
1460                 }
1461         }
1462
1463         if (nin > noff && kwboot_write(out, buf + noff, nin - noff) < 0)
1464                 return -1;
1465
1466         return 0;
1467 }
1468
1469 static int
1470 kwboot_terminal(int tty)
1471 {
1472         int rc, in, s, k;
1473         const char *kbs = NULL;
1474         const char *quit = "\34c";
1475         struct termios otio, tio;
1476
1477         rc = -1;
1478
1479         in = STDIN_FILENO;
1480         if (isatty(in)) {
1481                 rc = tcgetattr(in, &otio);
1482                 if (!rc) {
1483                         tio = otio;
1484                         cfmakeraw(&tio);
1485                         rc = tcsetattr(in, TCSANOW, &tio);
1486                 }
1487                 if (rc) {
1488                         perror("tcsetattr");
1489                         goto out;
1490                 }
1491
1492                 /*
1493                  * Get sequence for backspace key used by the current
1494                  * terminal. Every occurrence of this sequence will be
1495                  * replaced by '\b' byte which is the only recognized
1496                  * backspace byte by Marvell BootROM.
1497                  *
1498                  * Note that we cannot read this sequence from termios
1499                  * c_cc[VERASE] as VERASE is valid only when ICANON is
1500                  * set in termios c_lflag, which is not case for us.
1501                  *
1502                  * Also most terminals do not set termios c_cc[VERASE]
1503                  * as c_cc[VERASE] can specify only one-byte sequence
1504                  * and instead let applications to read (possible
1505                  * multi-byte) sequence for backspace key from "kbs"
1506                  * terminfo database based on $TERM env variable.
1507                  *
1508                  * So read "kbs" from terminfo database via tigetstr()
1509                  * call after successful setupterm(). Most terminals
1510                  * use byte 0x7F for backspace key, so replacement with
1511                  * '\b' is required.
1512                  */
1513                 if (setupterm(NULL, STDOUT_FILENO, &rc) == 0) {
1514                         kbs = tigetstr("kbs");
1515                         if (kbs == (char *)-1)
1516                                 kbs = NULL;
1517                 }
1518
1519                 kwboot_printv("[Type Ctrl-%c + %c to quit]\r\n",
1520                               quit[0] | 0100, quit[1]);
1521         } else
1522                 in = -1;
1523
1524         rc = 0;
1525         s = 0;
1526         k = 0;
1527
1528         do {
1529                 fd_set rfds;
1530                 int nfds = 0;
1531
1532                 FD_ZERO(&rfds);
1533                 FD_SET(tty, &rfds);
1534                 nfds = nfds < tty ? tty : nfds;
1535
1536                 if (in >= 0) {
1537                         FD_SET(in, &rfds);
1538                         nfds = nfds < in ? in : nfds;
1539                 }
1540
1541                 nfds = select(nfds + 1, &rfds, NULL, NULL, NULL);
1542                 if (nfds < 0)
1543                         break;
1544
1545                 if (FD_ISSET(tty, &rfds)) {
1546                         rc = kwboot_term_pipe(tty, STDOUT_FILENO, NULL, NULL, NULL, NULL);
1547                         if (rc)
1548                                 break;
1549                 }
1550
1551                 if (in >= 0 && FD_ISSET(in, &rfds)) {
1552                         rc = kwboot_term_pipe(in, tty, quit, &s, kbs, &k);
1553                         if (rc)
1554                                 break;
1555                 }
1556         } while (quit[s] != 0);
1557
1558         if (in >= 0)
1559                 tcsetattr(in, TCSANOW, &otio);
1560         printf("\n");
1561 out:
1562         return rc;
1563 }
1564
1565 static void *
1566 kwboot_read_image(const char *path, size_t *size, size_t reserve)
1567 {
1568         int rc, fd;
1569         struct stat st;
1570         void *img;
1571         off_t tot;
1572
1573         rc = -1;
1574         img = NULL;
1575
1576         fd = open(path, O_RDONLY);
1577         if (fd < 0)
1578                 goto out;
1579
1580         rc = fstat(fd, &st);
1581         if (rc)
1582                 goto out;
1583
1584         img = malloc(st.st_size + reserve);
1585         if (!img)
1586                 goto out;
1587
1588         tot = 0;
1589         while (tot < st.st_size) {
1590                 ssize_t rd = read(fd, img + tot, st.st_size - tot);
1591
1592                 if (rd < 0)
1593                         goto out;
1594
1595                 tot += rd;
1596
1597                 if (!rd && tot < st.st_size) {
1598                         errno = EIO;
1599                         goto out;
1600                 }
1601         }
1602
1603         rc = 0;
1604         *size = st.st_size;
1605 out:
1606         if (rc && img) {
1607                 free(img);
1608                 img = NULL;
1609         }
1610         if (fd >= 0)
1611                 close(fd);
1612
1613         return img;
1614 }
1615
1616 static uint8_t
1617 kwboot_hdr_csum8(const void *hdr)
1618 {
1619         const uint8_t *data = hdr;
1620         uint8_t csum;
1621         size_t size;
1622
1623         size = kwbheader_size_for_csum(hdr);
1624
1625         for (csum = 0; size-- > 0; data++)
1626                 csum += *data;
1627
1628         return csum;
1629 }
1630
1631 static uint32_t *
1632 kwboot_img_csum32_ptr(void *img)
1633 {
1634         struct main_hdr_v1 *hdr = img;
1635         uint32_t datasz;
1636
1637         datasz = le32_to_cpu(hdr->blocksize) - sizeof(uint32_t);
1638
1639         return img + le32_to_cpu(hdr->srcaddr) + datasz;
1640 }
1641
1642 static uint32_t
1643 kwboot_img_csum32(const void *img)
1644 {
1645         const struct main_hdr_v1 *hdr = img;
1646         uint32_t datasz, csum = 0;
1647         const uint32_t *data;
1648
1649         datasz = le32_to_cpu(hdr->blocksize) - sizeof(csum);
1650         if (datasz % sizeof(uint32_t))
1651                 return 0;
1652
1653         data = img + le32_to_cpu(hdr->srcaddr);
1654         while (datasz > 0) {
1655                 csum += le32_to_cpu(*data++);
1656                 datasz -= 4;
1657         }
1658
1659         return cpu_to_le32(csum);
1660 }
1661
1662 static int
1663 kwboot_img_is_secure(void *img)
1664 {
1665         struct opt_hdr_v1 *ohdr;
1666
1667         for_each_opt_hdr_v1 (ohdr, img)
1668                 if (ohdr->headertype == OPT_HDR_V1_SECURE_TYPE)
1669                         return 1;
1670
1671         return 0;
1672 }
1673
1674 static void *
1675 kwboot_img_grow_data_right(void *img, size_t *size, size_t grow)
1676 {
1677         struct main_hdr_v1 *hdr = img;
1678         void *result;
1679
1680         /*
1681          * 32-bit checksum comes after end of image code, so we will be putting
1682          * new code there. So we get this pointer and then increase data size
1683          * (since increasing data size changes kwboot_img_csum32_ptr() return
1684          *  value).
1685          */
1686         result = kwboot_img_csum32_ptr(img);
1687         hdr->blocksize = cpu_to_le32(le32_to_cpu(hdr->blocksize) + grow);
1688         *size += grow;
1689
1690         return result;
1691 }
1692
1693 static void
1694 kwboot_img_grow_hdr(void *img, size_t *size, size_t grow)
1695 {
1696         uint32_t hdrsz, datasz, srcaddr;
1697         struct main_hdr_v1 *hdr = img;
1698         struct opt_hdr_v1 *ohdr;
1699         uint8_t *data;
1700
1701         srcaddr = le32_to_cpu(hdr->srcaddr);
1702
1703         /* calculate real used space in kwbimage header */
1704         if (kwbimage_version(img) == 0) {
1705                 hdrsz = kwbheader_size(img);
1706         } else {
1707                 hdrsz = sizeof(*hdr);
1708                 for_each_opt_hdr_v1 (ohdr, hdr)
1709                         hdrsz += opt_hdr_v1_size(ohdr);
1710         }
1711
1712         data = (uint8_t *)img + srcaddr;
1713         datasz = *size - srcaddr;
1714
1715         /* only move data if there is not enough space */
1716         if (hdrsz + grow > srcaddr) {
1717                 size_t need = hdrsz + grow - srcaddr;
1718
1719                 /* move data by enough bytes */
1720                 memmove(data + need, data, datasz);
1721
1722                 hdr->srcaddr = cpu_to_le32(srcaddr + need);
1723                 *size += need;
1724         }
1725
1726         if (kwbimage_version(img) == 1) {
1727                 hdrsz += grow;
1728                 if (hdrsz > kwbheader_size(img)) {
1729                         hdr->headersz_msb = hdrsz >> 16;
1730                         hdr->headersz_lsb = cpu_to_le16(hdrsz & 0xffff);
1731                 }
1732         }
1733 }
1734
1735 static void *
1736 kwboot_add_bin_ohdr_v1(void *img, size_t *size, uint32_t binsz)
1737 {
1738         struct main_hdr_v1 *hdr = img;
1739         struct opt_hdr_v1 *ohdr;
1740         uint32_t num_args;
1741         uint32_t offset;
1742         uint32_t ohdrsz;
1743         uint8_t *prev_ext;
1744
1745         if (hdr->ext) {
1746                 for_each_opt_hdr_v1 (ohdr, img)
1747                         if (opt_hdr_v1_next(ohdr) == NULL)
1748                                 break;
1749
1750                 prev_ext = opt_hdr_v1_ext(ohdr);
1751                 ohdr = _opt_hdr_v1_next(ohdr);
1752         } else {
1753                 ohdr = (void *)(hdr + 1);
1754                 prev_ext = &hdr->ext;
1755         }
1756
1757         /*
1758          * ARM executable code inside the BIN header on some mvebu platforms
1759          * (e.g. A370, AXP) must always be aligned with the 128-bit boundary.
1760          * This requirement can be met by inserting dummy arguments into
1761          * BIN header, if needed.
1762          */
1763         offset = &ohdr->data[4] - (char *)img;
1764         num_args = ((16 - offset % 16) % 16) / sizeof(uint32_t);
1765
1766         ohdrsz = sizeof(*ohdr) + 4 + 4 * num_args + binsz + 4;
1767         kwboot_img_grow_hdr(hdr, size, ohdrsz);
1768
1769         *prev_ext = 1;
1770
1771         ohdr->headertype = OPT_HDR_V1_BINARY_TYPE;
1772         ohdr->headersz_msb = ohdrsz >> 16;
1773         ohdr->headersz_lsb = cpu_to_le16(ohdrsz & 0xffff);
1774
1775         memset(&ohdr->data[0], 0, ohdrsz - sizeof(*ohdr));
1776         *(uint32_t *)&ohdr->data[0] = cpu_to_le32(num_args);
1777
1778         return &ohdr->data[4 + 4 * num_args];
1779 }
1780
1781 static void
1782 _inject_baudrate_change_code(void *img, size_t *size, int for_data,
1783                              int old_baud, int new_baud)
1784 {
1785         struct main_hdr_v1 *hdr = img;
1786         uint32_t orig_datasz;
1787         uint32_t codesz;
1788         uint8_t *code;
1789
1790         if (for_data) {
1791                 orig_datasz = le32_to_cpu(hdr->blocksize) - sizeof(uint32_t);
1792
1793                 codesz = sizeof(kwboot_baud_code) +
1794                          sizeof(kwboot_baud_code_data_jump);
1795                 code = kwboot_img_grow_data_right(img, size, codesz);
1796         } else {
1797                 codesz = sizeof(kwboot_baud_code_binhdr_pre) +
1798                          sizeof(kwboot_baud_code) +
1799                          sizeof(kwboot_baud_code_binhdr_post);
1800                 code = kwboot_add_bin_ohdr_v1(img, size, codesz);
1801
1802                 codesz = sizeof(kwboot_baud_code_binhdr_pre);
1803                 memcpy(code, kwboot_baud_code_binhdr_pre, codesz);
1804                 code += codesz;
1805         }
1806
1807         codesz = sizeof(kwboot_baud_code) - 2 * sizeof(uint32_t);
1808         memcpy(code, kwboot_baud_code, codesz);
1809         code += codesz;
1810         *(uint32_t *)code = cpu_to_le32(old_baud);
1811         code += sizeof(uint32_t);
1812         *(uint32_t *)code = cpu_to_le32(new_baud);
1813         code += sizeof(uint32_t);
1814
1815         if (for_data) {
1816                 codesz = sizeof(kwboot_baud_code_data_jump) - sizeof(uint32_t);
1817                 memcpy(code, kwboot_baud_code_data_jump, codesz);
1818                 code += codesz;
1819                 *(uint32_t *)code = hdr->execaddr;
1820                 code += sizeof(uint32_t);
1821                 hdr->execaddr = cpu_to_le32(le32_to_cpu(hdr->destaddr) + orig_datasz);
1822         } else {
1823                 codesz = sizeof(kwboot_baud_code_binhdr_post);
1824                 memcpy(code, kwboot_baud_code_binhdr_post, codesz);
1825                 code += codesz;
1826         }
1827 }
1828
1829 static int
1830 kwboot_img_patch(void *img, size_t *size, int baudrate)
1831 {
1832         struct main_hdr_v1 *hdr;
1833         uint32_t srcaddr;
1834         uint8_t csum;
1835         size_t hdrsz;
1836         int image_ver;
1837         int is_secure;
1838
1839         hdr = img;
1840
1841         if (*size < sizeof(struct main_hdr_v1))
1842                 goto err;
1843
1844         image_ver = kwbimage_version(img);
1845         if (image_ver != 0 && image_ver != 1) {
1846                 fprintf(stderr, "Invalid image header version\n");
1847                 goto err;
1848         }
1849
1850         hdrsz = kwbheader_size(hdr);
1851
1852         if (*size < hdrsz)
1853                 goto err;
1854
1855         csum = kwboot_hdr_csum8(hdr) - hdr->checksum;
1856         if (csum != hdr->checksum)
1857                 goto err;
1858
1859         srcaddr = le32_to_cpu(hdr->srcaddr);
1860
1861         switch (hdr->blockid) {
1862         case IBR_HDR_SATA_ID:
1863                 if (srcaddr < 1)
1864                         goto err;
1865
1866                 hdr->srcaddr = cpu_to_le32((srcaddr - 1) * 512);
1867                 break;
1868
1869         case IBR_HDR_SDIO_ID:
1870                 hdr->srcaddr = cpu_to_le32(srcaddr * 512);
1871                 break;
1872
1873         case IBR_HDR_PEX_ID:
1874                 if (srcaddr == 0xFFFFFFFF)
1875                         hdr->srcaddr = cpu_to_le32(hdrsz);
1876                 break;
1877
1878         case IBR_HDR_SPI_ID:
1879                 if (hdr->destaddr == cpu_to_le32(0xFFFFFFFF)) {
1880                         kwboot_printv("Patching destination and execution addresses from SPI/NOR XIP area to DDR area 0x00800000\n");
1881                         hdr->destaddr = cpu_to_le32(0x00800000);
1882                         hdr->execaddr = cpu_to_le32(0x00800000);
1883                 }
1884                 break;
1885         }
1886
1887         if (hdrsz > le32_to_cpu(hdr->srcaddr) ||
1888             *size < le32_to_cpu(hdr->srcaddr) + le32_to_cpu(hdr->blocksize))
1889                 goto err;
1890
1891         if (kwboot_img_csum32(img) != *kwboot_img_csum32_ptr(img))
1892                 goto err;
1893
1894         is_secure = kwboot_img_is_secure(img);
1895
1896         if (hdr->blockid != IBR_HDR_UART_ID) {
1897                 if (is_secure) {
1898                         fprintf(stderr,
1899                                 "Image has secure header with signature for non-UART booting\n");
1900                         goto err;
1901                 }
1902
1903                 kwboot_printv("Patching image boot signature to UART\n");
1904                 hdr->blockid = IBR_HDR_UART_ID;
1905         }
1906
1907         if (!is_secure) {
1908                 if (image_ver == 1) {
1909                         /*
1910                          * Tell BootROM to send BootROM messages to UART port
1911                          * number 0 (used also for UART booting) with default
1912                          * baudrate (which should be 115200) and do not touch
1913                          * UART MPP configuration.
1914                          */
1915                         hdr->flags |= 0x1;
1916                         hdr->options &= ~0x1F;
1917                         hdr->options |= MAIN_HDR_V1_OPT_BAUD_DEFAULT;
1918                         hdr->options |= 0 << 3;
1919                 }
1920                 if (image_ver == 0)
1921                         ((struct main_hdr_v0 *)img)->nandeccmode = IBR_HDR_ECC_DISABLED;
1922                 hdr->nandpagesize = 0;
1923         }
1924
1925         if (baudrate) {
1926                 if (image_ver == 0) {
1927                         fprintf(stderr,
1928                                 "Cannot inject code for changing baudrate into v0 image header\n");
1929                         goto err;
1930                 }
1931
1932                 if (is_secure) {
1933                         fprintf(stderr,
1934                                 "Cannot inject code for changing baudrate into image with secure header\n");
1935                         goto err;
1936                 }
1937
1938                 /*
1939                  * First inject code that changes the baudrate from the default
1940                  * value of 115200 Bd to requested value. This code is inserted
1941                  * as a new opt hdr, so it is executed by BootROM after the
1942                  * header part is received.
1943                  */
1944                 kwboot_printv("Injecting binary header code for changing baudrate to %d Bd\n",
1945                               baudrate);
1946                 _inject_baudrate_change_code(img, size, 0, 115200, baudrate);
1947
1948                 /*
1949                  * Now inject code that changes the baudrate back to 115200 Bd.
1950                  * This code is appended after the data part of the image, and
1951                  * execaddr is changed so that it is executed before U-Boot
1952                  * proper.
1953                  */
1954                 kwboot_printv("Injecting code for changing baudrate back\n");
1955                 _inject_baudrate_change_code(img, size, 1, baudrate, 115200);
1956
1957                 /* Update the 32-bit data checksum */
1958                 *kwboot_img_csum32_ptr(img) = kwboot_img_csum32(img);
1959
1960                 /* recompute header size */
1961                 hdrsz = kwbheader_size(hdr);
1962         }
1963
1964         if (hdrsz % KWBOOT_XM_BLKSZ) {
1965                 size_t grow = KWBOOT_XM_BLKSZ - hdrsz % KWBOOT_XM_BLKSZ;
1966
1967                 if (is_secure) {
1968                         fprintf(stderr, "Cannot align image with secure header\n");
1969                         goto err;
1970                 }
1971
1972                 kwboot_printv("Aligning image header to Xmodem block size\n");
1973                 kwboot_img_grow_hdr(img, size, grow);
1974         }
1975
1976         hdr->checksum = kwboot_hdr_csum8(hdr) - csum;
1977
1978         *size = le32_to_cpu(hdr->srcaddr) + le32_to_cpu(hdr->blocksize);
1979         return 0;
1980 err:
1981         errno = EINVAL;
1982         return -1;
1983 }
1984
1985 static void
1986 kwboot_usage(FILE *stream, char *progname)
1987 {
1988         fprintf(stream,
1989                 "Usage: %s [OPTIONS] [-b <image> | -D <image> ] [-B <baud> ] <TTY>\n",
1990                 progname);
1991         fprintf(stream, "\n");
1992         fprintf(stream,
1993                 "  -b <image>: boot <image> with preamble (Kirkwood, Armada 370/XP)\n");
1994         fprintf(stream,
1995                 "  -D <image>: boot <image> without preamble (Dove)\n");
1996         fprintf(stream, "  -d: enter debug mode\n");
1997         fprintf(stream, "  -a: use timings for Armada XP\n");
1998         fprintf(stream, "  -s <resp-timeo>: use specific response-timeout\n");
1999         fprintf(stream,
2000                 "  -o <block-timeo>: use specific xmodem block timeout\n");
2001         fprintf(stream, "\n");
2002         fprintf(stream, "  -t: mini terminal\n");
2003         fprintf(stream, "\n");
2004         fprintf(stream, "  -B <baud>: set baud rate\n");
2005         fprintf(stream, "\n");
2006 }
2007
2008 int
2009 main(int argc, char **argv)
2010 {
2011         const char *ttypath, *imgpath;
2012         int rv, rc, tty, term;
2013         int bootmsg;
2014         int debugmsg;
2015         void *img;
2016         size_t size;
2017         size_t after_img_rsv;
2018         int baudrate;
2019         int prev_optind;
2020         int c;
2021
2022         rv = 1;
2023         tty = -1;
2024         bootmsg = 0;
2025         debugmsg = 0;
2026         imgpath = NULL;
2027         img = NULL;
2028         term = 0;
2029         size = 0;
2030         after_img_rsv = KWBOOT_XM_BLKSZ;
2031         baudrate = 115200;
2032
2033         printf("kwboot version %s\n", PLAIN_VERSION);
2034
2035         kwboot_verbose = isatty(STDOUT_FILENO);
2036
2037         do {
2038                 prev_optind = optind;
2039                 c = getopt(argc, argv, "hbptaB:dD:q:s:o:");
2040                 if (c < 0)
2041                         break;
2042
2043                 switch (c) {
2044                 case 'b':
2045                         if (imgpath || bootmsg || debugmsg)
2046                                 goto usage;
2047                         bootmsg = 1;
2048                         if (prev_optind == optind)
2049                                 goto usage;
2050                         if (optind < argc - 1 && argv[optind] && argv[optind][0] != '-')
2051                                 imgpath = argv[optind++];
2052                         break;
2053
2054                 case 'D':
2055                         if (imgpath || bootmsg || debugmsg)
2056                                 goto usage;
2057                         bootmsg = 0;
2058                         imgpath = optarg;
2059                         break;
2060
2061                 case 'd':
2062                         if (imgpath || bootmsg || debugmsg)
2063                                 goto usage;
2064                         debugmsg = 1;
2065                         break;
2066
2067                 case 'p':
2068                         /* nop, for backward compatibility */
2069                         break;
2070
2071                 case 't':
2072                         term = 1;
2073                         break;
2074
2075                 case 'a':
2076                         msg_rsp_timeo = KWBOOT_MSG_RSP_TIMEO_AXP;
2077                         break;
2078
2079                 case 'q':
2080                         /* nop, for backward compatibility */
2081                         break;
2082
2083                 case 's':
2084                         msg_rsp_timeo = atoi(optarg);
2085                         break;
2086
2087                 case 'o':
2088                         blk_rsp_timeo = atoi(optarg);
2089                         break;
2090
2091                 case 'B':
2092                         baudrate = atoi(optarg);
2093                         break;
2094
2095                 case 'h':
2096                         rv = 0;
2097                 default:
2098                         goto usage;
2099                 }
2100         } while (1);
2101
2102         if (!bootmsg && !term && !debugmsg && !imgpath)
2103                 goto usage;
2104
2105         ttypath = argv[optind++];
2106
2107         if (optind != argc)
2108                 goto usage;
2109
2110         tty = kwboot_open_tty(ttypath, imgpath ? 115200 : baudrate);
2111         if (tty < 0) {
2112                 perror(ttypath);
2113                 goto out;
2114         }
2115
2116         if (baudrate == 115200)
2117                 /* do not change baudrate during Xmodem to the same value */
2118                 baudrate = 0;
2119         else
2120                 /* ensure we have enough space for baudrate change code */
2121                 after_img_rsv += sizeof(struct opt_hdr_v1) + 8 + 16 +
2122                                  sizeof(kwboot_baud_code_binhdr_pre) +
2123                                  sizeof(kwboot_baud_code) +
2124                                  sizeof(kwboot_baud_code_binhdr_post) +
2125                                  KWBOOT_XM_BLKSZ +
2126                                  sizeof(kwboot_baud_code) +
2127                                  sizeof(kwboot_baud_code_data_jump) +
2128                                  KWBOOT_XM_BLKSZ;
2129
2130         if (imgpath) {
2131                 img = kwboot_read_image(imgpath, &size, after_img_rsv);
2132                 if (!img) {
2133                         perror(imgpath);
2134                         goto out;
2135                 }
2136
2137                 rc = kwboot_img_patch(img, &size, baudrate);
2138                 if (rc) {
2139                         fprintf(stderr, "%s: Invalid image.\n", imgpath);
2140                         goto out;
2141                 }
2142         }
2143
2144         if (debugmsg) {
2145                 rc = kwboot_debugmsg(tty);
2146                 if (rc)
2147                         goto out;
2148         } else if (bootmsg) {
2149                 rc = kwboot_bootmsg(tty);
2150                 if (rc)
2151                         goto out;
2152         }
2153
2154         if (img) {
2155                 rc = kwboot_xmodem(tty, img, size, baudrate);
2156                 if (rc) {
2157                         perror("xmodem");
2158                         goto out;
2159                 }
2160         }
2161
2162         if (term) {
2163                 rc = kwboot_terminal(tty);
2164                 if (rc && !(errno == EINTR)) {
2165                         perror("terminal");
2166                         goto out;
2167                 }
2168         }
2169
2170         rv = 0;
2171 out:
2172         if (tty >= 0)
2173                 close(tty);
2174
2175         if (img)
2176                 free(img);
2177
2178         return rv;
2179
2180 usage:
2181         kwboot_usage(rv ? stderr : stdout, basename(argv[0]));
2182         goto out;
2183 }