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 | ||
