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