
From: Henry Beberman henry.beberman@microsoft.com
This patch is a part of the i.MX Windows 10 IoT Core boot flow.
It adds an entry path for OP-TEE when loaded from a FIT blob when loadable has the OS type IH_OS_TEE. This booth path flushes and disables caches, disables interrupts, and jumps into OP-TEE passing the entry point for U-Boot Proper in one of the registers.
The CONFIG_SPL_OPTEE_BOOT option enables this boot path, and is also used to automatically set the CONFIG_SYS_NORMAL_WORLD Kconfig option while building U-Boot proper. This is because when OP-TEE returns to U-Boot proper's entry point, it will be in normal mode, so several secure world only initializations need to be omitted.
New Kconfig option: CONFIG_SPL_OPTEE_BOOT - Enables SPL FIT to boot in to OP-TEE, and will set the CONFIG_SYS_NORMAL_WORLD in U-Boot Proper to omit secure world only code.
Signed-off-by: Henry Beberman henry.beberman@microsoft.com Cc: Stefano Babic sbabic@denx.de Cc: Fabio Estevam fabio.estevam@nxp.com Cc: Tom Rini trini@konsulko.com --- arch/arm/cpu/armv7/Makefile | 1 + arch/arm/cpu/armv7/optee_jump.S | 31 +++++++++++++++++++++++++++++++ arch/arm/lib/spl.c | 16 ++++++++++++++++ common/spl/Kconfig | 9 +++++++++ common/spl/spl.c | 6 ++++++ include/spl.h | 21 +++++++++++++++++++++ 6 files changed, 84 insertions(+) create mode 100644 arch/arm/cpu/armv7/optee_jump.S
diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index 4f4647c90a..5bad36a8b8 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_ARMV7_PSCI) += psci.o psci-common.o obj-$(CONFIG_IPROC) += iproc-common/ obj-$(CONFIG_KONA) += kona-common/ obj-$(CONFIG_SYS_ARCH_TIMER) += arch_timer.o +obj-$(CONFIG_SPL_OPTEE_BOOT) += optee_jump.o
ifneq (,$(filter s5pc1xx exynos,$(SOC))) obj-y += s5p-common/ diff --git a/arch/arm/cpu/armv7/optee_jump.S b/arch/arm/cpu/armv7/optee_jump.S new file mode 100644 index 0000000000..2a1d994bcc --- /dev/null +++ b/arch/arm/cpu/armv7/optee_jump.S @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2018 Microsoft Corporation + */ + +#include <asm-offsets.h> +#include <config.h> +#include <asm/system.h> +#include <linux/linkage.h> + +#ifdef CONFIG_SPL_OPTEE_BOOT + + .globl arch_jump_to_image_optee + +/* + void __noreturn arch_jump_to_image_optee( + u32 optee_entry_point, + u32 pageable_part, + u32 uboot_entry_point + ); +*/ +ENTRY(arch_jump_to_image_optee) + + mov r3, r0 + mov r0, r1 + mov lr, r2 + + bx r3 + +ENDPROC(arch_jump_to_image_optee) +#endif diff --git a/arch/arm/lib/spl.c b/arch/arm/lib/spl.c index 33cc76ba3d..ee311d9fe8 100644 --- a/arch/arm/lib/spl.c +++ b/arch/arm/lib/spl.c @@ -73,3 +73,19 @@ void __noreturn jump_to_image_linux(struct spl_image_info *spl_image) } #endif /* CONFIG_ARM64 */ #endif + +#ifdef CONFIG_SPL_OPTEE_BOOT +void __noreturn arch_jump_to_image_optee(u32 optee_entry_point, + u32 pageable_part, + u32 uboot_entry_point); + +void __noreturn jump_to_image_optee(struct spl_image_info *spl_image) +{ + /* flush and turn off caches before jumping to OPTEE */ + cleanup_before_linux(); + + arch_jump_to_image_optee(spl_image->entry_point, + 0, + CONFIG_SYS_TEXT_BASE); +} +#endif diff --git a/common/spl/Kconfig b/common/spl/Kconfig index 0bbf8d5b02..643484a4a4 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -792,6 +792,15 @@ config SPL_ATF_NO_PLATFORM_PARAM
If your ATF is affected, say Y.
+config SPL_OPTEE_BOOT + depends on SPL + bool "Enable support for loading OPTEE and jumping to it from SPL" + default n + help + Configure SPL to boot OPTEE. SPL passes the U-Boot proper entry + point as the return address when it jumps to OPTEE, allowing OPTEE + to start U-Boot proper in normal mode when it returns. + config SPL_AM33XX_ENABLE_RTC32K_OSC bool "Enable the RTC32K OSC on AM33xx based platforms" default y if AM33XX diff --git a/common/spl/spl.c b/common/spl/spl.c index a09ada37d7..237083b08d 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -519,6 +519,12 @@ void board_init_r(gd_t *dummy1, ulong dummy2) spl_invoke_atf(&spl_image); break; #endif +#ifdef CONFIG_SPL_OPTEE_BOOT + case IH_OS_TEE: + debug("Jumping to OPTEE\n"); + jump_to_image_optee(&spl_image); + break; +#endif #ifdef CONFIG_SPL_OS_BOOT case IH_OS_LINUX: debug("Jumping to Linux\n"); diff --git a/include/spl.h b/include/spl.h index 8454ea7ad4..338b4b573d 100644 --- a/include/spl.h +++ b/include/spl.h @@ -125,6 +125,19 @@ int spl_board_ubi_load_image(u32 boot_device); */ void __noreturn jump_to_image_linux(struct spl_image_info *spl_image);
+#ifdef CONFIG_SPL_OPTEE_BOOT +/** + * jump_to_image_optee() - Jump to OP-TEE from SPL + * + * This jumps into OP-TEE using the information in @spl_image, passing + * it the entry point of U-Boot Proper so it can return there + * in non-secure mode + * + * @spl_image: Image description to set up + */ +void __noreturn jump_to_image_optee(struct spl_image_info *spl_image); +#endif + /** * spl_start_uboot() - Check if SPL should start the kernel or U-Boot * @@ -296,4 +309,12 @@ void spl_invoke_atf(struct spl_image_info *spl_image); * can implement 'board_return_to_bootrom'. */ void board_return_to_bootrom(void); + +#ifdef CONFIG_SPL_OPTEE_BOOT +#include <tee/optee.h> + +struct optee_image_info { + struct optee_header header; +}; +#endif #endif