diff options
Diffstat (limited to 'target-arm/helper.c')
-rw-r--r-- | target-arm/helper.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/target-arm/helper.c b/target-arm/helper.c index c8348dabde..fe642df748 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -2705,12 +2705,11 @@ int arm_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, ARMCPU *cpu = ARM_CPU(cs); CPUARMState *env = &cpu->env; + env->exception.vaddress = address; if (rw == 2) { cs->exception_index = EXCP_PREFETCH_ABORT; - env->cp15.c6_insn = address; } else { cs->exception_index = EXCP_DATA_ABORT; - env->cp15.c6_data = address; } return 1; } @@ -2928,6 +2927,9 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs) return; case EXCP_PREFETCH_ABORT: case EXCP_DATA_ABORT: + /* TODO: if we implemented the MPU registers, this is where we + * should set the MMFAR, etc from exception.fsr and exception.vaddress. + */ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM); return; case EXCP_BKPT: @@ -3042,9 +3044,11 @@ void arm_cpu_do_interrupt(CPUState *cs) return; } } - env->cp15.c5_insn = 2; + env->exception.fsr = 2; /* Fall through to prefetch abort. */ case EXCP_PREFETCH_ABORT: + env->cp15.c5_insn = env->exception.fsr; + env->cp15.c6_insn = env->exception.vaddress; qemu_log_mask(CPU_LOG_INT, "...with IFSR 0x%x IFAR 0x%x\n", env->cp15.c5_insn, env->cp15.c6_insn); new_mode = ARM_CPU_MODE_ABT; @@ -3053,6 +3057,8 @@ void arm_cpu_do_interrupt(CPUState *cs) offset = 4; break; case EXCP_DATA_ABORT: + env->cp15.c5_data = env->exception.fsr; + env->cp15.c6_data = env->exception.vaddress; qemu_log_mask(CPU_LOG_INT, "...with DFSR 0x%x DFAR 0x%x\n", env->cp15.c5_data, env->cp15.c6_data); new_mode = ARM_CPU_MODE_ABT; @@ -3703,16 +3709,15 @@ int arm_cpu_handle_mmu_fault(CPUState *cs, vaddr address, } if (access_type == 2) { - env->cp15.c5_insn = ret; - env->cp15.c6_insn = address; cs->exception_index = EXCP_PREFETCH_ABORT; } else { - env->cp15.c5_data = ret; - if (access_type == 1 && arm_feature(env, ARM_FEATURE_V6)) - env->cp15.c5_data |= (1 << 11); - env->cp15.c6_data = address; + if (access_type == 1 && arm_feature(env, ARM_FEATURE_V6)) { + ret |= (1 << 11); + } cs->exception_index = EXCP_DATA_ABORT; } + env->exception.vaddress = address; + env->exception.fsr = ret; return 1; } |