aboutsummaryrefslogtreecommitdiff
path: root/core/arch/arm/kernel/thread_spmc_a32.S
diff options
context:
space:
mode:
Diffstat (limited to 'core/arch/arm/kernel/thread_spmc_a32.S')
-rw-r--r--core/arch/arm/kernel/thread_spmc_a32.S141
1 files changed, 141 insertions, 0 deletions
diff --git a/core/arch/arm/kernel/thread_spmc_a32.S b/core/arch/arm/kernel/thread_spmc_a32.S
new file mode 100644
index 00000000..4d7a6b1a
--- /dev/null
+++ b/core/arch/arm/kernel/thread_spmc_a32.S
@@ -0,0 +1,141 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+/*
+ * Copyright (c) 2020, Linaro Limited
+ */
+
+#include <platform_config.h>
+
+#include <arm32_macros.S>
+#include <arm.h>
+#include <asm.S>
+#include <ffa.h>
+#include <generated/asm-defines.h>
+#include <keep.h>
+#include <kernel/thread_defs.h>
+#include <kernel/unwind.h>
+#include <optee_ffa.h>
+
+FUNC thread_ffa_msg_wait , :
+ mov_imm r0, FFA_MSG_WAIT /* FID */
+ mov r1, #FFA_TARGET_INFO_MBZ /* Target info MBZ */
+ mov r2, #FFA_PARAM_MBZ /* Param MBZ */
+ mov r3, #FFA_PARAM_MBZ /* Param MBZ */
+ mov r4, #FFA_PARAM_MBZ /* Param MBZ */
+ mov r5, #FFA_PARAM_MBZ /* Param MBZ */
+ mov r6, #FFA_PARAM_MBZ /* Param MBZ */
+ mov r7, #FFA_PARAM_MBZ /* Param MBZ */
+ b .ffa_msg_loop
+END_FUNC thread_ffa_msg_wait
+
+ /* Caller provides r1, r3-r7 params */
+LOCAL_FUNC ffa_msg_send_direct_resp , :
+ ldr r0, =FFA_MSG_SEND_DIRECT_RESP_32 /* FID */
+ mov r2, #FFA_PARAM_MBZ /* RES MBZ */
+
+.ffa_msg_loop:
+ /* Invoke SMC with caller provided parameters */
+ smc #0
+
+ /* Store the parameters as struct thread_smc_args on stack */
+ push {r0-r7}
+ mov r0, sp
+
+ /* parse and handle message */
+ bl thread_spmc_msg_recv
+
+ /* Load struct thread_smc_args into registers */
+ pop {r0-r7}
+ b .ffa_msg_loop
+END_FUNC ffa_msg_send_direct_resp
+
+FUNC thread_std_smc_entry , :
+UNWIND( .fnstart)
+UNWIND( .cantunwind)
+
+ ror r4, r0, #16 /* Save target info with src and dst swapped */
+ bl __thread_std_smc_entry
+ mov r5, r0 /* Save return value */
+
+ /* Mask all maskable exceptions before switching to temporary stack */
+ cpsid aif
+ bl thread_get_tmp_sp
+ mov sp, r0
+
+ bl thread_state_free
+
+ mov r1, r4 /* Target info */
+ mov r3, r5 /* Return value */
+ mov r4, #FFA_PARAM_MBZ /* Unused parameter */
+ mov r5, #FFA_PARAM_MBZ /* Unused parameter */
+ mov r6, #FFA_PARAM_MBZ /* Unused parameter */
+ mov r7, #FFA_PARAM_MBZ /* Unused parameter */
+ b ffa_msg_send_direct_resp
+UNWIND( .fnend)
+END_FUNC thread_std_smc_entry
+
+/* void thread_rpc(struct thread_rpc_arg *rpc_arg) */
+FUNC thread_rpc , :
+UNWIND( .fnstart)
+ push {r0, lr}
+UNWIND( .save {r0, lr})
+
+ bl thread_save_state
+ mov r4, r0 /* Save original CPSR */
+
+ /*
+ * Switch to temporary stack and SVC mode. Save CPSR to resume into.
+ */
+ bl thread_get_tmp_sp
+ ldr r8, [sp] /* Get pointer to rv[] */
+ cps #CPSR_MODE_SVC /* Change to SVC mode */
+ mov sp, r0 /* Switch to tmp stack */
+
+ mov r0, #THREAD_FLAGS_COPY_ARGS_ON_RETURN
+ mov r1, r4 /* CPSR to restore */
+ ldr r2, =.thread_rpc_return
+ bl thread_state_suspend
+ mov r7, r0 /* Supply thread index */
+ ldr r0, =FFA_MSG_SEND_DIRECT_RESP_32
+ mov r2, #FFA_PARAM_MBZ
+ mov r3, #0 /* Error code = 0 */
+ ldm r8, {r1, r4-r6} /* Load rv[] into r1,r4-r6 */
+ b ffa_msg_send_direct_resp
+
+.thread_rpc_return:
+ /*
+ * At this point has the stack pointer been restored to the value
+ * it had when thread_save_state() was called above.
+ *
+ * Jumps here from thread_resume above when RPC has returned. The
+ * IRQ and FIQ bits are restored to what they where when this
+ * function was originally entered.
+ */
+ pop {r12, lr} /* Get pointer to rv[] */
+ stm r12, {r0-r3} /* Store r0-r3 into rv[] */
+ bx lr
+UNWIND( .fnend)
+END_FUNC thread_rpc
+DECLARE_KEEP_PAGER thread_rpc
+
+/*
+ * void thread_foreign_intr_exit(uint32_t thread_index)
+ *
+ * This function is jumped to at the end of macro foreign_intr_handler().
+ * The current thread as indicated by @thread_index has just been
+ * suspended. The job here is just to inform normal world the thread id to
+ * resume when returning.
+ */
+FUNC thread_foreign_intr_exit , :
+ /* load threads[r0].tsd.rpc_target_info into r1 */
+ mov r1, #THREAD_CTX_SIZE
+ ldr r2, =threads
+ mla r1, r1, r0, r2
+ ldr r1, [r1, #THREAD_CTX_TSD_RPC_TARGET_INFO]
+ mov r2, #FFA_PARAM_MBZ
+ mov r3, #FFA_PARAM_MBZ
+ mov r4, #OPTEE_FFA_YIELDING_CALL_RETURN_INTERRUPT
+ mov r5, #FFA_PARAM_MBZ
+ mov r6, #FFA_PARAM_MBZ
+ mov r7, r0
+ b ffa_msg_send_direct_resp
+END_FUNC thread_foreign_intr_exit