1/* 2 * Copyright (c) 2013-2019, 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#if CTX_INCLUDE_PAUTH_REGS 18 .global pauth_context_restore 19 .global pauth_context_save 20#endif 21#if ENABLE_PAUTH 22 .global pauth_load_bl_apiakey 23#endif 24 .global save_gp_registers 25 .global restore_gp_registers 26 .global restore_gp_registers_eret 27 .global save_pmcr_disable_pmu 28 .global el3_exit 29 30/* ----------------------------------------------------- 31 * If ARMv8.5-PMU is implemented, cycle counting is 32 * disabled by seting MDCR_EL3.SCCD to 1. 33 * ----------------------------------------------------- 34 */ 35func save_pmcr_disable_pmu 36 /* ----------------------------------------------------- 37 * Check if earlier initialization MDCR_EL3.SCCD to 1 38 * failed, meaning that ARMv8-PMU is not implemented and 39 * PMCR_EL0 should be saved in non-secure context. 40 * ----------------------------------------------------- 41 */ 42 mrs x9, mdcr_el3 43 tst x9, #MDCR_SCCD_BIT 44 bne 1f 45 46 /* Secure Cycle Counter is not disabled */ 47 mrs x9, pmcr_el0 48 49 /* Check caller's security state */ 50 mrs x10, scr_el3 51 tst x10, #SCR_NS_BIT 52 beq 2f 53 54 /* Save PMCR_EL0 if called from Non-secure state */ 55 str x9, [sp, #CTX_EL3STATE_OFFSET + CTX_PMCR_EL0] 56 57 /* Disable cycle counter when event counting is prohibited */ 582: orr x9, x9, #PMCR_EL0_DP_BIT 59 msr pmcr_el0, x9 60 61 isb 621: ret 63endfunc save_pmcr_disable_pmu 64 65/* ----------------------------------------------------- 66 * The following function strictly follows the AArch64 67 * PCS to use x9-x17 (temporary caller-saved registers) 68 * to save EL1 system register context. It assumes that 69 * 'x0' is pointing to a 'el1_sys_regs' structure where 70 * the register context will be saved. 71 * ----------------------------------------------------- 72 */ 73func el1_sysregs_context_save 74 75 mrs x9, spsr_el1 76 mrs x10, elr_el1 77 stp x9, x10, [x0, #CTX_SPSR_EL1] 78 79 mrs x15, sctlr_el1 80 mrs x16, actlr_el1 81 stp x15, x16, [x0, #CTX_SCTLR_EL1] 82 83 mrs x17, cpacr_el1 84 mrs x9, csselr_el1 85 stp x17, x9, [x0, #CTX_CPACR_EL1] 86 87 mrs x10, sp_el1 88 mrs x11, esr_el1 89 stp x10, x11, [x0, #CTX_SP_EL1] 90 91 mrs x12, ttbr0_el1 92 mrs x13, ttbr1_el1 93 stp x12, x13, [x0, #CTX_TTBR0_EL1] 94 95 mrs x14, mair_el1 96 mrs x15, amair_el1 97 stp x14, x15, [x0, #CTX_MAIR_EL1] 98 99 mrs x16, tcr_el1 100 mrs x17, tpidr_el1 101 stp x16, x17, [x0, #CTX_TCR_EL1] 102 103 mrs x9, tpidr_el0 104 mrs x10, tpidrro_el0 105 stp x9, x10, [x0, #CTX_TPIDR_EL0] 106 107 mrs x13, par_el1 108 mrs x14, far_el1 109 stp x13, x14, [x0, #CTX_PAR_EL1] 110 111 mrs x15, afsr0_el1 112 mrs x16, afsr1_el1 113 stp x15, x16, [x0, #CTX_AFSR0_EL1] 114 115 mrs x17, contextidr_el1 116 mrs x9, vbar_el1 117 stp x17, x9, [x0, #CTX_CONTEXTIDR_EL1] 118 119 /* Save AArch32 system registers if the build has instructed so */ 120#if CTX_INCLUDE_AARCH32_REGS 121 mrs x11, spsr_abt 122 mrs x12, spsr_und 123 stp x11, x12, [x0, #CTX_SPSR_ABT] 124 125 mrs x13, spsr_irq 126 mrs x14, spsr_fiq 127 stp x13, x14, [x0, #CTX_SPSR_IRQ] 128 129 mrs x15, dacr32_el2 130 mrs x16, ifsr32_el2 131 stp x15, x16, [x0, #CTX_DACR32_EL2] 132#endif 133 134 /* Save NS timer registers if the build has instructed so */ 135#if NS_TIMER_SWITCH 136 mrs x10, cntp_ctl_el0 137 mrs x11, cntp_cval_el0 138 stp x10, x11, [x0, #CTX_CNTP_CTL_EL0] 139 140 mrs x12, cntv_ctl_el0 141 mrs x13, cntv_cval_el0 142 stp x12, x13, [x0, #CTX_CNTV_CTL_EL0] 143 144 mrs x14, cntkctl_el1 145 str x14, [x0, #CTX_CNTKCTL_EL1] 146#endif 147 148 ret 149endfunc el1_sysregs_context_save 150 151/* ----------------------------------------------------- 152 * The following function strictly follows the AArch64 153 * PCS to use x9-x17 (temporary caller-saved registers) 154 * to restore EL1 system register context. It assumes 155 * that 'x0' is pointing to a 'el1_sys_regs' structure 156 * from where the register context will be restored 157 * ----------------------------------------------------- 158 */ 159func el1_sysregs_context_restore 160 161 ldp x9, x10, [x0, #CTX_SPSR_EL1] 162 msr spsr_el1, x9 163 msr elr_el1, x10 164 165 ldp x15, x16, [x0, #CTX_SCTLR_EL1] 166 msr sctlr_el1, x15 167 msr actlr_el1, x16 168 169 ldp x17, x9, [x0, #CTX_CPACR_EL1] 170 msr cpacr_el1, x17 171 msr csselr_el1, x9 172 173 ldp x10, x11, [x0, #CTX_SP_EL1] 174 msr sp_el1, x10 175 msr esr_el1, x11 176 177 ldp x12, x13, [x0, #CTX_TTBR0_EL1] 178 msr ttbr0_el1, x12 179 msr ttbr1_el1, x13 180 181 ldp x14, x15, [x0, #CTX_MAIR_EL1] 182 msr mair_el1, x14 183 msr amair_el1, x15 184 185 ldp x16, x17, [x0, #CTX_TCR_EL1] 186 msr tcr_el1, x16 187 msr tpidr_el1, x17 188 189 ldp x9, x10, [x0, #CTX_TPIDR_EL0] 190 msr tpidr_el0, x9 191 msr tpidrro_el0, x10 192 193 ldp x13, x14, [x0, #CTX_PAR_EL1] 194 msr par_el1, x13 195 msr far_el1, x14 196 197 ldp x15, x16, [x0, #CTX_AFSR0_EL1] 198 msr afsr0_el1, x15 199 msr afsr1_el1, x16 200 201 ldp x17, x9, [x0, #CTX_CONTEXTIDR_EL1] 202 msr contextidr_el1, x17 203 msr vbar_el1, x9 204 205 /* Restore AArch32 system registers if the build has instructed so */ 206#if CTX_INCLUDE_AARCH32_REGS 207 ldp x11, x12, [x0, #CTX_SPSR_ABT] 208 msr spsr_abt, x11 209 msr spsr_und, x12 210 211 ldp x13, x14, [x0, #CTX_SPSR_IRQ] 212 msr spsr_irq, x13 213 msr spsr_fiq, x14 214 215 ldp x15, x16, [x0, #CTX_DACR32_EL2] 216 msr dacr32_el2, x15 217 msr ifsr32_el2, x16 218#endif 219 /* Restore NS timer registers if the build has instructed so */ 220#if NS_TIMER_SWITCH 221 ldp x10, x11, [x0, #CTX_CNTP_CTL_EL0] 222 msr cntp_ctl_el0, x10 223 msr cntp_cval_el0, x11 224 225 ldp x12, x13, [x0, #CTX_CNTV_CTL_EL0] 226 msr cntv_ctl_el0, x12 227 msr cntv_cval_el0, x13 228 229 ldr x14, [x0, #CTX_CNTKCTL_EL1] 230 msr cntkctl_el1, x14 231#endif 232 233 /* No explict ISB required here as ERET covers it */ 234 ret 235endfunc el1_sysregs_context_restore 236 237/* ----------------------------------------------------- 238 * The following function follows the aapcs_64 strictly 239 * to use x9-x17 (temporary caller-saved registers 240 * according to AArch64 PCS) to save floating point 241 * register context. It assumes that 'x0' is pointing to 242 * a 'fp_regs' structure where the register context will 243 * be saved. 244 * 245 * Access to VFP registers will trap if CPTR_EL3.TFP is 246 * set. However currently we don't use VFP registers 247 * nor set traps in Trusted Firmware, and assume it's 248 * cleared 249 * 250 * TODO: Revisit when VFP is used in secure world 251 * ----------------------------------------------------- 252 */ 253#if CTX_INCLUDE_FPREGS 254func fpregs_context_save 255 stp q0, q1, [x0, #CTX_FP_Q0] 256 stp q2, q3, [x0, #CTX_FP_Q2] 257 stp q4, q5, [x0, #CTX_FP_Q4] 258 stp q6, q7, [x0, #CTX_FP_Q6] 259 stp q8, q9, [x0, #CTX_FP_Q8] 260 stp q10, q11, [x0, #CTX_FP_Q10] 261 stp q12, q13, [x0, #CTX_FP_Q12] 262 stp q14, q15, [x0, #CTX_FP_Q14] 263 stp q16, q17, [x0, #CTX_FP_Q16] 264 stp q18, q19, [x0, #CTX_FP_Q18] 265 stp q20, q21, [x0, #CTX_FP_Q20] 266 stp q22, q23, [x0, #CTX_FP_Q22] 267 stp q24, q25, [x0, #CTX_FP_Q24] 268 stp q26, q27, [x0, #CTX_FP_Q26] 269 stp q28, q29, [x0, #CTX_FP_Q28] 270 stp q30, q31, [x0, #CTX_FP_Q30] 271 272 mrs x9, fpsr 273 str x9, [x0, #CTX_FP_FPSR] 274 275 mrs x10, fpcr 276 str x10, [x0, #CTX_FP_FPCR] 277 278#if CTX_INCLUDE_AARCH32_REGS 279 mrs x11, fpexc32_el2 280 str x11, [x0, #CTX_FP_FPEXC32_EL2] 281#endif 282 ret 283endfunc fpregs_context_save 284 285/* ----------------------------------------------------- 286 * The following function follows the aapcs_64 strictly 287 * to use x9-x17 (temporary caller-saved registers 288 * according to AArch64 PCS) to restore floating point 289 * register context. It assumes that 'x0' is pointing to 290 * a 'fp_regs' structure from where the register context 291 * will be restored. 292 * 293 * Access to VFP registers will trap if CPTR_EL3.TFP is 294 * set. However currently we don't use VFP registers 295 * nor set traps in Trusted Firmware, and assume it's 296 * cleared 297 * 298 * TODO: Revisit when VFP is used in secure world 299 * ----------------------------------------------------- 300 */ 301func fpregs_context_restore 302 ldp q0, q1, [x0, #CTX_FP_Q0] 303 ldp q2, q3, [x0, #CTX_FP_Q2] 304 ldp q4, q5, [x0, #CTX_FP_Q4] 305 ldp q6, q7, [x0, #CTX_FP_Q6] 306 ldp q8, q9, [x0, #CTX_FP_Q8] 307 ldp q10, q11, [x0, #CTX_FP_Q10] 308 ldp q12, q13, [x0, #CTX_FP_Q12] 309 ldp q14, q15, [x0, #CTX_FP_Q14] 310 ldp q16, q17, [x0, #CTX_FP_Q16] 311 ldp q18, q19, [x0, #CTX_FP_Q18] 312 ldp q20, q21, [x0, #CTX_FP_Q20] 313 ldp q22, q23, [x0, #CTX_FP_Q22] 314 ldp q24, q25, [x0, #CTX_FP_Q24] 315 ldp q26, q27, [x0, #CTX_FP_Q26] 316 ldp q28, q29, [x0, #CTX_FP_Q28] 317 ldp q30, q31, [x0, #CTX_FP_Q30] 318 319 ldr x9, [x0, #CTX_FP_FPSR] 320 msr fpsr, x9 321 322 ldr x10, [x0, #CTX_FP_FPCR] 323 msr fpcr, x10 324 325#if CTX_INCLUDE_AARCH32_REGS 326 ldr x11, [x0, #CTX_FP_FPEXC32_EL2] 327 msr fpexc32_el2, x11 328#endif 329 /* 330 * No explict ISB required here as ERET to 331 * switch to secure EL1 or non-secure world 332 * covers it 333 */ 334 335 ret 336endfunc fpregs_context_restore 337#endif /* CTX_INCLUDE_FPREGS */ 338 339#if CTX_INCLUDE_PAUTH_REGS 340/* ----------------------------------------------------- 341 * The following function strictly follows the AArch64 342 * PCS to use x9-x17 (temporary caller-saved registers) 343 * to save the ARMv8.3-PAuth register context. It assumes 344 * that 'sp' is pointing to a 'cpu_context_t' structure 345 * to where the register context will be saved. 346 * ----------------------------------------------------- 347 */ 348func pauth_context_save 349 add x11, sp, #CTX_PAUTH_REGS_OFFSET 350 351 mrs x9, APIAKeyLo_EL1 352 mrs x10, APIAKeyHi_EL1 353 stp x9, x10, [x11, #CTX_PACIAKEY_LO] 354 355 mrs x9, APIBKeyLo_EL1 356 mrs x10, APIBKeyHi_EL1 357 stp x9, x10, [x11, #CTX_PACIBKEY_LO] 358 359 mrs x9, APDAKeyLo_EL1 360 mrs x10, APDAKeyHi_EL1 361 stp x9, x10, [x11, #CTX_PACDAKEY_LO] 362 363 mrs x9, APDBKeyLo_EL1 364 mrs x10, APDBKeyHi_EL1 365 stp x9, x10, [x11, #CTX_PACDBKEY_LO] 366 367 mrs x9, APGAKeyLo_EL1 368 mrs x10, APGAKeyHi_EL1 369 stp x9, x10, [x11, #CTX_PACGAKEY_LO] 370 371 ret 372endfunc pauth_context_save 373 374/* ----------------------------------------------------- 375 * The following function strictly follows the AArch64 376 * PCS to use x9-x17 (temporary caller-saved registers) 377 * to restore the ARMv8.3-PAuth register context. It assumes 378 * that 'sp' is pointing to a 'cpu_context_t' structure 379 * from where the register context will be restored. 380 * ----------------------------------------------------- 381 */ 382func pauth_context_restore 383 add x11, sp, #CTX_PAUTH_REGS_OFFSET 384 385 ldp x9, x10, [x11, #CTX_PACIAKEY_LO] 386 msr APIAKeyLo_EL1, x9 387 msr APIAKeyHi_EL1, x10 388 389 ldp x9, x10, [x11, #CTX_PACIBKEY_LO] 390 msr APIBKeyLo_EL1, x9 391 msr APIBKeyHi_EL1, x10 392 393 ldp x9, x10, [x11, #CTX_PACDAKEY_LO] 394 msr APDAKeyLo_EL1, x9 395 msr APDAKeyHi_EL1, x10 396 397 ldp x9, x10, [x11, #CTX_PACDBKEY_LO] 398 msr APDBKeyLo_EL1, x9 399 msr APDBKeyHi_EL1, x10 400 401 ldp x9, x10, [x11, #CTX_PACGAKEY_LO] 402 msr APGAKeyLo_EL1, x9 403 msr APGAKeyHi_EL1, x10 404 405 ret 406endfunc pauth_context_restore 407#endif /* CTX_INCLUDE_PAUTH_REGS */ 408 409/* ----------------------------------------------------- 410 * The following function strictly follows the AArch64 411 * PCS to use x9-x17 (temporary caller-saved registers) 412 * to load the APIA key used by the firmware. 413 * ----------------------------------------------------- 414 */ 415#if ENABLE_PAUTH 416func pauth_load_bl_apiakey 417 /* Load instruction key A used by the Trusted Firmware. */ 418 adrp x11, plat_apiakey 419 add x11, x11, :lo12:plat_apiakey 420 ldp x9, x10, [x11, #0] 421 422 msr APIAKeyLo_EL1, x9 423 msr APIAKeyHi_EL1, x10 424 425 ret 426endfunc pauth_load_bl_apiakey 427#endif /* ENABLE_PAUTH */ 428 429/* ----------------------------------------------------- 430 * The following functions are used to save and restore 431 * all the general purpose registers. Ideally we would 432 * only save and restore the callee saved registers when 433 * a world switch occurs but that type of implementation 434 * is more complex. So currently we will always save and 435 * restore these registers on entry and exit of EL3. 436 * These are not macros to ensure their invocation fits 437 * within the 32 instructions per exception vector. 438 * clobbers: x18 439 * ----------------------------------------------------- 440 */ 441func save_gp_registers 442 stp x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0] 443 stp x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2] 444 stp x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4] 445 stp x6, x7, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X6] 446 stp x8, x9, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X8] 447 stp x10, x11, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X10] 448 stp x12, x13, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X12] 449 stp x14, x15, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X14] 450 stp x16, x17, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X16] 451 stp x18, x19, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X18] 452 stp x20, x21, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X20] 453 stp x22, x23, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X22] 454 stp x24, x25, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X24] 455 stp x26, x27, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X26] 456 stp x28, x29, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X28] 457 mrs x18, sp_el0 458 str x18, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_SP_EL0] 459 ret 460endfunc save_gp_registers 461 462/* ----------------------------------------------------- 463 * This function restores all general purpose registers except x30 from the 464 * CPU context. x30 register must be explicitly restored by the caller. 465 * ----------------------------------------------------- 466 */ 467func restore_gp_registers 468 ldp x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0] 469 ldp x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2] 470 ldp x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4] 471 ldp x6, x7, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X6] 472 ldp x8, x9, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X8] 473 ldp x10, x11, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X10] 474 ldp x12, x13, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X12] 475 ldp x14, x15, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X14] 476 ldp x16, x17, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X16] 477 ldp x18, x19, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X18] 478 ldp x20, x21, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X20] 479 ldp x22, x23, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X22] 480 ldp x24, x25, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X24] 481 ldp x26, x27, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X26] 482 ldr x28, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_SP_EL0] 483 msr sp_el0, x28 484 ldp x28, x29, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X28] 485 ret 486endfunc restore_gp_registers 487 488/* ----------------------------------------------------- 489 * Restore general purpose registers (including x30), and exit EL3 via ERET to 490 * a lower exception level. 491 * ----------------------------------------------------- 492 */ 493func restore_gp_registers_eret 494 bl restore_gp_registers 495 ldr x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR] 496 497#if IMAGE_BL31 && RAS_EXTENSION 498 /* 499 * Issue Error Synchronization Barrier to synchronize SErrors before 500 * exiting EL3. We're running with EAs unmasked, so any synchronized 501 * errors would be taken immediately; therefore no need to inspect 502 * DISR_EL1 register. 503 */ 504 esb 505#endif 506 eret 507endfunc restore_gp_registers_eret 508 509/* ----------------------------------------------------- 510 * This routine assumes that the SP_EL3 is pointing to 511 * a valid context structure from where the gp regs and 512 * other special registers can be retrieved. 513 * ----------------------------------------------------- 514 */ 515func el3_exit 516 /* ----------------------------------------------------- 517 * Save the current SP_EL0 i.e. the EL3 runtime stack 518 * which will be used for handling the next SMC. Then 519 * switch to SP_EL3 520 * ----------------------------------------------------- 521 */ 522 mov x17, sp 523 msr spsel, #1 524 str x17, [sp, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP] 525 526 /* ----------------------------------------------------- 527 * Restore SPSR_EL3, ELR_EL3 and SCR_EL3 prior to ERET 528 * ----------------------------------------------------- 529 */ 530 ldr x18, [sp, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3] 531 ldp x16, x17, [sp, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3] 532 msr scr_el3, x18 533 msr spsr_el3, x16 534 msr elr_el3, x17 535 536 /* ----------------------------------------------------- 537 * Restore PMCR_EL0 when returning to Non-secure state 538 * if Secure Cycle Counter is not disabled in MDCR_EL3 539 * when ARMv8.5-PMU is implemented 540 * ----------------------------------------------------- 541 */ 542 tst x18, #SCR_NS_BIT 543 beq 2f 544 545 /* ----------------------------------------------------- 546 * Back to Non-secure state. 547 * Check if earlier initialization MDCR_EL3.SCCD to 1 548 * failed, meaning that ARMv8-PMU is not implemented and 549 * PMCR_EL0 should be restored from non-secure context. 550 * ----------------------------------------------------- 551 */ 552 mrs x17, mdcr_el3 553 tst x17, #MDCR_SCCD_BIT 554 bne 2f 555 ldr x17, [sp, #CTX_EL3STATE_OFFSET + CTX_PMCR_EL0] 556 msr pmcr_el0, x17 5572: 558 559#if IMAGE_BL31 && DYNAMIC_WORKAROUND_CVE_2018_3639 560 /* Restore mitigation state as it was on entry to EL3 */ 561 ldr x17, [sp, #CTX_CVE_2018_3639_OFFSET + CTX_CVE_2018_3639_DISABLE] 562 cmp x17, xzr 563 beq 1f 564 blr x17 5651: 566#endif 567 568#if CTX_INCLUDE_PAUTH_REGS 569 /* Restore ARMv8.3-PAuth registers */ 570 bl pauth_context_restore 571#endif 572 573 /* Restore saved general purpose registers and return */ 574 b restore_gp_registers_eret 575endfunc el3_exit 576