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