From: Marco Felsch <m.felsch@pengutronix.de>
To: Sascha Hauer <s.hauer@pengutronix.de>,
BAREBOX <barebox@lists.infradead.org>
Cc: Marco Felsch <m.felsch@pengutronix.de>,
Ahmad Fatoum <a.fatoum@pengutronix.de>
Subject: [PATCH v2 02/15] ARM: i.MX8M: move BL32 setup into imx8m_tfa_start_bl31()
Date: Wed, 04 Feb 2026 21:01:18 +0100 [thread overview]
Message-ID: <20260204-v2025-09-0-topic-optee-of-handling-v2-2-da075e6818e0@pengutronix.de> (raw)
In-Reply-To: <20260204-v2025-09-0-topic-optee-of-handling-v2-0-da075e6818e0@pengutronix.de>
Each i.MX8M platform repeated the same pattern for loading the optional
BL32 image because of the firmware name handling and the BL32 location
(end of memory).
The firmware name handling can't be generalized without change the logic
to function-like macros but the rest can be handled within the common
imx8m_tfa_start_bl31() function.
Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
arch/arm/mach-imx/atf.c | 153 ++++++++++++++++++++++--------------------------
1 file changed, 70 insertions(+), 83 deletions(-)
diff --git a/arch/arm/mach-imx/atf.c b/arch/arm/mach-imx/atf.c
index a8fc017fb6c86b807aef465226808144514c28f7..a7ec09ea7e9a90e3af7c01126bb6da9626d2d09d 100644
--- a/arch/arm/mach-imx/atf.c
+++ b/arch/arm/mach-imx/atf.c
@@ -19,30 +19,75 @@
#include <mach/imx/xload.h>
#include <mach/imx/snvs.h>
+static void imx_adjust_optee_memory(void **bl32, void **bl32_image, size_t *bl32_size)
+{
+ struct optee_header *hdr = *bl32_image;
+ u64 membase;
+
+ if (optee_verify_header(hdr))
+ return;
+
+ imx_scratch_save_optee_hdr(hdr);
+
+ membase = (u64)hdr->init_load_addr_hi << 32;
+ membase |= hdr->init_load_addr_lo;
+
+ *bl32 = (void *)membase;
+ *bl32_size -= sizeof(*hdr);
+ *bl32_image += sizeof(*hdr);
+}
+
/**
* imx8m_tfa_start_bl31 - Load TF-A BL31 blob and transfer control to it
*
* @tfa: Pointer to the BL31 blob
* @tfa_size: Size of the BL31 blob
* @tfa_dest: Place where the BL31 is copied to and executed
+ * @tee: Pointer to the optional BL32 blob
+ * @tee_size: Size of the optional BL32 blob
*
* This function:
*
- * 1. Copies built-in BL31 blob to an address i.MX8M's BL31
+ * 1. Copies built-in BL32 blob (if any) to the well-known OP-TEE address
+ * (end of RAM) or the address specified via the OP-TEE v2 header if
+ * found.
+ *
+ * 2. Copies built-in BL31 blob to an address i.MX8M's BL31
* expects to be placed (TF-A v2.8+ is position-independent)
*
- * 2. Sets up temporary stack pointer for EL2, which is execution
+ * 3. Sets up temporary stack pointer for EL2, which is execution
* level that BL31 will drop us off at after it completes its
* initialization routine
*
- * 3. Transfers control to BL31
+ * 4. Transfers control to BL31
*/
-static __noreturn void imx8m_tfa_start_bl31(const void *tfa_bin, size_t tfa_size, void *tfa_dest)
+static __noreturn void
+imx8m_tfa_start_bl31(const void *tfa_bin, size_t tfa_size, void *tfa_dest,
+ void *tee_bin, size_t tee_size)
{
void __noreturn (*bl31)(void) = tfa_dest;
+ unsigned long endmem;
+ void *bl32 = NULL;
int ret;
+ endmem = MX8M_DDR_CSD1_BASE_ADDR;
+ if (cpu_is_mx8mn())
+ endmem += imx8m_barebox_earlymem_size(16);
+ else
+ endmem += imx8m_barebox_earlymem_size(32);
+
+ /* TEE (BL32) handling */
+ if (tee_bin && tee_size) {
+ imx8m_tzc380_init();
+
+ bl32 = (void *)arm_mem_optee(endmem);
+ imx_adjust_optee_memory(&bl32, &tee_bin, &tee_size);
+
+ memcpy(bl32, tee_bin, tee_size);
+ }
+
+ /* TF-A (BL31) handling */
BUG_ON(tfa_size > MX8M_ATF_BL31_SIZE_LIMIT);
if (IS_ENABLED(CONFIG_FSL_CAAM_RNG_PBL_INIT)) {
@@ -70,7 +115,7 @@ static __noreturn void imx8m_tfa_start_bl31(const void *tfa_bin, size_t tfa_size
*/
pr_debug("and jumping with SP: %p\n", tfa_dest - 16);
-
+ /* Stack setup and BL31 jump */
asm volatile("msr sp_el2, %0" : :
"r" (tfa_dest - 16) :
"cc");
@@ -140,24 +185,6 @@ void imx8mm_load_bl33(void *bl33)
memcpy(bl33, __image_start, barebox_pbl_size);
}
-static void imx_adjust_optee_memory(void **bl32, void **bl32_image, size_t *bl32_size)
-{
- struct optee_header *hdr = *bl32_image;
- u64 membase;
-
- if (optee_verify_header(hdr))
- return;
-
- imx_scratch_save_optee_hdr(hdr);
-
- membase = (u64)hdr->init_load_addr_hi << 32;
- membase |= hdr->init_load_addr_lo;
-
- *bl32 = (void *)membase;
- *bl32_size -= sizeof(*hdr);
- *bl32_image += sizeof(*hdr);
-}
-
__noreturn void imx8mm_load_and_start_image_via_tfa(void)
{
__imx8mm_load_and_start_image_via_tfa(NULL, (void *)MX8M_ATF_BL33_BASE_ADDR);
@@ -167,7 +194,8 @@ __noreturn void __imx8mm_load_and_start_image_via_tfa(void *fdt, void *bl33)
{
const void *bl31;
size_t bl31_size;
- unsigned long endmem = MX8M_DDR_CSD1_BASE_ADDR + imx8m_barebox_earlymem_size(32);
+ void *bl32 = NULL;
+ size_t bl32_size = 0;
imx_set_cpu_type(IMX_CPU_IMX8MM);
imx8mm_init_scratch_space();
@@ -176,25 +204,14 @@ __noreturn void __imx8mm_load_and_start_image_via_tfa(void *fdt, void *bl33)
imx8mm_load_bl33(bl33);
if (IS_ENABLED(CONFIG_FIRMWARE_IMX8MM_OPTEE)) {
- void *bl32 = (void *)arm_mem_optee(endmem);
- size_t bl32_size;
- void *bl32_image;
-
- imx8m_tzc380_init();
- get_builtin_firmware_ext(imx8mm_bl32_bin,
- bl33, &bl32_image,
- &bl32_size);
-
- imx_adjust_optee_memory(&bl32, &bl32_image, &bl32_size);
-
- memcpy(bl32, bl32_image, bl32_size);
-
+ get_builtin_firmware_ext(imx8mm_bl32_bin, bl33, &bl32, &bl32_size);
get_builtin_firmware(imx8mm_bl31_bin_optee, &bl31, &bl31_size);
} else {
get_builtin_firmware(imx8mm_bl31_bin, &bl31, &bl31_size);
}
- imx8m_tfa_start_bl31(bl31, bl31_size, (void *)MX8MM_ATF_BL31_BASE_ADDR);
+ imx8m_tfa_start_bl31(bl31, bl31_size, (void *)MX8MM_ATF_BL31_BASE_ADDR,
+ bl32, bl32_size);
}
void imx8mp_load_bl33(void *bl33)
@@ -242,7 +259,8 @@ __noreturn void __imx8mp_load_and_start_image_via_tfa(void *fdt, void *bl33)
{
const void *bl31;
size_t bl31_size;
- unsigned long endmem = MX8M_DDR_CSD1_BASE_ADDR + imx8m_barebox_earlymem_size(32);
+ void *bl32 = NULL;
+ size_t bl32_size = 0;
imx_set_cpu_type(IMX_CPU_IMX8MP);
imx8mp_init_scratch_space();
@@ -251,25 +269,14 @@ __noreturn void __imx8mp_load_and_start_image_via_tfa(void *fdt, void *bl33)
imx8mp_load_bl33(bl33);
if (IS_ENABLED(CONFIG_FIRMWARE_IMX8MP_OPTEE)) {
- void *bl32 = (void *)arm_mem_optee(endmem);
- size_t bl32_size;
- void *bl32_image;
-
- imx8m_tzc380_init();
- get_builtin_firmware_ext(imx8mp_bl32_bin,
- bl33, &bl32_image,
- &bl32_size);
-
- imx_adjust_optee_memory(&bl32, &bl32_image, &bl32_size);
-
- memcpy(bl32, bl32_image, bl32_size);
-
+ get_builtin_firmware_ext(imx8mp_bl32_bin, bl33, &bl32, &bl32_size);
get_builtin_firmware(imx8mp_bl31_bin_optee, &bl31, &bl31_size);
} else {
get_builtin_firmware(imx8mp_bl31_bin, &bl31, &bl31_size);
}
- imx8m_tfa_start_bl31(bl31, bl31_size, (void *)MX8MP_ATF_BL31_BASE_ADDR);
+ imx8m_tfa_start_bl31(bl31, bl31_size, (void *)MX8MP_ATF_BL31_BASE_ADDR,
+ bl32, bl32_size);
}
void imx8mn_load_bl33(void *bl33)
@@ -317,7 +324,8 @@ __noreturn void __imx8mn_load_and_start_image_via_tfa(void *fdt, void *bl33)
{
const void *bl31;
size_t bl31_size;
- unsigned long endmem = MX8M_DDR_CSD1_BASE_ADDR + imx8m_barebox_earlymem_size(16);
+ void *bl32 = NULL;
+ size_t bl32_size = 0;
imx_set_cpu_type(IMX_CPU_IMX8MN);
imx8mn_init_scratch_space();
@@ -326,25 +334,14 @@ __noreturn void __imx8mn_load_and_start_image_via_tfa(void *fdt, void *bl33)
imx8mn_load_bl33(bl33);
if (IS_ENABLED(CONFIG_FIRMWARE_IMX8MN_OPTEE)) {
- void *bl32 = (void *)arm_mem_optee(endmem);
- size_t bl32_size;
- void *bl32_image;
-
- imx8m_tzc380_init();
- get_builtin_firmware_ext(imx8mn_bl32_bin,
- bl33, &bl32_image,
- &bl32_size);
-
- imx_adjust_optee_memory(&bl32, &bl32_image, &bl32_size);
-
- memcpy(bl32, bl32_image, bl32_size);
-
+ get_builtin_firmware_ext(imx8mn_bl32_bin, bl33, &bl32, &bl32_size);
get_builtin_firmware(imx8mn_bl31_bin_optee, &bl31, &bl31_size);
} else {
get_builtin_firmware(imx8mn_bl31_bin, &bl31, &bl31_size);
}
- imx8m_tfa_start_bl31(bl31, bl31_size, (void *)MX8MN_ATF_BL31_BASE_ADDR);
+ imx8m_tfa_start_bl31(bl31, bl31_size, (void *)MX8MN_ATF_BL31_BASE_ADDR,
+ bl32, bl32_size);
}
void imx8mq_load_bl33(void *bl33)
@@ -386,7 +383,8 @@ __noreturn void __imx8mq_load_and_start_image_via_tfa(void *fdt, void *bl33)
{
const void *bl31;
size_t bl31_size;
- unsigned long endmem = MX8M_DDR_CSD1_BASE_ADDR + imx8m_barebox_earlymem_size(32);
+ void *bl32 = NULL;
+ size_t bl32_size = 0;
imx_set_cpu_type(IMX_CPU_IMX8MQ);
imx8mq_init_scratch_space();
@@ -395,25 +393,14 @@ __noreturn void __imx8mq_load_and_start_image_via_tfa(void *fdt, void *bl33)
imx8mq_load_bl33(bl33);
if (IS_ENABLED(CONFIG_FIRMWARE_IMX8MQ_OPTEE)) {
- void *bl32 = (void *)arm_mem_optee(endmem);
- size_t bl32_size;
- void *bl32_image;
-
- imx8m_tzc380_init();
- get_builtin_firmware_ext(imx8mq_bl32_bin,
- bl33, &bl32_image,
- &bl32_size);
-
- imx_adjust_optee_memory(&bl32, &bl32_image, &bl32_size);
-
- memcpy(bl32, bl32_image, bl32_size);
-
+ get_builtin_firmware_ext(imx8mq_bl32_bin, bl33, &bl32, &bl32_size);
get_builtin_firmware(imx8mq_bl31_bin_optee, &bl31, &bl31_size);
} else {
get_builtin_firmware(imx8mq_bl31_bin, &bl31, &bl31_size);
}
- imx8m_tfa_start_bl31(bl31, bl31_size, (void *)MX8MQ_ATF_BL31_BASE_ADDR);
+ imx8m_tfa_start_bl31(bl31, bl31_size, (void *)MX8MQ_ATF_BL31_BASE_ADDR,
+ bl32, bl32_size);
}
void __noreturn imx93_load_and_start_image_via_tfa(void)
--
2.47.3
next prev parent reply other threads:[~2026-02-04 20:02 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-04 20:01 [PATCH v2 00/15] Improve OP-TEE handling Marco Felsch
2026-02-04 20:01 ` [PATCH v2 01/15] ARM: i.MX8M: add support to pass DT via lowlevel __imx8m*_load_and_start_image_via_tfa() Marco Felsch
2026-02-06 9:04 ` Ahmad Fatoum
2026-02-04 20:01 ` Marco Felsch [this message]
2026-02-04 20:01 ` [PATCH v2 03/15] ARM: i.MX8M: imx8m_tfa_start_bl31() add support for bl33 and fdt Marco Felsch
2026-02-04 20:01 ` [PATCH v2 04/15] pbl: decomp: add pbl_dtbz_uncompress helper Marco Felsch
2026-02-04 20:01 ` [PATCH v2 05/15] pbl: fdt: add pbl_load_fdt helper Marco Felsch
2026-02-06 9:16 ` Ahmad Fatoum
2026-02-04 20:01 ` [PATCH v2 06/15] ARM: i.MX: scratch: add FDT support Marco Felsch
2026-02-06 9:40 ` Ahmad Fatoum
2026-02-06 10:02 ` Marco Felsch
2026-02-06 13:01 ` Ahmad Fatoum
2026-02-09 20:50 ` Marco Felsch
2026-02-09 20:59 ` Ahmad Fatoum
2026-02-10 9:35 ` Marco Felsch
2026-02-10 9:41 ` Ahmad Fatoum
2026-02-04 20:01 ` [PATCH v2 07/15] ARM: i.MX8M: esdctl: drop ddrc base from imx8m_ddrc_sdram_size Marco Felsch
2026-02-04 20:01 ` [PATCH v2 08/15] ARM: i.MX8M: esdctl: export imx8m_ddrc_sdram_size() Marco Felsch
2026-02-04 20:01 ` [PATCH v2 09/15] ARM: i.MX8M: add support to pass BL3x bl_params Marco Felsch
2026-02-05 17:02 ` Michael Tretter
2026-02-05 22:41 ` Marco Felsch
2026-02-06 10:20 ` Ahmad Fatoum
2026-02-06 13:46 ` Marco Felsch
2026-02-06 11:55 ` Ahmad Fatoum
2026-02-04 20:01 ` [PATCH v2 10/15] handoff-data: Add TEE_DT_OVL entry Marco Felsch
2026-02-06 11:56 ` Ahmad Fatoum
2026-02-04 20:01 ` [PATCH v2 11/15] security: optee: add optee_handoff_overlay helper Marco Felsch
2026-02-06 12:25 ` Ahmad Fatoum
2026-02-09 20:18 ` Marco Felsch
2026-02-04 20:01 ` [PATCH v2 12/15] security: optee: add helpers to register OF overlays Marco Felsch
2026-02-06 12:09 ` Ahmad Fatoum
2026-02-09 20:17 ` Marco Felsch
2026-02-04 20:01 ` [PATCH v2 13/15] ARM: i.MX8M: Pass optional OP-TEE overlay to barebox Marco Felsch
2026-02-06 12:04 ` Ahmad Fatoum
2026-02-04 20:01 ` [PATCH v2 14/15] of: base: register optional OP-TEE overlay Marco Felsch
2026-02-06 12:05 ` Ahmad Fatoum
2026-02-06 13:24 ` Marco Felsch
2026-02-04 20:01 ` [PATCH v2 15/15] handoff-data: add missing include Marco Felsch
2026-02-06 12:07 ` Ahmad Fatoum
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260204-v2025-09-0-topic-optee-of-handling-v2-2-da075e6818e0@pengutronix.de \
--to=m.felsch@pengutronix.de \
--cc=a.fatoum@pengutronix.de \
--cc=barebox@lists.infradead.org \
--cc=s.hauer@pengutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox