summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorRouven Czerwinski <r.czerwinski@pengutronix.de>2020-01-28 06:38:20 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2020-01-30 06:22:28 +0100
commit4b7c346be3b9ced3166a6290d8c2a5fac691d3f2 (patch)
treec81ce1ca8d38cbfc9096c4bd7caf5be6b0304e08 /arch
parent7e73f9a3b89dcabb5737e2989ede1f7558dff9f1 (diff)
downloadbarebox-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.h2
-rw-r--r--arch/arm/lib32/Makefile2
-rw-r--r--arch/arm/lib32/optee-early.c38
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;
+}