blob: fdb65e80a82832f7999281414869e91e00181b94 [file] [log] [blame]
Antonio Nino Diaz3c817f42018-03-21 10:49:27 +00001/*
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__ */