xref: /optee_os/core/arch/riscv/kernel/thread_optee_abi_rv.S (revision 4398aac4919e2aa1d0ee06cd7ada0cb638e52bfd)
1/* SPDX-License-Identifier: BSD-2-Clause */
2/*
3 * Copyright 2023 NXP
4 * Copyright (c) 2023 Andes Technology Corporation
5 */
6
7#include <asm.S>
8#include <generated/asm-defines.h>
9#include <keep.h>
10#include <kernel/thread.h>
11#include <kernel/thread_private.h>
12#include <riscv.h>
13#include <riscv_macros.S>
14#include <sbi.h>
15#include <tee/optee_abi.h>
16#include <tee/teeabi_opteed.h>
17#include <tee/teeabi_opteed_macros.h>
18
19/*
20 * Implement based on the transport method used to communicate between
21 * untrusted domain and trusted domain. It could be an SBI/ECALL-based to
22 * a security monitor running in M-Mode and panic or messaging-based across
23 * domains where we return to a messaging callback which parses and handles
24 * messages.
25 *
26 * void thread_return_to_udomain(unsigned long arg0, unsigned long arg1,
27 *                               unsigned long arg2, unsigned long arg3,
28 *                               unsigned long arg4, unsigned long arg5);
29 */
30FUNC thread_return_to_udomain , :
31	/* Caller should provide arguments in a0~a5 */
32#if defined(CFG_RISCV_WITH_M_MODE_SM)
33	li	a7, SBI_EXT_TEE		/* extension ID */
34	li	a6, 0			/* function ID (unused) */
35	ecall
36#else
37	/* Other protocol */
38#endif
39	/* ABI to REE should not return */
40	panic_at_abi_return
41END_FUNC thread_return_to_udomain
42
43FUNC thread_std_abi_entry , :
44	jal	__thread_std_abi_entry
45
46	/* Save return value */
47	mv	s0, a0
48
49	/* Mask all maskable exceptions before switching to temporary stack */
50	csrw	CSR_XIE, x0
51
52	/* Switch to temporary stack */
53	jal	thread_get_tmp_sp
54	mv	sp, a0
55
56	/*
57	 * We are returning from thread_alloc_and_run()
58	 * set thread state as free
59	 */
60	jal	thread_state_free
61
62	/* Restore __thread_std_abi_entry() return value */
63	mv	a1, s0
64	li	a2, 0
65	li	a3, 0
66	li	a4, 0
67	li	a5, 0
68	li	a0, TEEABI_OPTEED_RETURN_CALL_DONE
69
70	/* Return to untrusted domain */
71	jal	thread_return_to_udomain
72END_FUNC thread_std_abi_entry
73
74/*
75 * void thread_rpc_xstatus(uint32_t rv[THREAD_RPC_NUM_ARGS],
76 *                         unsigned long status);
77 */
78FUNC thread_rpc_xstatus , :
79	 /* Use stack for temporary storage */
80	addi	sp, sp, -REGOFF(8)
81
82	/* Read xSTATUS */
83	csrr	a2, CSR_XSTATUS
84
85	/* Mask all maskable exceptions before switching to temporary stack */
86	csrw	CSR_XIE, x0
87
88	/* Save return address xSTATUS and pointer to rv */
89	STR	a0, REGOFF(0)(sp)
90	STR	a1, REGOFF(1)(sp)
91	STR	s0, REGOFF(2)(sp)
92	STR	ra, REGOFF(3)(sp)
93	STR	a2, REGOFF(4)(sp)
94#ifdef CFG_UNWIND
95	addi	s0, sp, REGOFF(8)
96#endif
97
98	/* Save thread state */
99	jal	thread_get_ctx_regs
100	LDR	ra, REGOFF(3)(sp)
101	/* Save ra, sp, gp, tp, and s0~s11 */
102	store_xregs a0, THREAD_CTX_REG_RA, REG_RA, REG_TP
103	store_xregs a0, THREAD_CTX_REG_S0, REG_S0, REG_S1
104	store_xregs a0, THREAD_CTX_REG_S2, REG_S2, REG_S11
105
106	/* Get to tmp stack */
107	jal	thread_get_tmp_sp
108
109	/* Get pointer to rv */
110	LDR	s1, REGOFF(0)(sp)
111
112	/* xSTATUS to restore */
113	LDR	a1, REGOFF(1)(sp)
114	/* Switch to tmp stack */
115	mv	sp, a0
116
117	/* Early load rv[] into s2-s4 */
118	lw	s2, 0(s1)
119	lw	s3, 4(s1)
120	lw	s4, 8(s1)
121
122	li	a0, THREAD_FLAGS_COPY_ARGS_ON_RETURN
123	la	a2, .thread_rpc_return
124	jal	thread_state_suspend
125
126	mv	a4, a0	/* thread index */
127	mv	a1, s2	/* rv[0] */
128	mv	a2, s3	/* rv[1] */
129	mv	a3, s4	/* rv[2] */
130	li	a5, 0
131	li	a0, TEEABI_OPTEED_RETURN_CALL_DONE
132
133	/* Return to untrusted domain */
134	jal	thread_return_to_udomain
135.thread_rpc_return:
136	/*
137	 * Jumps here from thread_resume() above when RPC has returned.
138	 * At this point has the stack pointer been restored to the value
139	 * stored in THREAD_CTX above.
140	 */
141
142	/* Get pointer to rv[] */
143	LDR	a4, REGOFF(0)(sp)
144
145	/* Store a0-a3 into rv[] */
146	sw	a0, 0(a4)
147	sw	a1, 4(a4)
148	sw	a2, 8(a4)
149	sw	a3, 12(a4)
150
151	/* Pop saved XSTATUS from stack */
152	LDR	s0, REGOFF(4)(sp)
153	csrw	CSR_XSTATUS, s0
154
155	/* Pop s0 from stack */
156	LDR	s0, REGOFF(2)(sp)
157
158	addi	sp, sp, REGOFF(8)
159	ret
160END_FUNC thread_rpc_xstatus
161DECLARE_KEEP_PAGER thread_rpc_xstatus
162
163LOCAL_FUNC vector_std_abi_entry, : , .identity_map
164	jal	thread_handle_std_abi
165	/*
166	 * Normally thread_handle_std_abi() should return via
167	 * thread_exit(), thread_rpc(), but if thread_handle_std_abi()
168	 * hasn't switched stack (error detected) it will do a normal "C"
169	 * return.
170	 */
171	/* Restore thread_handle_std_abi() return value */
172	mv	a1, a0
173	li	a2, 0
174	li	a3, 0
175	li	a4, 0
176	li	a5, 0
177	li	a0, TEEABI_OPTEED_RETURN_CALL_DONE
178
179	/* Return to untrusted domain */
180	j	thread_return_to_udomain
181END_FUNC vector_std_abi_entry
182
183LOCAL_FUNC vector_fast_abi_entry , : , .identity_map
184	addi    sp, sp, -THREAD_ABI_ARGS_SIZE
185	store_xregs sp, THREAD_ABI_ARGS_A0, REG_A0, REG_A7
186	mv      a0, sp
187	jal	thread_handle_fast_abi
188	load_xregs sp, THREAD_ABI_ARGS_A0, REG_A1, REG_A7
189	addi    sp, sp, THREAD_ABI_ARGS_SIZE
190
191	li	a0, TEEABI_OPTEED_RETURN_CALL_DONE
192	/* Return to untrusted domain */
193	j	thread_return_to_udomain
194END_FUNC vector_fast_abi_entry
195
196LOCAL_FUNC vector_fiq_entry , : , .identity_map
197	/* Secure Monitor received a FIQ and passed control to us. */
198	jal	interrupt_main_handler
199
200	li	a0, TEEABI_OPTEED_RETURN_FIQ_DONE
201	li	a1, 0
202	li	a2, 0
203	li	a3, 0
204	li	a4, 0
205	li	a5, 0
206
207	/* Return to untrusted domain */
208	j	thread_return_to_udomain
209END_FUNC vector_fiq_entry
210
211/*
212 * Vector table supplied to M-mode secure monitor (e.g., openSBI) at
213 * initialization.
214 *
215 * Note that M-mode secure monitor depends on the layout of this vector table,
216 * any change in layout has to be synced with M-mode secure monitor.
217 */
218FUNC thread_vector_table , : , .identity_map, , nobti
219	.option push
220	.option norvc
221	j   vector_std_abi_entry
222	j   vector_fast_abi_entry
223	j   .
224	j   .
225	j   .
226	j   .
227	j   vector_fiq_entry
228	j   .
229	j   .
230	.option pop
231END_FUNC thread_vector_table
232DECLARE_KEEP_PAGER thread_vector_table
233