1/* SPDX-License-Identifier: BSD-2-Clause */
2/*
3 * Copyright (c) 2020, Linaro Limited
4 */
5
6#include <platform_config.h>
7
8#include <arm32_macros.S>
9#include <arm.h>
10#include <asm.S>
11#include <ffa.h>
12#include <generated/asm-defines.h>
13#include <keep.h>
14#include <kernel/thread_defs.h>
15#include <optee_ffa.h>
16
17FUNC thread_ffa_msg_wait , :
18	mov_imm	r0, FFA_MSG_WAIT		/* FID */
19	mov	r1, #FFA_TARGET_INFO_MBZ	/* Target info MBZ */
20	mov	r2, #FFA_PARAM_MBZ		/* Param MBZ */
21	mov	r3, #FFA_PARAM_MBZ		/* Param MBZ */
22	mov	r4, #FFA_PARAM_MBZ		/* Param MBZ */
23	mov	r5, #FFA_PARAM_MBZ		/* Param MBZ */
24	mov	r6, #FFA_PARAM_MBZ		/* Param MBZ */
25	mov	r7, #FFA_PARAM_MBZ		/* Param MBZ */
26	b	.ffa_msg_loop
27END_FUNC thread_ffa_msg_wait
28
29	/* Caller provides r1, r3-r7 params */
30LOCAL_FUNC ffa_msg_send_direct_resp , :
31	ldr	r0, =FFA_MSG_SEND_DIRECT_RESP_32	/* FID */
32	mov	r2, #FFA_PARAM_MBZ			/* RES MBZ */
33
34.ffa_msg_loop:
35	/* Invoke SMC with caller provided parameters */
36	smc	#0
37
38	/* Store the parameters as struct thread_smc_args on stack */
39	push	{r0-r7}
40	mov	r0, sp
41
42	/* parse and handle message */
43	bl	thread_spmc_msg_recv
44
45	/* Load struct thread_smc_args into registers */
46	pop	{r0-r7}
47	b	.ffa_msg_loop
48END_FUNC ffa_msg_send_direct_resp
49
50FUNC thread_std_smc_entry , :
51UNWIND(	.cantunwind)
52
53	push	{r4, r5} /* Pass these following the arm32 calling convention */
54	ror	r4, r0, #16 /* Save target info with src and dst swapped */
55	bl	__thread_std_smc_entry
56	add	sp, sp, #8 /* There's nothing return, just restore the sp */
57	mov	r5, r0	/* Save return value */
58
59	/* Mask all maskable exceptions before switching to temporary stack */
60	cpsid	aif
61	bl	thread_get_tmp_sp
62	mov	sp, r0
63
64	bl	thread_state_free
65
66	mov	r1, r4				/* Target info */
67	mov	r3, r5				/* Return value */
68	mov	r4, #FFA_PARAM_MBZ		/* Unused parameter */
69	mov	r5, #FFA_PARAM_MBZ		/* Unused parameter */
70	mov	r6, #FFA_PARAM_MBZ		/* Unused parameter */
71	mov	r7, #FFA_PARAM_MBZ		/* Unused parameter */
72	b	ffa_msg_send_direct_resp
73END_FUNC thread_std_smc_entry
74
75/* void thread_rpc(struct thread_rpc_arg *rpc_arg) */
76FUNC thread_rpc , :
77	push	{r0, lr}
78UNWIND(	.save	{r0, lr})
79
80	bl	thread_save_state
81	mov	r4, r0			/* Save original CPSR */
82
83	/*
84	 * Switch to temporary stack and SVC mode. Save CPSR to resume into.
85	 */
86	bl	thread_get_tmp_sp
87	ldr	r8, [sp]		/* Get pointer to rv[] */
88	cps	#CPSR_MODE_SVC		/* Change to SVC mode */
89	mov	sp, r0			/* Switch to tmp stack */
90
91	mov	r0, #THREAD_FLAGS_COPY_ARGS_ON_RETURN
92	mov	r1, r4			/* CPSR to restore */
93	ldr	r2, =.thread_rpc_return
94	bl	thread_state_suspend
95	mov	r7, r0			/* Supply thread index */
96	ldr	r0, =FFA_MSG_SEND_DIRECT_RESP_32
97	mov	r2, #FFA_PARAM_MBZ
98	mov	r3, #0			/* Error code = 0 */
99	ldm	r8, {r1, r4-r6}		/* Load rv[] into r1,r4-r6 */
100	b	ffa_msg_send_direct_resp
101
102.thread_rpc_return:
103	/*
104	 * At this point has the stack pointer been restored to the value
105	 * it had when thread_save_state() was called above.
106	 *
107	 * Jumps here from thread_resume above when RPC has returned. The
108	 * IRQ and FIQ bits are restored to what they where when this
109	 * function was originally entered.
110	 */
111	pop	{r12, lr}		/* Get pointer to rv[] */
112	stm	r12, {r0-r3}		/* Store r0-r3 into rv[] */
113	bx	lr
114END_FUNC thread_rpc
115DECLARE_KEEP_PAGER thread_rpc
116
117/*
118 * void thread_foreign_intr_exit(uint32_t thread_index)
119 *
120 * This function is jumped to at the end of macro foreign_intr_handler().
121 * The current thread as indicated by @thread_index has just been
122 * suspended.  The job here is just to inform normal world the thread id to
123 * resume when returning.
124 */
125FUNC thread_foreign_intr_exit , :
126	/* load threads[r0].tsd.rpc_target_info into r1 */
127	mov	r1, #THREAD_CTX_SIZE
128	ldr	r2, =threads
129	mla	r1, r1, r0, r2
130	ldr	r1, [r1, #THREAD_CTX_TSD_RPC_TARGET_INFO]
131	mov	r2, #FFA_PARAM_MBZ
132	mov	r3, #FFA_PARAM_MBZ
133	mov	r4, #OPTEE_FFA_YIELDING_CALL_RETURN_INTERRUPT
134	mov	r5, #FFA_PARAM_MBZ
135	mov	r6, #FFA_PARAM_MBZ
136	mov	r7, r0
137	b	ffa_msg_send_direct_resp
138END_FUNC thread_foreign_intr_exit
139