aboutsummaryrefslogtreecommitdiff
path: root/src/soc/qualcomm/ipq806x/tz_wrapper.S
diff options
context:
space:
mode:
authorVikas Das <vdas@codeaurora.org>2014-09-22 17:49:56 -0700
committerPatrick Georgi <pgeorgi@google.com>2015-04-15 21:56:56 +0200
commit08f249e7d07e7742e202d08305822af2b3ddec78 (patch)
treead7403d9915d06d309e1a7227b3af62a00e71dae /src/soc/qualcomm/ipq806x/tz_wrapper.S
parent239622677b3e3e20d1de8f79224edf1cc97d7083 (diff)
ipq806x: Load TZBSP blob from coreboot ramstage
Read the TZBSP blob from CBFS and run it. A side effect of the blob execution is switching the processor into User mode. Starting TZBSP requires processor running in Supervisor mode, TZBSP code is compiled for ARM. Coreboot is executing in System mode and is compiled for Thumb. An assembler wrapper switches the execution mode and interfaces between Thumb and ARM modes. BUG=chrome-os-partner:34161 BRANCH=Storm TEST=manual With the preceeding patches the system successfully loads to depthcharge in recovery mode. Change-Id: I812b5cef95ba5562a005e005162d6391e502ecf8 Signed-off-by: Patrick Georgi <pgeorgi@chromium.org> Original-Commit-Id: 7065cf3d17964a1d9038ec8906b469a08a79c6e2 Original-Change-Id: Ib14dbcbcbe489b595f4247d489d50f76a0e65948 Original-Signed-off-by: Varadarajan Narayanan <varada@qti.qualcomm.com> Original-Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Original-Reviewed-on: https://chromium-review.googlesource.com/229026 Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: http://review.coreboot.org/9690 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Diffstat (limited to 'src/soc/qualcomm/ipq806x/tz_wrapper.S')
-rw-r--r--src/soc/qualcomm/ipq806x/tz_wrapper.S106
1 files changed, 106 insertions, 0 deletions
diff --git a/src/soc/qualcomm/ipq806x/tz_wrapper.S b/src/soc/qualcomm/ipq806x/tz_wrapper.S
new file mode 100644
index 0000000000..70cc170f64
--- /dev/null
+++ b/src/soc/qualcomm/ipq806x/tz_wrapper.S
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * TZ expects the ARM core to be in 'ARM' mode. However, coreboot seems
+ * to be compiled in mixed thumb/arm mode. Hence create a glue function
+ * to invoke TZ.
+ */
+
+#include <arch/asm.h>
+
+/*
+ * Force ARM mode. Else this gets assembled with mixed ARM and
+ * Thumb instructions. We set up everything and jump to TZBSP
+ * using the 'blx' instruction. For 'blx' if the last bit of the
+ * destination address is zero, it switches to ARM mode. Since,
+ * we are already in ARM mode, nothing to switch as such.
+ *
+ * However, when TZBSP returns, the CPU is still in ARM mode.
+ * If the assembler inserts Thumb instructions between the point
+ * of return from TZBSP to the 'bx' instruction we are hosed.
+ * Hence forcing ARM mode.
+ *
+ * Rest of the code can be compiled in mixed ARM/Thumb mode.
+ * Since tz_init_wrapper is being forced as an ARM symbol,
+ * callers will use 'blx' to come here forcing a switch to
+ * ARM mode. The wrapper does its job and returns back to the
+ * Thumb caller.
+ */
+.arm
+/*
+ * int tz_init_wrapper(int, int, void *);
+ */
+ENTRY(tz_init_wrapper)
+ .global tz_init_wrapper
+
+ /*
+ * r0 = tz_arg1
+ * r1 = tz_arg2
+ * r2 = tz_load_addr
+ */
+
+ /*
+ * Per the AAPCS
+ * r0, r1, r2, r3, r12 can be clobbered
+ * r4, r5, r6, r7, r8, r9, r10, r11 have to be preserved
+ *
+ * Following code clobbers
+ * r0 - Setting return value to zero
+ * r1 - For doing a thumb return
+ * r3 - Passing 'SP' from current mode to 'svc' mode
+ * r4 - To save & restore CPSR
+ *
+ * Per AAPCS, save and restore r4, rest are 'clobberable' :)
+ * The invoked code takes care of saving and restoring the other
+ * preserved registers (i.e. r5 - r11)
+ *
+ * Stack Usage:
+ * SP -> | LR | (Lower address)
+ * | r4 |
+ * | CPSR |
+ * |-------|
+ * | . |
+ * | . |
+ * | . | (Higher address)
+ */
+
+ sub sp, sp, #12 /* Allocate stack frame */
+ str lr, [sp] /* Save return address */
+ str r4, [sp, #4] /* Use r4 to hold the new CPSR value */
+
+ mov r3, sp /* Get current stack pointer */
+
+ mrs r4, CPSR /* save CPSR */
+ str r4, [sp, #8]
+
+ bic r4, r4, 0x1f /* Clear mode bits */
+ orr r4, r4, 0x13 /* 'svc' mode */
+ msr cpsr_cxf, r4 /* Switch to Supervisor mode. */
+ mov sp, r3 /* Use the same stack as the previous mode */
+
+ blx r2 /* Jump to TZ in ARM mode */
+
+ nop /* back from TZ, in ARM mode */
+
+ ldr r4, [sp, #8] /* restore CPSR */
+ msr cpsr_cxf, r4
+
+ ldr r4, [sp, #4] /* restore r4 */
+
+ ldr lr, [sp] /* saved return address */
+ add sp, sp, #12 /* free stack frame */
+
+ bx lr /* back to thumb caller */
+
+ENDPROC(tz_init_wrapper)