summaryrefslogtreecommitdiff
path: root/arch/arm
diff options
context:
space:
mode:
authorYe Li <ye.li@nxp.com>2022-03-24 22:43:50 +0800
committerYe Li <ye.li@nxp.com>2022-04-06 18:06:15 +0800
commit9919053323be235a69520b8763e7e6ccf8b8d15f (patch)
tree7b635c1463fd4a209675e3a8d5c08b785435a41a /arch/arm
parentf0cc8bc2fab54ff1aa7b48c241c8e96042d8ad92 (diff)
LFU-278-18 imx: spl_imx_romapi: Workaround loading to OCRAM ECC region
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@nxp.com>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-imx/spl_imx_romapi.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/arch/arm/mach-imx/spl_imx_romapi.c b/arch/arm/mach-imx/spl_imx_romapi.c
index 4df9205af8..ff4a87132b 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;
@@ -72,6 +74,38 @@ static ulong spl_romapi_read_seekable(struct spl_load_info *load,
offset = sector * pagesize;
+ /* Handle corner case for ocram 0x980000 to 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;
}