[U-Boot] [PATCH 0/3] spl: fit: Allow to load FIT using UART boot

This series allows to load a FIT image using UART boot mode.
Tested: BBB: http://pastebin.ubuntu.com/16505294/
Lokesh Vutla (3): spl: fit: Do not print selected dtb during fit load spl: fit: Detect a FS load using filename spl: Add an option to load a FIT containing U-Boot from UART
common/spl/spl_fat.c | 4 +-- common/spl/spl_fit.c | 10 +++--- common/spl/spl_ymodem.c | 91 +++++++++++++++++++++++++++++++++++++++++++------ include/spl.h | 2 ++ 4 files changed, 88 insertions(+), 19 deletions(-)

Uart boot is failing when a printf is called while loading image. So, disable prints while loading FIT image.
Signed-off-by: Lokesh Vutla lokeshvutla@ti.com --- common/spl/spl_fit.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c index ace2543..a0ea44c 100644 --- a/common/spl/spl_fit.c +++ b/common/spl/spl_fit.c @@ -62,9 +62,7 @@ static int spl_fit_select_fdt(const void *fdt, int images, int *fdt_offsetp)
*fdt_offsetp = fdt_getprop_u32(fdt, fdt_node, "data-offset"); len = fdt_getprop_u32(fdt, fdt_node, "data-size"); -#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT - printf("FIT: Selected '%s'\n", name); -#endif + debug("FIT: Selected '%s'\n", name);
return len; }

On Thu, May 19, 2016 at 03:57:55PM +0530, Lokesh Vutla wrote:
Uart boot is failing when a printf is called while loading image. So, disable prints while loading FIT image.
Signed-off-by: Lokesh Vutla lokeshvutla@ti.com
Reviewed-by: Tom Rini trini@konsulko.com

Right now a FS load for fit is being detected using the priv field. But this can be used by others media. So, introduce a filename field to detect a FS load.
Signed-off-by: Lokesh Vutla lokeshvutla@ti.com --- common/spl/spl_fat.c | 4 ++-- common/spl/spl_fit.c | 6 +++--- include/spl.h | 2 ++ 3 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/common/spl/spl_fat.c b/common/spl/spl_fat.c index cdb9811..9df2fc2 100644 --- a/common/spl/spl_fat.c +++ b/common/spl/spl_fat.c @@ -45,7 +45,7 @@ static ulong spl_fit_read(struct spl_load_info *load, ulong file_offset, { loff_t actread; int ret; - char *filename = (char *)load->priv; + const char *filename = load->filename;
ret = fat_read_file(filename, buf, file_offset, size, &actread); if (ret) @@ -79,7 +79,7 @@ int spl_load_image_fat(struct blk_desc *block_dev, debug("Found FIT\n"); load.read = spl_fit_read; load.bl_len = 1; - load.priv = (void *)filename; + load.filename = filename;
return spl_load_simple_fit(&load, 0, header); } else { diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c index a0ea44c..78ce15f 100644 --- a/common/spl/spl_fit.c +++ b/common/spl/spl_fit.c @@ -87,7 +87,7 @@ static int get_aligned_image_offset(struct spl_load_info *info, int offset) * aligned to ARCH_DMA_MINALIGN. If it is raw read return the * block number to which offset belongs. */ - if (info->priv) + if (info->filename) return offset & ~(ARCH_DMA_MINALIGN - 1);
return offset / info->bl_len; @@ -101,7 +101,7 @@ static int get_aligned_image_overhead(struct spl_load_info *info, int offset) * ARCH_DMA_MINALIGN. If it is raw read return the offset within the * block. */ - if (info->priv) + if (info->filename) return offset & (ARCH_DMA_MINALIGN - 1);
return offset % info->bl_len; @@ -110,7 +110,7 @@ static int get_aligned_image_overhead(struct spl_load_info *info, int offset) static int get_aligned_image_size(struct spl_load_info *info, int data_size, int offset) { - if (info->priv) + if (info->filename) return data_size + get_aligned_image_overhead(info, offset);
return (data_size + info->bl_len - 1) / info->bl_len; diff --git a/include/spl.h b/include/spl.h index 358e81b..af02a6d 100644 --- a/include/spl.h +++ b/include/spl.h @@ -35,12 +35,14 @@ struct spl_image_info { * @dev: Pointer to the device, e.g. struct mmc * * @priv: Private data for the device * @bl_len: Block length for reading in bytes + * @filename: Name of the fit image file. * @read: Function to call to read from the device */ struct spl_load_info { void *dev; void *priv; int bl_len; + const char *filename; ulong (*read)(struct spl_load_info *load, ulong sector, ulong count, void *buf); };

On Thu, May 19, 2016 at 03:57:56PM +0530, Lokesh Vutla wrote:
Right now a FS load for fit is being detected using the priv field. But this can be used by others media. So, introduce a filename field to detect a FS load.
Signed-off-by: Lokesh Vutla lokeshvutla@ti.com
Reviewed-by: Tom Rini trini@konsulko.com

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 --- common/spl/spl_ymodem.c | 91 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 80 insertions(+), 11 deletions(-)
diff --git a/common/spl/spl_ymodem.c b/common/spl/spl_ymodem.c index 380d8dd..d7f8c92 100644 --- a/common/spl/spl_ymodem.c +++ b/common/spl/spl_ymodem.c @@ -14,15 +14,60 @@ #include <xyzModem.h> #include <asm/u-boot.h> #include <asm/utils.h> +#include <libfdt.h>
#define BUF_SIZE 1024
+/* + * Information required to load image using ymodem. + * + * @image_read: Now of bytes read from the image. + * @buf: pointer to the previous read block. + */ +struct ymodem_fit_info { + int image_read; + char *buf; +}; + static int getcymodem(void) { if (tstc()) return (getc()); return -1; }
+static ulong ymodem_read_fit(struct spl_load_info *load, ulong offset, + ulong size, void *addr) +{ + int res, err; + struct ymodem_fit_info *info = load->priv; + char *buf = info->buf; + + while (info->image_read < offset) { + res = xyzModem_stream_read(buf, BUF_SIZE, &err); + if (res <= 0) + return res; + info->image_read += res; + } + + if (info->image_read > offset) { + res = info->image_read - offset; + memcpy(addr, &buf[BUF_SIZE - res], res); + addr = addr + res; + } + + while (info->image_read < offset + size) { + res = xyzModem_stream_read(buf, BUF_SIZE, &err); + if (res <= 0) + return res; + + memcpy(addr, buf, res); + info->image_read += res; + addr += res; + } + + return size; +} + int spl_ymodem_load_image(void) { int size = 0; @@ -31,27 +76,51 @@ int spl_ymodem_load_image(void) int ret; connection_info_t info; char buf[BUF_SIZE]; - ulong store_addr = ~0; ulong addr = 0;
info.mode = xyzModem_ymodem; ret = xyzModem_stream_open(&info, &err); + if (ret) { + printf("spl: ymodem err - %s\n", xyzModem_error(err)); + return ret; + } + + res = xyzModem_stream_read(buf, BUF_SIZE, &err); + if (res <= 0) + goto end_stream; + + if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && + image_get_magic((struct image_header *)buf) == FDT_MAGIC) { + struct spl_load_info load; + struct ymodem_fit_info info; + + debug("Found FIT\n"); + load.dev = NULL; + load.priv = (void *)&info; + load.bl_len = 1; + info.buf = buf; + info.image_read = BUF_SIZE; + load.read = ymodem_read_fit; + ret = spl_load_simple_fit(&load, 0, (void *)buf); + size = info.image_read;
- if (!ret) { - while ((res = - xyzModem_stream_read(buf, BUF_SIZE, &err)) > 0) { - if (addr == 0) - spl_parse_image_header((struct image_header *)buf); - store_addr = addr + spl_image.load_addr; + while ((res = xyzModem_stream_read(buf, BUF_SIZE, &err)) > 0) + size += res; + } else { + spl_parse_image_header((struct image_header *)buf); + addr = spl_image.load_addr; + memcpy((void *)addr, buf, res); + size += res; + addr += res; + + while ((res = xyzModem_stream_read(buf, BUF_SIZE, &err)) > 0) { + memcpy((void *)addr, buf, res); size += res; addr += res; - memcpy((char *)(store_addr), buf, res); } - } else { - printf("spl: ymodem err - %s\n", xyzModem_error(err)); - return ret; }
+end_stream: xyzModem_stream_close(&err); xyzModem_stream_terminate(false, &getcymodem);

On Thu, May 19, 2016 at 03:57:57PM +0530, Lokesh Vutla wrote:
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
Reviewed-by: Tom Rini trini@konsulko.com
participants (2)
-
Lokesh Vutla
-
Tom Rini