target/arm: Implement support for taking exceptions to Hyp mode
Implement the necessary support code for taking exceptions to Hyp mode in AArch32. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> Reviewed-by: Luc Michel <luc.michel@greensocs.com> Message-id: 20180820153020.21478-5-peter.maydell@linaro.org
This commit is contained in:
parent
dea8378bb3
commit
b9bc21ff9f
|
@ -8073,6 +8073,83 @@ static void take_aarch32_exception(CPUARMState *env, int new_mode,
|
||||||
env->regs[15] = newpc;
|
env->regs[15] = newpc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void arm_cpu_do_interrupt_aarch32_hyp(CPUState *cs)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Handle exception entry to Hyp mode; this is sufficiently
|
||||||
|
* different to entry to other AArch32 modes that we handle it
|
||||||
|
* separately here.
|
||||||
|
*
|
||||||
|
* The vector table entry used is always the 0x14 Hyp mode entry point,
|
||||||
|
* unless this is an UNDEF/HVC/abort taken from Hyp to Hyp.
|
||||||
|
* The offset applied to the preferred return address is always zero
|
||||||
|
* (see DDI0487C.a section G1.12.3).
|
||||||
|
* PSTATE A/I/F masks are set based only on the SCR.EA/IRQ/FIQ values.
|
||||||
|
*/
|
||||||
|
uint32_t addr, mask;
|
||||||
|
ARMCPU *cpu = ARM_CPU(cs);
|
||||||
|
CPUARMState *env = &cpu->env;
|
||||||
|
|
||||||
|
switch (cs->exception_index) {
|
||||||
|
case EXCP_UDEF:
|
||||||
|
addr = 0x04;
|
||||||
|
break;
|
||||||
|
case EXCP_SWI:
|
||||||
|
addr = 0x14;
|
||||||
|
break;
|
||||||
|
case EXCP_BKPT:
|
||||||
|
/* Fall through to prefetch abort. */
|
||||||
|
case EXCP_PREFETCH_ABORT:
|
||||||
|
env->cp15.ifar_s = env->exception.vaddress;
|
||||||
|
qemu_log_mask(CPU_LOG_INT, "...with HIFAR 0x%x\n",
|
||||||
|
(uint32_t)env->exception.vaddress);
|
||||||
|
addr = 0x0c;
|
||||||
|
break;
|
||||||
|
case EXCP_DATA_ABORT:
|
||||||
|
env->cp15.dfar_s = env->exception.vaddress;
|
||||||
|
qemu_log_mask(CPU_LOG_INT, "...with HDFAR 0x%x\n",
|
||||||
|
(uint32_t)env->exception.vaddress);
|
||||||
|
addr = 0x10;
|
||||||
|
break;
|
||||||
|
case EXCP_IRQ:
|
||||||
|
addr = 0x18;
|
||||||
|
break;
|
||||||
|
case EXCP_FIQ:
|
||||||
|
addr = 0x1c;
|
||||||
|
break;
|
||||||
|
case EXCP_HVC:
|
||||||
|
addr = 0x08;
|
||||||
|
break;
|
||||||
|
case EXCP_HYP_TRAP:
|
||||||
|
addr = 0x14;
|
||||||
|
default:
|
||||||
|
cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cs->exception_index != EXCP_IRQ && cs->exception_index != EXCP_FIQ) {
|
||||||
|
env->cp15.esr_el[2] = env->exception.syndrome;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arm_current_el(env) != 2 && addr < 0x14) {
|
||||||
|
addr = 0x14;
|
||||||
|
}
|
||||||
|
|
||||||
|
mask = 0;
|
||||||
|
if (!(env->cp15.scr_el3 & SCR_EA)) {
|
||||||
|
mask |= CPSR_A;
|
||||||
|
}
|
||||||
|
if (!(env->cp15.scr_el3 & SCR_IRQ)) {
|
||||||
|
mask |= CPSR_I;
|
||||||
|
}
|
||||||
|
if (!(env->cp15.scr_el3 & SCR_FIQ)) {
|
||||||
|
mask |= CPSR_F;
|
||||||
|
}
|
||||||
|
|
||||||
|
addr += env->cp15.hvbar;
|
||||||
|
|
||||||
|
take_aarch32_exception(env, ARM_CPU_MODE_HYP, mask, 0, addr);
|
||||||
|
}
|
||||||
|
|
||||||
static void arm_cpu_do_interrupt_aarch32(CPUState *cs)
|
static void arm_cpu_do_interrupt_aarch32(CPUState *cs)
|
||||||
{
|
{
|
||||||
ARMCPU *cpu = ARM_CPU(cs);
|
ARMCPU *cpu = ARM_CPU(cs);
|
||||||
|
@ -8108,6 +8185,11 @@ static void arm_cpu_do_interrupt_aarch32(CPUState *cs)
|
||||||
env->cp15.mdscr_el1 = deposit64(env->cp15.mdscr_el1, 2, 4, moe);
|
env->cp15.mdscr_el1 = deposit64(env->cp15.mdscr_el1, 2, 4, moe);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (env->exception.target_el == 2) {
|
||||||
|
arm_cpu_do_interrupt_aarch32_hyp(cs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO: Vectored interrupt controller. */
|
/* TODO: Vectored interrupt controller. */
|
||||||
switch (cs->exception_index) {
|
switch (cs->exception_index) {
|
||||||
case EXCP_UDEF:
|
case EXCP_UDEF:
|
||||||
|
|
Loading…
Reference in a new issue