spl: imx: use trampoline buffer to load images to secure region
authorYe Li <ye.li@nxp.com>
Mon, 28 Apr 2025 10:37:36 +0000 (18:37 +0800)
committerFabio Estevam <festevam@gmail.com>
Sat, 3 May 2025 19:55:32 +0000 (16:55 -0300)
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.li@nxp.com>
Signed-off-by: Alice Guo <alice.guo@nxp.com>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
arch/arm/mach-imx/imx9/scmi/soc.c
common/spl/Kconfig
common/spl/spl_imx_container.c

index 3a5bddd..d2b0455 100644 (file)
@@ -729,3 +729,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);
+}
index b076f49..0bc96d0 100644 (file)
@@ -363,6 +363,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
index 2c31777..b3565ef 100644 (file)
 #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,27 @@ 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: failed to load image to a trampoline buffer\n", __func__);
+                       return NULL;
+               }
+
+               memcpy(buf, trampoline, images[image_index].size);
+       } else {
+               if (info->read(info, offset, size, buf) < images[image_index].size) {
+                               printf("%s: failed to load image to a non-secure region\n", __func__);
+                       return NULL;
+               }
        }
 
 #ifdef CONFIG_AHAB_BOOT