context.h 12.2 KB
Newer Older
1
/*
2
 * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
3
 *
dp-arm's avatar
dp-arm committed
4
 * SPDX-License-Identifier: BSD-3-Clause
5
6
7
8
9
 */

#ifndef __CONTEXT_H__
#define __CONTEXT_H__

10
11
12
13
/*******************************************************************************
 * Constants that allow assembler code to access members of and the 'gp_regs'
 * structure at their correct offsets.
 ******************************************************************************/
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#define CTX_GPREGS_OFFSET	U(0x0)
#define CTX_GPREG_X0		U(0x0)
#define CTX_GPREG_X1		U(0x8)
#define CTX_GPREG_X2		U(0x10)
#define CTX_GPREG_X3		U(0x18)
#define CTX_GPREG_X4		U(0x20)
#define CTX_GPREG_X5		U(0x28)
#define CTX_GPREG_X6		U(0x30)
#define CTX_GPREG_X7		U(0x38)
#define CTX_GPREG_X8		U(0x40)
#define CTX_GPREG_X9		U(0x48)
#define CTX_GPREG_X10		U(0x50)
#define CTX_GPREG_X11		U(0x58)
#define CTX_GPREG_X12		U(0x60)
#define CTX_GPREG_X13		U(0x68)
#define CTX_GPREG_X14		U(0x70)
#define CTX_GPREG_X15		U(0x78)
#define CTX_GPREG_X16		U(0x80)
#define CTX_GPREG_X17		U(0x88)
#define CTX_GPREG_X18		U(0x90)
#define CTX_GPREG_X19		U(0x98)
#define CTX_GPREG_X20		U(0xa0)
#define CTX_GPREG_X21		U(0xa8)
#define CTX_GPREG_X22		U(0xb0)
#define CTX_GPREG_X23		U(0xb8)
#define CTX_GPREG_X24		U(0xc0)
#define CTX_GPREG_X25		U(0xc8)
#define CTX_GPREG_X26		U(0xd0)
#define CTX_GPREG_X27		U(0xd8)
#define CTX_GPREG_X28		U(0xe0)
#define CTX_GPREG_X29		U(0xe8)
#define CTX_GPREG_LR		U(0xf0)
#define CTX_GPREG_SP_EL0	U(0xf8)
#define CTX_GPREGS_END		U(0x100)
48

49
50
51
52
53
54
55
56
57
58
59
60
61
62
#if WORKAROUND_CVE_2017_5715
#define CTX_CVE_2017_5715_OFFSET	(CTX_GPREGS_OFFSET + CTX_GPREGS_END)
#define CTX_CVE_2017_5715_QUAD0		U(0x0)
#define CTX_CVE_2017_5715_QUAD1		U(0x8)
#define	CTX_CVE_2017_5715_QUAD2		U(0x10)
#define CTX_CVE_2017_5715_QUAD3		U(0x18)
#define CTX_CVE_2017_5715_QUAD4		U(0x20)
#define CTX_CVE_2017_5715_QUAD5		U(0x28)
#define CTX_CVE_2017_5715_END		U(0x30)
#else
#define CTX_CVE_2017_5715_OFFSET	CTX_GPREGS_OFFSET
#define CTX_CVE_2017_5715_END		CTX_GPREGS_END
#endif

63
64
65
66
67
/*******************************************************************************
 * Constants that allow assembler code to access members of and the 'el3_state'
 * structure at their correct offsets. Note that some of the registers are only
 * 32-bits wide but are stored as 64-bit values for convenience
 ******************************************************************************/
68
#define CTX_EL3STATE_OFFSET	(CTX_CVE_2017_5715_OFFSET + CTX_CVE_2017_5715_END)
69
70
71
72
73
#define CTX_SCR_EL3		U(0x0)
#define CTX_RUNTIME_SP		U(0x8)
#define CTX_SPSR_EL3		U(0x10)
#define CTX_ELR_EL3		U(0x18)
#define CTX_EL3STATE_END	U(0x20)
74
75
76
77
78
79
80
81

/*******************************************************************************
 * Constants that allow assembler code to access members of and the
 * 'el1_sys_regs' structure at their correct offsets. Note that some of the
 * registers are only 32-bits wide but are stored as 64-bit values for
 * convenience
 ******************************************************************************/
#define CTX_SYSREGS_OFFSET	(CTX_EL3STATE_OFFSET + CTX_EL3STATE_END)
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#define CTX_SPSR_EL1		U(0x0)
#define CTX_ELR_EL1		U(0x8)
#define CTX_SCTLR_EL1		U(0x10)
#define CTX_ACTLR_EL1		U(0x18)
#define CTX_CPACR_EL1		U(0x20)
#define CTX_CSSELR_EL1		U(0x28)
#define CTX_SP_EL1		U(0x30)
#define CTX_ESR_EL1		U(0x38)
#define CTX_TTBR0_EL1		U(0x40)
#define CTX_TTBR1_EL1		U(0x48)
#define CTX_MAIR_EL1		U(0x50)
#define CTX_AMAIR_EL1		U(0x58)
#define CTX_TCR_EL1		U(0x60)
#define CTX_TPIDR_EL1		U(0x68)
#define CTX_TPIDR_EL0		U(0x70)
#define CTX_TPIDRRO_EL0		U(0x78)
#define CTX_PAR_EL1		U(0x80)
#define CTX_FAR_EL1		U(0x88)
#define CTX_AFSR0_EL1		U(0x90)
#define CTX_AFSR1_EL1		U(0x98)
#define CTX_CONTEXTIDR_EL1	U(0xa0)
#define CTX_VBAR_EL1		U(0xa8)
104
#define CTX_PMCR_EL0		U(0xb0)
105
106
107
108
109
110

/*
 * If the platform is AArch64-only, there is no need to save and restore these
 * AArch32 registers.
 */
#if CTX_INCLUDE_AARCH32_REGS
111
112
113
114
115
116
#define CTX_SPSR_ABT		U(0xc0)  /* Align to the next 16 byte boundary */
#define CTX_SPSR_UND		U(0xc8)
#define CTX_SPSR_IRQ		U(0xd0)
#define CTX_SPSR_FIQ		U(0xd8)
#define CTX_DACR32_EL2		U(0xe0)
#define CTX_IFSR32_EL2		U(0xe8)
David Cunado's avatar
David Cunado committed
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
121
#endif /* __CTX_INCLUDE_AARCH32_REGS__ */

122
123
124
125
126
/*
 * If the timer registers aren't saved and restored, we don't have to reserve
 * space for them in the context
 */
#if NS_TIMER_SWITCH
127
128
129
130
131
132
#define CTX_CNTP_CTL_EL0	(CTX_TIMER_SYSREGS_OFF + U(0x0))
#define CTX_CNTP_CVAL_EL0	(CTX_TIMER_SYSREGS_OFF + U(0x8))
#define CTX_CNTV_CTL_EL0	(CTX_TIMER_SYSREGS_OFF + U(0x10))
#define CTX_CNTV_CVAL_EL0	(CTX_TIMER_SYSREGS_OFF + U(0x18))
#define CTX_CNTKCTL_EL1		(CTX_TIMER_SYSREGS_OFF + U(0x20))
#define CTX_SYSREGS_END		(CTX_TIMER_SYSREGS_OFF + U(0x30)) /* Align to the next 16 byte boundary */
133
#else
134
135
#define CTX_SYSREGS_END		CTX_TIMER_SYSREGS_OFF
#endif /* __NS_TIMER_SWITCH__ */
136
137
138
139
140

/*******************************************************************************
 * Constants that allow assembler code to access members of and the 'fp_regs'
 * structure at their correct offsets.
 ******************************************************************************/
141
#if CTX_INCLUDE_FPREGS
142
#define CTX_FPREGS_OFFSET	(CTX_SYSREGS_OFFSET + CTX_SYSREGS_END)
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#define CTX_FP_Q0		U(0x0)
#define CTX_FP_Q1		U(0x10)
#define CTX_FP_Q2		U(0x20)
#define CTX_FP_Q3		U(0x30)
#define CTX_FP_Q4		U(0x40)
#define CTX_FP_Q5		U(0x50)
#define CTX_FP_Q6		U(0x60)
#define CTX_FP_Q7		U(0x70)
#define CTX_FP_Q8		U(0x80)
#define CTX_FP_Q9		U(0x90)
#define CTX_FP_Q10		U(0xa0)
#define CTX_FP_Q11		U(0xb0)
#define CTX_FP_Q12		U(0xc0)
#define CTX_FP_Q13		U(0xd0)
#define CTX_FP_Q14		U(0xe0)
#define CTX_FP_Q15		U(0xf0)
#define CTX_FP_Q16		U(0x100)
#define CTX_FP_Q17		U(0x110)
#define CTX_FP_Q18		U(0x120)
#define CTX_FP_Q19		U(0x130)
#define CTX_FP_Q20		U(0x140)
#define CTX_FP_Q21		U(0x150)
#define CTX_FP_Q22		U(0x160)
#define CTX_FP_Q23		U(0x170)
#define CTX_FP_Q24		U(0x180)
#define CTX_FP_Q25		U(0x190)
#define CTX_FP_Q26		U(0x1a0)
#define CTX_FP_Q27		U(0x1b0)
#define CTX_FP_Q28		U(0x1c0)
#define CTX_FP_Q29		U(0x1d0)
#define CTX_FP_Q30		U(0x1e0)
#define CTX_FP_Q31		U(0x1f0)
#define CTX_FP_FPSR		U(0x200)
#define CTX_FP_FPCR		U(0x208)
David Cunado's avatar
David Cunado committed
177
178
179
180
181
182
#if CTX_INCLUDE_AARCH32_REGS
#define CTX_FP_FPEXC32_EL2	U(0x210)
#define CTX_FPREGS_END		U(0x220) /* Align to the next 16 byte boundary */
#else
#define CTX_FPREGS_END		U(0x210) /* Align to the next 16 byte boundary */
#endif
183
#endif
184
185
186

#ifndef __ASSEMBLY__

187
#include <cassert.h>
188
#include <platform_def.h>	/* for CACHE_WRITEBACK_GRANULE */
189
190
#include <stdint.h>

191
192
193
194
/*
 * Common constants to help define the 'cpu_context' structure and its
 * members below.
 */
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
204
205
#if WORKAROUND_CVE_2017_5715
#define CTX_CVE_2017_5715_ALL	(CTX_CVE_2017_5715_END >> DWORD_SHIFT)
#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
211
#define CTX_EL3STATE_ALL	(CTX_EL3STATE_END >> DWORD_SHIFT)

212
/*
213
214
 * AArch64 general purpose register context structure. Usually x0-x18,
 * 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
217
 * does not touch the remaining. But in case of world switch during
 * exception handling, we need to save the callee registers too.
218
 */
219
DEFINE_REG_STRUCT(gp_regs, CTX_GPREG_ALL);
220

221
222
223
224
#if WORKAROUND_CVE_2017_5715
DEFINE_REG_STRUCT(cve_2017_5715_regs, CTX_CVE_2017_5715_ALL);
#endif

225
226
227
228
229
230
231
232
233
234
235
236
/*
 * AArch64 EL1 system register context structure for preserving the
 * architectural state during switches from one security state to
 * another in EL1.
 */
DEFINE_REG_STRUCT(el1_sys_regs, CTX_SYSREG_ALL);

/*
 * AArch64 floating point register context structure for preserving
 * the floating point state during switches from one security state to
 * another.
 */
237
#if CTX_INCLUDE_FPREGS
238
DEFINE_REG_STRUCT(fp_regs, CTX_FPREG_ALL);
239
#endif
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263

/*
 * Miscellaneous registers used by EL3 firmware to maintain its state
 * across exception entries and exits
 */
DEFINE_REG_STRUCT(el3_state, CTX_EL3STATE_ALL);

/*
 * Macros to access members of any of the above structures using their
 * offsets
 */
#define read_ctx_reg(ctx, offset)	((ctx)->_regs[offset >> DWORD_SHIFT])
#define write_ctx_reg(ctx, offset, val)	(((ctx)->_regs[offset >> DWORD_SHIFT]) \
					 = val)

/*
 * Top-level context structure which is used by EL3 firmware to
 * preserve the state of a core at EL1 in one of the two security
 * states and save enough EL3 meta data to be able to return to that
 * EL and security state. The context management library will be used
 * to ensure that SP_EL3 always points to an instance of this
 * structure at exception entry and exit. Each instance will
 * correspond to either the secure or the non-secure state.
 */
264
265
typedef struct cpu_context {
	gp_regs_t gpregs_ctx;
266
267
268
#if WORKAROUND_CVE_2017_5715
	cve_2017_5715_regs_t cve_2017_5715_regs_ctx;
#endif
269
270
	el3_state_t el3state_ctx;
	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
277
/* Macros to access members of the 'cpu_context_t' structure */
#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
282
#define get_sysregs_ctx(h)	(&((cpu_context_t *) h)->sysregs_ctx)
#define get_gpregs_ctx(h)	(&((cpu_context_t *) h)->gpregs_ctx)
283
284
285
286
287
288

/*
 * Compile time assertions related to the 'cpu_context' structure to
 * ensure that the assembler and the compiler view of the offsets of
 * the structure members is the same.
 */
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
299
	assert_core_context_el3state_offset_mismatch);

300
301
302
303
304
305
/*
 * Helper macro to set the general purpose registers that correspond to
 * parameters in an aapcs_64 call i.e. x0-x7
 */
#define set_aapcs_args0(ctx, x0)				do {	\
		write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X0, x0);	\
Soby Mathew's avatar
Soby Mathew committed
306
	} while (0)
307
308
309
#define set_aapcs_args1(ctx, x0, x1)				do {	\
		write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X1, x1);	\
		set_aapcs_args0(ctx, x0);				\
Soby Mathew's avatar
Soby Mathew committed
310
	} while (0)
311
312
313
#define set_aapcs_args2(ctx, x0, x1, x2)			do {	\
		write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X2, x2);	\
		set_aapcs_args1(ctx, x0, x1);				\
Soby Mathew's avatar
Soby Mathew committed
314
	} while (0)
315
316
317
#define set_aapcs_args3(ctx, x0, x1, x2, x3)			do {	\
		write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X3, x3);	\
		set_aapcs_args2(ctx, x0, x1, x2);			\
Soby Mathew's avatar
Soby Mathew committed
318
	} while (0)
319
320
321
#define set_aapcs_args4(ctx, x0, x1, x2, x3, x4)		do {	\
		write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X4, x4);	\
		set_aapcs_args3(ctx, x0, x1, x2, x3);			\
Soby Mathew's avatar
Soby Mathew committed
322
	} while (0)
323
324
325
#define set_aapcs_args5(ctx, x0, x1, x2, x3, x4, x5)		do {	\
		write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X5, x5);	\
		set_aapcs_args4(ctx, x0, x1, x2, x3, x4);		\
Soby Mathew's avatar
Soby Mathew committed
326
	} while (0)
327
328
329
#define set_aapcs_args6(ctx, x0, x1, x2, x3, x4, x5, x6)	do {	\
		write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X6, x6);	\
		set_aapcs_args5(ctx, x0, x1, x2, x3, x4, x5);		\
Soby Mathew's avatar
Soby Mathew committed
330
	} while (0)
331
332
333
#define set_aapcs_args7(ctx, x0, x1, x2, x3, x4, x5, x6, x7)	do {	\
		write_ctx_reg(get_gpregs_ctx(ctx), CTX_GPREG_X7, x7);	\
		set_aapcs_args6(ctx, x0, x1, x2, x3, x4, x5, x6);	\
Soby Mathew's avatar
Soby Mathew committed
334
	} while (0)
335

336
337
338
/*******************************************************************************
 * Function prototypes
 ******************************************************************************/
339
340
void el1_sysregs_context_save(el1_sys_regs_t *regs);
void el1_sysregs_context_restore(el1_sys_regs_t *regs);
341
#if CTX_INCLUDE_FPREGS
342
343
void fpregs_context_save(fp_regs_t *regs);
void fpregs_context_restore(fp_regs_t *regs);
344
#endif
345

346

347
#undef CTX_SYSREG_ALL
348
349
350
#if CTX_INCLUDE_FPREGS
#undef CTX_FPREG_ALL
#endif
351
#undef CTX_GPREG_ALL
352
353
354
355
356
#undef CTX_EL3STATE_ALL

#endif /* __ASSEMBLY__ */

#endif /* __CONTEXT_H__ */