Re: [PATCH v2 1/2] ARM: bootm: Add support for starting Linux through OpTee-OS on ARMv7a

Heinrich Schuchardt xypron.glpk at gmx.de
Mon Jun 30 07:18:33 CEST 2025


Am 30. Juni 2025 02:08:05 MESZ schrieb Marek Vasut <marek.vasut at mailbox.org>:
>Add support for jumping to Linux kernel through OpTee-OS on ARMv7a.
>This is only supported if U-Boot runs in PL1 secure. This change adds
>two components, one is fitImage OpTee-OS loadable handler, which makes
>a note of OpTee-OS being loaded and stores the load address for later
>jump to it. The second part is the actual jump to Linux through OpTee-OS.
>The jump through OpTee-OS requires set up of multiple CPU registers, r1
>and r2 are passed through, r0 and r3 have to be set to 0, lr is set to
>Linux kernel entry point. This setup is done by new assembler function
>boot_jump_linux_via_optee().
>
>The boot_jump_linux_via_optee() also includes STM32MP13xx late TZC
>configuration write, this cannot be moved easily, hence the ifdef.

Hello Marek,

Could you, please, add a documentation change to the series. This would allow reviewers to test your proposal.

Furthermore, please, provide tests on QEMU.

Best regards

Heinrich


>
>Signed-off-by: Marek Vasut <marek.vasut at mailbox.org>
>---
>Cc: Heinrich Schuchardt <xypron.glpk at gmx.de>
>Cc: Ilias Apalodimas <ilias.apalodimas at linaro.org>
>Cc: Janne Grunau <j at jannau.net>
>Cc: Mattijs Korpershoek <mkorpershoek at kernel.org>
>Cc: Patrick Rudolph <patrick.rudolph at 9elements.com>
>Cc: Sam Edwards <cfsworks at gmail.com>
>Cc: Simon Glass <sjg at chromium.org>
>Cc: Tom Rini <trini at konsulko.com>
>Cc: u-boot at lists.denx.de
>---
>V2: - Add ifdeffery around armv7_init_nonsec(), boot_jump_linux_via_optee(),
>      secure_ram_addr() due to external dependencies which may not be reachable
>    - Add ifdeffery around arch_tee_image_process() to avoid breaking OMAP2
>      IH_TYPE_TEE loading
>---
> arch/arm/include/asm/armv7.h |  2 ++
> arch/arm/lib/Makefile        |  3 ++
> arch/arm/lib/bootm-optee.S   | 30 +++++++++++++++++++
> arch/arm/lib/bootm.c         | 56 ++++++++++++++++++++++++++++++------
> 4 files changed, 82 insertions(+), 9 deletions(-)
> create mode 100644 arch/arm/lib/bootm-optee.S
>
>diff --git a/arch/arm/include/asm/armv7.h b/arch/arm/include/asm/armv7.h
>index c002998ac0b..bfffbbd5d9a 100644
>--- a/arch/arm/include/asm/armv7.h
>+++ b/arch/arm/include/asm/armv7.h
>@@ -142,6 +142,8 @@ bool armv7_boot_nonsec(void);
> unsigned int _nonsec_init(void);
> void _do_nonsec_entry(void *target_pc, unsigned long r0,
> 		      unsigned long r1, unsigned long r2);
>+void boot_jump_linux_via_optee(void *target_pc, unsigned long r1,
>+			       unsigned long r2, unsigned long tee_entry);
> void _smp_pen(void);
> 
> extern char __secure_start[];
>diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
>index ade42d0ca43..92149d7058c 100644
>--- a/arch/arm/lib/Makefile
>+++ b/arch/arm/lib/Makefile
>@@ -41,6 +41,9 @@ obj-$(CONFIG_CMD_BOOTZ) += zimage.o
> endif
> obj-$(CONFIG_OF_LIBFDT) += bootm-fdt.o
> endif
>+ifndef CONFIG_ARM64
>+obj-$(CONFIG_BOOTM_OPTEE) += bootm-optee.o
>+endif
> ifdef CONFIG_ARM64
> obj-$(CONFIG_$(PHASE_)USE_ARCH_MEMSET) += memset-arm64.o
> obj-$(CONFIG_$(PHASE_)USE_ARCH_MEMCPY) += memcpy-arm64.o
>diff --git a/arch/arm/lib/bootm-optee.S b/arch/arm/lib/bootm-optee.S
>new file mode 100644
>index 00000000000..9d1a77b563d
>--- /dev/null
>+++ b/arch/arm/lib/bootm-optee.S
>@@ -0,0 +1,30 @@
>+/* SPDX-License-Identifier: GPL-2.0+ */
>+/*
>+ *  Copyright (C) 2025 Marek Vasut
>+ */
>+#include <config.h>
>+#include <linux/linkage.h>
>+
>+ENTRY(boot_jump_linux_via_optee)
>+	mov	r4, r3
>+	mov	lr, r0
>+	mov	r3, #0
>+	mov	r0, #0
>+
>+	/*
>+	 * Special TZC handling on this platform, the last
>+	 * 'str' has to be immediately before 'bx' and can
>+	 * not be interleaved with any return from function
>+	 * call, if it is then the system hangs.
>+	 */
>+#if defined(CONFIG_STM32MP13X) && !defined(CONFIG_TFABOOT)
>+	ldr	r6, =STM32_TZC_BASE + 0x114 + (0x20 * 2)
>+	mov	r7, #0x0
>+	str	r7, [r6]
>+	ldr	r6, =STM32_TZC_BASE + 0x110 + (0x20 * 1)
>+	mov	r7, #0x1
>+	str	r7, [r6]
>+#endif
>+
>+	bx	r4
>+ENDPROC(boot_jump_linux_via_optee)
>diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
>index 7eb764e1f4e..82a2c9f2499 100644
>--- a/arch/arm/lib/bootm.c
>+++ b/arch/arm/lib/bootm.c
>@@ -258,6 +258,11 @@ bool armv7_boot_nonsec(void)
> 
> 	return nonsec;
> }
>+#else
>+bool armv7_boot_nonsec(void)
>+{
>+	return false;
>+}
> #endif
> 
> #ifdef CONFIG_ARM64
>@@ -283,9 +288,9 @@ static void switch_to_el1(void)
> #endif
> 
> /* Subcommand: GO */
>+#ifdef CONFIG_ARM64
> static void boot_jump_linux(struct bootm_headers *images, int flag)
> {
>-#ifdef CONFIG_ARM64
> 	void (*kernel_entry)(void *fdt_addr, void *res0, void *res1,
> 			void *res2);
> 	int fake = (flag & BOOTM_STATE_OS_FAKE_GO);
>@@ -323,7 +328,13 @@ static void boot_jump_linux(struct bootm_headers *images, int flag)
> 					    ES_TO_AARCH64);
> #endif
> 	}
>+}
> #else
>+static __maybe_unused bool boot_jump_via_optee;
>+static __maybe_unused unsigned long boot_jump_via_optee_addr;
>+
>+static void boot_jump_linux(struct bootm_headers *images, int flag)
>+{
> 	unsigned long machid = gd->bd->bi_arch_number;
> 	char *s;
> 	void (*kernel_entry)(int zero, int arch, uint params);
>@@ -335,6 +346,13 @@ static void boot_jump_linux(struct bootm_headers *images, int flag)
> 	ulong addr = (ulong)kernel_entry | 1;
> 	kernel_entry = (void *)addr;
> #endif
>+
>+	if (IS_ENABLED(CONFIG_ARMV7_NONSEC) && armv7_boot_nonsec() &&
>+	    boot_jump_via_optee) {
>+		printf("Cannot start OpTee-OS from NS\n");
>+		return;
>+	}
>+
> 	s = env_get("machid");
> 	if (s) {
> 		if (strict_strtoul(s, 16, &machid) < 0) {
>@@ -354,19 +372,39 @@ static void boot_jump_linux(struct bootm_headers *images, int flag)
> 	else
> 		r2 = gd->bd->bi_boot_params;
> 
>-	if (!fake) {
>+	if (fake)
>+		return;
>+
> #ifdef CONFIG_ARMV7_NONSEC
>-		if (armv7_boot_nonsec()) {
>-			armv7_init_nonsec();
>-			secure_ram_addr(_do_nonsec_entry)(kernel_entry,
>-							  0, machid, r2);
>-		} else
>+	if (armv7_boot_nonsec())
>+		armv7_init_nonsec();
> #endif
>-			kernel_entry(0, machid, r2);
>-	}
>+
>+#ifdef CONFIG_BOOTM_OPTEE
>+	if (boot_jump_via_optee)
>+		boot_jump_linux_via_optee(kernel_entry, machid, r2, boot_jump_via_optee_addr);
>+#endif
>+
>+#ifdef CONFIG_ARMV7_NONSEC
>+	if (armv7_boot_nonsec()) {
>+		secure_ram_addr(_do_nonsec_entry)(kernel_entry, 0, machid, r2);
>+	} else
> #endif
>+	{
>+		kernel_entry(0, machid, r2);
>+	}
> }
> 
>+#ifndef CONFIG_TI_SECURE_DEVICE
>+static void arch_tee_image_process(ulong image, size_t size)
>+{
>+	boot_jump_via_optee = true;
>+	boot_jump_via_optee_addr = image;
>+}
>+U_BOOT_FIT_LOADABLE_HANDLER(IH_TYPE_TEE, arch_tee_image_process);
>+#endif
>+#endif
>+
> /* Main Entry point for arm bootm implementation
>  *
>  * Modeled after the powerpc implementation



More information about the U-Boot mailing list