xref: /arm-trusted-firmware/include/lib/el3_runtime/aarch64/context.h (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
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