diff mbox

[U-Boot,v4,04/20] SPL: FIT: factor out spl_load_fit_image()

Message ID 1493166772-24598-5-git-send-email-andre.przywara@arm.com
State Accepted
Commit 8baa381882e8b5e8684b331f09b04e2e2784fb0d
Delegated to: Jagannadha Sutradharudu Teki
Headers show

Commit Message

Andre Przywara April 26, 2017, 12:32 a.m. UTC
At the moment we load two images from a FIT image: the actual U-Boot
image and the .dtb file. Both times we have very similar code, that deals
with alignment requirements the media we load from imposes upon us.
Factor out this code into a new function, which we just call twice.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
---
 common/spl/spl_fit.c | 162 +++++++++++++++++++++++++--------------------------
 1 file changed, 80 insertions(+), 82 deletions(-)

Comments

Heiko Stuebner May 5, 2017, 3:40 p.m. UTC | #1
Am Mittwoch, 26. April 2017, 01:32:36 CEST schrieb Andre Przywara:
> At the moment we load two images from a FIT image: the actual U-Boot
> image and the .dtb file. Both times we have very similar code, that deals
> with alignment requirements the media we load from imposes upon us.
> Factor out this code into a new function, which we just call twice.
> 
> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
> Reviewed-by: Simon Glass <sjg@chromium.org>

On a rk3399-firefly
Tested-by: Heiko Stuebner <heiko@sntech.de>
Kever Yang May 16, 2017, 1:36 a.m. UTC | #2
On 04/26/2017 08:32 AM, Andre Przywara wrote:
> At the moment we load two images from a FIT image: the actual U-Boot
> image and the .dtb file. Both times we have very similar code, that deals
> with alignment requirements the media we load from imposes upon us.
> Factor out this code into a new function, which we just call twice.
>
> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
> Reviewed-by: Simon Glass <sjg@chromium.org>

Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
Tested-by: Kever Yang <kever.yang@rock-chips.com>

Thanks,
- Kever
> ---
>   common/spl/spl_fit.c | 162 +++++++++++++++++++++++++--------------------------
>   1 file changed, 80 insertions(+), 82 deletions(-)
>
> diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c
> index ecd42d8..9d9338c 100644
> --- a/common/spl/spl_fit.c
> +++ b/common/spl/spl_fit.c
> @@ -159,19 +159,81 @@ static int get_aligned_image_size(struct spl_load_info *info, int data_size,
>   	return (data_size + info->bl_len - 1) / info->bl_len;
>   }
>   
> +/**
> + * spl_load_fit_image(): load the image described in a certain FIT node
> + * @info:	points to information about the device to load data from
> + * @sector:	the start sector of the FIT image on the device
> + * @fit:	points to the flattened device tree blob describing the FIT
> + * 		image
> + * @base_offset: the beginning of the data area containing the actual
> + *		image data, relative to the beginning of the FIT
> + * @node:	offset of the DT node describing the image to load (relative
> + * 		to @fit)
> + * @image_info:	will be filled with information about the loaded image
> + * 		If the FIT node does not contain a "load" (address) property,
> + * 		the image gets loaded to the address pointed to by the
> + * 		load_addr member in this struct.
> + *
> + * Return:	0 on success or a negative error number.
> + */
> +static int spl_load_fit_image(struct spl_load_info *info, ulong sector,
> +			      void *fit, ulong base_offset, int node,
> +			      struct spl_image_info *image_info)
> +{
> +	ulong offset;
> +	size_t length;
> +	ulong load_addr, load_ptr;
> +	void *src;
> +	ulong overhead;
> +	int nr_sectors;
> +	int align_len = ARCH_DMA_MINALIGN - 1;
> +
> +	offset = fdt_getprop_u32(fit, node, "data-offset");
> +	if (offset == FDT_ERROR)
> +		return -ENOENT;
> +	offset += base_offset;
> +	length = fdt_getprop_u32(fit, node, "data-size");
> +	if (length == FDT_ERROR)
> +		return -ENOENT;
> +	load_addr = fdt_getprop_u32(fit, node, "load");
> +	if (load_addr == FDT_ERROR && image_info)
> +		load_addr = image_info->load_addr;
> +	load_ptr = (load_addr + align_len) & ~align_len;
> +
> +	overhead = get_aligned_image_overhead(info, offset);
> +	nr_sectors = get_aligned_image_size(info, length, offset);
> +
> +	if (info->read(info, sector + get_aligned_image_offset(info, offset),
> +		       nr_sectors, (void*)load_ptr) != nr_sectors)
> +		return -EIO;
> +	debug("image: dst=%lx, offset=%lx, size=%lx\n", load_ptr, offset,
> +	      (unsigned long)length);
> +
> +	src = (void *)load_ptr + overhead;
> +#ifdef CONFIG_SPL_FIT_IMAGE_POST_PROCESS
> +	board_fit_image_post_process(&src, &length);
> +#endif
> +
> +	memcpy((void*)load_addr, src, length);
> +
> +	if (image_info) {
> +		image_info->load_addr = load_addr;
> +		image_info->size = length;
> +		image_info->entry_point = fdt_getprop_u32(fit, node, "entry");
> +	}
> +
> +	return 0;
> +}
> +
>   int spl_load_simple_fit(struct spl_image_info *spl_image,
>   			struct spl_load_info *info, ulong sector, void *fit)
>   {
>   	int sectors;
> -	ulong size, load;
> +	ulong size;
>   	unsigned long count;
> -	int node, images;
> -	void *load_ptr;
> -	int fdt_offset, fdt_len;
> -	int data_offset, data_size;
> +	struct spl_image_info image_info;
> +	int node, images, ret;
>   	int base_offset, align_len = ARCH_DMA_MINALIGN - 1;
> -	int src_sector;
> -	void *dst, *src;
>   
>   	/*
>   	 * Figure out where the external images start. This is the base for the
> @@ -223,46 +285,13 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,
>   		return -1;
>   	}
>   
> -	/* Get its information and set up the spl_image structure */
> -	data_offset = fdt_getprop_u32(fit, node, "data-offset");
> -	if (data_offset == FDT_ERROR)
> -		return -ENOENT;
> -	data_size = fdt_getprop_u32(fit, node, "data-size");
> -	if (data_size == FDT_ERROR)
> -		return -ENOENT;
> -	load = fdt_getprop_u32(fit, node, "load");
> -	debug("data_offset=%x, data_size=%x\n", data_offset, data_size);
> -	spl_image->load_addr = load;
> -	spl_image->entry_point = load;
> -	spl_image->os = IH_OS_U_BOOT;
> -
> -	/*
> -	 * Work out where to place the image. We read it so that the first
> -	 * byte will be at 'load'. This may mean we need to load it starting
> -	 * before then, since we can only read whole blocks.
> -	 */
> -	data_offset += base_offset;
> -	sectors = get_aligned_image_size(info, data_size, data_offset);
> -	load_ptr = (void *)load;
> -	debug("U-Boot size %x, data %p\n", data_size, load_ptr);
> -	dst = load_ptr;
> -
> -	/* Read the image */
> -	src_sector = sector + get_aligned_image_offset(info, data_offset);
> -	debug("Aligned image read: dst=%p, src_sector=%x, sectors=%x\n",
> -	      dst, src_sector, sectors);
> -	count = info->read(info, src_sector, sectors, dst);
> -	if (count != sectors)
> -		return -EIO;
> -	debug("image: dst=%p, data_offset=%x, size=%x\n", dst, data_offset,
> -	      data_size);
> -	src = dst + get_aligned_image_overhead(info, data_offset);
> +	/* Load the image and set up the spl_image structure */
> +	ret = spl_load_fit_image(info, sector, fit, base_offset, node,
> +				 spl_image);
> +	if (ret)
> +		return ret;
>   
> -#ifdef CONFIG_SPL_FIT_IMAGE_POST_PROCESS
> -	board_fit_image_post_process((void **)&src, (size_t *)&data_size);
> -#endif
> -
> -	memcpy(dst, src, data_size);
> +	spl_image->os = IH_OS_U_BOOT;
>   
>   	/* Figure out which device tree the board wants to use */
>   	node = spl_fit_get_image_node(fit, images, FIT_FDT_PROP, 0);
> @@ -270,43 +299,12 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,
>   		debug("%s: cannot find FDT node\n", __func__);
>   		return node;
>   	}
> -	fdt_offset = fdt_getprop_u32(fit, node, "data-offset");
> -	fdt_len = fdt_getprop_u32(fit, node, "data-size");
> -	if (fdt_offset == FDT_ERROR || fdt_len == FDT_ERROR) {
> -		debug("%s: cannot load FDT data\n" __func__);
> -		return -ENOENT;
> -	}
>   
>   	/*
> -	 * Read the device tree and place it after the image. There may be
> -	 * some extra data before it since we can only read entire blocks.
> -	 * And also align the destination address to ARCH_DMA_MINALIGN.
> +	 * Read the device tree and place it after the image.
> +	 * Align the destination address to ARCH_DMA_MINALIGN.
>   	 */
> -	dst = (void *)((load + data_size + align_len) & ~align_len);
> -	fdt_offset += base_offset;
> -	sectors = get_aligned_image_size(info, fdt_len, fdt_offset);
> -	src_sector = sector + get_aligned_image_offset(info, fdt_offset);
> -	count = info->read(info, src_sector, sectors, dst);
> -	debug("Aligned fdt read: dst %p, src_sector = %x, sectors %x\n",
> -	      dst, src_sector, sectors);
> -	if (count != sectors)
> -		return -EIO;
> -
> -	/*
> -	 * Copy the device tree so that it starts immediately after the image.
> -	 * After this we will have the U-Boot image and its device tree ready
> -	 * for us to start.
> -	 */
> -	debug("fdt: dst=%p, data_offset=%x, size=%x\n", dst, fdt_offset,
> -	      fdt_len);
> -	src = dst + get_aligned_image_overhead(info, fdt_offset);
> -	dst = load_ptr + data_size;
> -
> -#ifdef CONFIG_SPL_FIT_IMAGE_POST_PROCESS
> -	board_fit_image_post_process((void **)&src, (size_t *)&fdt_len);
> -#endif
> -
> -	memcpy(dst, src, fdt_len);
> -
> -	return 0;
> +	image_info.load_addr = spl_image->load_addr + spl_image->size;
> +	return spl_load_fit_image(info, sector, fit, base_offset, node,
> +				  &image_info);
>   }
diff mbox

Patch

diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c
index ecd42d8..9d9338c 100644
--- a/common/spl/spl_fit.c
+++ b/common/spl/spl_fit.c
@@ -159,19 +159,81 @@  static int get_aligned_image_size(struct spl_load_info *info, int data_size,
 	return (data_size + info->bl_len - 1) / info->bl_len;
 }
 
+/**
+ * spl_load_fit_image(): load the image described in a certain FIT node
+ * @info:	points to information about the device to load data from
+ * @sector:	the start sector of the FIT image on the device
+ * @fit:	points to the flattened device tree blob describing the FIT
+ * 		image
+ * @base_offset: the beginning of the data area containing the actual
+ *		image data, relative to the beginning of the FIT
+ * @node:	offset of the DT node describing the image to load (relative
+ * 		to @fit)
+ * @image_info:	will be filled with information about the loaded image
+ * 		If the FIT node does not contain a "load" (address) property,
+ * 		the image gets loaded to the address pointed to by the
+ * 		load_addr member in this struct.
+ *
+ * Return:	0 on success or a negative error number.
+ */
+static int spl_load_fit_image(struct spl_load_info *info, ulong sector,
+			      void *fit, ulong base_offset, int node,
+			      struct spl_image_info *image_info)
+{
+	ulong offset;
+	size_t length;
+	ulong load_addr, load_ptr;
+	void *src;
+	ulong overhead;
+	int nr_sectors;
+	int align_len = ARCH_DMA_MINALIGN - 1;
+
+	offset = fdt_getprop_u32(fit, node, "data-offset");
+	if (offset == FDT_ERROR)
+		return -ENOENT;
+	offset += base_offset;
+	length = fdt_getprop_u32(fit, node, "data-size");
+	if (length == FDT_ERROR)
+		return -ENOENT;
+	load_addr = fdt_getprop_u32(fit, node, "load");
+	if (load_addr == FDT_ERROR && image_info)
+		load_addr = image_info->load_addr;
+	load_ptr = (load_addr + align_len) & ~align_len;
+
+	overhead = get_aligned_image_overhead(info, offset);
+	nr_sectors = get_aligned_image_size(info, length, offset);
+
+	if (info->read(info, sector + get_aligned_image_offset(info, offset),
+		       nr_sectors, (void*)load_ptr) != nr_sectors)
+		return -EIO;
+	debug("image: dst=%lx, offset=%lx, size=%lx\n", load_ptr, offset,
+	      (unsigned long)length);
+
+	src = (void *)load_ptr + overhead;
+#ifdef CONFIG_SPL_FIT_IMAGE_POST_PROCESS
+	board_fit_image_post_process(&src, &length);
+#endif
+
+	memcpy((void*)load_addr, src, length);
+
+	if (image_info) {
+		image_info->load_addr = load_addr;
+		image_info->size = length;
+		image_info->entry_point = fdt_getprop_u32(fit, node, "entry");
+	}
+
+	return 0;
+}
+
 int spl_load_simple_fit(struct spl_image_info *spl_image,
 			struct spl_load_info *info, ulong sector, void *fit)
 {
 	int sectors;
-	ulong size, load;
+	ulong size;
 	unsigned long count;
-	int node, images;
-	void *load_ptr;
-	int fdt_offset, fdt_len;
-	int data_offset, data_size;
+	struct spl_image_info image_info;
+	int node, images, ret;
 	int base_offset, align_len = ARCH_DMA_MINALIGN - 1;
-	int src_sector;
-	void *dst, *src;
 
 	/*
 	 * Figure out where the external images start. This is the base for the
@@ -223,46 +285,13 @@  int spl_load_simple_fit(struct spl_image_info *spl_image,
 		return -1;
 	}
 
-	/* Get its information and set up the spl_image structure */
-	data_offset = fdt_getprop_u32(fit, node, "data-offset");
-	if (data_offset == FDT_ERROR)
-		return -ENOENT;
-	data_size = fdt_getprop_u32(fit, node, "data-size");
-	if (data_size == FDT_ERROR)
-		return -ENOENT;
-	load = fdt_getprop_u32(fit, node, "load");
-	debug("data_offset=%x, data_size=%x\n", data_offset, data_size);
-	spl_image->load_addr = load;
-	spl_image->entry_point = load;
-	spl_image->os = IH_OS_U_BOOT;
-
-	/*
-	 * Work out where to place the image. We read it so that the first
-	 * byte will be at 'load'. This may mean we need to load it starting
-	 * before then, since we can only read whole blocks.
-	 */
-	data_offset += base_offset;
-	sectors = get_aligned_image_size(info, data_size, data_offset);
-	load_ptr = (void *)load;
-	debug("U-Boot size %x, data %p\n", data_size, load_ptr);
-	dst = load_ptr;
-
-	/* Read the image */
-	src_sector = sector + get_aligned_image_offset(info, data_offset);
-	debug("Aligned image read: dst=%p, src_sector=%x, sectors=%x\n",
-	      dst, src_sector, sectors);
-	count = info->read(info, src_sector, sectors, dst);
-	if (count != sectors)
-		return -EIO;
-	debug("image: dst=%p, data_offset=%x, size=%x\n", dst, data_offset,
-	      data_size);
-	src = dst + get_aligned_image_overhead(info, data_offset);
+	/* Load the image and set up the spl_image structure */
+	ret = spl_load_fit_image(info, sector, fit, base_offset, node,
+				 spl_image);
+	if (ret)
+		return ret;
 
-#ifdef CONFIG_SPL_FIT_IMAGE_POST_PROCESS
-	board_fit_image_post_process((void **)&src, (size_t *)&data_size);
-#endif
-
-	memcpy(dst, src, data_size);
+	spl_image->os = IH_OS_U_BOOT;
 
 	/* Figure out which device tree the board wants to use */
 	node = spl_fit_get_image_node(fit, images, FIT_FDT_PROP, 0);
@@ -270,43 +299,12 @@  int spl_load_simple_fit(struct spl_image_info *spl_image,
 		debug("%s: cannot find FDT node\n", __func__);
 		return node;
 	}
-	fdt_offset = fdt_getprop_u32(fit, node, "data-offset");
-	fdt_len = fdt_getprop_u32(fit, node, "data-size");
-	if (fdt_offset == FDT_ERROR || fdt_len == FDT_ERROR) {
-		debug("%s: cannot load FDT data\n" __func__);
-		return -ENOENT;
-	}
 
 	/*
-	 * Read the device tree and place it after the image. There may be
-	 * some extra data before it since we can only read entire blocks.
-	 * And also align the destination address to ARCH_DMA_MINALIGN.
+	 * Read the device tree and place it after the image.
+	 * Align the destination address to ARCH_DMA_MINALIGN.
 	 */
-	dst = (void *)((load + data_size + align_len) & ~align_len);
-	fdt_offset += base_offset;
-	sectors = get_aligned_image_size(info, fdt_len, fdt_offset);
-	src_sector = sector + get_aligned_image_offset(info, fdt_offset);
-	count = info->read(info, src_sector, sectors, dst);
-	debug("Aligned fdt read: dst %p, src_sector = %x, sectors %x\n",
-	      dst, src_sector, sectors);
-	if (count != sectors)
-		return -EIO;
-
-	/*
-	 * Copy the device tree so that it starts immediately after the image.
-	 * After this we will have the U-Boot image and its device tree ready
-	 * for us to start.
-	 */
-	debug("fdt: dst=%p, data_offset=%x, size=%x\n", dst, fdt_offset,
-	      fdt_len);
-	src = dst + get_aligned_image_overhead(info, fdt_offset);
-	dst = load_ptr + data_size;
-
-#ifdef CONFIG_SPL_FIT_IMAGE_POST_PROCESS
-	board_fit_image_post_process((void **)&src, (size_t *)&fdt_len);
-#endif
-
-	memcpy(dst, src, fdt_len);
-
-	return 0;
+	image_info.load_addr = spl_image->load_addr + spl_image->size;
+	return spl_load_fit_image(info, sector, fit, base_offset, node,
+				  &image_info);
 }