[PATCH 11/17] imx9: scmi: soc: Override h_spl_load_read with trampoline buffer

Alice Guo alice.guo at oss.nxp.com
Wed Oct 16 09:18:04 CEST 2024


From: Ye Li <ye.li at 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 override h_spl_load_read to use a trampoline buffer in nonsecure
region, then use CPU to copy the image from trampoline buffer to
destination secure region.

Signed-off-by: Ye Li <ye.li at nxp.com>
Signed-off-by: Alice Guo <alice.guo at nxp.com>
Reviewed-by: Peng Fan <peng.fan at nxp.com>
---
 arch/arm/mach-imx/imx9/scmi/soc.c | 40 +++++++++++++++++++++++++++++++++++++++
 common/spl/spl_mmc.c              |  2 +-
 2 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-imx/imx9/scmi/soc.c b/arch/arm/mach-imx/imx9/scmi/soc.c
index fefb1a6f4ca58722a5d93c39e4f6a7aaf85aa177..8a7df24afecc1d6d77b7162be639b56af95fd975 100644
--- a/arch/arm/mach-imx/imx9/scmi/soc.c
+++ b/arch/arm/mach-imx/imx9/scmi/soc.c
@@ -41,6 +41,8 @@
 #include <scmi_agent.h>
 #include <scmi_protocols.h>
 #endif
+#include <spl.h>
+#include <mmc.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -830,3 +832,41 @@ enum boot_device get_boot_device(void)
 	return boot_dev;
 }
 #endif
+
+ulong h_spl_load_read(struct spl_load_info *load, ulong off,
+		      ulong size, void *buf)
+{
+	struct blk_desc *bd = load->priv;
+	lbaint_t sector = off >> bd->log2blksz;
+	lbaint_t count = size >> bd->log2blksz;
+	ulong trampoline_sz = SZ_16M;
+	void *trampoline = (void *)((ulong)CFG_SYS_SDRAM_BASE + PHYS_SDRAM_SIZE - trampoline_sz);
+	ulong ns_ddr_end = CFG_SYS_SDRAM_BASE + PHYS_SDRAM_SIZE;
+	ulong read_count, trampoline_cnt = trampoline_sz >> bd->log2blksz, actual, total;
+
+#ifdef PHYS_SDRAM_2_SIZE
+	ns_ddr_end += PHYS_SDRAM_2_SIZE;
+#endif
+
+	/* Check if the buf is in non-secure world, otherwise copy from trampoline */
+	if ((ulong)buf < CFG_SYS_SDRAM_BASE || (ulong)buf + (count * sector) > ns_ddr_end) {
+		total = 0;
+		while (count) {
+			read_count = trampoline_cnt > count ? count : trampoline_cnt;
+			actual = blk_dread(bd, sector, read_count, trampoline);
+			if (actual != read_count) {
+				printf("Error in blk_dread, %lu, %lu\n", read_count, actual);
+				return 0;
+			}
+			memcpy(buf, trampoline, actual * 512);
+			buf += actual * 512;
+			sector += actual;
+			total += actual;
+			count -= actual;
+		}
+
+		return total << bd->log2blksz;
+	}
+
+	return blk_dread(bd, sector, count, buf) << bd->log2blksz;
+}
diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c
index 1f69659321620739d066bd806acd1d282b66bad3..d15a6945f9c24ee427b847c036413c52475c44a8 100644
--- a/common/spl/spl_mmc.c
+++ b/common/spl/spl_mmc.c
@@ -17,7 +17,7 @@
 #include <image.h>
 #include <imx_container.h>
 
-static ulong h_spl_load_read(struct spl_load_info *load, ulong off,
+ulong __weak h_spl_load_read(struct spl_load_info *load, ulong off,
 			     ulong size, void *buf)
 {
 	struct blk_desc *bd = load->priv;

-- 
2.34.1



More information about the U-Boot mailing list