From: Ye Li <ye...@nxp.com>

When SPL loading image to secure region, for example, ATF and tee to
DDR secure region. Because the USDHC controller is non-secure master,
it can't access this region and will cause loading issue.

So use a trampoline buffer in non-secure region, then use CPU to copy the
image from trampoline buffer to destination secure region.

Signed-off-by: Ye Li <ye...@nxp.com>
Signed-off-by: Alice Guo <alice....@nxp.com>
Reviewed-by: Peng Fan <peng....@nxp.com>
---
 arch/arm/mach-imx/imx9/scmi/soc.c | 18 +++++++++++++++++
 common/spl/Kconfig                |  6 ++++++
 common/spl/spl_imx_container.c    | 41 +++++++++++++++++++++++++++++++++------
 3 files changed, 59 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-imx/imx9/scmi/soc.c 
b/arch/arm/mach-imx/imx9/scmi/soc.c
index 217e7ed41a..1bacf52657 100644
--- a/arch/arm/mach-imx/imx9/scmi/soc.c
+++ b/arch/arm/mach-imx/imx9/scmi/soc.c
@@ -786,3 +786,21 @@ enum boot_device get_boot_device(void)
        return boot_dev;
 }
 #endif
+
+bool arch_check_dst_in_secure(void *start, ulong size)
+{
+       ulong ns_end = CFG_SYS_SDRAM_BASE + PHYS_SDRAM_SIZE;
+#ifdef PHYS_SDRAM_2_SIZE
+       ns_end += PHYS_SDRAM_2_SIZE;
+#endif
+
+       if ((ulong)start < CFG_SYS_SDRAM_BASE || (ulong)start + size > ns_end)
+               return true;
+
+       return false;
+}
+
+void *arch_get_container_trampoline(void)
+{
+       return (void *)((ulong)CFG_SYS_SDRAM_BASE + PHYS_SDRAM_SIZE - SZ_16M);
+}
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index 7d6780936d..29bc119bb2 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -362,6 +362,12 @@ config SPL_LOAD_IMX_CONTAINER
          Support booting U-Boot from an i.MX8 container image. If you are not
          using i.MX8, say 'n'.
 
+config SPL_IMX_CONTAINER_USE_TRAMPOLINE
+       bool
+       depends on SPL
+       help
+         Enable SPL load reader to load data to a trampoline buffer.
+
 config IMX_CONTAINER_CFG
        string "i.MX8 Container config file"
        depends on SPL && SPL_LOAD_IMX_CONTAINER
diff --git a/common/spl/spl_imx_container.c b/common/spl/spl_imx_container.c
index 2c31777fcd..47fb2e65e3 100644
--- a/common/spl/spl_imx_container.c
+++ b/common/spl/spl_imx_container.c
@@ -14,6 +14,16 @@
 #include <asm/mach-imx/ahab.h>
 #endif
 
+__weak bool arch_check_dst_in_secure(void *start, ulong size)
+{
+       return false;
+}
+
+__weak void *arch_get_container_trampoline(void)
+{
+       return NULL;
+}
+
 static struct boot_img_t *read_auth_image(struct spl_image_info *spl_image,
                                          struct spl_load_info *info,
                                          struct container_hdr *container,
@@ -22,6 +32,7 @@ static struct boot_img_t *read_auth_image(struct 
spl_image_info *spl_image,
 {
        struct boot_img_t *images;
        ulong offset, overhead, size;
+       void *buf, *trampoline;
 
        if (image_index > container->num_images) {
                debug("Invalid image number\n");
@@ -42,12 +53,30 @@ static struct boot_img_t *read_auth_image(struct 
spl_image_info *spl_image,
 
        debug("%s: container: %p offset: %lu size: %lu\n", __func__,
              container, offset, size);
-       if (info->read(info, offset, size,
-                      map_sysmem(images[image_index].dst - overhead,
-                                 images[image_index].size)) <
-           images[image_index].size) {
-               printf("%s wrong\n", __func__);
-               return NULL;
+
+       buf = map_sysmem(images[image_index].dst - overhead, 
images[image_index].size);
+       if (IS_ENABLED(CONFIG_SPL_IMX_CONTAINER_USE_TRAMPOLINE) &&
+           arch_check_dst_in_secure(buf, size)) {
+               trampoline = arch_get_container_trampoline();
+               if (!trampoline) {
+                       printf("%s: trampoline size is zero\n", __func__);
+                       return NULL;
+               }
+
+               if (info->read(info, offset, size, trampoline) < 
images[image_index].size) {
+                       printf("%s wrong\n", __func__);
+                       return NULL;
+               }
+
+               memcpy(buf, trampoline, images[image_index].size);
+       } else {
+               if (info->read(info, offset, size,
+                              map_sysmem(images[image_index].dst - overhead,
+                                         images[image_index].size)) <
+                   images[image_index].size) {
+                       printf("%s wrong\n", __func__);
+                       return NULL;
+               }
        }
 
 #ifdef CONFIG_AHAB_BOOT

-- 
2.43.0

Reply via email to