[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