diff options
author | Nicolas Pitre <nico@cam.org> | 2006-01-14 11:36:12 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2006-01-14 11:36:12 -0500 |
commit | dd35afc22b76766e827c9e67ebc4b7bf6e31ecab (patch) | |
tree | 3336355470c2d57a2b11a47f8d9bcc1e86546735 /arch/arm/kernel/entry-common.S | |
parent | 687ad0191488a067b3b3cc94f670cc21f93811e1 (diff) |
[ARM] 3110/5: old ABI compat: multi-ABI syscall entry support
Patch from Nicolas Pitre
This patch adds the required code to support both user space ABIs at
the same time. A second syscall table is created to include legacy ABI
syscalls that need an ABI compat wrapper.
Signed-off-by: Nicolas Pitre <nico@cam.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel/entry-common.S')
-rw-r--r-- | arch/arm/kernel/entry-common.S | 78 |
1 files changed, 71 insertions, 7 deletions
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 59ce1bcec42b..8826d9803aeb 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S | |||
@@ -123,23 +123,49 @@ ENTRY(vector_swi) | |||
123 | /* | 123 | /* |
124 | * Get the system call number. | 124 | * Get the system call number. |
125 | */ | 125 | */ |
126 | #if defined(CONFIG_AEABI) | ||
127 | 126 | ||
128 | @ syscall number is in scno (r7) already. | 127 | #if defined(CONFIG_OABI_COMPAT) |
129 | 128 | ||
129 | /* | ||
130 | * If we have CONFIG_OABI_COMPAT then we need to look at the swi | ||
131 | * value to determine if it is an EABI or an old ABI call. | ||
132 | */ | ||
133 | #ifdef CONFIG_ARM_THUMB | ||
134 | tst r8, #PSR_T_BIT | ||
135 | movne r10, #0 @ no thumb OABI emulation | ||
136 | ldreq r10, [lr, #-4] @ get SWI instruction | ||
137 | #else | ||
138 | ldr r10, [lr, #-4] @ get SWI instruction | ||
139 | A710( and ip, r10, #0x0f000000 @ check for SWI ) | ||
140 | A710( teq ip, #0x0f000000 ) | ||
141 | A710( bne .Larm710bug ) | ||
142 | #endif | ||
143 | |||
144 | #elif defined(CONFIG_AEABI) | ||
145 | |||
146 | /* | ||
147 | * Pure EABI user space always put syscall number into scno (r7). | ||
148 | */ | ||
130 | A710( ldr ip, [lr, #-4] @ get SWI instruction ) | 149 | A710( ldr ip, [lr, #-4] @ get SWI instruction ) |
131 | A710( and ip, ip, #0x0f000000 @ check for SWI ) | 150 | A710( and ip, ip, #0x0f000000 @ check for SWI ) |
132 | A710( teq ip, #0x0f000000 ) | 151 | A710( teq ip, #0x0f000000 ) |
133 | A710( bne .Larm710bug ) | 152 | A710( bne .Larm710bug ) |
153 | |||
134 | #elif defined(CONFIG_ARM_THUMB) | 154 | #elif defined(CONFIG_ARM_THUMB) |
155 | |||
156 | /* Legacy ABI only, possibly thumb mode. */ | ||
135 | tst r8, #PSR_T_BIT @ this is SPSR from save_user_regs | 157 | tst r8, #PSR_T_BIT @ this is SPSR from save_user_regs |
136 | addne scno, r7, #__NR_SYSCALL_BASE @ put OS number in | 158 | addne scno, r7, #__NR_SYSCALL_BASE @ put OS number in |
137 | ldreq scno, [lr, #-4] | 159 | ldreq scno, [lr, #-4] |
160 | |||
138 | #else | 161 | #else |
162 | |||
163 | /* Legacy ABI only. */ | ||
139 | ldr scno, [lr, #-4] @ get SWI instruction | 164 | ldr scno, [lr, #-4] @ get SWI instruction |
140 | A710( and ip, scno, #0x0f000000 @ check for SWI ) | 165 | A710( and ip, scno, #0x0f000000 @ check for SWI ) |
141 | A710( teq ip, #0x0f000000 ) | 166 | A710( teq ip, #0x0f000000 ) |
142 | A710( bne .Larm710bug ) | 167 | A710( bne .Larm710bug ) |
168 | |||
143 | #endif | 169 | #endif |
144 | 170 | ||
145 | #ifdef CONFIG_ALIGNMENT_TRAP | 171 | #ifdef CONFIG_ALIGNMENT_TRAP |
@@ -150,12 +176,24 @@ ENTRY(vector_swi) | |||
150 | enable_irq | 176 | enable_irq |
151 | 177 | ||
152 | get_thread_info tsk | 178 | get_thread_info tsk |
179 | adr tbl, sys_call_table @ load syscall table pointer | ||
153 | ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing | 180 | ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing |
154 | #ifndef CONFIG_AEABI | 181 | |
182 | #if defined(CONFIG_OABI_COMPAT) | ||
183 | /* | ||
184 | * If the swi argument is zero, this is an EABI call and we do nothing. | ||
185 | * | ||
186 | * If this is an old ABI call, get the syscall number into scno and | ||
187 | * get the old ABI syscall table address. | ||
188 | */ | ||
189 | bics r10, r10, #0xff000000 | ||
190 | eorne scno, r10, #__NR_OABI_SYSCALL_BASE | ||
191 | ldrne tbl, =sys_oabi_call_table | ||
192 | #elif !defined(CONFIG_AEABI) | ||
155 | bic scno, scno, #0xff000000 @ mask off SWI op-code | 193 | bic scno, scno, #0xff000000 @ mask off SWI op-code |
156 | eor scno, scno, #__NR_SYSCALL_BASE @ check OS number | 194 | eor scno, scno, #__NR_SYSCALL_BASE @ check OS number |
157 | #endif | 195 | #endif |
158 | adr tbl, sys_call_table @ load syscall table pointer | 196 | |
159 | stmdb sp!, {r4, r5} @ push fifth and sixth args | 197 | stmdb sp!, {r4, r5} @ push fifth and sixth args |
160 | tst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls? | 198 | tst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls? |
161 | bne __sys_trace | 199 | bne __sys_trace |
@@ -200,10 +238,24 @@ __sys_trace_return: | |||
200 | __cr_alignment: | 238 | __cr_alignment: |
201 | .word cr_alignment | 239 | .word cr_alignment |
202 | #endif | 240 | #endif |
241 | .ltorg | ||
242 | |||
243 | /* | ||
244 | * This is the syscall table declaration for native ABI syscalls. | ||
245 | * With EABI a couple syscalls are obsolete and defined as sys_ni_syscall. | ||
246 | */ | ||
247 | #define ABI(native, compat) native | ||
248 | #ifdef CONFIG_AEABI | ||
249 | #define OBSOLETE(syscall) sys_ni_syscall | ||
250 | #else | ||
251 | #define OBSOLETE(syscall) syscall | ||
252 | #endif | ||
203 | 253 | ||
204 | .type sys_call_table, #object | 254 | .type sys_call_table, #object |
205 | ENTRY(sys_call_table) | 255 | ENTRY(sys_call_table) |
206 | #include "calls.S" | 256 | #include "calls.S" |
257 | #undef ABI | ||
258 | #undef OBSOLETE | ||
207 | 259 | ||
208 | /*============================================================================ | 260 | /*============================================================================ |
209 | * Special system call wrappers | 261 | * Special system call wrappers |
@@ -212,8 +264,7 @@ ENTRY(sys_call_table) | |||
212 | @ r8 = syscall table | 264 | @ r8 = syscall table |
213 | .type sys_syscall, #function | 265 | .type sys_syscall, #function |
214 | sys_syscall: | 266 | sys_syscall: |
215 | #ifndef CONFIG_AEABI | 267 | eor scno, r0, #__NR_OABI_SYSCALL_BASE |
216 | eor scno, r0, #__NR_SYSCALL_BASE | ||
217 | cmp scno, #__NR_syscall - __NR_SYSCALL_BASE | 268 | cmp scno, #__NR_syscall - __NR_SYSCALL_BASE |
218 | cmpne scno, #NR_syscalls @ check range | 269 | cmpne scno, #NR_syscalls @ check range |
219 | stmloia sp, {r5, r6} @ shuffle args | 270 | stmloia sp, {r5, r6} @ shuffle args |
@@ -222,7 +273,6 @@ sys_syscall: | |||
222 | movlo r2, r3 | 273 | movlo r2, r3 |
223 | movlo r3, r4 | 274 | movlo r3, r4 |
224 | ldrlo pc, [tbl, scno, lsl #2] | 275 | ldrlo pc, [tbl, scno, lsl #2] |
225 | #endif | ||
226 | b sys_ni_syscall | 276 | b sys_ni_syscall |
227 | 277 | ||
228 | sys_fork_wrapper: | 278 | sys_fork_wrapper: |
@@ -290,6 +340,7 @@ sys_mmap2: | |||
290 | #endif | 340 | #endif |
291 | 341 | ||
292 | #ifdef CONFIG_OABI_COMPAT | 342 | #ifdef CONFIG_OABI_COMPAT |
343 | |||
293 | /* | 344 | /* |
294 | * These are syscalls with argument register differences | 345 | * These are syscalls with argument register differences |
295 | */ | 346 | */ |
@@ -318,5 +369,18 @@ sys_oabi_readahead: | |||
318 | mov r2, r1 | 369 | mov r2, r1 |
319 | b sys_readahead | 370 | b sys_readahead |
320 | 371 | ||
372 | /* | ||
373 | * Let's declare a second syscall table for old ABI binaries | ||
374 | * using the compatibility syscall entries. | ||
375 | */ | ||
376 | #define ABI(native, compat) compat | ||
377 | #define OBSOLETE(syscall) syscall | ||
378 | |||
379 | .type sys_oabi_call_table, #object | ||
380 | ENTRY(sys_oabi_call_table) | ||
381 | #include "calls.S" | ||
382 | #undef ABI | ||
383 | #undef OBSOLETE | ||
384 | |||
321 | #endif | 385 | #endif |
322 | 386 | ||