First version
[3rdparty/ote_partner/tlk.git] / lib / monitor / arm64 / monitor_vector.S
1 /*
2  * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files
6  * (the "Software"), to deal in the Software without restriction,
7  * including without limitation the rights to use, copy, modify, merge,
8  * publish, distribute, sublicense, and/or sell copies of the Software,
9  * and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23 #include <config.h>
24 #include <asm.h>
25 #include <arm64/asm.h>
26 #include <arm64/monitor_macros.h>
27 #include <lib/monitor/monitor_vector.h>
28
29 #define EC_BIT_POS              26
30 #define EC_WIDTH                6
31
32 #define EC_SMC_AARCH32          0x13
33 #define EC_SMC_AARCH64          0x17
34
35 /*
36  * Occurs from either non-secure/secure EL1.
37  *
38  * If coming from the non-secure world, we may have to save more state
39  * depending on if we're going to transition to EL1 in secure mode. This
40  * is needed if passing along a standard call SMC, which launches a
41  * separate thread.
42  *
43  * If coming from S-EL1, detectable by NS=0 already, then just need to
44  * save the GP regs (all the other NS-EL1 state has been saved already).
45  *
46  * Args are passed in x0-x6 and x18-x30 are callee saved.
47  */
48 FUNCTION(handle_exc_aarch32)
49         stp     x9, x10, [sp, #-16]!    // create scratch
50
51         /* get exception code */
52         mrs     x9, esr_el3
53         ubfx    x9, x9, #EC_BIT_POS, #EC_WIDTH
54
55         cmp     x9, #EC_SMC_AARCH32
56         b.ne    .               // fail
57
58         /* incoming SMC should be from secure world */
59         mrs     x9, scr_el3
60         tst     x9, #1
61         b.ne    .               // fail
62
63         /* call function at tos_table[idx] */
64         and     w0, w0, #SMC_TOS_FUNC_ID_MASK
65         adr     x9, tos_table
66         ldr     x10, [x9, x0, lsl #3]
67         br      x10
68
69 tos_completion:
70         ldp     x9, x10, [sp], #16      // restore scratch
71
72         /* save secure EL1 state */
73         adr     x3, el1_secure_context
74         mon_save_el1_regs x3
75
76         /* restore NS EL1 state (loads spsr_el3/elr_el3) */
77         adr     x3, el1_non_secure_context
78         mon_restore_el1_regs x3
79
80         /* switch non-secure for return */
81         mon_scr_non_secure_64 x3
82
83         /* load SMC results into registers */
84         ldr     x3, el1_smc_args_results
85         ldp     x0, x1, [x3], #16
86         ldp     x2, x3, [x3], #16
87
88         eret
89
90 tos_initial_ns_return:
91         ldp     x9, x10, [sp], #16      // restore scratch
92
93         /* save S EL1 state */
94         adr     x3, el1_secure_context
95         mon_save_el1_regs x3
96
97         bl      platform_psci_coldboot_epilog
98         b       mon_init_return
99
100 tos_init_shared_addr:
101         ldp     x9, x10, [sp], #16      // restore scratch
102
103         /* save shared mem address (in x1) and return */
104         adr     x3, el1_smc_args_results
105         str     x1, [x3]
106
107         eret
108
109 /*
110  * This TOS call is serviced entirely within the monitor and returns
111  * to secure EL1. If the virt->phys translation is for the normal world,
112  * then make that MMU state current.
113  */
114 tos_addr_translation:
115         /* get virt address and type */
116         ldr     x9, el1_smc_args_results
117         ldp     x0, x1, [x9]
118
119         /* translate in current or non-secure world */
120         tst     x1, 0x4
121         b.eq    write_vreg      // current: no need to change state */
122
123         /* make non-secure MMU state current (corrupts x0, x1) */
124         adr     x3, el1_secure_context
125         mon_save_el1_mmu x3
126         adr     x3, el1_non_secure_context
127         mon_restore_el1_mmu x3
128
129         /* switch non-secure for translation */
130         mon_scr_non_secure_64 x3
131
132         /* reload args */
133         ldp     x0, x1, [x9]
134
135 write_vreg:
136         mov     x10, x1
137         and     x10, x10, #3
138         adr     x2, v2p_table
139         add     x2, x2, x10, lsl #3     // each type is 2 instrs
140         br      x2
141
142 v2p_table:
143         at      s12e1r, x0      // S12 priv read
144         b       read_par
145         at      s12e1w, x0      // S12 priv write
146         b       read_par
147         at      s12e0r, x0      // S12 user read
148         b       read_par
149         at      s12e0w, x0      // S12 user write
150
151 read_par:
152         mrs     x0, par_el1
153         str     x0, [x9]        // return par in x0
154
155         /* translate in current or non-secure world */
156         tst     x1, 0x4
157         b.eq    do_return       // current: no need to restore state */
158
159         /* restore secure MMU state */
160         adr     x3, el1_secure_context
161         mon_restore_el1_mmu x3
162
163         /* go back to secure mode */
164         mon_scr_secure_32 x3
165
166 do_return:
167         ldp     x9, x10, [sp], #16      // restore scratch
168         eret
169
170 /*
171  * Callbacks from secure->non-secure (not ready yet)
172  */
173 tos_callback:
174         b       .
175
176 fail:
177         movn    x0, #0
178         eret
179
180 /*
181  * SMCs from 64bit non-secure world.
182  *
183  * This would be the path for PSCI calls and Trusted OS SMCs interfacing
184  * with secure TAs. For PSCI, they'd be serviced here, but Trusted OS
185  * SMCs need to transition to the secureos in EL1.
186  */
187 FUNCTION(handle_exc_aarch64)
188         stp     x9, x10, [sp, #-16]!    // create scratch
189
190         /* get exception code */
191         mrs     x9, esr_el3
192         ubfx    x10, x9, #EC_BIT_POS, #EC_WIDTH
193
194         cmp     x10, #EC_SMC_AARCH64
195         b.ne    .                       // fail
196
197         /* for now, only expect non-secure EL1 */
198         mrs     x9, scr_el3
199         tst     x9, #1
200         b.eq    secure_el1_smc64        // fail
201         b       non_secure_el1_smc64
202
203         /*
204          * SMCs from 64bit secure world.
205          * Currently these are unexpected as secureos runs in a 32bit mode.
206          */
207 secure_el1_smc64:
208         b       .
209         ldp     x9, x10, [sp], #16      // restore scratch
210         movn    x0, #0
211         eret
212
213         /*
214          * SMCs from 64bit non-secure world.
215          *
216          * This is the path for PSCI calls and Trusted OS SMCs interfacing
217          * with secure TAs. For PSCI, they would be serviced entirely within
218          * the monitor (none are currently being used). Trusted OS SMCs
219          * need to transition to the secureos in EL1 for servicing.
220          */
221 non_secure_el1_smc64:
222         /*
223          * Currently, only handle ARM STD (pcsi) fastcalls, all
224          * others take the standard call code path.
225          */
226         tst     x0, #SMC_FASTCALL
227         b.eq    non_secure_stdcall
228         tst     x0, #(SMC_OWNER_ARM_STD << SMC_OWNER_SHIFT)
229         b.eq    non_secure_stdcall
230
231         str     lr, [sp, #-8]!          // save lr
232
233         /*
234          * Find index in fastcall_table. If index >= TRUSTED_BASE,
235          * route through TRUSTED_SERVICE (covers OS/APP fastcalls).
236          */
237         lsr     x10, x0, #SMC_OWNER_SHIFT
238         and     x10, x10, #SMC_OWNER_MASK
239         cmp     x10, #SMC_OWNER_TRUSTED_BASE
240         mov     x9, #SMC_OWNER_TRUSTED_SERVICE
241         csel    x10, x9, x10, ge
242
243         /* call fastcall handler */
244         adr     x9, fastcall_table
245         ldr     x10, [x9, x10, lsl #3]
246         blr     x10
247
248         ldr     lr, [sp], #8            // restore lr
249         ldp     x9, x10, [sp], #16      // restore scratch
250         eret
251
252 non_secure_stdcall:
253         /* save incoming SMC args from registers */
254         ldr     x9, el1_smc_args_results
255         stp     x0, x1, [x9], #16
256         stp     x2, x3, [x9], #16
257         stp     x4, x5, [x9], #16
258         stp     x6, x7, [x9], #16
259
260         ldp     x9, x10, [sp], #16      // restore scratch
261
262         /*
263          * Some SMCs (besides PSCI) don't transition to the secureos.
264          * For instance, the registration of IRQ and FS callback handlers.
265          *
266          * It does mean we're not supporting this functionality at the
267          * moment, but the intent is to change the implementation, to not
268          * require returning to a different PC than where we were called.
269          */
270         ldr     w3, =0x32000004         // SMC_TOS_NS_IRQ_PENDING_VECTOR
271         cmp     w0, w3
272         ldr     w3, =0x32000008         // SMC_TOS_SS_REGISTER_HANDLER
273         ccmp    w0, w3, #0x4, ne
274         b.ne    call_secureos
275
276         mov     x0, #0
277         eret
278
279 call_secureos:
280         /* save NS EL1 state */
281         adr     x3, el1_non_secure_context
282         mon_save_el1_regs x3
283
284         /* restore S EL1 state (including spsr_el3/elr_el3) */
285         adr     x3, el1_secure_context
286         mon_restore_el1_regs x3
287
288         /* set scr to secure32 */
289         mon_scr_secure_32 x3
290         eret
291
292 unimp_fastcall:
293         b       .
294
295 .align 3
296 el1_secure_context:
297         .rept   NUM_CTX_REGS
298         .quad   0
299         .endr
300
301 el1_non_secure_context:
302         .rept   NUM_CTX_REGS
303         .quad   0
304         .endr
305
306 /* fastcall SMCs issued from non-secure */
307 fastcall_table:
308         .quad   unimp_fastcall          /* ARM Arch service */
309         .quad   unimp_fastcall          /* CPU service */
310         .quad   unimp_fastcall          /* SIP service */
311         .quad   unimp_fastcall          /* OEM service */
312         .quad   arm_std_fastcall        /* ARM Standard service */
313         .quad   unimp_fastcall          /* Trusted (OS/TA) service */
314
315 /* SMCs issued from the Trusted OS */
316 tos_table:
317         .quad   -1
318         .quad   tos_completion
319         .quad   tos_callback            /* IRQ */
320         .quad   tos_callback            /* filesystem */
321         .quad   tos_initial_ns_return
322         .quad   tos_addr_translation
323         .quad   tos_init_shared_addr
324
325 /* address of shared mem for passing SMC args/results */
326 el1_smc_args_results:
327         .quad   0