[PATCH 29/41] imx: spl_imx_romapi: Workaround loading to OCRAM ECC region

Peng Fan (OSS) peng.fan at oss.nxp.com
Mon Jan 23 10:16:48 CET 2023


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

ROM API has a limitation that ROM valid access range does not
include the OCRAM ECC 64KB on i.MX8MP.
When loading image from nand, the spl_load_fit_image will handle
the page unaligned access. In worst case, it requires to read to
more 2 pages. For ATF on iMX8MP, it default address is 0x970000,
so it is highly possible to read data into OCRAM ECC region after
adding more 2 pages.

To handle the case, we use a temp buffer to replace the OCRAM ECC
region for ROM API. Then copy to OCRAM ECC region.

Signed-off-by: Ye Li <ye.li at nxp.com>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 arch/arm/mach-imx/spl_imx_romapi.c | 37 ++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/arch/arm/mach-imx/spl_imx_romapi.c b/arch/arm/mach-imx/spl_imx_romapi.c
index aa5d23a6fbe..4480d3c7115 100644
--- a/arch/arm/mach-imx/spl_imx_romapi.c
+++ b/arch/arm/mach-imx/spl_imx_romapi.c
@@ -12,6 +12,8 @@
 #include <spl.h>
 #include <asm/mach-imx/image.h>
 #include <asm/arch/sys_proto.h>
+#include <asm/cache.h>
+#include <malloc.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -62,6 +64,41 @@ static ulong spl_romapi_read_seekable(struct spl_load_info *load,
 
 	offset = sector * pagesize;
 
+	/* Corner case for ocram [0x980000:0x98ffff] ecc region, ROM does not allow to access it */
+	if (is_imx8mp()) {
+		ulong ret;
+		void *new_buf;
+
+		if (((ulong)buf >= 0x980000 && (ulong)buf <= 0x98ffff)) {
+			new_buf = memalign(ARCH_DMA_MINALIGN, byte);
+			if (!new_buf) {
+				printf("Fail to allocate read buffer\n");
+				return 0;
+			}
+			ret = spl_romapi_raw_seekable_read(offset, byte, new_buf);
+			memcpy(buf, new_buf, ret);
+			free(new_buf);
+			return ret / pagesize;
+		} else if ((ulong)(buf + byte) >= 0x980000 && (ulong)(buf + byte) <= 0x98ffff) {
+			u32 over_size = (ulong)(buf + byte) - 0x97ffff;
+
+			over_size = (over_size + pagesize - 1) / pagesize * pagesize;
+
+			ret = spl_romapi_raw_seekable_read(offset, byte - over_size, buf);
+			new_buf = memalign(ARCH_DMA_MINALIGN, over_size);
+			if (!new_buf) {
+				printf("Fail to allocate read buffer\n");
+				return 0;
+			}
+
+			ret += spl_romapi_raw_seekable_read(offset + byte - over_size,
+							    over_size, new_buf);
+			memcpy(buf + byte - over_size, new_buf, ret);
+			free(new_buf);
+			return ret / pagesize;
+		}
+	}
+
 	return spl_romapi_raw_seekable_read(offset, byte, buf) / pagesize;
 }
 
-- 
2.36.0



More information about the U-Boot mailing list