diff options
author | Peter Maydell | 2014-09-30 12:02:06 +0200 |
---|---|---|
committer | Peter Maydell | 2014-09-30 12:02:06 +0200 |
commit | 29429c7244c73eefada3d0ec6dd30c5698782d08 (patch) | |
tree | ca318448a3a953a6897001a4e04cb97f566f1456 /target-arm/helper-a64.c | |
parent | Merge remote-tracking branch 'remotes/spice/tags/pull-spice-20140929-1' into ... (diff) | |
parent | target-arm: Add support for VIRQ and VFIQ (diff) | |
download | qemu-29429c7244c73eefada3d0ec6dd30c5698782d08.tar.gz qemu-29429c7244c73eefada3d0ec6dd30c5698782d08.tar.xz qemu-29429c7244c73eefada3d0ec6dd30c5698782d08.zip |
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20140929' into staging
target-arm:
* more EL2/EL3 preparation work
* don't handle c15_cpar changes via tb_flush()
* fix some unused function warnings in ARM devices
* build the GDB XML for 32 bit CPUs into qemu-*-aarch64
* implement guest breakpoint support
# gpg: Signature made Mon 29 Sep 2014 19:25:37 BST using RSA key ID 14360CDE
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>"
* remotes/pmaydell/tags/pull-target-arm-20140929:
target-arm: Add support for VIRQ and VFIQ
target-arm: Add IRQ and FIQ routing to EL2 and 3
target-arm: A64: Emulate the SMC insn
target-arm: Add a Hypervisor Trap exception type
target-arm: A64: Emulate the HVC insn
target-arm: A64: Correct updates to FAR and ESR on exceptions
target-arm: Don't take interrupts targeting lower ELs
target-arm: Break out exception masking to a separate func
target-arm: A64: Refactor aarch64_cpu_do_interrupt
target-arm: Add SCR_EL3
target-arm: Add HCR_EL2
target-arm: Don't handle c15_cpar changes via tb_flush()
hw/input/tsc210x.c: Delete unused array tsc2101_rates
hw/display/pxa2xx_lcd.c: Remove unused function pxa2xx_dma_rdst_set
hw/intc/imx_avic.c: Remove unused function imx_avic_set_prio()
hw/display/blizzard.c: Delete unused function blizzard_rgb2yuv
configure: Build GDB XML for 32 bit ARM CPUs into qemu aarch64 binaries
target-arm: Implement handling of breakpoint firing
target-arm: Implement setting guest breakpoints
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target-arm/helper-a64.c')
-rw-r--r-- | target-arm/helper-a64.c | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c index 2e9ef64786..8228e29486 100644 --- a/target-arm/helper-a64.c +++ b/target-arm/helper-a64.c @@ -443,10 +443,12 @@ void aarch64_cpu_do_interrupt(CPUState *cs) { ARMCPU *cpu = ARM_CPU(cs); CPUARMState *env = &cpu->env; - target_ulong addr = env->cp15.vbar_el[1]; + unsigned int new_el = arm_excp_target_el(cs, cs->exception_index); + target_ulong addr = env->cp15.vbar_el[new_el]; + unsigned int new_mode = aarch64_pstate_mode(new_el, true); int i; - if (arm_current_pl(env) == 0) { + if (arm_current_pl(env) < new_el) { if (env->aarch64) { addr += 0x400; } else { @@ -464,23 +466,27 @@ void aarch64_cpu_do_interrupt(CPUState *cs) env->exception.syndrome); } - env->cp15.esr_el[1] = env->exception.syndrome; - env->cp15.far_el[1] = env->exception.vaddress; - switch (cs->exception_index) { case EXCP_PREFETCH_ABORT: case EXCP_DATA_ABORT: + env->cp15.far_el[new_el] = env->exception.vaddress; qemu_log_mask(CPU_LOG_INT, "...with FAR 0x%" PRIx64 "\n", - env->cp15.far_el[1]); - break; + env->cp15.far_el[new_el]); + /* fall through */ case EXCP_BKPT: case EXCP_UDEF: case EXCP_SWI: + case EXCP_HVC: + case EXCP_HYP_TRAP: + case EXCP_SMC: + env->cp15.esr_el[new_el] = env->exception.syndrome; break; case EXCP_IRQ: + case EXCP_VIRQ: addr += 0x80; break; case EXCP_FIQ: + case EXCP_VFIQ: addr += 0x100; break; default: @@ -488,15 +494,15 @@ void aarch64_cpu_do_interrupt(CPUState *cs) } if (is_a64(env)) { - env->banked_spsr[aarch64_banked_spsr_index(1)] = pstate_read(env); + env->banked_spsr[aarch64_banked_spsr_index(new_el)] = pstate_read(env); aarch64_save_sp(env, arm_current_pl(env)); - env->elr_el[1] = env->pc; + env->elr_el[new_el] = env->pc; } else { env->banked_spsr[0] = cpsr_read(env); if (!env->thumb) { - env->cp15.esr_el[1] |= 1 << 25; + env->cp15.esr_el[new_el] |= 1 << 25; } - env->elr_el[1] = env->regs[15]; + env->elr_el[new_el] = env->regs[15]; for (i = 0; i < 15; i++) { env->xregs[i] = env->regs[i]; @@ -505,9 +511,9 @@ void aarch64_cpu_do_interrupt(CPUState *cs) env->condexec_bits = 0; } - pstate_write(env, PSTATE_DAIF | PSTATE_MODE_EL1h); + pstate_write(env, PSTATE_DAIF | new_mode); env->aarch64 = 1; - aarch64_restore_sp(env, 1); + aarch64_restore_sp(env, new_el); env->pc = addr; cs->interrupt_request |= CPU_INTERRUPT_EXITTB; |