[PATCH 1/2] imx: spl_imx_romapi: avoid tricky use of spl_load_simple_fit() to get full FIT size

Rasmus Villemoes rasmus.villemoes at prevas.dk
Tue May 23 13:36:50 CEST 2023


Currently, spl_imx_romapi uses a somewhat tricky workaround for the
fact that a FIT image with external data doesn't directly allow one to
know the full size of the file: It does a dummy spl_load_simple_fit(),
having the ->read callback remember the largest offset requested, and
then does a last call to rom_api_download_image() to fetch the
remaining part of the full FIT image.

We can avoid that by just keeping track of how much we have downloaded
already, and if the ->read() requests something outside the current
valid buffer, fetch up to the end of the current request.

The current method also suffers from not working when CONFIG_IMX_HAB
is enabled, because the first call of spl_load_simple_fit() will have
written garbage to the various locations, so the
board_spl_fit_post_load() call panics. The downstream NXP kernel
carries a workaround for this, but that workaround should not be
necessary with this, since we only ever memcpy() valid image data.

This only affects the CONFIG_SPL_LOAD_FIT case - I don't have any
hardware or experience with the CONFIG_SPL_LOAD_IMX_CONTAINER case, so
I leave that alone for now.

Signed-off-by: Rasmus Villemoes <rasmus.villemoes at prevas.dk>
---
 arch/arm/mach-imx/spl_imx_romapi.c | 50 ++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/arch/arm/mach-imx/spl_imx_romapi.c b/arch/arm/mach-imx/spl_imx_romapi.c
index 830d5d12c2..e4e2297ac0 100644
--- a/arch/arm/mach-imx/spl_imx_romapi.c
+++ b/arch/arm/mach-imx/spl_imx_romapi.c
@@ -126,6 +126,41 @@ static int spl_romapi_load_image_seekable(struct spl_image_info *spl_image,
 	return 0;
 }
 
+struct stream_state {
+	u8 *base;
+	u8 *end;
+	u32 pagesize;
+};
+
+static ulong spl_romapi_read_stream(struct spl_load_info *load, ulong sector,
+			       ulong count, void *buf)
+{
+	struct stream_state *ss = load->priv;
+	u8 *end = (u8*)(sector + count);
+	u32 bytes;
+	int ret;
+
+	if (end > ss->end) {
+		bytes = end - ss->end;
+		bytes += ss->pagesize - 1;
+		bytes /= ss->pagesize;
+		bytes *= ss->pagesize;
+
+		debug("downloading another 0x%x bytes\n", bytes);
+		ret = rom_api_download_image(ss->end, 0, bytes);
+
+		if (ret != ROM_API_OKAY) {
+			printf("Failure download %d\n", bytes);
+			return 0;
+		}
+
+		ss->end = end;
+	}
+
+	memcpy(buf, (void *)(sector), count);
+	return count;
+}
+
 static ulong spl_ram_load_read(struct spl_load_info *load, ulong sector,
 			       ulong count, void *buf)
 {
@@ -309,6 +344,21 @@ static int spl_romapi_load_image_stream(struct spl_image_info *spl_image,
 		}
 	}
 
+	if (IS_ENABLED(CONFIG_SPL_LOAD_FIT)) {
+		struct stream_state ss;
+
+		ss.base = phdr;
+		ss.end = p;
+		ss.pagesize = pagesize;
+
+		memset(&load, 0, sizeof(load));
+		load.bl_len = 1;
+		load.read = spl_romapi_read_stream;
+		load.priv = &ss;
+
+		return spl_load_simple_fit(spl_image, &load, (ulong)phdr, phdr);
+	}
+
 	total = img_total_size(phdr);
 	total += 3;
 	total &= ~0x3;
-- 
2.37.2



More information about the U-Boot mailing list