Commit c165945d193be510337de656f6564ad0f6ab35a4
1 parent
37846d2c90
Exists in
v2016.05-smarct4x
and in
3 other branches
spl: Add an option to load a FIT containing U-Boot from UART
This provides a way to load a FIT containing U-Boot and a selection of device tree files from UART. Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
Showing 1 changed file with 74 additions and 11 deletions Side-by-side Diff
common/spl/spl_ymodem.c
... | ... | @@ -14,6 +14,7 @@ |
14 | 14 | #include <xyzModem.h> |
15 | 15 | #include <asm/u-boot.h> |
16 | 16 | #include <asm/utils.h> |
17 | +#include <libfdt.h> | |
17 | 18 | |
18 | 19 | #define BUF_SIZE 1024 |
19 | 20 | |
... | ... | @@ -23,6 +24,44 @@ |
23 | 24 | return -1; |
24 | 25 | } |
25 | 26 | |
27 | +struct ymodem_fit_info { | |
28 | + int image_read; | |
29 | + char *buf; | |
30 | +}; | |
31 | + | |
32 | +static ulong ymodem_read_fit(struct spl_load_info *load, ulong offset, | |
33 | + ulong size, void *addr) | |
34 | +{ | |
35 | + int res, err; | |
36 | + struct ymodem_fit_info *info = load->priv; | |
37 | + char *buf = info->buf; | |
38 | + | |
39 | + while (info->image_read < offset) { | |
40 | + res = xyzModem_stream_read(buf, BUF_SIZE, &err); | |
41 | + if (res <= 0) | |
42 | + return res; | |
43 | + info->image_read += res; | |
44 | + } | |
45 | + | |
46 | + if (info->image_read > offset) { | |
47 | + res = info->image_read - offset; | |
48 | + memcpy(addr, &buf[BUF_SIZE - res], res); | |
49 | + addr = addr + res; | |
50 | + } | |
51 | + | |
52 | + while (info->image_read < offset + size) { | |
53 | + res = xyzModem_stream_read(buf, BUF_SIZE, &err); | |
54 | + if (res <= 0) | |
55 | + return res; | |
56 | + | |
57 | + memcpy(addr, buf, res); | |
58 | + info->image_read += res; | |
59 | + addr += res; | |
60 | + } | |
61 | + | |
62 | + return size; | |
63 | +} | |
64 | + | |
26 | 65 | int spl_ymodem_load_image(void) |
27 | 66 | { |
28 | 67 | int size = 0; |
29 | 68 | |
30 | 69 | |
31 | 70 | |
32 | 71 | |
33 | 72 | |
34 | 73 | |
... | ... | @@ -31,27 +70,51 @@ |
31 | 70 | int ret; |
32 | 71 | connection_info_t info; |
33 | 72 | char buf[BUF_SIZE]; |
34 | - ulong store_addr = ~0; | |
35 | 73 | ulong addr = 0; |
36 | 74 | |
37 | 75 | info.mode = xyzModem_ymodem; |
38 | 76 | ret = xyzModem_stream_open(&info, &err); |
77 | + if (ret) { | |
78 | + printf("spl: ymodem err - %s\n", xyzModem_error(err)); | |
79 | + return ret; | |
80 | + } | |
39 | 81 | |
40 | - if (!ret) { | |
41 | - while ((res = | |
42 | - xyzModem_stream_read(buf, BUF_SIZE, &err)) > 0) { | |
43 | - if (addr == 0) | |
44 | - spl_parse_image_header((struct image_header *)buf); | |
45 | - store_addr = addr + spl_image.load_addr; | |
82 | + res = xyzModem_stream_read(buf, BUF_SIZE, &err); | |
83 | + if (res <= 0) | |
84 | + goto end_stream; | |
85 | + | |
86 | + if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && | |
87 | + image_get_magic((struct image_header *)buf) == FDT_MAGIC) { | |
88 | + struct spl_load_info load; | |
89 | + struct ymodem_fit_info info; | |
90 | + | |
91 | + debug("Found FIT\n"); | |
92 | + load.dev = NULL; | |
93 | + load.priv = (void *)&info; | |
94 | + load.bl_len = 1; | |
95 | + info.buf = buf; | |
96 | + info.image_read = BUF_SIZE; | |
97 | + load.read = ymodem_read_fit; | |
98 | + ret = spl_load_simple_fit(&load, 0, (void *)buf); | |
99 | + size = info.image_read; | |
100 | + | |
101 | + while ((res = xyzModem_stream_read(buf, BUF_SIZE, &err)) > 0) | |
46 | 102 | size += res; |
103 | + } else { | |
104 | + spl_parse_image_header((struct image_header *)buf); | |
105 | + addr = spl_image.load_addr; | |
106 | + memcpy((void *)addr, buf, res); | |
107 | + size += res; | |
108 | + addr += res; | |
109 | + | |
110 | + while ((res = xyzModem_stream_read(buf, BUF_SIZE, &err)) > 0) { | |
111 | + memcpy((void *)addr, buf, res); | |
112 | + size += res; | |
47 | 113 | addr += res; |
48 | - memcpy((char *)(store_addr), buf, res); | |
49 | 114 | } |
50 | - } else { | |
51 | - printf("spl: ymodem err - %s\n", xyzModem_error(err)); | |
52 | - return ret; | |
53 | 115 | } |
54 | 116 | |
117 | +end_stream: | |
55 | 118 | xyzModem_stream_close(&err); |
56 | 119 | xyzModem_stream_terminate(false, &getcymodem); |
57 | 120 |