aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/entry-common.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kernel/entry-common.S')
-rw-r--r--arch/arm/kernel/entry-common.S65
1 files changed, 44 insertions, 21 deletions
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 53a7e0dea44d..3f8d0e3aefab 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -9,19 +9,10 @@
9 */ 9 */
10#include <linux/config.h> 10#include <linux/config.h>
11 11
12#include <asm/thread_info.h>
13#include <asm/ptrace.h>
14#include <asm/unistd.h> 12#include <asm/unistd.h>
15 13
16#include "entry-header.S" 14#include "entry-header.S"
17 15
18/*
19 * We rely on the fact that R0 is at the bottom of the stack (due to
20 * slow/fast restore user regs).
21 */
22#if S_R0 != 0
23#error "Please fix"
24#endif
25 16
26 .align 5 17 .align 5
27/* 18/*
@@ -30,11 +21,19 @@
30 * stack. 21 * stack.
31 */ 22 */
32ret_fast_syscall: 23ret_fast_syscall:
33 disable_irq r1 @ disable interrupts 24 disable_irq @ disable interrupts
34 ldr r1, [tsk, #TI_FLAGS] 25 ldr r1, [tsk, #TI_FLAGS]
35 tst r1, #_TIF_WORK_MASK 26 tst r1, #_TIF_WORK_MASK
36 bne fast_work_pending 27 bne fast_work_pending
37 fast_restore_user_regs 28
29 @ fast_restore_user_regs
30 ldr r1, [sp, #S_OFF + S_PSR] @ get calling cpsr
31 ldr lr, [sp, #S_OFF + S_PC]! @ get pc
32 msr spsr_cxsf, r1 @ save in spsr_svc
33 ldmdb sp, {r1 - lr}^ @ get calling r1 - lr
34 mov r0, r0
35 add sp, sp, #S_FRAME_SIZE - S_PC
36 movs pc, lr @ return & move spsr_svc into cpsr
38 37
39/* 38/*
40 * Ok, we need to do extra processing, enter the slow path. 39 * Ok, we need to do extra processing, enter the slow path.
@@ -49,7 +48,7 @@ work_pending:
49 mov r0, sp @ 'regs' 48 mov r0, sp @ 'regs'
50 mov r2, why @ 'syscall' 49 mov r2, why @ 'syscall'
51 bl do_notify_resume 50 bl do_notify_resume
52 disable_irq r1 @ disable interrupts 51 disable_irq @ disable interrupts
53 b no_work_pending 52 b no_work_pending
54 53
55work_resched: 54work_resched:
@@ -59,12 +58,19 @@ work_resched:
59 */ 58 */
60ENTRY(ret_to_user) 59ENTRY(ret_to_user)
61ret_slow_syscall: 60ret_slow_syscall:
62 disable_irq r1 @ disable interrupts 61 disable_irq @ disable interrupts
63 ldr r1, [tsk, #TI_FLAGS] 62 ldr r1, [tsk, #TI_FLAGS]
64 tst r1, #_TIF_WORK_MASK 63 tst r1, #_TIF_WORK_MASK
65 bne work_pending 64 bne work_pending
66no_work_pending: 65no_work_pending:
67 slow_restore_user_regs 66 @ slow_restore_user_regs
67 ldr r1, [sp, #S_PSR] @ get calling cpsr
68 ldr lr, [sp, #S_PC]! @ get pc
69 msr spsr_cxsf, r1 @ save in spsr_svc
70 ldmdb sp, {r0 - lr}^ @ get calling r1 - lr
71 mov r0, r0
72 add sp, sp, #S_FRAME_SIZE - S_PC
73 movs pc, lr @ return & move spsr_svc into cpsr
68 74
69/* 75/*
70 * This is how we return from a fork. 76 * This is how we return from a fork.
@@ -116,9 +122,26 @@ ENTRY(ret_from_fork)
116 122
117 .align 5 123 .align 5
118ENTRY(vector_swi) 124ENTRY(vector_swi)
119 save_user_regs 125 sub sp, sp, #S_FRAME_SIZE
126 stmia sp, {r0 - r12} @ Calling r0 - r12
127 add r8, sp, #S_PC
128 stmdb r8, {sp, lr}^ @ Calling sp, lr
129 mrs r8, spsr @ called from non-FIQ mode, so ok.
130 str lr, [sp, #S_PC] @ Save calling PC
131 str r8, [sp, #S_PSR] @ Save CPSR
132 str r0, [sp, #S_OLD_R0] @ Save OLD_R0
120 zero_fp 133 zero_fp
121 get_scno 134
135 /*
136 * Get the system call number.
137 */
138#ifdef CONFIG_ARM_THUMB
139 tst r8, #PSR_T_BIT @ this is SPSR from save_user_regs
140 addne scno, r7, #__NR_SYSCALL_BASE @ put OS number in
141 ldreq scno, [lr, #-4]
142#else
143 ldr scno, [lr, #-4] @ get SWI instruction
144#endif
122 arm710_bug_check scno, ip 145 arm710_bug_check scno, ip
123 146
124#ifdef CONFIG_ALIGNMENT_TRAP 147#ifdef CONFIG_ALIGNMENT_TRAP
@@ -126,14 +149,14 @@ ENTRY(vector_swi)
126 ldr ip, [ip] 149 ldr ip, [ip]
127 mcr p15, 0, ip, c1, c0 @ update control register 150 mcr p15, 0, ip, c1, c0 @ update control register
128#endif 151#endif
129 enable_irq ip 152 enable_irq
130 153
131 str r4, [sp, #-S_OFF]! @ push fifth arg 154 str r4, [sp, #-S_OFF]! @ push fifth arg
132 155
133 get_thread_info tsk 156 get_thread_info tsk
134 ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing 157 ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing
135 bic scno, scno, #0xff000000 @ mask off SWI op-code 158 bic scno, scno, #0xff000000 @ mask off SWI op-code
136 eor scno, scno, #OS_NUMBER << 20 @ check OS number 159 eor scno, scno, #__NR_SYSCALL_BASE @ check OS number
137 adr tbl, sys_call_table @ load syscall table pointer 160 adr tbl, sys_call_table @ load syscall table pointer
138 tst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls? 161 tst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls?
139 bne __sys_trace 162 bne __sys_trace
@@ -144,8 +167,8 @@ ENTRY(vector_swi)
144 167
145 add r1, sp, #S_OFF 168 add r1, sp, #S_OFF
1462: mov why, #0 @ no longer a real syscall 1692: mov why, #0 @ no longer a real syscall
147 cmp scno, #ARMSWI_OFFSET 170 cmp scno, #(__ARM_NR_BASE - __NR_SYSCALL_BASE)
148 eor r0, scno, #OS_NUMBER << 20 @ put OS number back 171 eor r0, scno, #__NR_SYSCALL_BASE @ put OS number back
149 bcs arm_syscall 172 bcs arm_syscall
150 b sys_ni_syscall @ not private func 173 b sys_ni_syscall @ not private func
151 174
@@ -190,7 +213,7 @@ ENTRY(sys_call_table)
190@ r5 = syscall table 213@ r5 = syscall table
191 .type sys_syscall, #function 214 .type sys_syscall, #function
192sys_syscall: 215sys_syscall:
193 eor scno, r0, #OS_NUMBER << 20 216 eor scno, r0, #__NR_SYSCALL_BASE
194 cmp scno, #__NR_syscall - __NR_SYSCALL_BASE 217 cmp scno, #__NR_syscall - __NR_SYSCALL_BASE
195 cmpne scno, #NR_syscalls @ check range 218 cmpne scno, #NR_syscalls @ check range
196 stmloia sp, {r5, r6} @ shuffle args 219 stmloia sp, {r5, r6} @ shuffle args