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