1/* 2 * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7#include <arch.h> 8#include <asm_macros.S> 9#include <context.h> 10 11 .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 19 .global restore_gp_registers_eret 20 .global el3_exit 21 22/* ----------------------------------------------------- 23 * The following function strictly follows the AArch64 24 * PCS to use x9-x17 (temporary caller-saved registers) 25 * 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 */ 30func el1_sysregs_context_save 31 32 mrs x9, spsr_el1 33 mrs x10, elr_el1 34 stp x9, x10, [x0, #CTX_SPSR_EL1] 35 36 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 64 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 76 mrs x10, pmcr_el0 77 str x10, [x0, #CTX_PMCR_EL0] 78 79 /* 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] 92#endif 93 94 /* Save NS timer registers if the build has instructed so */ 95#if NS_TIMER_SWITCH 96 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 105 str x14, [x0, #CTX_CNTKCTL_EL1] 106#endif 107 108 ret 109endfunc el1_sysregs_context_save 110 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 */ 119func el1_sysregs_context_restore 120 121 ldp x9, x10, [x0, #CTX_SPSR_EL1] 122 msr spsr_el1, x9 123 msr elr_el1, x10 124 125 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 153 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 165 ldr x10, [x0, #CTX_PMCR_EL0] 166 msr pmcr_el0, x10 167 168 /* 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 181#endif 182 /* Restore NS timer registers if the build has instructed so */ 183#if NS_TIMER_SWITCH 184 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 192 ldr x14, [x0, #CTX_CNTKCTL_EL1] 193 msr cntkctl_el1, x14 194#endif 195 196 /* No explict ISB required here as ERET covers it */ 197 ret 198endfunc el1_sysregs_context_restore 199 200/* ----------------------------------------------------- 201 * The following function follows the aapcs_64 strictly 202 * 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 */ 216#if CTX_INCLUDE_FPREGS 217func fpregs_context_save 218 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 241#if CTX_INCLUDE_AARCH32_REGS 242 mrs x11, fpexc32_el2 243 str x11, [x0, #CTX_FP_FPEXC32_EL2] 244#endif 245 ret 246endfunc fpregs_context_save 247 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 */ 264func fpregs_context_restore 265 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 285 ldr x10, [x0, #CTX_FP_FPCR] 286 msr fpcr, x10 287 288#if CTX_INCLUDE_AARCH32_REGS 289 ldr x11, [x0, #CTX_FP_FPEXC32_EL2] 290 msr fpexc32_el2, x11 291#endif 292 /* 293 * No explict ISB required here as ERET to 294 * switch to secure EL1 or non-secure world 295 * covers it 296 */ 297 298 ret 299endfunc fpregs_context_restore 300#endif /* CTX_INCLUDE_FPREGS */ 301 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 335/* 336 * This function restores all general purpose registers except x30 from the 337 * CPU context. x30 register must be explicitly restored by the caller. 338 */ 339func restore_gp_registers 340 ldp x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0] 341 ldp x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2] 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 x16, x17, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X16] 349 ldp x18, x19, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X18] 350 ldp x20, x21, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X20] 351 ldp x22, x23, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X22] 352 ldp x24, x25, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X24] 353 ldp x26, x27, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X26] 354 ldr x28, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_SP_EL0] 355 msr sp_el0, x28 356 ldp x28, x29, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X28] 357 ret 358endfunc restore_gp_registers 359 360/* 361 * Restore general purpose registers (including x30), and exit EL3 via. ERET to 362 * a lower exception level. 363 */ 364func restore_gp_registers_eret 365 bl restore_gp_registers 366 ldr x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR] 367 368#if IMAGE_BL31 && RAS_EXTENSION 369 /* 370 * Issue Error Synchronization Barrier to synchronize SErrors before 371 * exiting EL3. We're running with EAs unmasked, so any synchronized 372 * errors would be taken immediately; therefore no need to inspect 373 * DISR_EL1 register. 374 */ 375 esb 376#endif 377 eret 378endfunc restore_gp_registers_eret 379 380 /* ----------------------------------------------------- 381 * This routine assumes that the SP_EL3 is pointing to 382 * a valid context structure from where the gp regs and 383 * other special registers can be retrieved. 384 * ----------------------------------------------------- 385 */ 386func el3_exit 387 /* ----------------------------------------------------- 388 * Save the current SP_EL0 i.e. the EL3 runtime stack 389 * which will be used for handling the next SMC. Then 390 * switch to SP_EL3 391 * ----------------------------------------------------- 392 */ 393 mov x17, sp 394 msr spsel, #1 395 str x17, [sp, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP] 396 397 /* ----------------------------------------------------- 398 * Restore SPSR_EL3, ELR_EL3 and SCR_EL3 prior to ERET 399 * ----------------------------------------------------- 400 */ 401 ldr x18, [sp, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3] 402 ldp x16, x17, [sp, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3] 403 msr scr_el3, x18 404 msr spsr_el3, x16 405 msr elr_el3, x17 406 407#if IMAGE_BL31 && DYNAMIC_WORKAROUND_CVE_2018_3639 408 /* Restore mitigation state as it was on entry to EL3 */ 409 ldr x17, [sp, #CTX_CVE_2018_3639_OFFSET + CTX_CVE_2018_3639_DISABLE] 410 cmp x17, xzr 411 beq 1f 412 blr x17 413#endif 414 4151: 416 /* Restore saved general purpose registers and return */ 417 b restore_gp_registers_eret 418endfunc el3_exit 419