Commit c165945d193be510337de656f6564ad0f6ab35a4

Authored by Lokesh Vutla
1 parent 37846d2c90

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