[PATCH 1/2] ARM: i.MX8MQ: Streamline lowlevel startup code

Sascha Hauer s.hauer at pengutronix.de
Fri Nov 10 01:46:21 PST 2023


Most i.MX8M SoCs have a imx8m[nmp]_load_and_start_image_via_tfa()
function which does all the magic of loading and starting TF-A,
barebox proper and OP-TEE images. Only the i.MX8MQ boards have the
same open coded in the lowlevel code.
Implement a imx8mq_load_and_start_image_via_tfa() and switch the
i.MX8MQ boards over to it.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm/boards/mnt-reform/lowlevel.c        | 28 +------------
 arch/arm/boards/nxp-imx8mq-evk/lowlevel.c    | 26 +------------
 arch/arm/boards/phytec-som-imx8mq/lowlevel.c | 27 ++-----------
 arch/arm/boards/zii-imx8mq-dev/lowlevel.c    | 20 +---------
 arch/arm/mach-imx/atf.c                      | 41 ++++++++++++++++++++
 include/mach/imx/atf.h                       |  1 +
 include/mach/imx/xload.h                     |  2 +
 7 files changed, 51 insertions(+), 94 deletions(-)

diff --git a/arch/arm/boards/mnt-reform/lowlevel.c b/arch/arm/boards/mnt-reform/lowlevel.c
index 074beba099..a82991c466 100644
--- a/arch/arm/boards/mnt-reform/lowlevel.c
+++ b/arch/arm/boards/mnt-reform/lowlevel.c
@@ -128,33 +128,7 @@ static __noreturn noinline void mnt_reform_start(void)
 
 		imx8mq_ddr_init(&mnt_reform_dram_timing, DRAM_TYPE_LPDDR4);
 
-		imx8mq_get_boot_source(&src, &instance);
-		switch (src) {
-		case BOOTSOURCE_MMC:
-			imx8m_esdhc_load_image(instance, false);
-			break;
-		case BOOTSOURCE_SERIAL:
-			imx8m_esdhc_load_image(1, false);
-			break;
-		default:
-			printf("Unhandled bootsource BOOTSOURCE_%d\n", src);
-			hang();
-		}
-
-		/*
-		 * On completion the TF-A will jump to MX8M_ATF_BL33_BASE_ADDR
-		 * in EL2. Copy the image there, but replace the PBL part of
-		 * that image with ourselves. On a high assurance boot only the
-		 * currently running code is validated and contains the checksum
-		 * for the piggy data, so we need to ensure that we are running
-		 * the same code in DRAM.
-		 */
-		memcpy((void *)MX8M_ATF_BL33_BASE_ADDR,
-		       __image_start, barebox_pbl_size);
-
-		get_builtin_firmware(imx8mq_bl31_bin, &bl31, &bl31_size);
-
-		imx8mq_atf_load_bl31(bl31, bl31_size);
+		imx8mq_load_and_start_image_via_tfa();
 	}
 
 	/*
diff --git a/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c b/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c
index 5167c5f606..d1a517dddb 100644
--- a/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c
+++ b/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c
@@ -65,33 +65,9 @@ static __noreturn noinline void nxp_imx8mq_evk_start(void)
 	 * to DRAM in EL2.
 	 */
 	if (current_el() == 3) {
-		enum bootsource src = BOOTSOURCE_UNKNOWN;
-		int instance = BOOTSOURCE_INSTANCE_UNKNOWN;
-		int ret = -ENOTSUPP;
-		size_t bl31_size;
-		const u8 *bl31;
-
 		ddr_init();
 
-		/*
-		 * On completion the TF-A will jump to MX8MQ_ATF_BL33_BASE_ADDR
-		 * in EL2. Copy the image there, but replace the PBL part of
-		 * that image with ourselves. On a high assurance boot only the
-		 * currently running code is validated and contains the checksum
-		 * for the piggy data, so we need to ensure that we are running
-		 * the same code in DRAM.
-		 */
-		imx8mq_get_boot_source(&src, &instance);
-		if (src == BOOTSOURCE_MMC)
-			ret = imx8m_esdhc_load_image(instance, false);
-		BUG_ON(ret);
-
-		memcpy((void *)MX8MQ_ATF_BL33_BASE_ADDR,
-		       __image_start, barebox_pbl_size);
-
-		get_builtin_firmware(imx8mq_bl31_bin, &bl31, &bl31_size);
-		imx8mq_atf_load_bl31(bl31, bl31_size);
-		/* not reached */
+		imx8mq_load_and_start_image_via_tfa();
 	}
 
 	/*
diff --git a/arch/arm/boards/phytec-som-imx8mq/lowlevel.c b/arch/arm/boards/phytec-som-imx8mq/lowlevel.c
index ba5f987d22..5708c8d754 100644
--- a/arch/arm/boards/phytec-som-imx8mq/lowlevel.c
+++ b/arch/arm/boards/phytec-som-imx8mq/lowlevel.c
@@ -43,22 +43,6 @@ static void setup_uart(void)
 	putc_ll('>');
 }
 
-static void phytec_imx8mq_som_sram_setup(void)
-{
-	enum bootsource src = BOOTSOURCE_UNKNOWN;
-	int instance = BOOTSOURCE_INSTANCE_UNKNOWN;
-	int ret = -ENOTSUPP;
-
-	ddr_init();
-
-	imx8mq_get_boot_source(&src, &instance);
-
-	if (src == BOOTSOURCE_MMC)
-		ret = imx8m_esdhc_load_image(instance, true);
-
-	BUG_ON(ret);
-}
-
 static __noreturn noinline void phytec_phycore_imx8mq_start(void)
 {
 	setup_uart();
@@ -70,7 +54,7 @@ static __noreturn noinline void phytec_phycore_imx8mq_start(void)
 		 * that means DDR needs to be initialized for the
 		 * first time.
 		 */
-		phytec_imx8mq_som_sram_setup();
+		ddr_init();
 	}
 	/*
 	 * Straight from the power-on we are at EL3, so the following
@@ -80,13 +64,8 @@ static __noreturn noinline void phytec_phycore_imx8mq_start(void)
 	 * initialization routine, it is EL2 which means we'll skip
 	 * loadting ATF blob again
 	 */
-	if (current_el() == 3) {
-		const u8 *bl31;
-		size_t bl31_size;
-
-		get_builtin_firmware(imx8mq_bl31_bin, &bl31, &bl31_size);
-		imx8mq_atf_load_bl31(bl31, bl31_size);
-	}
+	if (current_el() == 3)
+		imx8mq_load_and_start_image_via_tfa();
 
 	/*
 	 * Standard entry we hit once we initialized both DDR and ATF
diff --git a/arch/arm/boards/zii-imx8mq-dev/lowlevel.c b/arch/arm/boards/zii-imx8mq-dev/lowlevel.c
index d8c429d195..42cd05d3f1 100644
--- a/arch/arm/boards/zii-imx8mq-dev/lowlevel.c
+++ b/arch/arm/boards/zii-imx8mq-dev/lowlevel.c
@@ -63,21 +63,10 @@ static __noreturn void ddr_helper_halt(void)
 
 static void zii_imx8mq_dev_sram_setup(void)
 {
-	enum bootsource src = BOOTSOURCE_UNKNOWN;
-	int instance = BOOTSOURCE_INSTANCE_UNKNOWN;
-	int ret = -ENOTSUPP;
-
 	ddr_init();
 
 	if (running_as_ddr_helper())
 		ddr_helper_halt();
-
-	imx8mq_get_boot_source(&src, &instance);
-
-	if (src == BOOTSOURCE_MMC)
-		ret = imx8m_esdhc_load_image(instance, true);
-
-	BUG_ON(ret);
 }
 
 enum zii_platform_imx8mq_type {
@@ -141,13 +130,8 @@ static __noreturn noinline void zii_imx8mq_dev_start(void)
 	 * initialization routine, it is EL2 which means we'll skip
 	 * loadting ATF blob again
 	 */
-	if (current_el() == 3) {
-		const u8 *bl31;
-		size_t bl31_size;
-
-		get_builtin_firmware(imx8mq_bl31_bin, &bl31, &bl31_size);
-		imx8mq_atf_load_bl31(bl31, bl31_size);
-	}
+	if (current_el() == 3)
+		imx8mq_load_and_start_image_via_tfa();
 
 	system_type = get_system_type();
 
diff --git a/arch/arm/mach-imx/atf.c b/arch/arm/mach-imx/atf.c
index 834a3e3dea..6f9b69ff9a 100644
--- a/arch/arm/mach-imx/atf.c
+++ b/arch/arm/mach-imx/atf.c
@@ -244,3 +244,44 @@ __noreturn void imx8mn_load_and_start_image_via_tfa(void)
 	else
 		imx8mn_load_and_start_tfa(imx8mn_bl31_bin);
 }
+
+void imx8mq_load_bl33(void *bl33)
+{
+	enum bootsource src;
+	int instance;
+
+	imx8mn_get_boot_source(&src, &instance);
+	switch (src) {
+	case BOOTSOURCE_MMC:
+		imx8m_esdhc_load_image(instance, false);
+		break;
+	default:
+		printf("Unhandled bootsource BOOTSOURCE_%d\n", src);
+		hang();
+	}
+
+
+	/*
+	 * On completion the TF-A will jump to MX8M_ATF_BL33_BASE_ADDR
+	 * in EL2. Copy the image there, but replace the PBL part of
+	 * that image with ourselves. On a high assurance boot only the
+	 * currently running code is validated and contains the checksum
+	 * for the piggy data, so we need to ensure that we are running
+	 * the same code in DRAM.
+	 */
+	memcpy(bl33, __image_start, barebox_pbl_size);
+}
+
+__noreturn void imx8mq_load_and_start_image_via_tfa(void)
+{
+	void *bl33 = (void *)MX8M_ATF_BL33_BASE_ADDR;
+	unsigned long endmem = MX8M_DDR_CSD1_BASE_ADDR + imx8m_barebox_earlymem_size(16);
+
+	imx8m_save_bootrom_log((void *)arm_mem_scratch(endmem));
+	imx8mq_load_bl33(bl33);
+
+	if (IS_ENABLED(CONFIG_FIRMWARE_IMX8MN_OPTEE))
+		imx8m_load_and_start_optee_via_tfa(imx8mq, (void *)arm_mem_optee(endmem), bl33);
+	else
+		imx8mq_load_and_start_tfa(imx8mq_bl31_bin);
+}
diff --git a/include/mach/imx/atf.h b/include/mach/imx/atf.h
index aed294def9..a823562bc7 100644
--- a/include/mach/imx/atf.h
+++ b/include/mach/imx/atf.h
@@ -33,5 +33,6 @@ void __noreturn imx8mq_atf_load_bl31(const void *fw, size_t fw_size);
 #define imx8mm_load_and_start_tfa(fw_name) imx8m_load_and_start_tfa(imx8mm, fw_name)
 #define imx8mn_load_and_start_tfa(fw_name) imx8m_load_and_start_tfa(imx8mn, fw_name)
 #define imx8mp_load_and_start_tfa(fw_name) imx8m_load_and_start_tfa(imx8mp, fw_name)
+#define imx8mq_load_and_start_tfa(fw_name) imx8m_load_and_start_tfa(imx8mq, fw_name)
 
 #endif
diff --git a/include/mach/imx/xload.h b/include/mach/imx/xload.h
index a52b1e8ea1..27d2c33855 100644
--- a/include/mach/imx/xload.h
+++ b/include/mach/imx/xload.h
@@ -24,10 +24,12 @@ int imx8mp_qspi_load_image(int instance, bool start);
 void imx8mm_load_bl33(void *bl33);
 void imx8mn_load_bl33(void *bl33);
 void imx8mp_load_bl33(void *bl33);
+void imx8mq_load_bl33(void *bl33);
 
 void __noreturn imx8mm_load_and_start_image_via_tfa(void);
 void __noreturn imx8mn_load_and_start_image_via_tfa(void);
 void __noreturn imx8mp_load_and_start_image_via_tfa(void);
+void __noreturn imx8mq_load_and_start_image_via_tfa(void);
 
 int imx_load_image(ptrdiff_t address, ptrdiff_t entry, u32 offset,
 		   u32 ivt_offset, bool start, unsigned int alignment,
-- 
2.39.2




More information about the barebox mailing list