[PATCH 17/17] imx: Fix ROMAPI driver to load container image

Alice Guo alice.guo at oss.nxp.com
Wed Oct 16 09:18:10 CEST 2024


From: Ye Li <ye.li at nxp.com>

When using ROM API, the size and offset must be aligned with page size.
However when loading container image, the rule is not followed for
container header. It is ok for eMMC/SD/flexspinor, but fails for
flexspi NAND which page size is 4K.

Fix the issue by providing spl_romapi_read API to handle the unaligned
read and around container header size to page size

Signed-off-by: Ye Li <ye.li at nxp.com>
Signed-off-by: Alice Guo <alice.guo at nxp.com>
Reviewed-by: Peng Fan <peng.fan at nxp.com>
---
 arch/arm/include/asm/mach-imx/sys_proto.h |  4 +--
 arch/arm/mach-imx/image-container.c       |  5 ++--
 arch/arm/mach-imx/spl_imx_romapi.c        | 47 +++++++++++++++++++++++++++++--
 3 files changed, 49 insertions(+), 7 deletions(-)

diff --git a/arch/arm/include/asm/mach-imx/sys_proto.h b/arch/arm/include/asm/mach-imx/sys_proto.h
index 878a4821996392e36d9bb02613276e502f463eef..076ff41652315d2d8276424843862ef30008b3ad 100644
--- a/arch/arm/include/asm/mach-imx/sys_proto.h
+++ b/arch/arm/include/asm/mach-imx/sys_proto.h
@@ -207,8 +207,8 @@ enum boot_stage_type {
 extern struct rom_api *g_rom_api;
 extern unsigned long rom_pointer[];
 
-ulong spl_romapi_raw_seekable_read(u32 offset, u32 size, void *buf);
-ulong spl_romapi_get_uboot_base(u32 image_offset, u32 rom_bt_dev);
+ulong spl_romapi_read(u32 offset, u32 size, void *buf);
+ulong spl_romapi_get_uboot_base(u32 image_offset, u32 rom_bt_dev, u32 pagesize);
 
 u32 rom_api_download_image(u8 *dest, u32 offset, u32 size);
 u32 rom_api_query_boot_infor(u32 info_type, u32 *info);
diff --git a/arch/arm/mach-imx/image-container.c b/arch/arm/mach-imx/image-container.c
index 27dc162f2517b6d75b0ed95510c09385f7cbc859..73dd8fb2f2bf1523032bdf17da2e347598403527 100644
--- a/arch/arm/mach-imx/image-container.c
+++ b/arch/arm/mach-imx/image-container.c
@@ -141,7 +141,7 @@ static int get_dev_container_size(void *dev, int dev_type, unsigned long offset,
 
 #ifdef CONFIG_SPL_BOOTROM_SUPPORT
 	if (dev_type == ROM_API_DEV) {
-		ret = spl_romapi_raw_seekable_read(offset, CONTAINER_HDR_ALIGNMENT, buf);
+		ret = spl_romapi_read(offset, CONTAINER_HDR_ALIGNMENT, buf);
 		if (!ret) {
 			printf("Read container image from ROM API failed\n");
 			return -EIO;
@@ -376,7 +376,7 @@ u32 __weak spl_arch_boot_image_offset(u32 image_offset, u32 rom_bt_dev)
 	return image_offset;
 }
 
-ulong spl_romapi_get_uboot_base(u32 image_offset, u32 rom_bt_dev)
+ulong spl_romapi_get_uboot_base(u32 image_offset, u32 rom_bt_dev, u32 pagesize)
 {
 	ulong end;
 
@@ -384,6 +384,7 @@ ulong spl_romapi_get_uboot_base(u32 image_offset, u32 rom_bt_dev)
 
 	end = get_imageset_end((void *)(ulong)image_offset, ROM_API_DEV);
 	end = ROUND(end, SZ_1K);
+	end = ROUND(end, pagesize);
 
 	printf("Load image from 0x%lx by ROM_API\n", end);
 
diff --git a/arch/arm/mach-imx/spl_imx_romapi.c b/arch/arm/mach-imx/spl_imx_romapi.c
index 3982f4cca184716f0000a28767c14a57567ed54d..6a5d66a8e157b6030318211d4ca04b799ceb2527 100644
--- a/arch/arm/mach-imx/spl_imx_romapi.c
+++ b/arch/arm/mach-imx/spl_imx_romapi.c
@@ -14,8 +14,10 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+u32 rom_dev_page_size;
+
 /* Caller need ensure the offset and size to align with page size */
-ulong spl_romapi_raw_seekable_read(u32 offset, u32 size, void *buf)
+static ulong spl_romapi_raw_seekable_read(u32 offset, u32 size, void *buf)
 {
 	int ret;
 
@@ -31,7 +33,46 @@ ulong spl_romapi_raw_seekable_read(u32 offset, u32 size, void *buf)
 	return 0;
 }
 
-ulong __weak spl_romapi_get_uboot_base(u32 image_offset, u32 rom_bt_dev)
+ulong spl_romapi_read(u32 offset, u32 size, void *buf)
+{
+	u32 off_in_page, aligned_size, readsize;
+	int ret;
+	u8 *tmp;
+
+	if (!rom_dev_page_size) {
+		ret = rom_api_query_boot_infor(QUERY_PAGE_SZ, &rom_dev_page_size);
+		if (ret != ROM_API_OKAY) {
+			puts("ROMAPI: Failure query boot infor pagesize/offset\n");
+			return 0;
+		}
+	}
+
+	off_in_page = offset % rom_dev_page_size;
+	aligned_size = ALIGN(size + off_in_page, rom_dev_page_size);
+
+	if (aligned_size != size) {
+		tmp = malloc(aligned_size);
+		if (!tmp) {
+			printf("%s: Failed to malloc %u bytes\n", __func__, aligned_size);
+			return 0;
+		}
+
+		readsize = spl_romapi_raw_seekable_read(offset - off_in_page, aligned_size, tmp);
+		if (readsize != aligned_size) {
+			printf("%s: Failed read %u, actual %u\n", __func__, aligned_size, readsize);
+			free(tmp);
+			return 0;
+		}
+
+		memcpy(buf, tmp + off_in_page, size);
+		free(tmp);
+		return size;
+	}
+
+	return spl_romapi_raw_seekable_read(offset, size, buf);
+}
+
+ulong __weak spl_romapi_get_uboot_base(u32 image_offset, u32 rom_bt_dev, u32 pagesize)
 {
 	u32 sector = 0;
 
@@ -94,7 +135,7 @@ static int spl_romapi_load_image_seekable(struct spl_image_info *spl_image,
 	printf("image offset 0x%x, pagesize 0x%x, ivt offset 0x%x\n",
 	       image_offset, pagesize, offset);
 
-	offset = spl_romapi_get_uboot_base(image_offset, rom_bt_dev);
+	offset = spl_romapi_get_uboot_base(image_offset, rom_bt_dev, pagesize);
 
 	size = ALIGN(sizeof(struct legacy_img_hdr), pagesize);
 	ret = rom_api_download_image((u8 *)header, offset, size);

-- 
2.34.1



More information about the U-Boot mailing list