context.h 17.7 KB
Newer Older
1
/*
Zelalem's avatar
Zelalem committed
2
 * Copyright (c) 2013-2020, 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
#ifndef CONTEXT_H
#define CONTEXT_H
9

10
#include <lib/utils_def.h>
11

12
13
14
15
/*******************************************************************************
 * Constants that allow assembler code to access members of and the 'gp_regs'
 * structure at their correct offsets.
 ******************************************************************************/
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
48
49
#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)
50

51
52
53
54
55
/*******************************************************************************
 * 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
 ******************************************************************************/
56
#define CTX_EL3STATE_OFFSET	(CTX_GPREGS_OFFSET + CTX_GPREGS_END)
57
#define CTX_SCR_EL3		U(0x0)
58
59
60
61
#define CTX_ESR_EL3		U(0x8)
#define CTX_RUNTIME_SP		U(0x10)
#define CTX_SPSR_EL3		U(0x18)
#define CTX_ELR_EL3		U(0x20)
62
#define CTX_PMCR_EL0		U(0x28)
63
#define CTX_EL3STATE_END	U(0x30)
64
65
66
67
68
69
70

/*******************************************************************************
 * 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
 ******************************************************************************/
71
#define CTX_EL1_SYSREGS_OFFSET	(CTX_EL3STATE_OFFSET + CTX_EL3STATE_END)
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#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)
94
95
96
97
98
99

/*
 * If the platform is AArch64-only, there is no need to save and restore these
 * AArch32 registers.
 */
#if CTX_INCLUDE_AARCH32_REGS
100
101
102
103
104
105
106
#define CTX_SPSR_ABT		U(0xb0)	/* Align to the next 16 byte boundary */
#define CTX_SPSR_UND		U(0xb8)
#define CTX_SPSR_IRQ		U(0xc0)
#define CTX_SPSR_FIQ		U(0xc8)
#define CTX_DACR32_EL2		U(0xd0)
#define CTX_IFSR32_EL2		U(0xd8)
#define CTX_AARCH32_END		U(0xe0) /* Align to the next 16 byte boundary */
107
#else
108
#define CTX_AARCH32_END		U(0xb0)	/* Align to the next 16 byte boundary */
109
#endif /* CTX_INCLUDE_AARCH32_REGS */
110

111
112
113
114
115
/*
 * 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
116
117
118
119
120
121
#define CTX_CNTP_CTL_EL0	(CTX_AARCH32_END + U(0x0))
#define CTX_CNTP_CVAL_EL0	(CTX_AARCH32_END + U(0x8))
#define CTX_CNTV_CTL_EL0	(CTX_AARCH32_END + U(0x10))
#define CTX_CNTV_CVAL_EL0	(CTX_AARCH32_END + U(0x18))
#define CTX_CNTKCTL_EL1		(CTX_AARCH32_END + U(0x20))
#define CTX_TIMER_SYSREGS_END	(CTX_AARCH32_END + U(0x30)) /* Align to the next 16 byte boundary */
122
#else
123
124
125
#define CTX_TIMER_SYSREGS_END	CTX_AARCH32_END
#endif /* NS_TIMER_SWITCH */

126
127
128
129
130
131
132
133
134
135
136
137
#if CTX_INCLUDE_MTE_REGS
#define CTX_TFSRE0_EL1		(CTX_TIMER_SYSREGS_END + U(0x0))
#define CTX_TFSR_EL1		(CTX_TIMER_SYSREGS_END + U(0x8))
#define CTX_RGSR_EL1		(CTX_TIMER_SYSREGS_END + U(0x10))
#define CTX_GCR_EL1		(CTX_TIMER_SYSREGS_END + U(0x18))

/* Align to the next 16 byte boundary */
#define CTX_MTE_REGS_END	(CTX_TIMER_SYSREGS_END + U(0x20))
#else
#define CTX_MTE_REGS_END	CTX_TIMER_SYSREGS_END
#endif /* CTX_INCLUDE_MTE_REGS */

138
/*
139
140
141
142
143
144
 * End of system registers.
 */
#define CTX_EL1_SYSREGS_END		CTX_MTE_REGS_END

/*
 * EL2 register set
145
146
147
148
149
150
151
152
153
154
 */

#if CTX_INCLUDE_EL2_REGS
/* For later discussion
 * ICH_AP0R<n>_EL2
 * ICH_AP1R<n>_EL2
 * AMEVCNTVOFF0<n>_EL2
 * AMEVCNTVOFF1<n>_EL2
 * ICH_LR<n>_EL2
 */
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#define CTX_EL2_SYSREGS_OFFSET	(CTX_EL1_SYSREGS_OFFSET + CTX_EL1_SYSREGS_END)

#define CTX_ACTLR_EL2		U(0x0)
#define CTX_AFSR0_EL2		U(0x8)
#define CTX_AFSR1_EL2		U(0x10)
#define CTX_AMAIR_EL2		U(0x18)
#define CTX_CNTHCTL_EL2		U(0x20)
#define CTX_CNTHP_CTL_EL2	U(0x28)
#define CTX_CNTHP_CVAL_EL2	U(0x30)
#define CTX_CNTHP_TVAL_EL2	U(0x38)
#define CTX_CNTVOFF_EL2		U(0x40)
#define CTX_CPTR_EL2		U(0x48)
#define CTX_DBGVCR32_EL2	U(0x50)
#define CTX_ELR_EL2		U(0x58)
#define CTX_ESR_EL2		U(0x60)
#define CTX_FAR_EL2		U(0x68)
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
#define CTX_HACR_EL2		U(0x70)
#define CTX_HCR_EL2		U(0x78)
#define CTX_HPFAR_EL2		U(0x80)
#define CTX_HSTR_EL2		U(0x88)
#define CTX_ICC_SRE_EL2		U(0x90)
#define CTX_ICH_HCR_EL2		U(0x98)
#define CTX_ICH_VMCR_EL2	U(0xa0)
#define CTX_MAIR_EL2		U(0xa8)
#define CTX_MDCR_EL2		U(0xb0)
#define CTX_PMSCR_EL2		U(0xb8)
#define CTX_SCTLR_EL2		U(0xc0)
#define CTX_SPSR_EL2		U(0xc8)
#define CTX_SP_EL2		U(0xd0)
#define CTX_TCR_EL2		U(0xd8)
#define CTX_TPIDR_EL2		U(0xe0)
#define CTX_TTBR0_EL2		U(0xe8)
#define CTX_VBAR_EL2		U(0xf0)
#define CTX_VMPIDR_EL2		U(0xf8)
#define CTX_VPIDR_EL2		U(0x100)
#define CTX_VTCR_EL2		U(0x108)
#define CTX_VTTBR_EL2		U(0x110)
192
193

// Only if MTE registers in use
194
#define CTX_TFSR_EL2		U(0x118)
195
196

// Only if ENABLE_MPAM_FOR_LOWER_ELS==1
197
198
199
200
201
202
203
204
205
206
207
#define CTX_MPAM2_EL2		U(0x120)
#define CTX_MPAMHCR_EL2		U(0x128)
#define CTX_MPAMVPM0_EL2	U(0x130)
#define CTX_MPAMVPM1_EL2	U(0x138)
#define CTX_MPAMVPM2_EL2	U(0x140)
#define CTX_MPAMVPM3_EL2	U(0x148)
#define CTX_MPAMVPM4_EL2	U(0x150)
#define CTX_MPAMVPM5_EL2	U(0x158)
#define CTX_MPAMVPM6_EL2	U(0x160)
#define CTX_MPAMVPM7_EL2	U(0x168)
#define CTX_MPAMVPMV_EL2	U(0x170)
208
209

// Starting with Armv8.6
210
211
212
213
214
215
216
#define CTX_HAFGRTR_EL2		U(0x178)
#define CTX_HDFGRTR_EL2		U(0x180)
#define CTX_HDFGWTR_EL2		U(0x188)
#define CTX_HFGITR_EL2		U(0x190)
#define CTX_HFGRTR_EL2		U(0x198)
#define CTX_HFGWTR_EL2		U(0x1a0)
#define CTX_CNTPOFF_EL2		U(0x1a8)
217
218

// Starting with Armv8.4
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
#define CTX_CNTHPS_CTL_EL2	U(0x1b0)
#define CTX_CNTHPS_CVAL_EL2	U(0x1b8)
#define CTX_CNTHPS_TVAL_EL2	U(0x1c0)
#define CTX_CNTHVS_CTL_EL2	U(0x1c8)
#define CTX_CNTHVS_CVAL_EL2	U(0x1d0)
#define CTX_CNTHVS_TVAL_EL2	U(0x1d8)
#define CTX_CNTHV_CTL_EL2	U(0x1e0)
#define CTX_CNTHV_CVAL_EL2	U(0x1e8)
#define CTX_CNTHV_TVAL_EL2	U(0x1f0)
#define CTX_CONTEXTIDR_EL2	U(0x1f8)
#define CTX_SDER32_EL2		U(0x200)
#define CTX_TTBR1_EL2		U(0x208)
#define CTX_VDISR_EL2		U(0x210)
#define CTX_VNCR_EL2		U(0x218)
#define CTX_VSESR_EL2		U(0x220)
#define CTX_VSTCR_EL2		U(0x228)
#define CTX_VSTTBR_EL2		U(0x230)
#define CTX_TRFCR_EL2		U(0x238)
237
238

// Starting with Armv8.5
239
#define CTX_SCXTNUM_EL2		U(0x240)
240
/* Align to the next 16 byte boundary */
241
#define CTX_EL2_SYSREGS_END	U(0x250)
242

243
244
#endif /* CTX_INCLUDE_EL2_REGS */

245
246
247
248
/*******************************************************************************
 * Constants that allow assembler code to access members of and the 'fp_regs'
 * structure at their correct offsets.
 ******************************************************************************/
249
250
251
252
253
#if CTX_INCLUDE_EL2_REGS
# define CTX_FPREGS_OFFSET	(CTX_EL2_SYSREGS_OFFSET + CTX_EL2_SYSREGS_END)
#else
# define CTX_FPREGS_OFFSET	(CTX_EL1_SYSREGS_OFFSET + CTX_EL1_SYSREGS_END)
#endif
254
#if CTX_INCLUDE_FPREGS
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
#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
289
290
291
292
293
294
#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
295
296
#else
#define CTX_FPREGS_END		U(0)
297
#endif
298

299
300
301
/*******************************************************************************
 * Registers related to CVE-2018-3639
 ******************************************************************************/
302
303
304
305
#define CTX_CVE_2018_3639_OFFSET	(CTX_FPREGS_OFFSET + CTX_FPREGS_END)
#define CTX_CVE_2018_3639_DISABLE	U(0)
#define CTX_CVE_2018_3639_END		U(0x10) /* Align to the next 16 byte boundary */

306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
/*******************************************************************************
 * Registers related to ARMv8.3-PAuth.
 ******************************************************************************/
#define CTX_PAUTH_REGS_OFFSET	(CTX_CVE_2018_3639_OFFSET + CTX_CVE_2018_3639_END)
#if CTX_INCLUDE_PAUTH_REGS
#define CTX_PACIAKEY_LO		U(0x0)
#define CTX_PACIAKEY_HI		U(0x8)
#define CTX_PACIBKEY_LO		U(0x10)
#define CTX_PACIBKEY_HI		U(0x18)
#define CTX_PACDAKEY_LO		U(0x20)
#define CTX_PACDAKEY_HI		U(0x28)
#define CTX_PACDBKEY_LO		U(0x30)
#define CTX_PACDBKEY_HI		U(0x38)
#define CTX_PACGAKEY_LO		U(0x40)
#define CTX_PACGAKEY_HI		U(0x48)
321
#define CTX_PAUTH_REGS_END	U(0x50) /* Align to the next 16 byte boundary */
322
323
324
325
#else
#define CTX_PAUTH_REGS_END	U(0)
#endif /* CTX_INCLUDE_PAUTH_REGS */

326
#ifndef __ASSEMBLER__
327

328
329
#include <stdint.h>

330
331
#include <lib/cassert.h>

332
333
334
335
/*
 * Common constants to help define the 'cpu_context' structure and its
 * members below.
 */
336
#define DWORD_SHIFT		U(3)
337
#define DEFINE_REG_STRUCT(name, num_regs)	\
338
	typedef struct name {			\
Zelalem's avatar
Zelalem committed
339
		uint64_t ctx_regs[num_regs];	\
340
	}  __aligned(16) name##_t
341
342

/* Constants to determine the size of individual context structures */
343
#define CTX_GPREG_ALL		(CTX_GPREGS_END >> DWORD_SHIFT)
344
345
346
347
#define CTX_EL1_SYSREGS_ALL	(CTX_EL1_SYSREGS_END >> DWORD_SHIFT)
#if CTX_INCLUDE_EL2_REGS
# define CTX_EL2_SYSREGS_ALL	(CTX_EL2_SYSREGS_END >> DWORD_SHIFT)
#endif
348
#if CTX_INCLUDE_FPREGS
349
# define CTX_FPREG_ALL		(CTX_FPREGS_END >> DWORD_SHIFT)
350
#endif
351
#define CTX_EL3STATE_ALL	(CTX_EL3STATE_END >> DWORD_SHIFT)
352
#define CTX_CVE_2018_3639_ALL	(CTX_CVE_2018_3639_END >> DWORD_SHIFT)
353
354
355
#if CTX_INCLUDE_PAUTH_REGS
# define CTX_PAUTH_REGS_ALL	(CTX_PAUTH_REGS_END >> DWORD_SHIFT)
#endif
356

357
/*
358
359
 * AArch64 general purpose register context structure. Usually x0-x18,
 * lr are saved as the compiler is expected to preserve the remaining
360
 * callee saved registers if used by the C runtime and the assembler
361
362
 * does not touch the remaining. But in case of world switch during
 * exception handling, we need to save the callee registers too.
363
 */
364
DEFINE_REG_STRUCT(gp_regs, CTX_GPREG_ALL);
365

366
/*
367
 * AArch64 EL1 system register context structure for preserving the
368
 * architectural state during world switches.
369
 */
370
371
372
373
374
375
376
377
378
379
DEFINE_REG_STRUCT(el1_sysregs, CTX_EL1_SYSREGS_ALL);


/*
 * AArch64 EL2 system register context structure for preserving the
 * architectural state during world switches.
 */
#if CTX_INCLUDE_EL2_REGS
DEFINE_REG_STRUCT(el2_sysregs, CTX_EL2_SYSREGS_ALL);
#endif
380
381
382
383
384
385

/*
 * AArch64 floating point register context structure for preserving
 * the floating point state during switches from one security state to
 * another.
 */
386
#if CTX_INCLUDE_FPREGS
387
DEFINE_REG_STRUCT(fp_regs, CTX_FPREG_ALL);
388
#endif
389
390
391
392
393
394
395

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

396
397
398
/* Function pointer used by CVE-2018-3639 dynamic mitigation */
DEFINE_REG_STRUCT(cve_2018_3639, CTX_CVE_2018_3639_ALL);

399
400
401
402
403
/* Registers associated to ARMv8.3-PAuth */
#if CTX_INCLUDE_PAUTH_REGS
DEFINE_REG_STRUCT(pauth, CTX_PAUTH_REGS_ALL);
#endif

404
405
406
407
/*
 * Macros to access members of any of the above structures using their
 * offsets
 */
Zelalem's avatar
Zelalem committed
408
409
#define read_ctx_reg(ctx, offset)	((ctx)->ctx_regs[(offset) >> DWORD_SHIFT])
#define write_ctx_reg(ctx, offset, val)	(((ctx)->ctx_regs[(offset) >> DWORD_SHIFT]) \
Jeenu Viswambharan's avatar
Jeenu Viswambharan committed
410
					 = (uint64_t) (val))
411
412
413
414
415
416
417
418
419
420

/*
 * 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.
 */
421
422
423
typedef struct cpu_context {
	gp_regs_t gpregs_ctx;
	el3_state_t el3state_ctx;
424
425
426
427
	el1_sysregs_t el1_sysregs_ctx;
#if CTX_INCLUDE_EL2_REGS
	el2_sysregs_t el2_sysregs_ctx;
#endif
428
#if CTX_INCLUDE_FPREGS
429
	fp_regs_t fpregs_ctx;
430
#endif
431
	cve_2018_3639_t cve_2018_3639_ctx;
432
433
434
#if CTX_INCLUDE_PAUTH_REGS
	pauth_t pauth_ctx;
#endif
435
} cpu_context_t;
436

437
438
/* Macros to access members of the 'cpu_context_t' structure */
#define get_el3state_ctx(h)	(&((cpu_context_t *) h)->el3state_ctx)
439
#if CTX_INCLUDE_FPREGS
440
# define get_fpregs_ctx(h)	(&((cpu_context_t *) h)->fpregs_ctx)
441
#endif
442
443
444
445
#define get_el1_sysregs_ctx(h)	(&((cpu_context_t *) h)->el1_sysregs_ctx)
#if CTX_INCLUDE_EL2_REGS
# define get_el2_sysregs_ctx(h)	(&((cpu_context_t *) h)->el2_sysregs_ctx)
#endif
446
#define get_gpregs_ctx(h)	(&((cpu_context_t *) h)->gpregs_ctx)
447
#define get_cve_2018_3639_ctx(h)	(&((cpu_context_t *) h)->cve_2018_3639_ctx)
448
449
450
#if CTX_INCLUDE_PAUTH_REGS
# define get_pauth_ctx(h)	(&((cpu_context_t *) h)->pauth_ctx)
#endif
451
452
453
454
455
456

/*
 * 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.
 */
457
CASSERT(CTX_GPREGS_OFFSET == __builtin_offsetof(cpu_context_t, gpregs_ctx), \
458
	assert_core_context_gp_offset_mismatch);
459
460
461
462
463
464
CASSERT(CTX_EL1_SYSREGS_OFFSET == __builtin_offsetof(cpu_context_t, el1_sysregs_ctx), \
	assert_core_context_el1_sys_offset_mismatch);
#if CTX_INCLUDE_EL2_REGS
CASSERT(CTX_EL2_SYSREGS_OFFSET == __builtin_offsetof(cpu_context_t, el2_sysregs_ctx), \
	assert_core_context_el2_sys_offset_mismatch);
#endif
465
#if CTX_INCLUDE_FPREGS
466
CASSERT(CTX_FPREGS_OFFSET == __builtin_offsetof(cpu_context_t, fpregs_ctx), \
467
	assert_core_context_fp_offset_mismatch);
468
#endif
469
CASSERT(CTX_EL3STATE_OFFSET == __builtin_offsetof(cpu_context_t, el3state_ctx), \
470
	assert_core_context_el3state_offset_mismatch);
471
472
CASSERT(CTX_CVE_2018_3639_OFFSET == __builtin_offsetof(cpu_context_t, cve_2018_3639_ctx), \
	assert_core_context_cve_2018_3639_offset_mismatch);
473
474
475
476
#if CTX_INCLUDE_PAUTH_REGS
CASSERT(CTX_PAUTH_REGS_OFFSET == __builtin_offsetof(cpu_context_t, pauth_ctx), \
	assert_core_context_pauth_offset_mismatch);
#endif
477

478
479
480
481
482
483
/*
 * 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
484
	} while (0)
485
486
487
#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
488
	} while (0)
489
490
491
#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
492
	} while (0)
493
494
495
#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
496
	} while (0)
497
498
499
#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
500
	} while (0)
501
502
503
#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
504
	} while (0)
505
506
507
#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
508
	} while (0)
509
510
511
#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
512
	} while (0)
513

514
515
516
/*******************************************************************************
 * Function prototypes
 ******************************************************************************/
517
518
void el1_sysregs_context_save(el1_sysregs_t *regs);
void el1_sysregs_context_restore(el1_sysregs_t *regs);
519
520

#if CTX_INCLUDE_EL2_REGS
521
522
void el2_sysregs_context_save(el2_sysregs_t *regs);
void el2_sysregs_context_restore(el2_sysregs_t *regs);
523
524
#endif

525
#if CTX_INCLUDE_FPREGS
526
527
void fpregs_context_save(fp_regs_t *regs);
void fpregs_context_restore(fp_regs_t *regs);
528
#endif
529

530
#endif /* __ASSEMBLER__ */
531

532
#endif /* CONTEXT_H */