1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #ifndef CONTEXT_H 8*91f16700Schasinglulu #define CONTEXT_H 9*91f16700Schasinglulu 10*91f16700Schasinglulu #include <lib/el3_runtime/cpu_data.h> 11*91f16700Schasinglulu #include <lib/utils_def.h> 12*91f16700Schasinglulu 13*91f16700Schasinglulu /******************************************************************************* 14*91f16700Schasinglulu * Constants that allow assembler code to access members of and the 'gp_regs' 15*91f16700Schasinglulu * structure at their correct offsets. 16*91f16700Schasinglulu ******************************************************************************/ 17*91f16700Schasinglulu #define CTX_GPREGS_OFFSET U(0x0) 18*91f16700Schasinglulu #define CTX_GPREG_X0 U(0x0) 19*91f16700Schasinglulu #define CTX_GPREG_X1 U(0x8) 20*91f16700Schasinglulu #define CTX_GPREG_X2 U(0x10) 21*91f16700Schasinglulu #define CTX_GPREG_X3 U(0x18) 22*91f16700Schasinglulu #define CTX_GPREG_X4 U(0x20) 23*91f16700Schasinglulu #define CTX_GPREG_X5 U(0x28) 24*91f16700Schasinglulu #define CTX_GPREG_X6 U(0x30) 25*91f16700Schasinglulu #define CTX_GPREG_X7 U(0x38) 26*91f16700Schasinglulu #define CTX_GPREG_X8 U(0x40) 27*91f16700Schasinglulu #define CTX_GPREG_X9 U(0x48) 28*91f16700Schasinglulu #define CTX_GPREG_X10 U(0x50) 29*91f16700Schasinglulu #define CTX_GPREG_X11 U(0x58) 30*91f16700Schasinglulu #define CTX_GPREG_X12 U(0x60) 31*91f16700Schasinglulu #define CTX_GPREG_X13 U(0x68) 32*91f16700Schasinglulu #define CTX_GPREG_X14 U(0x70) 33*91f16700Schasinglulu #define CTX_GPREG_X15 U(0x78) 34*91f16700Schasinglulu #define CTX_GPREG_X16 U(0x80) 35*91f16700Schasinglulu #define CTX_GPREG_X17 U(0x88) 36*91f16700Schasinglulu #define CTX_GPREG_X18 U(0x90) 37*91f16700Schasinglulu #define CTX_GPREG_X19 U(0x98) 38*91f16700Schasinglulu #define CTX_GPREG_X20 U(0xa0) 39*91f16700Schasinglulu #define CTX_GPREG_X21 U(0xa8) 40*91f16700Schasinglulu #define CTX_GPREG_X22 U(0xb0) 41*91f16700Schasinglulu #define CTX_GPREG_X23 U(0xb8) 42*91f16700Schasinglulu #define CTX_GPREG_X24 U(0xc0) 43*91f16700Schasinglulu #define CTX_GPREG_X25 U(0xc8) 44*91f16700Schasinglulu #define CTX_GPREG_X26 U(0xd0) 45*91f16700Schasinglulu #define CTX_GPREG_X27 U(0xd8) 46*91f16700Schasinglulu #define CTX_GPREG_X28 U(0xe0) 47*91f16700Schasinglulu #define CTX_GPREG_X29 U(0xe8) 48*91f16700Schasinglulu #define CTX_GPREG_LR U(0xf0) 49*91f16700Schasinglulu #define CTX_GPREG_SP_EL0 U(0xf8) 50*91f16700Schasinglulu #define CTX_GPREGS_END U(0x100) 51*91f16700Schasinglulu 52*91f16700Schasinglulu /******************************************************************************* 53*91f16700Schasinglulu * Constants that allow assembler code to access members of and the 'el3_state' 54*91f16700Schasinglulu * structure at their correct offsets. Note that some of the registers are only 55*91f16700Schasinglulu * 32-bits wide but are stored as 64-bit values for convenience 56*91f16700Schasinglulu ******************************************************************************/ 57*91f16700Schasinglulu #define CTX_EL3STATE_OFFSET (CTX_GPREGS_OFFSET + CTX_GPREGS_END) 58*91f16700Schasinglulu #define CTX_SCR_EL3 U(0x0) 59*91f16700Schasinglulu #define CTX_ESR_EL3 U(0x8) 60*91f16700Schasinglulu #define CTX_RUNTIME_SP U(0x10) 61*91f16700Schasinglulu #define CTX_SPSR_EL3 U(0x18) 62*91f16700Schasinglulu #define CTX_ELR_EL3 U(0x20) 63*91f16700Schasinglulu #define CTX_PMCR_EL0 U(0x28) 64*91f16700Schasinglulu #define CTX_IS_IN_EL3 U(0x30) 65*91f16700Schasinglulu #define CTX_MPAM3_EL3 U(0x38) 66*91f16700Schasinglulu /* Constants required in supporting nested exception in EL3 */ 67*91f16700Schasinglulu #define CTX_SAVED_ELR_EL3 U(0x40) 68*91f16700Schasinglulu /* 69*91f16700Schasinglulu * General purpose flag, to save various EL3 states 70*91f16700Schasinglulu * FFH mode : Used to identify if handling nested exception 71*91f16700Schasinglulu * KFH mode : Used as counter value 72*91f16700Schasinglulu */ 73*91f16700Schasinglulu #define CTX_NESTED_EA_FLAG U(0x48) 74*91f16700Schasinglulu #if FFH_SUPPORT 75*91f16700Schasinglulu #define CTX_SAVED_ESR_EL3 U(0x50) 76*91f16700Schasinglulu #define CTX_SAVED_SPSR_EL3 U(0x58) 77*91f16700Schasinglulu #define CTX_SAVED_GPREG_LR U(0x60) 78*91f16700Schasinglulu #define CTX_EL3STATE_END U(0x70) /* Align to the next 16 byte boundary */ 79*91f16700Schasinglulu #else 80*91f16700Schasinglulu #define CTX_EL3STATE_END U(0x50) /* Align to the next 16 byte boundary */ 81*91f16700Schasinglulu #endif 82*91f16700Schasinglulu 83*91f16700Schasinglulu /******************************************************************************* 84*91f16700Schasinglulu * Constants that allow assembler code to access members of and the 85*91f16700Schasinglulu * 'el1_sys_regs' structure at their correct offsets. Note that some of the 86*91f16700Schasinglulu * registers are only 32-bits wide but are stored as 64-bit values for 87*91f16700Schasinglulu * convenience 88*91f16700Schasinglulu ******************************************************************************/ 89*91f16700Schasinglulu #define CTX_EL1_SYSREGS_OFFSET (CTX_EL3STATE_OFFSET + CTX_EL3STATE_END) 90*91f16700Schasinglulu #define CTX_SPSR_EL1 U(0x0) 91*91f16700Schasinglulu #define CTX_ELR_EL1 U(0x8) 92*91f16700Schasinglulu #define CTX_SCTLR_EL1 U(0x10) 93*91f16700Schasinglulu #define CTX_TCR_EL1 U(0x18) 94*91f16700Schasinglulu #define CTX_CPACR_EL1 U(0x20) 95*91f16700Schasinglulu #define CTX_CSSELR_EL1 U(0x28) 96*91f16700Schasinglulu #define CTX_SP_EL1 U(0x30) 97*91f16700Schasinglulu #define CTX_ESR_EL1 U(0x38) 98*91f16700Schasinglulu #define CTX_TTBR0_EL1 U(0x40) 99*91f16700Schasinglulu #define CTX_TTBR1_EL1 U(0x48) 100*91f16700Schasinglulu #define CTX_MAIR_EL1 U(0x50) 101*91f16700Schasinglulu #define CTX_AMAIR_EL1 U(0x58) 102*91f16700Schasinglulu #define CTX_ACTLR_EL1 U(0x60) 103*91f16700Schasinglulu #define CTX_TPIDR_EL1 U(0x68) 104*91f16700Schasinglulu #define CTX_TPIDR_EL0 U(0x70) 105*91f16700Schasinglulu #define CTX_TPIDRRO_EL0 U(0x78) 106*91f16700Schasinglulu #define CTX_PAR_EL1 U(0x80) 107*91f16700Schasinglulu #define CTX_FAR_EL1 U(0x88) 108*91f16700Schasinglulu #define CTX_AFSR0_EL1 U(0x90) 109*91f16700Schasinglulu #define CTX_AFSR1_EL1 U(0x98) 110*91f16700Schasinglulu #define CTX_CONTEXTIDR_EL1 U(0xa0) 111*91f16700Schasinglulu #define CTX_VBAR_EL1 U(0xa8) 112*91f16700Schasinglulu 113*91f16700Schasinglulu /* 114*91f16700Schasinglulu * If the platform is AArch64-only, there is no need to save and restore these 115*91f16700Schasinglulu * AArch32 registers. 116*91f16700Schasinglulu */ 117*91f16700Schasinglulu #if CTX_INCLUDE_AARCH32_REGS 118*91f16700Schasinglulu #define CTX_SPSR_ABT U(0xb0) /* Align to the next 16 byte boundary */ 119*91f16700Schasinglulu #define CTX_SPSR_UND U(0xb8) 120*91f16700Schasinglulu #define CTX_SPSR_IRQ U(0xc0) 121*91f16700Schasinglulu #define CTX_SPSR_FIQ U(0xc8) 122*91f16700Schasinglulu #define CTX_DACR32_EL2 U(0xd0) 123*91f16700Schasinglulu #define CTX_IFSR32_EL2 U(0xd8) 124*91f16700Schasinglulu #define CTX_AARCH32_END U(0xe0) /* Align to the next 16 byte boundary */ 125*91f16700Schasinglulu #else 126*91f16700Schasinglulu #define CTX_AARCH32_END U(0xb0) /* Align to the next 16 byte boundary */ 127*91f16700Schasinglulu #endif /* CTX_INCLUDE_AARCH32_REGS */ 128*91f16700Schasinglulu 129*91f16700Schasinglulu /* 130*91f16700Schasinglulu * If the timer registers aren't saved and restored, we don't have to reserve 131*91f16700Schasinglulu * space for them in the context 132*91f16700Schasinglulu */ 133*91f16700Schasinglulu #if NS_TIMER_SWITCH 134*91f16700Schasinglulu #define CTX_CNTP_CTL_EL0 (CTX_AARCH32_END + U(0x0)) 135*91f16700Schasinglulu #define CTX_CNTP_CVAL_EL0 (CTX_AARCH32_END + U(0x8)) 136*91f16700Schasinglulu #define CTX_CNTV_CTL_EL0 (CTX_AARCH32_END + U(0x10)) 137*91f16700Schasinglulu #define CTX_CNTV_CVAL_EL0 (CTX_AARCH32_END + U(0x18)) 138*91f16700Schasinglulu #define CTX_CNTKCTL_EL1 (CTX_AARCH32_END + U(0x20)) 139*91f16700Schasinglulu #define CTX_TIMER_SYSREGS_END (CTX_AARCH32_END + U(0x30)) /* Align to the next 16 byte boundary */ 140*91f16700Schasinglulu #else 141*91f16700Schasinglulu #define CTX_TIMER_SYSREGS_END CTX_AARCH32_END 142*91f16700Schasinglulu #endif /* NS_TIMER_SWITCH */ 143*91f16700Schasinglulu 144*91f16700Schasinglulu #if CTX_INCLUDE_MTE_REGS 145*91f16700Schasinglulu #define CTX_TFSRE0_EL1 (CTX_TIMER_SYSREGS_END + U(0x0)) 146*91f16700Schasinglulu #define CTX_TFSR_EL1 (CTX_TIMER_SYSREGS_END + U(0x8)) 147*91f16700Schasinglulu #define CTX_RGSR_EL1 (CTX_TIMER_SYSREGS_END + U(0x10)) 148*91f16700Schasinglulu #define CTX_GCR_EL1 (CTX_TIMER_SYSREGS_END + U(0x18)) 149*91f16700Schasinglulu 150*91f16700Schasinglulu /* Align to the next 16 byte boundary */ 151*91f16700Schasinglulu #define CTX_MTE_REGS_END (CTX_TIMER_SYSREGS_END + U(0x20)) 152*91f16700Schasinglulu #else 153*91f16700Schasinglulu #define CTX_MTE_REGS_END CTX_TIMER_SYSREGS_END 154*91f16700Schasinglulu #endif /* CTX_INCLUDE_MTE_REGS */ 155*91f16700Schasinglulu 156*91f16700Schasinglulu /* 157*91f16700Schasinglulu * End of system registers. 158*91f16700Schasinglulu */ 159*91f16700Schasinglulu #define CTX_EL1_SYSREGS_END CTX_MTE_REGS_END 160*91f16700Schasinglulu 161*91f16700Schasinglulu /* 162*91f16700Schasinglulu * EL2 register set 163*91f16700Schasinglulu */ 164*91f16700Schasinglulu 165*91f16700Schasinglulu #if CTX_INCLUDE_EL2_REGS 166*91f16700Schasinglulu /* For later discussion 167*91f16700Schasinglulu * ICH_AP0R<n>_EL2 168*91f16700Schasinglulu * ICH_AP1R<n>_EL2 169*91f16700Schasinglulu * AMEVCNTVOFF0<n>_EL2 170*91f16700Schasinglulu * AMEVCNTVOFF1<n>_EL2 171*91f16700Schasinglulu * ICH_LR<n>_EL2 172*91f16700Schasinglulu */ 173*91f16700Schasinglulu #define CTX_EL2_SYSREGS_OFFSET (CTX_EL1_SYSREGS_OFFSET + CTX_EL1_SYSREGS_END) 174*91f16700Schasinglulu 175*91f16700Schasinglulu #define CTX_ACTLR_EL2 U(0x0) 176*91f16700Schasinglulu #define CTX_AFSR0_EL2 U(0x8) 177*91f16700Schasinglulu #define CTX_AFSR1_EL2 U(0x10) 178*91f16700Schasinglulu #define CTX_AMAIR_EL2 U(0x18) 179*91f16700Schasinglulu #define CTX_CNTHCTL_EL2 U(0x20) 180*91f16700Schasinglulu #define CTX_CNTVOFF_EL2 U(0x28) 181*91f16700Schasinglulu #define CTX_CPTR_EL2 U(0x30) 182*91f16700Schasinglulu #define CTX_DBGVCR32_EL2 U(0x38) 183*91f16700Schasinglulu #define CTX_ELR_EL2 U(0x40) 184*91f16700Schasinglulu #define CTX_ESR_EL2 U(0x48) 185*91f16700Schasinglulu #define CTX_FAR_EL2 U(0x50) 186*91f16700Schasinglulu #define CTX_HACR_EL2 U(0x58) 187*91f16700Schasinglulu #define CTX_HCR_EL2 U(0x60) 188*91f16700Schasinglulu #define CTX_HPFAR_EL2 U(0x68) 189*91f16700Schasinglulu #define CTX_HSTR_EL2 U(0x70) 190*91f16700Schasinglulu #define CTX_ICC_SRE_EL2 U(0x78) 191*91f16700Schasinglulu #define CTX_ICH_HCR_EL2 U(0x80) 192*91f16700Schasinglulu #define CTX_ICH_VMCR_EL2 U(0x88) 193*91f16700Schasinglulu #define CTX_MAIR_EL2 U(0x90) 194*91f16700Schasinglulu #define CTX_MDCR_EL2 U(0x98) 195*91f16700Schasinglulu #define CTX_PMSCR_EL2 U(0xa0) 196*91f16700Schasinglulu #define CTX_SCTLR_EL2 U(0xa8) 197*91f16700Schasinglulu #define CTX_SPSR_EL2 U(0xb0) 198*91f16700Schasinglulu #define CTX_SP_EL2 U(0xb8) 199*91f16700Schasinglulu #define CTX_TCR_EL2 U(0xc0) 200*91f16700Schasinglulu #define CTX_TPIDR_EL2 U(0xc8) 201*91f16700Schasinglulu #define CTX_TTBR0_EL2 U(0xd0) 202*91f16700Schasinglulu #define CTX_VBAR_EL2 U(0xd8) 203*91f16700Schasinglulu #define CTX_VMPIDR_EL2 U(0xe0) 204*91f16700Schasinglulu #define CTX_VPIDR_EL2 U(0xe8) 205*91f16700Schasinglulu #define CTX_VTCR_EL2 U(0xf0) 206*91f16700Schasinglulu #define CTX_VTTBR_EL2 U(0xf8) 207*91f16700Schasinglulu 208*91f16700Schasinglulu // Only if MTE registers in use 209*91f16700Schasinglulu #define CTX_TFSR_EL2 U(0x100) 210*91f16700Schasinglulu 211*91f16700Schasinglulu #define CTX_MPAM2_EL2 U(0x108) 212*91f16700Schasinglulu #define CTX_MPAMHCR_EL2 U(0x110) 213*91f16700Schasinglulu #define CTX_MPAMVPM0_EL2 U(0x118) 214*91f16700Schasinglulu #define CTX_MPAMVPM1_EL2 U(0x120) 215*91f16700Schasinglulu #define CTX_MPAMVPM2_EL2 U(0x128) 216*91f16700Schasinglulu #define CTX_MPAMVPM3_EL2 U(0x130) 217*91f16700Schasinglulu #define CTX_MPAMVPM4_EL2 U(0x138) 218*91f16700Schasinglulu #define CTX_MPAMVPM5_EL2 U(0x140) 219*91f16700Schasinglulu #define CTX_MPAMVPM6_EL2 U(0x148) 220*91f16700Schasinglulu #define CTX_MPAMVPM7_EL2 U(0x150) 221*91f16700Schasinglulu #define CTX_MPAMVPMV_EL2 U(0x158) 222*91f16700Schasinglulu 223*91f16700Schasinglulu // Starting with Armv8.6 224*91f16700Schasinglulu #define CTX_HDFGRTR_EL2 U(0x160) 225*91f16700Schasinglulu #define CTX_HAFGRTR_EL2 U(0x168) 226*91f16700Schasinglulu #define CTX_HDFGWTR_EL2 U(0x170) 227*91f16700Schasinglulu #define CTX_HFGITR_EL2 U(0x178) 228*91f16700Schasinglulu #define CTX_HFGRTR_EL2 U(0x180) 229*91f16700Schasinglulu #define CTX_HFGWTR_EL2 U(0x188) 230*91f16700Schasinglulu #define CTX_CNTPOFF_EL2 U(0x190) 231*91f16700Schasinglulu 232*91f16700Schasinglulu // Starting with Armv8.4 233*91f16700Schasinglulu #define CTX_CONTEXTIDR_EL2 U(0x198) 234*91f16700Schasinglulu #define CTX_TTBR1_EL2 U(0x1a0) 235*91f16700Schasinglulu #define CTX_VDISR_EL2 U(0x1a8) 236*91f16700Schasinglulu #define CTX_VSESR_EL2 U(0x1b0) 237*91f16700Schasinglulu #define CTX_VNCR_EL2 U(0x1b8) 238*91f16700Schasinglulu #define CTX_TRFCR_EL2 U(0x1c0) 239*91f16700Schasinglulu 240*91f16700Schasinglulu // Starting with Armv8.5 241*91f16700Schasinglulu #define CTX_SCXTNUM_EL2 U(0x1c8) 242*91f16700Schasinglulu 243*91f16700Schasinglulu // Register for FEAT_HCX 244*91f16700Schasinglulu #define CTX_HCRX_EL2 U(0x1d0) 245*91f16700Schasinglulu 246*91f16700Schasinglulu // Starting with Armv8.9 247*91f16700Schasinglulu #define CTX_TCR2_EL2 U(0x1d8) 248*91f16700Schasinglulu #define CTX_POR_EL2 U(0x1e0) 249*91f16700Schasinglulu #define CTX_PIRE0_EL2 U(0x1e8) 250*91f16700Schasinglulu #define CTX_PIR_EL2 U(0x1f0) 251*91f16700Schasinglulu #define CTX_S2PIR_EL2 U(0x1f8) 252*91f16700Schasinglulu #define CTX_GCSCR_EL2 U(0x200) 253*91f16700Schasinglulu #define CTX_GCSPR_EL2 U(0x208) 254*91f16700Schasinglulu 255*91f16700Schasinglulu /* Align to the next 16 byte boundary */ 256*91f16700Schasinglulu #define CTX_EL2_SYSREGS_END U(0x210) 257*91f16700Schasinglulu 258*91f16700Schasinglulu #endif /* CTX_INCLUDE_EL2_REGS */ 259*91f16700Schasinglulu 260*91f16700Schasinglulu /******************************************************************************* 261*91f16700Schasinglulu * Constants that allow assembler code to access members of and the 'fp_regs' 262*91f16700Schasinglulu * structure at their correct offsets. 263*91f16700Schasinglulu ******************************************************************************/ 264*91f16700Schasinglulu #if CTX_INCLUDE_EL2_REGS 265*91f16700Schasinglulu # define CTX_FPREGS_OFFSET (CTX_EL2_SYSREGS_OFFSET + CTX_EL2_SYSREGS_END) 266*91f16700Schasinglulu #else 267*91f16700Schasinglulu # define CTX_FPREGS_OFFSET (CTX_EL1_SYSREGS_OFFSET + CTX_EL1_SYSREGS_END) 268*91f16700Schasinglulu #endif 269*91f16700Schasinglulu #if CTX_INCLUDE_FPREGS 270*91f16700Schasinglulu #define CTX_FP_Q0 U(0x0) 271*91f16700Schasinglulu #define CTX_FP_Q1 U(0x10) 272*91f16700Schasinglulu #define CTX_FP_Q2 U(0x20) 273*91f16700Schasinglulu #define CTX_FP_Q3 U(0x30) 274*91f16700Schasinglulu #define CTX_FP_Q4 U(0x40) 275*91f16700Schasinglulu #define CTX_FP_Q5 U(0x50) 276*91f16700Schasinglulu #define CTX_FP_Q6 U(0x60) 277*91f16700Schasinglulu #define CTX_FP_Q7 U(0x70) 278*91f16700Schasinglulu #define CTX_FP_Q8 U(0x80) 279*91f16700Schasinglulu #define CTX_FP_Q9 U(0x90) 280*91f16700Schasinglulu #define CTX_FP_Q10 U(0xa0) 281*91f16700Schasinglulu #define CTX_FP_Q11 U(0xb0) 282*91f16700Schasinglulu #define CTX_FP_Q12 U(0xc0) 283*91f16700Schasinglulu #define CTX_FP_Q13 U(0xd0) 284*91f16700Schasinglulu #define CTX_FP_Q14 U(0xe0) 285*91f16700Schasinglulu #define CTX_FP_Q15 U(0xf0) 286*91f16700Schasinglulu #define CTX_FP_Q16 U(0x100) 287*91f16700Schasinglulu #define CTX_FP_Q17 U(0x110) 288*91f16700Schasinglulu #define CTX_FP_Q18 U(0x120) 289*91f16700Schasinglulu #define CTX_FP_Q19 U(0x130) 290*91f16700Schasinglulu #define CTX_FP_Q20 U(0x140) 291*91f16700Schasinglulu #define CTX_FP_Q21 U(0x150) 292*91f16700Schasinglulu #define CTX_FP_Q22 U(0x160) 293*91f16700Schasinglulu #define CTX_FP_Q23 U(0x170) 294*91f16700Schasinglulu #define CTX_FP_Q24 U(0x180) 295*91f16700Schasinglulu #define CTX_FP_Q25 U(0x190) 296*91f16700Schasinglulu #define CTX_FP_Q26 U(0x1a0) 297*91f16700Schasinglulu #define CTX_FP_Q27 U(0x1b0) 298*91f16700Schasinglulu #define CTX_FP_Q28 U(0x1c0) 299*91f16700Schasinglulu #define CTX_FP_Q29 U(0x1d0) 300*91f16700Schasinglulu #define CTX_FP_Q30 U(0x1e0) 301*91f16700Schasinglulu #define CTX_FP_Q31 U(0x1f0) 302*91f16700Schasinglulu #define CTX_FP_FPSR U(0x200) 303*91f16700Schasinglulu #define CTX_FP_FPCR U(0x208) 304*91f16700Schasinglulu #if CTX_INCLUDE_AARCH32_REGS 305*91f16700Schasinglulu #define CTX_FP_FPEXC32_EL2 U(0x210) 306*91f16700Schasinglulu #define CTX_FPREGS_END U(0x220) /* Align to the next 16 byte boundary */ 307*91f16700Schasinglulu #else 308*91f16700Schasinglulu #define CTX_FPREGS_END U(0x210) /* Align to the next 16 byte boundary */ 309*91f16700Schasinglulu #endif 310*91f16700Schasinglulu #else 311*91f16700Schasinglulu #define CTX_FPREGS_END U(0) 312*91f16700Schasinglulu #endif 313*91f16700Schasinglulu 314*91f16700Schasinglulu /******************************************************************************* 315*91f16700Schasinglulu * Registers related to CVE-2018-3639 316*91f16700Schasinglulu ******************************************************************************/ 317*91f16700Schasinglulu #define CTX_CVE_2018_3639_OFFSET (CTX_FPREGS_OFFSET + CTX_FPREGS_END) 318*91f16700Schasinglulu #define CTX_CVE_2018_3639_DISABLE U(0) 319*91f16700Schasinglulu #define CTX_CVE_2018_3639_END U(0x10) /* Align to the next 16 byte boundary */ 320*91f16700Schasinglulu 321*91f16700Schasinglulu /******************************************************************************* 322*91f16700Schasinglulu * Registers related to ARMv8.3-PAuth. 323*91f16700Schasinglulu ******************************************************************************/ 324*91f16700Schasinglulu #define CTX_PAUTH_REGS_OFFSET (CTX_CVE_2018_3639_OFFSET + CTX_CVE_2018_3639_END) 325*91f16700Schasinglulu #if CTX_INCLUDE_PAUTH_REGS 326*91f16700Schasinglulu #define CTX_PACIAKEY_LO U(0x0) 327*91f16700Schasinglulu #define CTX_PACIAKEY_HI U(0x8) 328*91f16700Schasinglulu #define CTX_PACIBKEY_LO U(0x10) 329*91f16700Schasinglulu #define CTX_PACIBKEY_HI U(0x18) 330*91f16700Schasinglulu #define CTX_PACDAKEY_LO U(0x20) 331*91f16700Schasinglulu #define CTX_PACDAKEY_HI U(0x28) 332*91f16700Schasinglulu #define CTX_PACDBKEY_LO U(0x30) 333*91f16700Schasinglulu #define CTX_PACDBKEY_HI U(0x38) 334*91f16700Schasinglulu #define CTX_PACGAKEY_LO U(0x40) 335*91f16700Schasinglulu #define CTX_PACGAKEY_HI U(0x48) 336*91f16700Schasinglulu #define CTX_PAUTH_REGS_END U(0x50) /* Align to the next 16 byte boundary */ 337*91f16700Schasinglulu #else 338*91f16700Schasinglulu #define CTX_PAUTH_REGS_END U(0) 339*91f16700Schasinglulu #endif /* CTX_INCLUDE_PAUTH_REGS */ 340*91f16700Schasinglulu 341*91f16700Schasinglulu /******************************************************************************* 342*91f16700Schasinglulu * Registers initialised in a per-world context. 343*91f16700Schasinglulu ******************************************************************************/ 344*91f16700Schasinglulu #define CTX_CPTR_EL3 U(0x0) 345*91f16700Schasinglulu #define CTX_ZCR_EL3 U(0x8) 346*91f16700Schasinglulu #define CTX_GLOBAL_EL3STATE_END U(0x10) 347*91f16700Schasinglulu 348*91f16700Schasinglulu #ifndef __ASSEMBLER__ 349*91f16700Schasinglulu 350*91f16700Schasinglulu #include <stdint.h> 351*91f16700Schasinglulu 352*91f16700Schasinglulu #include <lib/cassert.h> 353*91f16700Schasinglulu 354*91f16700Schasinglulu /* 355*91f16700Schasinglulu * Common constants to help define the 'cpu_context' structure and its 356*91f16700Schasinglulu * members below. 357*91f16700Schasinglulu */ 358*91f16700Schasinglulu #define DWORD_SHIFT U(3) 359*91f16700Schasinglulu #define DEFINE_REG_STRUCT(name, num_regs) \ 360*91f16700Schasinglulu typedef struct name { \ 361*91f16700Schasinglulu uint64_t ctx_regs[num_regs]; \ 362*91f16700Schasinglulu } __aligned(16) name##_t 363*91f16700Schasinglulu 364*91f16700Schasinglulu /* Constants to determine the size of individual context structures */ 365*91f16700Schasinglulu #define CTX_GPREG_ALL (CTX_GPREGS_END >> DWORD_SHIFT) 366*91f16700Schasinglulu #define CTX_EL1_SYSREGS_ALL (CTX_EL1_SYSREGS_END >> DWORD_SHIFT) 367*91f16700Schasinglulu #if CTX_INCLUDE_EL2_REGS 368*91f16700Schasinglulu # define CTX_EL2_SYSREGS_ALL (CTX_EL2_SYSREGS_END >> DWORD_SHIFT) 369*91f16700Schasinglulu #endif 370*91f16700Schasinglulu #if CTX_INCLUDE_FPREGS 371*91f16700Schasinglulu # define CTX_FPREG_ALL (CTX_FPREGS_END >> DWORD_SHIFT) 372*91f16700Schasinglulu #endif 373*91f16700Schasinglulu #define CTX_EL3STATE_ALL (CTX_EL3STATE_END >> DWORD_SHIFT) 374*91f16700Schasinglulu #define CTX_CVE_2018_3639_ALL (CTX_CVE_2018_3639_END >> DWORD_SHIFT) 375*91f16700Schasinglulu #if CTX_INCLUDE_PAUTH_REGS 376*91f16700Schasinglulu # define CTX_PAUTH_REGS_ALL (CTX_PAUTH_REGS_END >> DWORD_SHIFT) 377*91f16700Schasinglulu #endif 378*91f16700Schasinglulu 379*91f16700Schasinglulu /* 380*91f16700Schasinglulu * AArch64 general purpose register context structure. Usually x0-x18, 381*91f16700Schasinglulu * lr are saved as the compiler is expected to preserve the remaining 382*91f16700Schasinglulu * callee saved registers if used by the C runtime and the assembler 383*91f16700Schasinglulu * does not touch the remaining. But in case of world switch during 384*91f16700Schasinglulu * exception handling, we need to save the callee registers too. 385*91f16700Schasinglulu */ 386*91f16700Schasinglulu DEFINE_REG_STRUCT(gp_regs, CTX_GPREG_ALL); 387*91f16700Schasinglulu 388*91f16700Schasinglulu /* 389*91f16700Schasinglulu * AArch64 EL1 system register context structure for preserving the 390*91f16700Schasinglulu * architectural state during world switches. 391*91f16700Schasinglulu */ 392*91f16700Schasinglulu DEFINE_REG_STRUCT(el1_sysregs, CTX_EL1_SYSREGS_ALL); 393*91f16700Schasinglulu 394*91f16700Schasinglulu 395*91f16700Schasinglulu /* 396*91f16700Schasinglulu * AArch64 EL2 system register context structure for preserving the 397*91f16700Schasinglulu * architectural state during world switches. 398*91f16700Schasinglulu */ 399*91f16700Schasinglulu #if CTX_INCLUDE_EL2_REGS 400*91f16700Schasinglulu DEFINE_REG_STRUCT(el2_sysregs, CTX_EL2_SYSREGS_ALL); 401*91f16700Schasinglulu #endif 402*91f16700Schasinglulu 403*91f16700Schasinglulu /* 404*91f16700Schasinglulu * AArch64 floating point register context structure for preserving 405*91f16700Schasinglulu * the floating point state during switches from one security state to 406*91f16700Schasinglulu * another. 407*91f16700Schasinglulu */ 408*91f16700Schasinglulu #if CTX_INCLUDE_FPREGS 409*91f16700Schasinglulu DEFINE_REG_STRUCT(fp_regs, CTX_FPREG_ALL); 410*91f16700Schasinglulu #endif 411*91f16700Schasinglulu 412*91f16700Schasinglulu /* 413*91f16700Schasinglulu * Miscellaneous registers used by EL3 firmware to maintain its state 414*91f16700Schasinglulu * across exception entries and exits 415*91f16700Schasinglulu */ 416*91f16700Schasinglulu DEFINE_REG_STRUCT(el3_state, CTX_EL3STATE_ALL); 417*91f16700Schasinglulu 418*91f16700Schasinglulu /* Function pointer used by CVE-2018-3639 dynamic mitigation */ 419*91f16700Schasinglulu DEFINE_REG_STRUCT(cve_2018_3639, CTX_CVE_2018_3639_ALL); 420*91f16700Schasinglulu 421*91f16700Schasinglulu /* Registers associated to ARMv8.3-PAuth */ 422*91f16700Schasinglulu #if CTX_INCLUDE_PAUTH_REGS 423*91f16700Schasinglulu DEFINE_REG_STRUCT(pauth, CTX_PAUTH_REGS_ALL); 424*91f16700Schasinglulu #endif 425*91f16700Schasinglulu 426*91f16700Schasinglulu /* 427*91f16700Schasinglulu * Macros to access members of any of the above structures using their 428*91f16700Schasinglulu * offsets 429*91f16700Schasinglulu */ 430*91f16700Schasinglulu #define read_ctx_reg(ctx, offset) ((ctx)->ctx_regs[(offset) >> DWORD_SHIFT]) 431*91f16700Schasinglulu #define write_ctx_reg(ctx, offset, val) (((ctx)->ctx_regs[(offset) >> DWORD_SHIFT]) \ 432*91f16700Schasinglulu = (uint64_t) (val)) 433*91f16700Schasinglulu 434*91f16700Schasinglulu /* 435*91f16700Schasinglulu * Top-level context structure which is used by EL3 firmware to preserve 436*91f16700Schasinglulu * the state of a core at the next lower EL in a given security state and 437*91f16700Schasinglulu * save enough EL3 meta data to be able to return to that EL and security 438*91f16700Schasinglulu * state. The context management library will be used to ensure that 439*91f16700Schasinglulu * SP_EL3 always points to an instance of this structure at exception 440*91f16700Schasinglulu * entry and exit. 441*91f16700Schasinglulu */ 442*91f16700Schasinglulu typedef struct cpu_context { 443*91f16700Schasinglulu gp_regs_t gpregs_ctx; 444*91f16700Schasinglulu el3_state_t el3state_ctx; 445*91f16700Schasinglulu el1_sysregs_t el1_sysregs_ctx; 446*91f16700Schasinglulu #if CTX_INCLUDE_EL2_REGS 447*91f16700Schasinglulu el2_sysregs_t el2_sysregs_ctx; 448*91f16700Schasinglulu #endif 449*91f16700Schasinglulu #if CTX_INCLUDE_FPREGS 450*91f16700Schasinglulu fp_regs_t fpregs_ctx; 451*91f16700Schasinglulu #endif 452*91f16700Schasinglulu cve_2018_3639_t cve_2018_3639_ctx; 453*91f16700Schasinglulu #if CTX_INCLUDE_PAUTH_REGS 454*91f16700Schasinglulu pauth_t pauth_ctx; 455*91f16700Schasinglulu #endif 456*91f16700Schasinglulu } cpu_context_t; 457*91f16700Schasinglulu 458*91f16700Schasinglulu /* 459*91f16700Schasinglulu * Per-World Context. 460*91f16700Schasinglulu * It stores registers whose values can be shared across CPUs. 461*91f16700Schasinglulu */ 462*91f16700Schasinglulu typedef struct per_world_context { 463*91f16700Schasinglulu uint64_t ctx_cptr_el3; 464*91f16700Schasinglulu uint64_t ctx_zcr_el3; 465*91f16700Schasinglulu } per_world_context_t; 466*91f16700Schasinglulu 467*91f16700Schasinglulu extern per_world_context_t per_world_context[CPU_DATA_CONTEXT_NUM]; 468*91f16700Schasinglulu 469*91f16700Schasinglulu /* Macros to access members of the 'cpu_context_t' structure */ 470*91f16700Schasinglulu #define get_el3state_ctx(h) (&((cpu_context_t *) h)->el3state_ctx) 471*91f16700Schasinglulu #if CTX_INCLUDE_FPREGS 472*91f16700Schasinglulu # define get_fpregs_ctx(h) (&((cpu_context_t *) h)->fpregs_ctx) 473*91f16700Schasinglulu #endif 474*91f16700Schasinglulu #define get_el1_sysregs_ctx(h) (&((cpu_context_t *) h)->el1_sysregs_ctx) 475*91f16700Schasinglulu #if CTX_INCLUDE_EL2_REGS 476*91f16700Schasinglulu # define get_el2_sysregs_ctx(h) (&((cpu_context_t *) h)->el2_sysregs_ctx) 477*91f16700Schasinglulu #endif 478*91f16700Schasinglulu #define get_gpregs_ctx(h) (&((cpu_context_t *) h)->gpregs_ctx) 479*91f16700Schasinglulu #define get_cve_2018_3639_ctx(h) (&((cpu_context_t *) h)->cve_2018_3639_ctx) 480*91f16700Schasinglulu #if CTX_INCLUDE_PAUTH_REGS 481*91f16700Schasinglulu # define get_pauth_ctx(h) (&((cpu_context_t *) h)->pauth_ctx) 482*91f16700Schasinglulu #endif 483*91f16700Schasinglulu 484*91f16700Schasinglulu /* 485*91f16700Schasinglulu * Compile time assertions related to the 'cpu_context' structure to 486*91f16700Schasinglulu * ensure that the assembler and the compiler view of the offsets of 487*91f16700Schasinglulu * the structure members is the same. 488*91f16700Schasinglulu */ 489*91f16700Schasinglulu CASSERT(CTX_GPREGS_OFFSET == __builtin_offsetof(cpu_context_t, gpregs_ctx), 490*91f16700Schasinglulu assert_core_context_gp_offset_mismatch); 491*91f16700Schasinglulu CASSERT(CTX_EL1_SYSREGS_OFFSET == __builtin_offsetof(cpu_context_t, el1_sysregs_ctx), 492*91f16700Schasinglulu assert_core_context_el1_sys_offset_mismatch); 493*91f16700Schasinglulu #if CTX_INCLUDE_EL2_REGS 494*91f16700Schasinglulu CASSERT(CTX_EL2_SYSREGS_OFFSET == __builtin_offsetof(cpu_context_t, el2_sysregs_ctx), 495*91f16700Schasinglulu assert_core_context_el2_sys_offset_mismatch); 496*91f16700Schasinglulu #endif 497*91f16700Schasinglulu #if CTX_INCLUDE_FPREGS 498*91f16700Schasinglulu CASSERT(CTX_FPREGS_OFFSET == __builtin_offsetof(cpu_context_t, fpregs_ctx), 499*91f16700Schasinglulu assert_core_context_fp_offset_mismatch); 500*91f16700Schasinglulu #endif 501*91f16700Schasinglulu CASSERT(CTX_EL3STATE_OFFSET == __builtin_offsetof(cpu_context_t, el3state_ctx), 502*91f16700Schasinglulu assert_core_context_el3state_offset_mismatch); 503*91f16700Schasinglulu CASSERT(CTX_CVE_2018_3639_OFFSET == __builtin_offsetof(cpu_context_t, cve_2018_3639_ctx), 504*91f16700Schasinglulu assert_core_context_cve_2018_3639_offset_mismatch); 505*91f16700Schasinglulu #if CTX_INCLUDE_PAUTH_REGS 506*91f16700Schasinglulu CASSERT(CTX_PAUTH_REGS_OFFSET == __builtin_offsetof(cpu_context_t, pauth_ctx), 507*91f16700Schasinglulu assert_core_context_pauth_offset_mismatch); 508*91f16700Schasinglulu #endif 509*91f16700Schasinglulu 510*91f16700Schasinglulu /* 511*91f16700Schasinglulu * Helper macro to set the general purpose registers that correspond to 512*91f16700Schasinglulu * parameters in an aapcs_64 call i.e. x0-x7 513*91f16700Schasinglulu */ 514*91f16700Schasinglulu #define set_aapcs_args0(ctx, x0) do { \ 515*91f16700Schasinglulu write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X0, x0); \ 516*91f16700Schasinglulu } while (0) 517*91f16700Schasinglulu #define set_aapcs_args1(ctx, x0, x1) do { \ 518*91f16700Schasinglulu write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X1, x1); \ 519*91f16700Schasinglulu set_aapcs_args0(ctx, x0); \ 520*91f16700Schasinglulu } while (0) 521*91f16700Schasinglulu #define set_aapcs_args2(ctx, x0, x1, x2) do { \ 522*91f16700Schasinglulu write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X2, x2); \ 523*91f16700Schasinglulu set_aapcs_args1(ctx, x0, x1); \ 524*91f16700Schasinglulu } while (0) 525*91f16700Schasinglulu #define set_aapcs_args3(ctx, x0, x1, x2, x3) do { \ 526*91f16700Schasinglulu write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X3, x3); \ 527*91f16700Schasinglulu set_aapcs_args2(ctx, x0, x1, x2); \ 528*91f16700Schasinglulu } while (0) 529*91f16700Schasinglulu #define set_aapcs_args4(ctx, x0, x1, x2, x3, x4) do { \ 530*91f16700Schasinglulu write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X4, x4); \ 531*91f16700Schasinglulu set_aapcs_args3(ctx, x0, x1, x2, x3); \ 532*91f16700Schasinglulu } while (0) 533*91f16700Schasinglulu #define set_aapcs_args5(ctx, x0, x1, x2, x3, x4, x5) do { \ 534*91f16700Schasinglulu write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X5, x5); \ 535*91f16700Schasinglulu set_aapcs_args4(ctx, x0, x1, x2, x3, x4); \ 536*91f16700Schasinglulu } while (0) 537*91f16700Schasinglulu #define set_aapcs_args6(ctx, x0, x1, x2, x3, x4, x5, x6) do { \ 538*91f16700Schasinglulu write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X6, x6); \ 539*91f16700Schasinglulu set_aapcs_args5(ctx, x0, x1, x2, x3, x4, x5); \ 540*91f16700Schasinglulu } while (0) 541*91f16700Schasinglulu #define set_aapcs_args7(ctx, x0, x1, x2, x3, x4, x5, x6, x7) do { \ 542*91f16700Schasinglulu write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X7, x7); \ 543*91f16700Schasinglulu set_aapcs_args6(ctx, x0, x1, x2, x3, x4, x5, x6); \ 544*91f16700Schasinglulu } while (0) 545*91f16700Schasinglulu 546*91f16700Schasinglulu /******************************************************************************* 547*91f16700Schasinglulu * Function prototypes 548*91f16700Schasinglulu ******************************************************************************/ 549*91f16700Schasinglulu void el1_sysregs_context_save(el1_sysregs_t *regs); 550*91f16700Schasinglulu void el1_sysregs_context_restore(el1_sysregs_t *regs); 551*91f16700Schasinglulu 552*91f16700Schasinglulu #if CTX_INCLUDE_FPREGS 553*91f16700Schasinglulu void fpregs_context_save(fp_regs_t *regs); 554*91f16700Schasinglulu void fpregs_context_restore(fp_regs_t *regs); 555*91f16700Schasinglulu #endif 556*91f16700Schasinglulu 557*91f16700Schasinglulu #endif /* __ASSEMBLER__ */ 558*91f16700Schasinglulu 559*91f16700Schasinglulu #endif /* CONTEXT_H */ 560