1
2
3
4
5
6
7
8
9
10
11#include <asm/assembler.h>
12#include <asm/unistd.h>
13#include <asm/ftrace.h>
14#include <asm/unwind.h>
15
16#ifdef CONFIG_NEED_RET_TO_USER
17#include <mach/entry-macro.S>
18#else
19 .macro arch_ret_to_user, tmp1, tmp2
20 .endm
21#endif
22
23#include "entry-header.S"
24
25
26 .align 5
27
28
29
30
31
32
33
34ret_fast_syscall:
35 UNWIND(.fnstart )
36 UNWIND(.cantunwind )
37 disable_irq_notrace @ disable interrupts
38 ldr r1, [tsk,
39 tst r1,
40 bne fast_work_pending
41
42
43 arch_ret_to_user r1, lr
44
45 restore_user_regs fast = 1, offset = S_OFF
46 UNWIND(.fnend )
47ENDPROC(ret_fast_syscall)
48
49
50fast_work_pending:
51 str r0, [sp,
52
53#else
54
55
56
57
58
59ret_fast_syscall:
60 UNWIND(.fnstart )
61 UNWIND(.cantunwind )
62 str r0, [sp,
63 disable_irq_notrace @ disable interrupts
64 ldr r1, [tsk,
65 tst r1,
66 beq no_work_pending
67 UNWIND(.fnend )
68ENDPROC(ret_fast_syscall)
69
70
71#endif
72
73 tst r1,
74 bne __sys_trace_return_nosave
75slow_work_pending:
76 mov r0, sp @ 'regs'
77 mov r2, why @ 'syscall'
78 bl do_work_pending
79 cmp r0,
80 beq no_work_pending
81 movlt scno,
82 ldmia sp, {r0 - r6} @ have to reload r0 - r6
83 b local_restart @ ... and off we go
84ENDPROC(ret_fast_syscall)
85
86
87
88
89
90
91
92ENTRY(ret_to_user)
93ret_slow_syscall:
94 disable_irq_notrace @ disable interrupts
95ENTRY(ret_to_user_from_irq)
96 ldr r1, [tsk,
97 tst r1,
98 bne slow_work_pending
99no_work_pending:
100 asm_trace_hardirqs_on save = 0
101
102
103 arch_ret_to_user r1, lr
104 ct_user_enter save = 0
105
106 restore_user_regs fast = 0, offset = 0
107ENDPROC(ret_to_user_from_irq)
108ENDPROC(ret_to_user)
109
110
111
112
113ENTRY(ret_from_fork)
114 bl schedule_tail
115 cmp r5,
116 movne r0, r4
117 badrne lr, 1f
118 retne r5
1191: get_thread_info tsk
120 b ret_slow_syscall
121ENDPROC(ret_from_fork)
122
123 .equ NR_syscalls,0
124#define CALL(x) .equ NR_syscalls,NR_syscalls+1
125#include "calls.S"
126
127
128
129
130
131.ifne NR_syscalls - __NR_syscalls
132.error "__NR_syscalls is not equal to the size of the syscall table"
133.endif
134
135#undef CALL
136#define CALL(x) .long x
137
138
139
140
141
142
143 .align 5
144ENTRY(vector_swi)
145#ifdef CONFIG_CPU_V7M
146 v7m_exception_entry
147#else
148 sub sp, sp,
149 stmia sp, {r0 - r12} @ Calling r0 - r12
150 ARM( add r8, sp,
151 ARM( stmdb r8, {sp, lr}^ ) @ Calling sp, lr
152 THUMB( mov r8, sp )
153 THUMB( store_user_sp_lr r8, r10, S_SP ) @ calling sp, lr
154 mrs r8, spsr @ called from non-FIQ mode, so ok.
155 str lr, [sp,
156 str r8, [sp,
157 str r0, [sp,
158#endif
159 zero_fp
160 alignment_trap r10, ip, __cr_alignment
161 enable_irq
162 ct_user_exit
163 get_thread_info tsk
164
165
166
167
168
169
170
171
172
173
174
175#ifdef CONFIG_ARM_THUMB
176 tst r8,
177 movne r10,
178 USER( ldreq r10, [lr,
179#else
180 USER( ldr r10, [lr,
181#endif
182 ARM_BE8(rev r10, r10) @ little endian instruction
183
184
185
186
187
188
189
190
191 tst r8,
192 addne scno, r7,
193 USER( ldreq scno, [lr,
194
195#else
196
197 USER( ldr scno, [lr,
198#endif
199
200 uaccess_disable tbl
201
202 adr tbl, sys_call_table @ load syscall table pointer
203
204
205
206
207
208
209
210
211 bics r10, r10,
212 eorne scno, r10,
213 ldrne tbl, =sys_oabi_call_table
214
215 bic scno, scno,
216 eor scno, scno,
217#endif
218
219local_restart:
220 ldr r10, [tsk,
221 stmdb sp!, {r4, r5} @ push fifth and sixth args
222
223 tst r10,
224 bne __sys_trace
225
226 cmp scno,
227 badr lr, ret_fast_syscall @ return address
228 ldrcc pc, [tbl, scno, lsl
229
230 add r1, sp,
2312: cmp scno,
232 eor r0, scno,
233 bcs arm_syscall
234 mov why,
235 b sys_ni_syscall @ not private func
236
237
238
239
240
241
242
243
244
245
2469001:
247 sub lr, lr,
248 str lr, [sp,
249 b ret_fast_syscall
250#endif
251ENDPROC(vector_swi)
252
253
254
255
256
257__sys_trace:
258 mov r1, scno
259 add r0, sp,
260 bl syscall_trace_enter
261
262 badr lr, __sys_trace_return @ return address
263 mov scno, r0 @ syscall number (possibly new)
264 add r1, sp,
265 cmp scno,
266 ldmccia r1, {r0 - r6} @ have to reload r0 - r6
267 stmccia sp, {r4, r5} @ and update the stack args
268 ldrcc pc, [tbl, scno, lsl
269 cmp scno,
270 bne 2b
271 add sp, sp,
272 b ret_slow_syscall
273
274__sys_trace_return:
275 str r0, [sp,
276 mov r0, sp
277 bl syscall_trace_exit
278 b ret_slow_syscall
279
280__sys_trace_return_nosave:
281 enable_irq_notrace
282 mov r0, sp
283 bl syscall_trace_exit
284 b ret_slow_syscall
285
286 .align 5
287#ifdef CONFIG_ALIGNMENT_TRAP
288 .type __cr_alignment,
289__cr_alignment:
290 .word cr_alignment
291#endif
292 .ltorg
293
294
295
296
297
298#define ABI(native, compat) native
299#ifdef CONFIG_AEABI
300#define OBSOLETE(syscall) sys_ni_syscall
301#else
302#define OBSOLETE(syscall) syscall
303#endif
304
305 .type sys_call_table,
306ENTRY(sys_call_table)
307#include "calls.S"
308#undef ABI
309#undef OBSOLETE
310
311
312
313
314@ r0 = syscall number
315@ r8 = syscall table
316sys_syscall:
317 bic scno, r0,
318 cmp scno,
319 cmpne scno,
320 stmloia sp, {r5, r6} @ shuffle args
321 movlo r0, r1
322 movlo r1, r2
323 movlo r2, r3
324 movlo r3, r4
325 ldrlo pc, [tbl, scno, lsl
326 b sys_ni_syscall
327ENDPROC(sys_syscall)
328
329sys_sigreturn_wrapper:
330 add r0, sp,
331 mov why,
332 b sys_sigreturn
333ENDPROC(sys_sigreturn_wrapper)
334
335sys_rt_sigreturn_wrapper:
336 add r0, sp,
337 mov why,
338 b sys_rt_sigreturn
339ENDPROC(sys_rt_sigreturn_wrapper)
340
341sys_statfs64_wrapper:
342 teq r1,
343 moveq r1,
344 b sys_statfs64
345ENDPROC(sys_statfs64_wrapper)
346
347sys_fstatfs64_wrapper:
348 teq r1,
349 moveq r1,
350 b sys_fstatfs64
351ENDPROC(sys_fstatfs64_wrapper)
352
353
354
355
356
357sys_mmap2:
358
359 tst r5,
360 moveq r5, r5, lsr
361 streq r5, [sp,
362 beq sys_mmap_pgoff
363 mov r0,
364 ret lr
365#else
366 str r5, [sp,
367 b sys_mmap_pgoff
368#endif
369ENDPROC(sys_mmap2)
370
371#ifdef CONFIG_OABI_COMPAT
372
373
374
375
376
377sys_oabi_pread64:
378 stmia sp, {r3, r4}
379 b sys_pread64
380ENDPROC(sys_oabi_pread64)
381
382sys_oabi_pwrite64:
383 stmia sp, {r3, r4}
384 b sys_pwrite64
385ENDPROC(sys_oabi_pwrite64)
386
387sys_oabi_truncate64:
388 mov r3, r2
389 mov r2, r1
390 b sys_truncate64
391ENDPROC(sys_oabi_truncate64)
392
393sys_oabi_ftruncate64:
394 mov r3, r2
395 mov r2, r1
396 b sys_ftruncate64
397ENDPROC(sys_oabi_ftruncate64)
398
399sys_oabi_readahead:
400 str r3, [sp]
401 mov r3, r2
402 mov r2, r1
403 b sys_readahead
404ENDPROC(sys_oabi_readahead)
405
406
407
408
409
410#define ABI(native, compat) compat
411#define OBSOLETE(syscall) syscall
412
413 .type sys_oabi_call_table,
414ENTRY(sys_oabi_call_table)
415#include "calls.S"
416#undef ABI
417#undef OBSOLETE
418
419#endif
420
421