1 #include <linux/config.h>
2 /*============================================================================
3 * All exits to user mode from the kernel go through this code.
10 #error SMP not supported
12 ldr \rd, __softirq_state
16 .globl ret_from_sys_call
20 str r0, [sp, #S_R0 + S_OFF] @ returned r0
23 ret_from_sys_call: @ external entry
26 mov r4, #1 @ flag this as being syscall return
28 blne SYMBOL_NAME(do_softirq)
29 ret_with_reschedule: @ external entry (__irq_usr)
31 ldr r0, [r5, #TSK_NEED_RESCHED]
32 ldr r1, [r5, #TSK_SIGPENDING]
35 teq r1, #0 @ check for signals
38 ret_from_all: restore_user_regs @ internal
40 ret_signal: mov r1, sp @ internal
41 adrsvc al, lr, ret_from_all
43 b SYMBOL_NAME(do_signal)
45 ret_reschedule: adrsvc al, lr, ret_with_reschedule @ internal
46 b SYMBOL_NAME(schedule)
48 .globl ret_from_exception
49 ret_from_exception: @ external entry
54 blne SYMBOL_NAME(do_softirq)
56 tst r0, #3 @ returning to user mode?
57 beq ret_with_reschedule
62 /*=============================================================================
64 *-----------------------------------------------------------------------------
68 * Create some aliases for some registers. These should allow
69 * us to have in theory up to 7 arguments to a function.
71 scno .req r9 @ syscall number
72 tbl .req r8 @ syscall table pointer
73 tip .req r7 @ temporary IP
76 vector_swi: save_user_regs
79 ldr scno, [lr, #-4] @ get SWI instruction
80 arm700_bug_check scno, ip
81 #ifdef CONFIG_ALIGNMENT_TRAP
84 mcr p15, 0, ip, c1, c0
88 str r4, [sp, #-S_OFF]! @ push fifth arg
89 adrsvc al, lr, fast_syscall_return
91 bic scno, scno, #0xff000000 @ mask off SWI op-code
92 eor scno, scno, #OS_NUMBER<<20 @ check OS number
93 cmp scno, #NR_syscalls @ check upper syscall limit
97 ldr ip, [ip, #TSK_FLAGS] @ check for syscall tracing
98 adr tbl, SYMBOL_NAME(sys_call_table)
100 ldreq pc, [tbl, scno, lsl #2] @ call sys routine
102 ldr tip, [sp, #S_IP + S_OFF] @ save old IP
104 str ip, [sp, #S_IP + S_OFF] @ trace entry [IP = 0]
105 bl SYMBOL_NAME(syscall_trace)
106 str tip, [sp, #S_IP + S_OFF]
109 ldmia ip, {r0 - r3} @ have to reload r0 - r3
111 ldr pc, [tbl, scno, lsl #2] @ call sys routine
112 str r0, [sp, #S_R0 + S_OFF] @ returned r0
115 str ip, [sp, #S_IP + S_OFF] @ trace exit [IP = 1]
116 bl SYMBOL_NAME(syscall_trace)
117 str tip, [sp, #S_IP + S_OFF]
118 b slow_syscall_return
120 2: add r1, sp, #S_OFF
121 tst scno, #0x00f00000 @ is it a Unix SWI?
123 subs r0, scno, #(KSWI_SYS_BASE - KSWI_BASE)
124 bcs SYMBOL_NAME(arm_syscall)
125 b SYMBOL_NAME(sys_ni_syscall) @ not private func
127 3: eor r0, scno, #OS_NUMBER <<20 @ Put OS number back
128 adrsvc al, lr, slow_syscall_return
129 b SYMBOL_NAME(deferred)
132 .type __softirq_state, #object
134 .word SYMBOL_NAME(softirq_state)
136 .type sys_call_table, #object
137 ENTRY(sys_call_table)
140 /*============================================================================
141 * Special system call wrappers
143 @ r0 = syscall number
145 .type sys_syscall, #function
146 SYMBOL_NAME(sys_syscall):
147 eor scno, r0, #OS_NUMBER << 20
148 cmp scno, #NR_syscalls @ check range
150 stmleia sp, {r5, r6} @ shuffle args
155 ldrle pc, [tbl, scno, lsl #2]
160 b SYMBOL_NAME(sys_fork)
164 b SYMBOL_NAME(sys_vfork)
168 b SYMBOL_NAME(sys_execve)
172 b SYMBOL_NAME(sys_clone)
174 sys_sigsuspend_wrapper:
176 b SYMBOL_NAME(sys_sigsuspend)
178 sys_rt_sigsuspend_wrapper:
180 b SYMBOL_NAME(sys_rt_sigsuspend)
182 sys_sigreturn_wrapper:
184 b SYMBOL_NAME(sys_sigreturn)
186 sys_rt_sigreturn_wrapper:
188 b SYMBOL_NAME(sys_rt_sigreturn)
190 sys_sigaltstack_wrapper:
191 ldr r2, [sp, #S_OFF + S_SP]
195 * Note: off_4k (r5) is always units of 4K. If we can't do the requested
196 * offset, we return EINVAL.
201 moveq r5, r5, lsr #PGOFF_SHIFT
214 .word fpe_not_present