blob: 620ec16ffe9f9de3e6c783531e10ad648827c1ce [file] [log] [blame]
Achin Gupta9ac63c52014-01-16 12:08:03 +00001/*
dp-armee3457b2017-05-23 09:32:49 +01002 * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
Achin Gupta9ac63c52014-01-16 12:08:03 +00003 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Achin Gupta9ac63c52014-01-16 12:08:03 +00005 */
6
Dan Handley2bd4ef22014-04-09 13:14:54 +01007#include <arch.h>
Andrew Thoelke38bde412014-03-18 13:46:55 +00008#include <asm_macros.S>
Dan Handley2bd4ef22014-04-09 13:14:54 +01009#include <context.h>
Achin Gupta9ac63c52014-01-16 12:08:03 +000010
Yatharth Kochar6c0566c2015-10-02 17:56:48 +010011 .global el1_sysregs_context_save
12 .global el1_sysregs_context_restore
13#if CTX_INCLUDE_FPREGS
14 .global fpregs_context_save
15 .global fpregs_context_restore
16#endif
17 .global save_gp_registers
18 .global restore_gp_registers_eret
19 .global restore_gp_registers_callee_eret
20 .global el3_exit
21
Achin Gupta9ac63c52014-01-16 12:08:03 +000022/* -----------------------------------------------------
23 * The following function strictly follows the AArch64
24 * PCS to use x9-x17 (temporary caller-saved registers)
Achin Gupta9ac63c52014-01-16 12:08:03 +000025 * to save EL1 system register context. It assumes that
26 * 'x0' is pointing to a 'el1_sys_regs' structure where
27 * the register context will be saved.
28 * -----------------------------------------------------
29 */
Andrew Thoelke38bde412014-03-18 13:46:55 +000030func el1_sysregs_context_save
Achin Gupta9ac63c52014-01-16 12:08:03 +000031
32 mrs x9, spsr_el1
33 mrs x10, elr_el1
34 stp x9, x10, [x0, #CTX_SPSR_EL1]
35
Achin Gupta9ac63c52014-01-16 12:08:03 +000036 mrs x15, sctlr_el1
37 mrs x16, actlr_el1
38 stp x15, x16, [x0, #CTX_SCTLR_EL1]
39
40 mrs x17, cpacr_el1
41 mrs x9, csselr_el1
42 stp x17, x9, [x0, #CTX_CPACR_EL1]
43
44 mrs x10, sp_el1
45 mrs x11, esr_el1
46 stp x10, x11, [x0, #CTX_SP_EL1]
47
48 mrs x12, ttbr0_el1
49 mrs x13, ttbr1_el1
50 stp x12, x13, [x0, #CTX_TTBR0_EL1]
51
52 mrs x14, mair_el1
53 mrs x15, amair_el1
54 stp x14, x15, [x0, #CTX_MAIR_EL1]
55
56 mrs x16, tcr_el1
57 mrs x17, tpidr_el1
58 stp x16, x17, [x0, #CTX_TCR_EL1]
59
60 mrs x9, tpidr_el0
61 mrs x10, tpidrro_el0
62 stp x9, x10, [x0, #CTX_TPIDR_EL0]
63
Achin Gupta9ac63c52014-01-16 12:08:03 +000064 mrs x13, par_el1
65 mrs x14, far_el1
66 stp x13, x14, [x0, #CTX_PAR_EL1]
67
68 mrs x15, afsr0_el1
69 mrs x16, afsr1_el1
70 stp x15, x16, [x0, #CTX_AFSR0_EL1]
71
72 mrs x17, contextidr_el1
73 mrs x9, vbar_el1
74 stp x17, x9, [x0, #CTX_CONTEXTIDR_EL1]
75
David Cunado4168f2f2017-10-02 17:41:39 +010076 mrs x10, pmcr_el0
77 str x10, [x0, #CTX_PMCR_EL0]
78
Soby Mathewd75d2ba2016-05-17 14:01:32 +010079 /* Save AArch32 system registers if the build has instructed so */
80#if CTX_INCLUDE_AARCH32_REGS
81 mrs x11, spsr_abt
82 mrs x12, spsr_und
83 stp x11, x12, [x0, #CTX_SPSR_ABT]
84
85 mrs x13, spsr_irq
86 mrs x14, spsr_fiq
87 stp x13, x14, [x0, #CTX_SPSR_IRQ]
88
89 mrs x15, dacr32_el2
90 mrs x16, ifsr32_el2
91 stp x15, x16, [x0, #CTX_DACR32_EL2]
Soby Mathewd75d2ba2016-05-17 14:01:32 +010092#endif
93
Jeenu Viswambharand1b60152014-05-12 15:28:47 +010094 /* Save NS timer registers if the build has instructed so */
95#if NS_TIMER_SWITCH
Achin Gupta9ac63c52014-01-16 12:08:03 +000096 mrs x10, cntp_ctl_el0
97 mrs x11, cntp_cval_el0
98 stp x10, x11, [x0, #CTX_CNTP_CTL_EL0]
99
100 mrs x12, cntv_ctl_el0
101 mrs x13, cntv_cval_el0
102 stp x12, x13, [x0, #CTX_CNTV_CTL_EL0]
103
104 mrs x14, cntkctl_el1
Jeenu Viswambharand1b60152014-05-12 15:28:47 +0100105 str x14, [x0, #CTX_CNTKCTL_EL1]
106#endif
107
Achin Gupta9ac63c52014-01-16 12:08:03 +0000108 ret
Kévin Petita877c252015-03-24 14:03:57 +0000109endfunc el1_sysregs_context_save
Achin Gupta9ac63c52014-01-16 12:08:03 +0000110
111/* -----------------------------------------------------
112 * The following function strictly follows the AArch64
113 * PCS to use x9-x17 (temporary caller-saved registers)
114 * to restore EL1 system register context. It assumes
115 * that 'x0' is pointing to a 'el1_sys_regs' structure
116 * from where the register context will be restored
117 * -----------------------------------------------------
118 */
Andrew Thoelke38bde412014-03-18 13:46:55 +0000119func el1_sysregs_context_restore
Achin Gupta9ac63c52014-01-16 12:08:03 +0000120
121 ldp x9, x10, [x0, #CTX_SPSR_EL1]
122 msr spsr_el1, x9
123 msr elr_el1, x10
124
Achin Gupta9ac63c52014-01-16 12:08:03 +0000125 ldp x15, x16, [x0, #CTX_SCTLR_EL1]
126 msr sctlr_el1, x15
127 msr actlr_el1, x16
128
129 ldp x17, x9, [x0, #CTX_CPACR_EL1]
130 msr cpacr_el1, x17
131 msr csselr_el1, x9
132
133 ldp x10, x11, [x0, #CTX_SP_EL1]
134 msr sp_el1, x10
135 msr esr_el1, x11
136
137 ldp x12, x13, [x0, #CTX_TTBR0_EL1]
138 msr ttbr0_el1, x12
139 msr ttbr1_el1, x13
140
141 ldp x14, x15, [x0, #CTX_MAIR_EL1]
142 msr mair_el1, x14
143 msr amair_el1, x15
144
145 ldp x16, x17, [x0, #CTX_TCR_EL1]
146 msr tcr_el1, x16
147 msr tpidr_el1, x17
148
149 ldp x9, x10, [x0, #CTX_TPIDR_EL0]
150 msr tpidr_el0, x9
151 msr tpidrro_el0, x10
152
Achin Gupta9ac63c52014-01-16 12:08:03 +0000153 ldp x13, x14, [x0, #CTX_PAR_EL1]
154 msr par_el1, x13
155 msr far_el1, x14
156
157 ldp x15, x16, [x0, #CTX_AFSR0_EL1]
158 msr afsr0_el1, x15
159 msr afsr1_el1, x16
160
161 ldp x17, x9, [x0, #CTX_CONTEXTIDR_EL1]
162 msr contextidr_el1, x17
163 msr vbar_el1, x9
164
David Cunado4168f2f2017-10-02 17:41:39 +0100165 ldr x10, [x0, #CTX_PMCR_EL0]
166 msr pmcr_el0, x10
167
Soby Mathewd75d2ba2016-05-17 14:01:32 +0100168 /* Restore AArch32 system registers if the build has instructed so */
169#if CTX_INCLUDE_AARCH32_REGS
170 ldp x11, x12, [x0, #CTX_SPSR_ABT]
171 msr spsr_abt, x11
172 msr spsr_und, x12
173
174 ldp x13, x14, [x0, #CTX_SPSR_IRQ]
175 msr spsr_irq, x13
176 msr spsr_fiq, x14
177
178 ldp x15, x16, [x0, #CTX_DACR32_EL2]
179 msr dacr32_el2, x15
180 msr ifsr32_el2, x16
Soby Mathewd75d2ba2016-05-17 14:01:32 +0100181#endif
Jeenu Viswambharand1b60152014-05-12 15:28:47 +0100182 /* Restore NS timer registers if the build has instructed so */
183#if NS_TIMER_SWITCH
Achin Gupta9ac63c52014-01-16 12:08:03 +0000184 ldp x10, x11, [x0, #CTX_CNTP_CTL_EL0]
185 msr cntp_ctl_el0, x10
186 msr cntp_cval_el0, x11
187
188 ldp x12, x13, [x0, #CTX_CNTV_CTL_EL0]
189 msr cntv_ctl_el0, x12
190 msr cntv_cval_el0, x13
191
Jeenu Viswambharand1b60152014-05-12 15:28:47 +0100192 ldr x14, [x0, #CTX_CNTKCTL_EL1]
Achin Gupta9ac63c52014-01-16 12:08:03 +0000193 msr cntkctl_el1, x14
Jeenu Viswambharand1b60152014-05-12 15:28:47 +0100194#endif
195
Achin Gupta9ac63c52014-01-16 12:08:03 +0000196 /* No explict ISB required here as ERET covers it */
Achin Gupta9ac63c52014-01-16 12:08:03 +0000197 ret
Kévin Petita877c252015-03-24 14:03:57 +0000198endfunc el1_sysregs_context_restore
Achin Gupta9ac63c52014-01-16 12:08:03 +0000199
200/* -----------------------------------------------------
Sandrine Bailleux046cd3f2014-08-06 11:27:23 +0100201 * The following function follows the aapcs_64 strictly
Achin Gupta9ac63c52014-01-16 12:08:03 +0000202 * to use x9-x17 (temporary caller-saved registers
203 * according to AArch64 PCS) to save floating point
204 * register context. It assumes that 'x0' is pointing to
205 * a 'fp_regs' structure where the register context will
206 * be saved.
207 *
208 * Access to VFP registers will trap if CPTR_EL3.TFP is
209 * set. However currently we don't use VFP registers
210 * nor set traps in Trusted Firmware, and assume it's
211 * cleared
212 *
213 * TODO: Revisit when VFP is used in secure world
214 * -----------------------------------------------------
215 */
Juan Castillo258e94f2014-06-25 17:26:36 +0100216#if CTX_INCLUDE_FPREGS
Andrew Thoelke38bde412014-03-18 13:46:55 +0000217func fpregs_context_save
Achin Gupta9ac63c52014-01-16 12:08:03 +0000218 stp q0, q1, [x0, #CTX_FP_Q0]
219 stp q2, q3, [x0, #CTX_FP_Q2]
220 stp q4, q5, [x0, #CTX_FP_Q4]
221 stp q6, q7, [x0, #CTX_FP_Q6]
222 stp q8, q9, [x0, #CTX_FP_Q8]
223 stp q10, q11, [x0, #CTX_FP_Q10]
224 stp q12, q13, [x0, #CTX_FP_Q12]
225 stp q14, q15, [x0, #CTX_FP_Q14]
226 stp q16, q17, [x0, #CTX_FP_Q16]
227 stp q18, q19, [x0, #CTX_FP_Q18]
228 stp q20, q21, [x0, #CTX_FP_Q20]
229 stp q22, q23, [x0, #CTX_FP_Q22]
230 stp q24, q25, [x0, #CTX_FP_Q24]
231 stp q26, q27, [x0, #CTX_FP_Q26]
232 stp q28, q29, [x0, #CTX_FP_Q28]
233 stp q30, q31, [x0, #CTX_FP_Q30]
234
235 mrs x9, fpsr
236 str x9, [x0, #CTX_FP_FPSR]
237
238 mrs x10, fpcr
239 str x10, [x0, #CTX_FP_FPCR]
240
David Cunadod1a1fd42017-10-20 11:30:57 +0100241#if CTX_INCLUDE_AARCH32_REGS
242 mrs x11, fpexc32_el2
243 str x11, [x0, #CTX_FP_FPEXC32_EL2]
244#endif
Achin Gupta9ac63c52014-01-16 12:08:03 +0000245 ret
Kévin Petita877c252015-03-24 14:03:57 +0000246endfunc fpregs_context_save
Achin Gupta9ac63c52014-01-16 12:08:03 +0000247
248/* -----------------------------------------------------
249 * The following function follows the aapcs_64 strictly
250 * to use x9-x17 (temporary caller-saved registers
251 * according to AArch64 PCS) to restore floating point
252 * register context. It assumes that 'x0' is pointing to
253 * a 'fp_regs' structure from where the register context
254 * will be restored.
255 *
256 * Access to VFP registers will trap if CPTR_EL3.TFP is
257 * set. However currently we don't use VFP registers
258 * nor set traps in Trusted Firmware, and assume it's
259 * cleared
260 *
261 * TODO: Revisit when VFP is used in secure world
262 * -----------------------------------------------------
263 */
Andrew Thoelke38bde412014-03-18 13:46:55 +0000264func fpregs_context_restore
Achin Gupta9ac63c52014-01-16 12:08:03 +0000265 ldp q0, q1, [x0, #CTX_FP_Q0]
266 ldp q2, q3, [x0, #CTX_FP_Q2]
267 ldp q4, q5, [x0, #CTX_FP_Q4]
268 ldp q6, q7, [x0, #CTX_FP_Q6]
269 ldp q8, q9, [x0, #CTX_FP_Q8]
270 ldp q10, q11, [x0, #CTX_FP_Q10]
271 ldp q12, q13, [x0, #CTX_FP_Q12]
272 ldp q14, q15, [x0, #CTX_FP_Q14]
273 ldp q16, q17, [x0, #CTX_FP_Q16]
274 ldp q18, q19, [x0, #CTX_FP_Q18]
275 ldp q20, q21, [x0, #CTX_FP_Q20]
276 ldp q22, q23, [x0, #CTX_FP_Q22]
277 ldp q24, q25, [x0, #CTX_FP_Q24]
278 ldp q26, q27, [x0, #CTX_FP_Q26]
279 ldp q28, q29, [x0, #CTX_FP_Q28]
280 ldp q30, q31, [x0, #CTX_FP_Q30]
281
282 ldr x9, [x0, #CTX_FP_FPSR]
283 msr fpsr, x9
284
Soby Mathewe77e1162015-12-03 09:42:50 +0000285 ldr x10, [x0, #CTX_FP_FPCR]
Achin Gupta9ac63c52014-01-16 12:08:03 +0000286 msr fpcr, x10
287
David Cunadod1a1fd42017-10-20 11:30:57 +0100288#if CTX_INCLUDE_AARCH32_REGS
289 ldr x11, [x0, #CTX_FP_FPEXC32_EL2]
290 msr fpexc32_el2, x11
291#endif
Achin Gupta9ac63c52014-01-16 12:08:03 +0000292 /*
293 * No explict ISB required here as ERET to
Sandrine Bailleuxf4119ec2015-12-17 13:58:58 +0000294 * switch to secure EL1 or non-secure world
Achin Gupta9ac63c52014-01-16 12:08:03 +0000295 * covers it
296 */
297
298 ret
Kévin Petita877c252015-03-24 14:03:57 +0000299endfunc fpregs_context_restore
Juan Castillo258e94f2014-06-25 17:26:36 +0100300#endif /* CTX_INCLUDE_FPREGS */
Yatharth Kochar6c0566c2015-10-02 17:56:48 +0100301
302/* -----------------------------------------------------
303 * The following functions are used to save and restore
304 * all the general purpose registers. Ideally we would
305 * only save and restore the callee saved registers when
306 * a world switch occurs but that type of implementation
307 * is more complex. So currently we will always save and
308 * restore these registers on entry and exit of EL3.
309 * These are not macros to ensure their invocation fits
310 * within the 32 instructions per exception vector.
311 * clobbers: x18
312 * -----------------------------------------------------
313 */
314func save_gp_registers
315 stp x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
316 stp x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2]
317 stp x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4]
318 stp x6, x7, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X6]
319 stp x8, x9, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X8]
320 stp x10, x11, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X10]
321 stp x12, x13, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X12]
322 stp x14, x15, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X14]
323 stp x16, x17, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X16]
324 stp x18, x19, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X18]
325 stp x20, x21, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X20]
326 stp x22, x23, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X22]
327 stp x24, x25, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X24]
328 stp x26, x27, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X26]
329 stp x28, x29, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X28]
330 mrs x18, sp_el0
331 str x18, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_SP_EL0]
332 ret
333endfunc save_gp_registers
334
335func restore_gp_registers_eret
336 ldp x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
337 ldp x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2]
338 b restore_gp_registers_callee_eret
339endfunc restore_gp_registers_eret
340
341func restore_gp_registers_callee_eret
342 ldp x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4]
343 ldp x6, x7, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X6]
344 ldp x8, x9, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X8]
345 ldp x10, x11, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X10]
346 ldp x12, x13, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X12]
347 ldp x14, x15, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X14]
348 ldp x18, x19, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X18]
349 ldp x20, x21, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X20]
350 ldp x22, x23, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X22]
351 ldp x24, x25, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X24]
352 ldp x26, x27, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X26]
353 ldp x28, x29, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X28]
dp-armee3457b2017-05-23 09:32:49 +0100354 ldp x30, x17, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
Yatharth Kochar6c0566c2015-10-02 17:56:48 +0100355 msr sp_el0, x17
356 ldp x16, x17, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X16]
357 eret
358endfunc restore_gp_registers_callee_eret
359
360 /* -----------------------------------------------------
361 * This routine assumes that the SP_EL3 is pointing to
362 * a valid context structure from where the gp regs and
363 * other special registers can be retrieved.
364 * -----------------------------------------------------
365 */
366func el3_exit
367 /* -----------------------------------------------------
368 * Save the current SP_EL0 i.e. the EL3 runtime stack
369 * which will be used for handling the next SMC. Then
370 * switch to SP_EL3
371 * -----------------------------------------------------
372 */
373 mov x17, sp
374 msr spsel, #1
375 str x17, [sp, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]
376
377 /* -----------------------------------------------------
378 * Restore SPSR_EL3, ELR_EL3 and SCR_EL3 prior to ERET
379 * -----------------------------------------------------
380 */
381 ldr x18, [sp, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
382 ldp x16, x17, [sp, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
383 msr scr_el3, x18
384 msr spsr_el3, x16
385 msr elr_el3, x17
386
387 /* Restore saved general purpose registers and return */
388 b restore_gp_registers_eret
389endfunc el3_exit