diff options
author | Rouven Czerwinski <r.czerwinski@pengutronix.de> | 2020-01-28 06:38:20 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2020-01-30 06:22:28 +0100 |
commit | 4b7c346be3b9ced3166a6290d8c2a5fac691d3f2 (patch) | |
tree | c81ce1ca8d38cbfc9096c4bd7caf5be6b0304e08 /arch | |
parent | 7e73f9a3b89dcabb5737e2989ede1f7558dff9f1 (diff) | |
download | barebox-4b7c346be3b9ced3166a6290d8c2a5fac691d3f2.tar.gz barebox-4b7c346be3b9ced3166a6290d8c2a5fac691d3f2.tar.xz |
ARM: add optee early loading function
Add a OP-TEE early loading function which expects a pointer to a valid
tee binary and the device tree. OP-TEE will then be started and barebox
will continue to run in normal mode.
The function start_optee_early should be used in a boards lowlevel.c
file. Ensure that barebox has been relocated and a proper c environment
has been setup beforehand. Depending on the OP-TEE configuration, the
fdt will be modified. If the internal barebox device tree is passed,
OP-TEE will overwrite barebox PBL memory during this modification. Copy
the fdt to a save memory location beforehand to avoid a corruption of
barebox PBL memory.
This also moves the OP-TEE Kconfig symbols into a separate menu.
Signed-off-by: Rouven Czerwinski <r.czerwinski@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/include/asm/barebox-arm.h | 2 | ||||
-rw-r--r-- | arch/arm/lib32/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/lib32/optee-early.c | 38 |
3 files changed, 41 insertions, 1 deletions
diff --git a/arch/arm/include/asm/barebox-arm.h b/arch/arm/include/asm/barebox-arm.h index 8b2ecd9ab2..599852d644 100644 --- a/arch/arm/include/asm/barebox-arm.h +++ b/arch/arm/include/asm/barebox-arm.h @@ -119,7 +119,7 @@ void *barebox_arm_boot_dtb(void); static inline unsigned long arm_mem_stack_top(unsigned long membase, unsigned long endmem) { - if (IS_ENABLED(CONFIG_BOOTM_OPTEE)) + if (IS_ENABLED(CONFIG_BOOTM_OPTEE) || IS_ENABLED(CONFIG_PBL_OPTEE)) endmem -= OPTEE_SIZE; return endmem - SZ_64K; diff --git a/arch/arm/lib32/Makefile b/arch/arm/lib32/Makefile index cfcf3bc8f1..597bc07905 100644 --- a/arch/arm/lib32/Makefile +++ b/arch/arm/lib32/Makefile @@ -30,3 +30,5 @@ pbl-y += ashldi3.o pbl-y += div0.o obj-pbl-y += setjmp.o + +pbl-$(CONFIG_PBL_OPTEE) += optee-early.o diff --git a/arch/arm/lib32/optee-early.c b/arch/arm/lib32/optee-early.c new file mode 100644 index 0000000000..197325b8a0 --- /dev/null +++ b/arch/arm/lib32/optee-early.c @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * optee-early.c - start OP-TEE during PBL + * + * Copyright (c) 2019 Rouven Czerwinski <r.czerwinski@pengutronix.de>, Pengutronix + * + */ +#include <asm/cache.h> +#include <asm/setjmp.h> +#include <tee/optee.h> +#include <debug_ll.h> + +static jmp_buf tee_buf; + +int start_optee_early(void *fdt, void *tee) +{ + void (*tee_start)(void *r0, void *r1, void *r2); + struct optee_header *hdr; + int ret; + + hdr = tee; + ret = optee_verify_header(hdr); + if (ret < 0) + return ret; + + memcpy((void *)hdr->init_load_addr_lo, tee + sizeof(*hdr), hdr->init_size); + tee_start = (void *) hdr->init_load_addr_lo; + + /* We use setjmp/longjmp here because OP-TEE clobbers most registers */ + ret = setjmp(tee_buf); + if (ret == 0) { + sync_caches_for_execution(); + tee_start(0, 0, fdt); + longjmp(tee_buf, 1); + } + + return 0; +} |