Commit e8925712 authored by Richard Henderson's avatar Richard Henderson Committed by Peter Maydell
Browse files

target-arm: Use cpu_exec_interrupt qom hook



Cc: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: default avatarRichard Henderson <rth@twiddle.net>
Message-id: 1410626734-3804-15-git-send-email-rth@twiddle.net
Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parent d8bb9159
Loading
Loading
Loading
Loading
+0 −23
Original line number Diff line number Diff line
@@ -562,29 +562,6 @@ int cpu_exec(CPUArchState *env)
                            }
                        }
                    }
#elif defined(TARGET_ARM)
                    if (interrupt_request & CPU_INTERRUPT_FIQ
                        && !(env->daif & PSTATE_F)) {
                        cpu->exception_index = EXCP_FIQ;
                        cc->do_interrupt(cpu);
                        next_tb = 0;
                    }
                    /* ARMv7-M interrupt return works by loading a magic value
                       into the PC.  On real hardware the load causes the
                       return to occur.  The qemu implementation performs the
                       jump normally, then does the exception return when the
                       CPU tries to execute code at the magic address.
                       This will cause the magic PC value to be pushed to
                       the stack if an interrupt occurred at the wrong time.
                       We avoid this by disabling interrupts when
                       pc contains a magic address.  */
                    if (interrupt_request & CPU_INTERRUPT_HARD
                        && !(env->daif & PSTATE_I)
                        && (!IS_M(env) || env->regs[15] < 0xfffffff0)) {
                        cpu->exception_index = EXCP_IRQ;
                        cc->do_interrupt(cpu);
                        next_tb = 0;
                    }
#endif
                    /* The target hook has 3 exit conditions:
                       False when the interrupt isn't processed,
+1 −0
Original line number Diff line number Diff line
@@ -192,6 +192,7 @@ void init_cpreg_list(ARMCPU *cpu);

void arm_cpu_do_interrupt(CPUState *cpu);
void arm_v7m_cpu_do_interrupt(CPUState *cpu);
bool arm_cpu_exec_interrupt(CPUState *cpu, int int_req);

void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
                        int flags);
+34 −0
Original line number Diff line number Diff line
@@ -188,6 +188,39 @@ static void arm_cpu_reset(CPUState *s)
    hw_watchpoint_update_all(cpu);
}

bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{
    CPUClass *cc = CPU_GET_CLASS(cs);
    ARMCPU *cpu = ARM_CPU(cs);
    CPUARMState *env = &cpu->env;
    bool ret = false;

    if (interrupt_request & CPU_INTERRUPT_FIQ
        && !(env->daif & PSTATE_F)) {
        cs->exception_index = EXCP_FIQ;
        cc->do_interrupt(cs);
        ret = true;
    }
    /* ARMv7-M interrupt return works by loading a magic value
       into the PC.  On real hardware the load causes the
       return to occur.  The qemu implementation performs the
       jump normally, then does the exception return when the
       CPU tries to execute code at the magic address.
       This will cause the magic PC value to be pushed to
       the stack if an interrupt occurred at the wrong time.
       We avoid this by disabling interrupts when
       pc contains a magic address.  */
    if (interrupt_request & CPU_INTERRUPT_HARD
        && !(env->daif & PSTATE_I)
        && (!IS_M(env) || env->regs[15] < 0xfffffff0)) {
        cs->exception_index = EXCP_IRQ;
        cc->do_interrupt(cs);
        ret = true;
    }

    return ret;
}

#ifndef CONFIG_USER_ONLY
static void arm_cpu_set_irq(void *opaque, int irq, int level)
{
@@ -1053,6 +1086,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
    cc->class_by_name = arm_cpu_class_by_name;
    cc->has_work = arm_cpu_has_work;
    cc->do_interrupt = arm_cpu_do_interrupt;
    cc->cpu_exec_interrupt = arm_cpu_exec_interrupt;
    cc->dump_state = arm_cpu_dump_state;
    cc->set_pc = arm_cpu_set_pc;
    cc->gdb_read_register = arm_cpu_gdb_read_register;
+1 −0
Original line number Diff line number Diff line
@@ -197,6 +197,7 @@ static void aarch64_cpu_class_init(ObjectClass *oc, void *data)
    CPUClass *cc = CPU_CLASS(oc);

    cc->do_interrupt = aarch64_cpu_do_interrupt;
    cc->cpu_exec_interrupt = arm_cpu_exec_interrupt;
    cc->set_pc = aarch64_cpu_set_pc;
    cc->gdb_read_register = aarch64_cpu_gdb_read_register;
    cc->gdb_write_register = aarch64_cpu_gdb_write_register;