Commit 192c7bd92722d0d4a55cc9ed59b642e0aaf0d5c8
1 parent
b48a8bb6
ARM Thumb syscalls (Paul Brook)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1415 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
16 additions
and
4 deletions
linux-user/arm/syscall.h
@@ -26,6 +26,7 @@ struct target_pt_regs { | @@ -26,6 +26,7 @@ struct target_pt_regs { | ||
26 | #define ARM_ORIG_r0 uregs[17] | 26 | #define ARM_ORIG_r0 uregs[17] |
27 | 27 | ||
28 | #define ARM_SYSCALL_BASE 0x900000 | 28 | #define ARM_SYSCALL_BASE 0x900000 |
29 | +#define ARM_THUMB_SYSCALL 0 | ||
29 | 30 | ||
30 | #define ARM_NR_cacheflush (ARM_SYSCALL_BASE + 0xf0000 + 2) | 31 | #define ARM_NR_cacheflush (ARM_SYSCALL_BASE + 0xf0000 + 2) |
31 | 32 |
linux-user/main.c
@@ -359,16 +359,27 @@ void cpu_loop(CPUARMState *env) | @@ -359,16 +359,27 @@ void cpu_loop(CPUARMState *env) | ||
359 | case EXCP_SWI: | 359 | case EXCP_SWI: |
360 | { | 360 | { |
361 | /* system call */ | 361 | /* system call */ |
362 | - insn = ldl((void *)(env->regs[15] - 4)); | ||
363 | - n = insn & 0xffffff; | 362 | + if (env->thumb) { |
363 | + insn = lduw((void *)(env->regs[15] - 2)); | ||
364 | + n = insn & 0xff; | ||
365 | + } else { | ||
366 | + insn = ldl((void *)(env->regs[15] - 4)); | ||
367 | + n = insn & 0xffffff; | ||
368 | + } | ||
369 | + | ||
364 | if (n == ARM_NR_cacheflush) { | 370 | if (n == ARM_NR_cacheflush) { |
365 | arm_cache_flush(env->regs[0], env->regs[1]); | 371 | arm_cache_flush(env->regs[0], env->regs[1]); |
366 | } else if (n == ARM_NR_semihosting | 372 | } else if (n == ARM_NR_semihosting |
367 | || n == ARM_NR_thumb_semihosting) { | 373 | || n == ARM_NR_thumb_semihosting) { |
368 | env->regs[0] = do_arm_semihosting (env); | 374 | env->regs[0] = do_arm_semihosting (env); |
369 | - } else if (n >= ARM_SYSCALL_BASE) { | 375 | + } else if (n >= ARM_SYSCALL_BASE |
376 | + || (env->thumb && n == ARM_THUMB_SYSCALL)) { | ||
370 | /* linux syscall */ | 377 | /* linux syscall */ |
371 | - n -= ARM_SYSCALL_BASE; | 378 | + if (env->thumb) { |
379 | + n = env->regs[7]; | ||
380 | + } else { | ||
381 | + n -= ARM_SYSCALL_BASE; | ||
382 | + } | ||
372 | env->regs[0] = do_syscall(env, | 383 | env->regs[0] = do_syscall(env, |
373 | n, | 384 | n, |
374 | env->regs[0], | 385 | env->regs[0], |