[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