diff options
author | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2005-11-26 10:38:39 +0000 |
---|---|---|
committer | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2005-11-26 10:38:39 +0000 |
commit | b5ff1b3127119aa430a6fd309591d584803b7b6e (patch) | |
tree | 5857296f0bebe0d8ee9e803b60a79d277493b7e0 /linux-user | |
parent | 0e43e99c045eb22415a7e52e2f88dbdb8e2d96f5 (diff) |
ARM system emulation (Paul Brook)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1661 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'linux-user')
-rw-r--r-- | linux-user/main.c | 10 | ||||
-rw-r--r-- | linux-user/signal.c | 10 |
2 files changed, 15 insertions, 5 deletions
diff --git a/linux-user/main.c b/linux-user/main.c index 1ae4656d3a..1b747d8738 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -331,6 +331,7 @@ void cpu_loop(CPUARMState *env) int trapnr; unsigned int n, insn; target_siginfo_t info; + uint32_t addr; for(;;) { trapnr = cpu_arm_exec(env); @@ -397,13 +398,18 @@ void cpu_loop(CPUARMState *env) /* just indicate that signals should be handled asap */ break; case EXCP_PREFETCH_ABORT: + addr = env->cp15.c6_data; + goto do_segv; case EXCP_DATA_ABORT: + addr = env->cp15.c6_insn; + goto do_segv; + do_segv: { info.si_signo = SIGSEGV; info.si_errno = 0; /* XXX: check env->error_code */ info.si_code = TARGET_SEGV_MAPERR; - info._sifields._sigfault._addr = env->cp15_6; + info._sifields._sigfault._addr = addr; queue_signal(info.si_signo, &info); } break; @@ -1190,10 +1196,10 @@ int main(int argc, char **argv) #elif defined(TARGET_ARM) { int i; + cpsr_write(env, regs->uregs[16], 0xffffffff); for(i = 0; i < 16; i++) { env->regs[i] = regs->uregs[i]; } - env->cpsr = regs->uregs[16]; ts->stack_base = info->start_stack; ts->heap_base = info->brk; /* This will be filled in on the first SYS_HEAPINFO call. */ diff --git a/linux-user/signal.c b/linux-user/signal.c index a7c06c9fb8..29933bda43 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -1003,7 +1003,7 @@ setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/ __put_user_error(env->regs[14], &sc->arm_lr, err); __put_user_error(env->regs[15], &sc->arm_pc, err); #ifdef TARGET_CONFIG_CPU_32 - __put_user_error(env->cpsr, &sc->arm_cpsr, err); + __put_user_error(cpsr_read(env), &sc->arm_cpsr, err); #endif __put_user_error(/* current->thread.trap_no */ 0, &sc->trap_no, err); @@ -1040,9 +1040,9 @@ setup_return(CPUState *env, struct emulated_sigaction *ka, target_ulong retcode; int thumb = 0; #if defined(TARGET_CONFIG_CPU_32) +#if 0 target_ulong cpsr = env->cpsr; -#if 0 /* * Maybe we need to deliver a 32-bit signal to a 26-bit task. */ @@ -1088,9 +1088,11 @@ setup_return(CPUState *env, struct emulated_sigaction *ka, env->regs[14] = retcode; env->regs[15] = handler & (thumb ? ~1 : ~3); +#if 0 #ifdef TARGET_CONFIG_CPU_32 env->cpsr = cpsr; #endif +#endif return 0; } @@ -1157,6 +1159,7 @@ static int restore_sigcontext(CPUState *env, struct target_sigcontext *sc) { int err = 0; + uint32_t cpsr; __get_user_error(env->regs[0], &sc->arm_r0, err); __get_user_error(env->regs[1], &sc->arm_r1, err); @@ -1175,7 +1178,8 @@ restore_sigcontext(CPUState *env, struct target_sigcontext *sc) __get_user_error(env->regs[14], &sc->arm_lr, err); __get_user_error(env->regs[15], &sc->arm_pc, err); #ifdef TARGET_CONFIG_CPU_32 - __get_user_error(env->cpsr, &sc->arm_cpsr, err); + __get_user_error(cpsr, &sc->arm_cpsr, err); + cpsr_write(env, cpsr, 0xffffffff); #endif err |= !valid_user_regs(env); |