xref: /rk3399_ARM-atf/bl32/tsp/aarch64/tsp_entrypoint.S (revision dff8e47a4b6797e862a20559d34a9e2a056ab6e1)
1/*
2 * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
9 *
10 * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 *
14 * Neither the name of ARM nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without specific
16 * prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include <arch.h>
32#include <asm_macros.S>
33#include <tsp.h>
34
35
36	.globl	tsp_entrypoint
37	.globl  tsp_vector_table
38
39
40
41	/* ---------------------------------------------
42	 * Populate the params in x0-x7 from the pointer
43	 * to the smc args structure in x0.
44	 * ---------------------------------------------
45	 */
46	.macro restore_args_call_smc
47	ldp	x6, x7, [x0, #TSP_ARG6]
48	ldp	x4, x5, [x0, #TSP_ARG4]
49	ldp	x2, x3, [x0, #TSP_ARG2]
50	ldp	x0, x1, [x0, #TSP_ARG0]
51	smc	#0
52	.endm
53
54	.macro	save_eret_context reg1 reg2
55	mrs	\reg1, elr_el1
56	mrs	\reg2, spsr_el1
57	stp	\reg1, \reg2, [sp, #-0x10]!
58	stp	x30, x18, [sp, #-0x10]!
59	.endm
60
61	.macro restore_eret_context reg1 reg2
62	ldp	x30, x18, [sp], #0x10
63	ldp	\reg1, \reg2, [sp], #0x10
64	msr	elr_el1, \reg1
65	msr	spsr_el1, \reg2
66	.endm
67
68	.section	.text, "ax"
69	.align 3
70
71func tsp_entrypoint
72
73	/* ---------------------------------------------
74	 * The entrypoint is expected to be executed
75	 * only by the primary cpu (at least for now).
76	 * So, make sure no secondary has lost its way.
77	 * ---------------------------------------------
78	 */
79	mrs	x0, mpidr_el1
80	bl	platform_is_primary_cpu
81	cbz	x0, tsp_entrypoint_panic
82
83	/* ---------------------------------------------
84	 * Set the exception vector to something sane.
85	 * ---------------------------------------------
86	 */
87	adr	x0, tsp_exceptions
88	msr	vbar_el1, x0
89
90	/* ---------------------------------------------
91	 * Enable the instruction cache.
92	 * ---------------------------------------------
93	 */
94	mrs	x0, sctlr_el1
95	orr	x0, x0, #SCTLR_I_BIT
96	msr	sctlr_el1, x0
97	isb
98
99	/* ---------------------------------------------
100	 * Zero out NOBITS sections. There are 2 of them:
101	 *   - the .bss section;
102	 *   - the coherent memory section.
103	 * ---------------------------------------------
104	 */
105	ldr	x0, =__BSS_START__
106	ldr	x1, =__BSS_SIZE__
107	bl	zeromem16
108
109	ldr	x0, =__COHERENT_RAM_START__
110	ldr	x1, =__COHERENT_RAM_UNALIGNED_SIZE__
111	bl	zeromem16
112
113	/* --------------------------------------------
114	 * Give ourselves a small coherent stack to
115	 * ease the pain of initializing the MMU
116	 * --------------------------------------------
117	 */
118	mrs	x0, mpidr_el1
119	bl	platform_set_coherent_stack
120
121	/* ---------------------------------------------
122	 * Perform early platform setup & platform
123	 * specific early arch. setup e.g. mmu setup
124	 * ---------------------------------------------
125	 */
126	bl	bl32_early_platform_setup
127	bl	bl32_plat_arch_setup
128
129	/* ---------------------------------------------
130	 * Give ourselves a stack allocated in Normal
131	 * -IS-WBWA memory
132	 * ---------------------------------------------
133	 */
134	mrs	x0, mpidr_el1
135	bl	platform_set_stack
136
137	/* ---------------------------------------------
138	 * Jump to main function.
139	 * ---------------------------------------------
140	 */
141	bl	tsp_main
142
143	/* ---------------------------------------------
144	 * Tell TSPD that we are done initialising
145	 * ---------------------------------------------
146	 */
147	mov	x1, x0
148	mov	x0, #TSP_ENTRY_DONE
149	smc	#0
150
151tsp_entrypoint_panic:
152	b	tsp_entrypoint_panic
153
154
155	/* -------------------------------------------
156	 * Table of entrypoint vectors provided to the
157	 * TSPD for the various entrypoints
158	 * -------------------------------------------
159	 */
160func tsp_vector_table
161	b	tsp_std_smc_entry
162	b	tsp_fast_smc_entry
163	b	tsp_cpu_on_entry
164	b	tsp_cpu_off_entry
165	b	tsp_cpu_resume_entry
166	b	tsp_cpu_suspend_entry
167	b	tsp_fiq_entry
168
169	/*---------------------------------------------
170	 * This entrypoint is used by the TSPD when this
171	 * cpu is to be turned off through a CPU_OFF
172	 * psci call to ask the TSP to perform any
173	 * bookeeping necessary. In the current
174	 * implementation, the TSPD expects the TSP to
175	 * re-initialise its state so nothing is done
176	 * here except for acknowledging the request.
177	 * ---------------------------------------------
178	 */
179func tsp_cpu_off_entry
180	bl	tsp_cpu_off_main
181	restore_args_call_smc
182
183	/*---------------------------------------------
184	 * This entrypoint is used by the TSPD when this
185	 * cpu is turned on using a CPU_ON psci call to
186	 * ask the TSP to initialise itself i.e. setup
187	 * the mmu, stacks etc. Minimal architectural
188	 * state will be initialised by the TSPD when
189	 * this function is entered i.e. Caches and MMU
190	 * will be turned off, the execution state
191	 * will be aarch64 and exceptions masked.
192	 * ---------------------------------------------
193	 */
194func tsp_cpu_on_entry
195	/* ---------------------------------------------
196	 * Set the exception vector to something sane.
197	 * ---------------------------------------------
198	 */
199	adr	x0, tsp_exceptions
200	msr	vbar_el1, x0
201
202	/* ---------------------------------------------
203	 * Enable the instruction cache.
204	 * ---------------------------------------------
205	 */
206	mrs	x0, sctlr_el1
207	orr	x0, x0, #SCTLR_I_BIT
208	msr	sctlr_el1, x0
209	isb
210
211	/* --------------------------------------------
212	 * Give ourselves a small coherent stack to
213	 * ease the pain of initializing the MMU
214	 * --------------------------------------------
215	 */
216	mrs	x0, mpidr_el1
217	bl	platform_set_coherent_stack
218
219	/* ---------------------------------------------
220	 * Initialise the MMU
221	 * ---------------------------------------------
222	 */
223	bl	bl32_plat_enable_mmu
224
225	/* ---------------------------------------------
226	 * Give ourselves a stack allocated in Normal
227	 * -IS-WBWA memory
228	 * ---------------------------------------------
229	 */
230	mrs	x0, mpidr_el1
231	bl	platform_set_stack
232
233	/* ---------------------------------------------
234	 * Enter C runtime to perform any remaining
235	 * book keeping
236	 * ---------------------------------------------
237	 */
238	bl	tsp_cpu_on_main
239	restore_args_call_smc
240
241	/* Should never reach here */
242tsp_cpu_on_entry_panic:
243	b	tsp_cpu_on_entry_panic
244
245	/*---------------------------------------------
246	 * This entrypoint is used by the TSPD when this
247	 * cpu is to be suspended through a CPU_SUSPEND
248	 * psci call to ask the TSP to perform any
249	 * bookeeping necessary. In the current
250	 * implementation, the TSPD saves and restores
251	 * the EL1 state.
252	 * ---------------------------------------------
253	 */
254func tsp_cpu_suspend_entry
255	bl	tsp_cpu_suspend_main
256	restore_args_call_smc
257
258	/*---------------------------------------------
259	 * This entrypoint is used by the TSPD to pass
260	 * control for handling a pending S-EL1 FIQ.
261	 * 'x0' contains a magic number which indicates
262	 * this. TSPD expects control to be handed back
263	 * at the end of FIQ processing. This is done
264	 * through an SMC. The handover agreement is:
265	 *
266	 * 1. PSTATE.DAIF are set upon entry. 'x1' has
267	 *    the ELR_EL3 from the non-secure state.
268	 * 2. TSP has to preserve the callee saved
269	 *    general purpose registers, SP_EL1/EL0 and
270	 *    LR.
271	 * 3. TSP has to preserve the system and vfp
272	 *    registers (if applicable).
273	 * 4. TSP can use 'x0-x18' to enable its C
274	 *    runtime.
275	 * 5. TSP returns to TSPD using an SMC with
276	 *    'x0' = TSP_HANDLED_S_EL1_FIQ
277	 * ---------------------------------------------
278	 */
279func	tsp_fiq_entry
280#if DEBUG
281	mov	x2, #(TSP_HANDLE_FIQ_AND_RETURN & ~0xffff)
282	movk	x2, #(TSP_HANDLE_FIQ_AND_RETURN &  0xffff)
283	cmp	x0, x2
284	b.ne	tsp_fiq_entry_panic
285#endif
286	/*---------------------------------------------
287	 * Save any previous context needed to perform
288	 * an exception return from S-EL1 e.g. context
289	 * from a previous IRQ. Update statistics and
290	 * handle the FIQ before returning to the TSPD.
291	 * IRQ/FIQs are not enabled since that will
292	 * complicate the implementation. Execution
293	 * will be transferred back to the normal world
294	 * in any case. A non-zero return value from the
295	 * fiq handler is an error.
296	 * ---------------------------------------------
297	 */
298	save_eret_context x2 x3
299	bl	tsp_update_sync_fiq_stats
300	bl	tsp_fiq_handler
301	cbnz	x0, tsp_fiq_entry_panic
302	restore_eret_context x2 x3
303	mov	x0, #(TSP_HANDLED_S_EL1_FIQ & ~0xffff)
304	movk	x0, #(TSP_HANDLED_S_EL1_FIQ &  0xffff)
305	smc	#0
306
307tsp_fiq_entry_panic:
308	b	tsp_fiq_entry_panic
309
310	/*---------------------------------------------
311	 * This entrypoint is used by the TSPD when this
312	 * cpu resumes execution after an earlier
313	 * CPU_SUSPEND psci call to ask the TSP to
314	 * restore its saved context. In the current
315	 * implementation, the TSPD saves and restores
316	 * EL1 state so nothing is done here apart from
317	 * acknowledging the request.
318	 * ---------------------------------------------
319	 */
320func tsp_cpu_resume_entry
321	bl	tsp_cpu_resume_main
322	restore_args_call_smc
323tsp_cpu_resume_panic:
324	b	tsp_cpu_resume_panic
325
326	/*---------------------------------------------
327	 * This entrypoint is used by the TSPD to ask
328	 * the TSP to service a fast smc request.
329	 * ---------------------------------------------
330	 */
331func tsp_fast_smc_entry
332	bl	tsp_smc_handler
333	restore_args_call_smc
334tsp_fast_smc_entry_panic:
335	b	tsp_fast_smc_entry_panic
336
337	/*---------------------------------------------
338	 * This entrypoint is used by the TSPD to ask
339	 * the TSP to service a std smc request.
340	 * We will enable preemption during execution
341	 * of tsp_smc_handler.
342	 * ---------------------------------------------
343	 */
344func tsp_std_smc_entry
345	msr	daifclr, #DAIF_FIQ_BIT | DAIF_IRQ_BIT
346	bl	tsp_smc_handler
347	msr	daifset, #DAIF_FIQ_BIT | DAIF_IRQ_BIT
348	restore_args_call_smc
349tsp_std_smc_entry_panic:
350	b	tsp_std_smc_entry_panic
351