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>
Subject: [PATCH 06/23] ARM: i.MX8M: move BL32 setup into imx8m_tfa_start_bl31()
Date: Mon, 10 Nov 2025 21:34:46 +0100 [thread overview]
Message-ID: <20251110-v2025-09-0-topic-optee-of-handling-v1-6-8f0625ac5471@pengutronix.de> (raw)
In-Reply-To: <20251110-v2025-09-0-topic-optee-of-handling-v1-0-8f0625ac5471@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. While on it the commit adds a sanity
check that the BL32 image size is > 0.
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
arch/arm/mach-imx/atf.c | 154 ++++++++++++++++++++++--------------------------
1 file changed, 72 insertions(+), 82 deletions(-)
diff --git a/arch/arm/mach-imx/atf.c b/arch/arm/mach-imx/atf.c
index dd861f1ad87c98c8baffa2986aeef40eacedc88c..531ded2c57b1f194a2f209161ea086f41fccf58f 100644
--- a/arch/arm/mach-imx/atf.c
+++ b/arch/arm/mach-imx/atf.c
@@ -18,30 +18,77 @@
#include <mach/imx/ele.h>
#include <mach/imx/xload.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) {
+ BUG_ON(tee_size <= 0);
+
+ 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)) {
@@ -54,6 +101,7 @@ static __noreturn void imx8m_tfa_start_bl31(const void *tfa_bin, size_t tfa_size
memcpy(bl31, tfa_bin, tfa_size);
+ /* Stack setup and BL31 jump */
asm volatile("msr sp_el2, %0" : :
"r" (tfa_dest - 16) :
"cc");
@@ -123,24 +171,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 *fdt)
{
__imx8mm_load_and_start_image_via_tfa(fdt, (void *)MX8M_ATF_BL33_BASE_ADDR);
@@ -150,7 +180,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();
@@ -158,25 +189,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)
@@ -224,7 +244,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();
@@ -232,25 +253,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)
@@ -298,7 +308,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();
@@ -306,25 +317,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)
@@ -366,7 +366,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();
@@ -374,25 +375,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:[~2025-11-10 20:35 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-10 20:34 [PATCH 00/23] Improve OP-TEE handling Marco Felsch
2025-11-10 20:34 ` [PATCH 01/23] pbl: compressed-dtb: add missing includes Marco Felsch
2025-11-10 20:34 ` [PATCH 02/23] pbl: fdt: fix fdt_fixup_mem error handling Marco Felsch
2025-11-10 20:34 ` [PATCH 03/23] ARM: atf: add missing includes in atf_common.h Marco Felsch
2025-11-10 20:34 ` [PATCH 04/23] ARM: i.MX8M: add support to pass DT via imx8m{m,n,q,p}_load_and_start_image_via_tfa() Marco Felsch
2025-11-10 20:34 ` [PATCH 05/23] ARM: i.MX8M: cosmetic cleanup Marco Felsch
2025-11-10 20:34 ` Marco Felsch [this message]
2025-11-10 20:34 ` [PATCH 07/23] ARM: i.MX8M: imx8m_tfa_start_bl31() add support for bl33 and fdt Marco Felsch
2025-11-10 20:34 ` [PATCH 08/23] pbl: decomp: add pbl_dtbz_uncompress helper Marco Felsch
2025-11-10 20:34 ` [PATCH 09/23] pbl: fdt: add pbl_load_fdt helper Marco Felsch
2025-11-10 20:34 ` [PATCH 10/23] ARM: i.MX: scratch: add FDT support Marco Felsch
2025-11-10 20:34 ` [PATCH 11/23] ARM: i.MX8M: esdctl: drop ddrc base from imx8m_ddrc_sdram_size Marco Felsch
2025-11-10 20:34 ` [PATCH 12/23] ARM: i.MX8M: esdctl: export imx8m_ddrc_sdram_size() Marco Felsch
2025-11-10 20:34 ` [PATCH 13/23] ARM: i.MX8M: add support to pass BL3x bl_params Marco Felsch
2025-11-10 20:34 ` [PATCH 14/23] ARM: i.MX: scratch: add OP-TEE FDTO support Marco Felsch
2025-11-10 20:34 ` [PATCH 15/23] pbl: string: add strncmp Marco Felsch
2025-11-10 20:34 ` [PATCH 16/23] pbl: fdt: add fdt_copy_node helper Marco Felsch
2025-11-10 20:34 ` [PATCH 17/23] handoff-data: Add BL32_DT_OVL entry Marco Felsch
2025-11-10 20:34 ` [PATCH 18/23] security: optee: add optee_extract_fdto helper Marco Felsch
2025-11-10 20:34 ` [PATCH 19/23] security: optee: add helpers to apply OP-TEE FDTO Marco Felsch
2025-11-10 20:35 ` [PATCH 20/23] ARM: i.MX8M: Add support to extract OP-TEE provided informations Marco Felsch
2025-11-10 20:35 ` [PATCH 21/23] of: base: register optional OP-TEE overlay Marco Felsch
2025-11-10 20:35 ` [PATCH 22/23] pbl: add support to disable/remove the /secure-chosen/stdout-path Marco Felsch
2025-11-10 20:35 ` [PATCH 23/23] ARM: i.MX8M: remove /secure-chosen/stdout-path if requested Marco Felsch
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=20251110-v2025-09-0-topic-optee-of-handling-v1-6-8f0625ac5471@pengutronix.de \
--to=m.felsch@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