xref: /rk3399_ARM-atf/include/arch/aarch32/smccc_macros.S (revision c948f77136c42a92d0bb660543a3600c36dcf7f1)
1/*
2 * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6#ifndef SMCCC_MACROS_S
7#define SMCCC_MACROS_S
8
9#include <arch.h>
10
11/*
12 * Macro to save the General purpose registers (r0 - r12), the banked
13 * spsr, lr, sp registers and the `scr` register to the SMC context on entry
14 * due a SMC call. The `lr` of the current mode (monitor) is expected to be
15 * already saved. The `sp` must point to the `smc_ctx_t` to save to.
16 * Additionally, also save the 'pmcr' register as this is updated whilst
17 * executing in the secure world.
18 */
19	.macro smccc_save_gp_mode_regs
20	/* Save r0 - r12 in the SMC context */
21	stm	sp, {r0-r12}
22	mov	r0, sp
23	add	r0, r0, #SMC_CTX_SP_USR
24
25#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION)
26	/* Must be in secure state to restore Monitor mode */
27	ldcopr	r4, SCR
28	bic	r2, r4, #SCR_NS_BIT
29	stcopr	r2, SCR
30	isb
31
32	cps	#MODE32_sys
33	stm	r0!, {sp, lr}
34
35	cps	#MODE32_irq
36	mrs	r2, spsr
37	stm	r0!, {r2, sp, lr}
38
39	cps	#MODE32_fiq
40	mrs	r2, spsr
41	stm	r0!, {r2, sp, lr}
42
43	cps	#MODE32_svc
44	mrs	r2, spsr
45	stm	r0!, {r2, sp, lr}
46
47	cps	#MODE32_abt
48	mrs	r2, spsr
49	stm	r0!, {r2, sp, lr}
50
51	cps	#MODE32_und
52	mrs	r2, spsr
53	stm	r0!, {r2, sp, lr}
54
55	/* lr_mon is already saved by caller */
56	cps	#MODE32_mon
57	mrs	r2, spsr
58	stm	r0!, {r2}
59
60	stcopr	r4, SCR
61	isb
62#else
63	/* Save the banked registers including the current SPSR and LR */
64	mrs	r4, sp_usr
65	mrs	r5, lr_usr
66	mrs	r6, spsr_irq
67	mrs	r7, sp_irq
68	mrs	r8, lr_irq
69	mrs	r9, spsr_fiq
70	mrs	r10, sp_fiq
71	mrs	r11, lr_fiq
72	mrs	r12, spsr_svc
73	stm	r0!, {r4-r12}
74
75	mrs	r4, sp_svc
76	mrs	r5, lr_svc
77	mrs	r6, spsr_abt
78	mrs	r7, sp_abt
79	mrs	r8, lr_abt
80	mrs	r9, spsr_und
81	mrs	r10, sp_und
82	mrs	r11, lr_und
83	mrs	r12, spsr
84	stm	r0!, {r4-r12}
85	/* lr_mon is already saved by caller */
86
87	ldcopr	r4, SCR
88#endif
89	str	r4, [sp, #SMC_CTX_SCR]
90	ldcopr	r4, PMCR
91	str	r4, [sp, #SMC_CTX_PMCR]
92	.endm
93
94/*
95 * Macro to restore the `smc_ctx_t`, which includes the General purpose
96 * registers and banked mode registers, and exit from the monitor mode.
97 * r0 must point to the `smc_ctx_t` to restore from.
98 */
99	.macro monitor_exit
100	/*
101	 * Save the current sp and restore the smc context
102	 * pointer to sp which will be used for handling the
103	 * next SMC.
104	 */
105	str	sp, [r0, #SMC_CTX_SP_MON]
106	mov	sp, r0
107
108	/*
109	 * Restore SCR first so that we access the right banked register
110	 * when the other mode registers are restored.
111	 */
112	ldr	r1, [r0, #SMC_CTX_SCR]
113	stcopr	r1, SCR
114	isb
115
116	/*
117	 * Restore the PMCR register.
118	 */
119	ldr	r1, [r0, #SMC_CTX_PMCR]
120	stcopr	r1, PMCR
121
122	/* Restore the banked registers including the current SPSR */
123	add	r1, r0, #SMC_CTX_SP_USR
124
125#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_VIRTUALIZATION)
126	/* Must be in secure state to restore Monitor mode */
127	ldcopr	r4, SCR
128	bic	r2, r4, #SCR_NS_BIT
129	stcopr	r2, SCR
130	isb
131
132	cps	#MODE32_sys
133	ldm	r1!, {sp, lr}
134
135	cps	#MODE32_irq
136	ldm	r1!, {r2, sp, lr}
137	msr	spsr_fsxc, r2
138
139	cps	#MODE32_fiq
140	ldm	r1!, {r2, sp, lr}
141	msr	spsr_fsxc, r2
142
143	cps	#MODE32_svc
144	ldm	r1!, {r2, sp, lr}
145	msr	spsr_fsxc, r2
146
147	cps	#MODE32_abt
148	ldm	r1!, {r2, sp, lr}
149	msr	spsr_fsxc, r2
150
151	cps	#MODE32_und
152	ldm	r1!, {r2, sp, lr}
153	msr	spsr_fsxc, r2
154
155	cps	#MODE32_mon
156	ldm	r1!, {r2}
157	msr	spsr_fsxc, r2
158
159	stcopr	r4, SCR
160	isb
161#else
162	ldm	r1!, {r4-r12}
163	msr	sp_usr, r4
164	msr	lr_usr, r5
165	msr	spsr_irq, r6
166	msr	sp_irq, r7
167	msr	lr_irq, r8
168	msr	spsr_fiq, r9
169	msr	sp_fiq, r10
170	msr	lr_fiq, r11
171	msr	spsr_svc, r12
172
173	ldm	r1!, {r4-r12}
174	msr	sp_svc, r4
175	msr	lr_svc, r5
176	msr	spsr_abt, r6
177	msr	sp_abt, r7
178	msr	lr_abt, r8
179	msr	spsr_und, r9
180	msr	sp_und, r10
181	msr	lr_und, r11
182	/*
183	 * Use the `_fsxc` suffix explicitly to instruct the assembler
184	 * to update all the 32 bits of SPSR. Else, by default, the
185	 * assembler assumes `_fc` suffix which only modifies
186	 * f->[31:24] and c->[7:0] bits of SPSR.
187	 */
188	msr	spsr_fsxc, r12
189#endif
190
191	/* Restore the LR */
192	ldr	lr, [r0, #SMC_CTX_LR_MON]
193
194	/* Restore the rest of the general purpose registers */
195	ldm	r0, {r0-r12}
196	eret
197	.endm
198
199#endif /* SMCCC_MACROS_S */
200