From: Ye Li <ye...@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...@nxp.com> Signed-off-by: Peng Fan <peng....@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