xref: /rk3399_ARM-atf/include/lib/el3_runtime/aarch64/context.h (revision 6eabbb07d7ee2aac3a8e8e734649c8eaa8385af6)
1 /*
2  * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef __CONTEXT_H__
8 #define __CONTEXT_H__
9 
10 /*******************************************************************************
11  * Constants that allow assembler code to access members of and the 'gp_regs'
12  * structure at their correct offsets.
13  ******************************************************************************/
14 #define CTX_GPREGS_OFFSET	U(0x0)
15 #define CTX_GPREG_X0		U(0x0)
16 #define CTX_GPREG_X1		U(0x8)
17 #define CTX_GPREG_X2		U(0x10)
18 #define CTX_GPREG_X3		U(0x18)
19 #define CTX_GPREG_X4		U(0x20)
20 #define CTX_GPREG_X5		U(0x28)
21 #define CTX_GPREG_X6		U(0x30)
22 #define CTX_GPREG_X7		U(0x38)
23 #define CTX_GPREG_X8		U(0x40)
24 #define CTX_GPREG_X9		U(0x48)
25 #define CTX_GPREG_X10		U(0x50)
26 #define CTX_GPREG_X11		U(0x58)
27 #define CTX_GPREG_X12		U(0x60)
28 #define CTX_GPREG_X13		U(0x68)
29 #define CTX_GPREG_X14		U(0x70)
30 #define CTX_GPREG_X15		U(0x78)
31 #define CTX_GPREG_X16		U(0x80)
32 #define CTX_GPREG_X17		U(0x88)
33 #define CTX_GPREG_X18		U(0x90)
34 #define CTX_GPREG_X19		U(0x98)
35 #define CTX_GPREG_X20		U(0xa0)
36 #define CTX_GPREG_X21		U(0xa8)
37 #define CTX_GPREG_X22		U(0xb0)
38 #define CTX_GPREG_X23		U(0xb8)
39 #define CTX_GPREG_X24		U(0xc0)
40 #define CTX_GPREG_X25		U(0xc8)
41 #define CTX_GPREG_X26		U(0xd0)
42 #define CTX_GPREG_X27		U(0xd8)
43 #define CTX_GPREG_X28		U(0xe0)
44 #define CTX_GPREG_X29		U(0xe8)
45 #define CTX_GPREG_LR		U(0xf0)
46 #define CTX_GPREG_SP_EL0	U(0xf8)
47 #define CTX_GPREGS_END		U(0x100)
48 
49 #if WORKAROUND_CVE_2017_5715
50 #define CTX_CVE_2017_5715_OFFSET	(CTX_GPREGS_OFFSET + CTX_GPREGS_END)
51 #define CTX_CVE_2017_5715_QUAD0		U(0x0)
52 #define CTX_CVE_2017_5715_QUAD1		U(0x8)
53 #define	CTX_CVE_2017_5715_QUAD2		U(0x10)
54 #define CTX_CVE_2017_5715_QUAD3		U(0x18)
55 #define CTX_CVE_2017_5715_QUAD4		U(0x20)
56 #define CTX_CVE_2017_5715_QUAD5		U(0x28)
57 #define CTX_CVE_2017_5715_END		U(0x30)
58 #else
59 #define CTX_CVE_2017_5715_OFFSET	CTX_GPREGS_OFFSET
60 #define CTX_CVE_2017_5715_END		CTX_GPREGS_END
61 #endif
62 
63 /*******************************************************************************
64  * Constants that allow assembler code to access members of and the 'el3_state'
65  * structure at their correct offsets. Note that some of the registers are only
66  * 32-bits wide but are stored as 64-bit values for convenience
67  ******************************************************************************/
68 #define CTX_EL3STATE_OFFSET	(CTX_CVE_2017_5715_OFFSET + CTX_CVE_2017_5715_END)
69 #define CTX_SCR_EL3		U(0x0)
70 #define CTX_RUNTIME_SP		U(0x8)
71 #define CTX_SPSR_EL3		U(0x10)
72 #define CTX_ELR_EL3		U(0x18)
73 #define CTX_EL3STATE_END	U(0x20)
74 
75 /*******************************************************************************
76  * Constants that allow assembler code to access members of and the
77  * 'el1_sys_regs' structure at their correct offsets. Note that some of the
78  * registers are only 32-bits wide but are stored as 64-bit values for
79  * convenience
80  ******************************************************************************/
81 #define CTX_SYSREGS_OFFSET	(CTX_EL3STATE_OFFSET + CTX_EL3STATE_END)
82 #define CTX_SPSR_EL1		U(0x0)
83 #define CTX_ELR_EL1		U(0x8)
84 #define CTX_SCTLR_EL1		U(0x10)
85 #define CTX_ACTLR_EL1		U(0x18)
86 #define CTX_CPACR_EL1		U(0x20)
87 #define CTX_CSSELR_EL1		U(0x28)
88 #define CTX_SP_EL1		U(0x30)
89 #define CTX_ESR_EL1		U(0x38)
90 #define CTX_TTBR0_EL1		U(0x40)
91 #define CTX_TTBR1_EL1		U(0x48)
92 #define CTX_MAIR_EL1		U(0x50)
93 #define CTX_AMAIR_EL1		U(0x58)
94 #define CTX_TCR_EL1		U(0x60)
95 #define CTX_TPIDR_EL1		U(0x68)
96 #define CTX_TPIDR_EL0		U(0x70)
97 #define CTX_TPIDRRO_EL0		U(0x78)
98 #define CTX_PAR_EL1		U(0x80)
99 #define CTX_FAR_EL1		U(0x88)
100 #define CTX_AFSR0_EL1		U(0x90)
101 #define CTX_AFSR1_EL1		U(0x98)
102 #define CTX_CONTEXTIDR_EL1	U(0xa0)
103 #define CTX_VBAR_EL1		U(0xa8)
104 #define CTX_PMCR_EL0		U(0xb0)
105 
106 /*
107  * If the platform is AArch64-only, there is no need to save and restore these
108  * AArch32 registers.
109  */
110 #if CTX_INCLUDE_AARCH32_REGS
111 #define CTX_SPSR_ABT		U(0xc0)  /* Align to the next 16 byte boundary */
112 #define CTX_SPSR_UND		U(0xc8)
113 #define CTX_SPSR_IRQ		U(0xd0)
114 #define CTX_SPSR_FIQ		U(0xd8)
115 #define CTX_DACR32_EL2		U(0xe0)
116 #define CTX_IFSR32_EL2		U(0xe8)
117 #define CTX_TIMER_SYSREGS_OFF	U(0xf0) /* Align to the next 16 byte boundary */
118 #else
119 #define CTX_TIMER_SYSREGS_OFF	U(0xc0)  /* Align to the next 16 byte boundary */
120 #endif /* __CTX_INCLUDE_AARCH32_REGS__ */
121 
122 /*
123  * If the timer registers aren't saved and restored, we don't have to reserve
124  * space for them in the context
125  */
126 #if NS_TIMER_SWITCH
127 #define CTX_CNTP_CTL_EL0	(CTX_TIMER_SYSREGS_OFF + U(0x0))
128 #define CTX_CNTP_CVAL_EL0	(CTX_TIMER_SYSREGS_OFF + U(0x8))
129 #define CTX_CNTV_CTL_EL0	(CTX_TIMER_SYSREGS_OFF + U(0x10))
130 #define CTX_CNTV_CVAL_EL0	(CTX_TIMER_SYSREGS_OFF + U(0x18))
131 #define CTX_CNTKCTL_EL1		(CTX_TIMER_SYSREGS_OFF + U(0x20))
132 #define CTX_SYSREGS_END		(CTX_TIMER_SYSREGS_OFF + U(0x30)) /* Align to the next 16 byte boundary */
133 #else
134 #define CTX_SYSREGS_END		CTX_TIMER_SYSREGS_OFF
135 #endif /* __NS_TIMER_SWITCH__ */
136 
137 /*******************************************************************************
138  * Constants that allow assembler code to access members of and the 'fp_regs'
139  * structure at their correct offsets.
140  ******************************************************************************/
141 #if CTX_INCLUDE_FPREGS
142 #define CTX_FPREGS_OFFSET	(CTX_SYSREGS_OFFSET + CTX_SYSREGS_END)
143 #define CTX_FP_Q0		U(0x0)
144 #define CTX_FP_Q1		U(0x10)
145 #define CTX_FP_Q2		U(0x20)
146 #define CTX_FP_Q3		U(0x30)
147 #define CTX_FP_Q4		U(0x40)
148 #define CTX_FP_Q5		U(0x50)
149 #define CTX_FP_Q6		U(0x60)
150 #define CTX_FP_Q7		U(0x70)
151 #define CTX_FP_Q8		U(0x80)
152 #define CTX_FP_Q9		U(0x90)
153 #define CTX_FP_Q10		U(0xa0)
154 #define CTX_FP_Q11		U(0xb0)
155 #define CTX_FP_Q12		U(0xc0)
156 #define CTX_FP_Q13		U(0xd0)
157 #define CTX_FP_Q14		U(0xe0)
158 #define CTX_FP_Q15		U(0xf0)
159 #define CTX_FP_Q16		U(0x100)
160 #define CTX_FP_Q17		U(0x110)
161 #define CTX_FP_Q18		U(0x120)
162 #define CTX_FP_Q19		U(0x130)
163 #define CTX_FP_Q20		U(0x140)
164 #define CTX_FP_Q21		U(0x150)
165 #define CTX_FP_Q22		U(0x160)
166 #define CTX_FP_Q23		U(0x170)
167 #define CTX_FP_Q24		U(0x180)
168 #define CTX_FP_Q25		U(0x190)
169 #define CTX_FP_Q26		U(0x1a0)
170 #define CTX_FP_Q27		U(0x1b0)
171 #define CTX_FP_Q28		U(0x1c0)
172 #define CTX_FP_Q29		U(0x1d0)
173 #define CTX_FP_Q30		U(0x1e0)
174 #define CTX_FP_Q31		U(0x1f0)
175 #define CTX_FP_FPSR		U(0x200)
176 #define CTX_FP_FPCR		U(0x208)
177 #if CTX_INCLUDE_AARCH32_REGS
178 #define CTX_FP_FPEXC32_EL2	U(0x210)
179 #define CTX_FPREGS_END		U(0x220) /* Align to the next 16 byte boundary */
180 #else
181 #define CTX_FPREGS_END		U(0x210) /* Align to the next 16 byte boundary */
182 #endif
183 #endif
184 
185 #ifndef __ASSEMBLY__
186 
187 #include <cassert.h>
188 #include <platform_def.h>	/* for CACHE_WRITEBACK_GRANULE */
189 #include <stdint.h>
190 
191 /*
192  * Common constants to help define the 'cpu_context' structure and its
193  * members below.
194  */
195 #define DWORD_SHIFT		U(3)
196 #define DEFINE_REG_STRUCT(name, num_regs)	\
197 	typedef struct name {			\
198 		uint64_t _regs[num_regs];	\
199 	}  __aligned(16) name##_t
200 
201 /* Constants to determine the size of individual context structures */
202 #define CTX_GPREG_ALL		(CTX_GPREGS_END >> DWORD_SHIFT)
203 #if WORKAROUND_CVE_2017_5715
204 #define CTX_CVE_2017_5715_ALL	(CTX_CVE_2017_5715_END >> DWORD_SHIFT)
205 #endif
206 #define CTX_SYSREG_ALL		(CTX_SYSREGS_END >> DWORD_SHIFT)
207 #if CTX_INCLUDE_FPREGS
208 #define CTX_FPREG_ALL		(CTX_FPREGS_END >> DWORD_SHIFT)
209 #endif
210 #define CTX_EL3STATE_ALL	(CTX_EL3STATE_END >> DWORD_SHIFT)
211 
212 /*
213  * AArch64 general purpose register context structure. Usually x0-x18,
214  * lr are saved as the compiler is expected to preserve the remaining
215  * callee saved registers if used by the C runtime and the assembler
216  * does not touch the remaining. But in case of world switch during
217  * exception handling, we need to save the callee registers too.
218  */
219 DEFINE_REG_STRUCT(gp_regs, CTX_GPREG_ALL);
220 
221 #if WORKAROUND_CVE_2017_5715
222 DEFINE_REG_STRUCT(cve_2017_5715_regs, CTX_CVE_2017_5715_ALL);
223 #endif
224 
225 /*
226  * AArch64 EL1 system register context structure for preserving the
227  * architectural state during switches from one security state to
228  * another in EL1.
229  */
230 DEFINE_REG_STRUCT(el1_sys_regs, CTX_SYSREG_ALL);
231 
232 /*
233  * AArch64 floating point register context structure for preserving
234  * the floating point state during switches from one security state to
235  * another.
236  */
237 #if CTX_INCLUDE_FPREGS
238 DEFINE_REG_STRUCT(fp_regs, CTX_FPREG_ALL);
239 #endif
240 
241 /*
242  * Miscellaneous registers used by EL3 firmware to maintain its state
243  * across exception entries and exits
244  */
245 DEFINE_REG_STRUCT(el3_state, CTX_EL3STATE_ALL);
246 
247 /*
248  * Macros to access members of any of the above structures using their
249  * offsets
250  */
251 #define read_ctx_reg(ctx, offset)	((ctx)->_regs[offset >> DWORD_SHIFT])
252 #define write_ctx_reg(ctx, offset, val)	(((ctx)->_regs[offset >> DWORD_SHIFT]) \
253 					 = val)
254 
255 /*
256  * Top-level context structure which is used by EL3 firmware to
257  * preserve the state of a core at EL1 in one of the two security
258  * states and save enough EL3 meta data to be able to return to that
259  * EL and security state. The context management library will be used
260  * to ensure that SP_EL3 always points to an instance of this
261  * structure at exception entry and exit. Each instance will
262  * correspond to either the secure or the non-secure state.
263  */
264 typedef struct cpu_context {
265 	gp_regs_t gpregs_ctx;
266 #if WORKAROUND_CVE_2017_5715
267 	cve_2017_5715_regs_t cve_2017_5715_regs_ctx;
268 #endif
269 	el3_state_t el3state_ctx;
270 	el1_sys_regs_t sysregs_ctx;
271 #if CTX_INCLUDE_FPREGS
272 	fp_regs_t fpregs_ctx;
273 #endif
274 } cpu_context_t;
275 
276 /* Macros to access members of the 'cpu_context_t' structure */
277 #define get_el3state_ctx(h)	(&((cpu_context_t *) h)->el3state_ctx)
278 #if CTX_INCLUDE_FPREGS
279 #define get_fpregs_ctx(h)	(&((cpu_context_t *) h)->fpregs_ctx)
280 #endif
281 #define get_sysregs_ctx(h)	(&((cpu_context_t *) h)->sysregs_ctx)
282 #define get_gpregs_ctx(h)	(&((cpu_context_t *) h)->gpregs_ctx)
283 
284 /*
285  * Compile time assertions related to the 'cpu_context' structure to
286  * ensure that the assembler and the compiler view of the offsets of
287  * the structure members is the same.
288  */
289 CASSERT(CTX_GPREGS_OFFSET == __builtin_offsetof(cpu_context_t, gpregs_ctx), \
290 	assert_core_context_gp_offset_mismatch);
291 CASSERT(CTX_SYSREGS_OFFSET == __builtin_offsetof(cpu_context_t, sysregs_ctx), \
292 	assert_core_context_sys_offset_mismatch);
293 #if CTX_INCLUDE_FPREGS
294 CASSERT(CTX_FPREGS_OFFSET == __builtin_offsetof(cpu_context_t, fpregs_ctx), \
295 	assert_core_context_fp_offset_mismatch);
296 #endif
297 CASSERT(CTX_EL3STATE_OFFSET == __builtin_offsetof(cpu_context_t, el3state_ctx), \
298 	assert_core_context_el3state_offset_mismatch);
299 
300 /*
301  * Helper macro to set the general purpose registers that correspond to
302  * parameters in an aapcs_64 call i.e. x0-x7
303  */
304 #define set_aapcs_args0(ctx, x0)				do {	\
305 		write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X0, x0);	\
306 	} while (0)
307 #define set_aapcs_args1(ctx, x0, x1)				do {	\
308 		write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X1, x1);	\
309 		set_aapcs_args0(ctx, x0);				\
310 	} while (0)
311 #define set_aapcs_args2(ctx, x0, x1, x2)			do {	\
312 		write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X2, x2);	\
313 		set_aapcs_args1(ctx, x0, x1);				\
314 	} while (0)
315 #define set_aapcs_args3(ctx, x0, x1, x2, x3)			do {	\
316 		write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X3, x3);	\
317 		set_aapcs_args2(ctx, x0, x1, x2);			\
318 	} while (0)
319 #define set_aapcs_args4(ctx, x0, x1, x2, x3, x4)		do {	\
320 		write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X4, x4);	\
321 		set_aapcs_args3(ctx, x0, x1, x2, x3);			\
322 	} while (0)
323 #define set_aapcs_args5(ctx, x0, x1, x2, x3, x4, x5)		do {	\
324 		write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X5, x5);	\
325 		set_aapcs_args4(ctx, x0, x1, x2, x3, x4);		\
326 	} while (0)
327 #define set_aapcs_args6(ctx, x0, x1, x2, x3, x4, x5, x6)	do {	\
328 		write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X6, x6);	\
329 		set_aapcs_args5(ctx, x0, x1, x2, x3, x4, x5);		\
330 	} while (0)
331 #define set_aapcs_args7(ctx, x0, x1, x2, x3, x4, x5, x6, x7)	do {	\
332 		write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X7, x7);	\
333 		set_aapcs_args6(ctx, x0, x1, x2, x3, x4, x5, x6);	\
334 	} while (0)
335 
336 /*******************************************************************************
337  * Function prototypes
338  ******************************************************************************/
339 void el1_sysregs_context_save(el1_sys_regs_t *regs);
340 void el1_sysregs_context_restore(el1_sys_regs_t *regs);
341 #if CTX_INCLUDE_FPREGS
342 void fpregs_context_save(fp_regs_t *regs);
343 void fpregs_context_restore(fp_regs_t *regs);
344 #endif
345 
346 
347 #undef CTX_SYSREG_ALL
348 #if CTX_INCLUDE_FPREGS
349 #undef CTX_FPREG_ALL
350 #endif
351 #undef CTX_GPREG_ALL
352 #undef CTX_EL3STATE_ALL
353 
354 #endif /* __ASSEMBLY__ */
355 
356 #endif /* __CONTEXT_H__ */
357