Am 30. Juni 2025 02:08:05 MESZ schrieb Marek Vasut <marek.va...@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.va...@mailbox.org> >--- >Cc: Heinrich Schuchardt <xypron.g...@gmx.de> >Cc: Ilias Apalodimas <ilias.apalodi...@linaro.org> >Cc: Janne Grunau <j...@jannau.net> >Cc: Mattijs Korpershoek <mkorpersh...@kernel.org> >Cc: Patrick Rudolph <patrick.rudo...@9elements.com> >Cc: Sam Edwards <cfswo...@gmail.com> >Cc: Simon Glass <s...@chromium.org> >Cc: Tom Rini <tr...@konsulko.com> >Cc: u-boot@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