Commit 97a8ea5a authored by Andreas Färber's avatar Andreas Färber
Browse files

cpu: Replace do_interrupt() by CPUClass::do_interrupt method



This removes a global per-target function and thus takes us one step
closer to compiling multiple targets into one executable.

It will also allow to override the interrupt handling for certain CPU
families.

Signed-off-by: default avatarAndreas Färber <afaerber@suse.de>
parent c3affe56
Loading
Loading
Loading
Loading
+20 −16
Original line number Diff line number Diff line
@@ -198,6 +198,10 @@ volatile sig_atomic_t exit_request;
int cpu_exec(CPUArchState *env)
{
    CPUState *cpu = ENV_GET_CPU(env);
#if !(defined(CONFIG_USER_ONLY) && \
      (defined(TARGET_M68K) || defined(TARGET_PPC) || defined(TARGET_S390X)))
    CPUClass *cc = CPU_GET_CLASS(cpu);
#endif
    int ret, interrupt_request;
    TranslationBlock *tb;
    uint8_t *tc_ptr;
@@ -265,12 +269,12 @@ int cpu_exec(CPUArchState *env)
                       which will be handled outside the cpu execution
                       loop */
#if defined(TARGET_I386)
                    do_interrupt(env);
                    cc->do_interrupt(cpu);
#endif
                    ret = env->exception_index;
                    break;
#else
                    do_interrupt(env);
                    cc->do_interrupt(cpu);
                    env->exception_index = -1;
#endif
                }
@@ -380,7 +384,7 @@ int cpu_exec(CPUArchState *env)
                    if ((interrupt_request & CPU_INTERRUPT_HARD)
                        && (env->ie & IE_IE)) {
                        env->exception_index = EXCP_IRQ;
                        do_interrupt(env);
                        cc->do_interrupt(cpu);
                        next_tb = 0;
                    }
#elif defined(TARGET_MICROBLAZE)
@@ -389,7 +393,7 @@ int cpu_exec(CPUArchState *env)
                        && !(env->sregs[SR_MSR] & (MSR_EIP | MSR_BIP))
                        && !(env->iflags & (D_FLAG | IMM_FLAG))) {
                        env->exception_index = EXCP_IRQ;
                        do_interrupt(env);
                        cc->do_interrupt(cpu);
                        next_tb = 0;
                    }
#elif defined(TARGET_MIPS)
@@ -398,7 +402,7 @@ int cpu_exec(CPUArchState *env)
                        /* Raise it */
                        env->exception_index = EXCP_EXT_INTERRUPT;
                        env->error_code = 0;
                        do_interrupt(env);
                        cc->do_interrupt(cpu);
                        next_tb = 0;
                    }
#elif defined(TARGET_OPENRISC)
@@ -414,7 +418,7 @@ int cpu_exec(CPUArchState *env)
                        }
                        if (idx >= 0) {
                            env->exception_index = idx;
                            do_interrupt(env);
                            cc->do_interrupt(cpu);
                            next_tb = 0;
                        }
                    }
@@ -429,7 +433,7 @@ int cpu_exec(CPUArchState *env)
                                  cpu_pil_allowed(env, pil)) ||
                                  type != TT_EXTINT) {
                                env->exception_index = env->interrupt_index;
                                do_interrupt(env);
                                cc->do_interrupt(cpu);
                                next_tb = 0;
                            }
                        }
@@ -438,7 +442,7 @@ int cpu_exec(CPUArchState *env)
                    if (interrupt_request & CPU_INTERRUPT_FIQ
                        && !(env->uncached_cpsr & CPSR_F)) {
                        env->exception_index = EXCP_FIQ;
                        do_interrupt(env);
                        cc->do_interrupt(cpu);
                        next_tb = 0;
                    }
                    /* ARMv7-M interrupt return works by loading a magic value
@@ -454,19 +458,19 @@ int cpu_exec(CPUArchState *env)
                        && ((IS_M(env) && env->regs[15] < 0xfffffff0)
                            || !(env->uncached_cpsr & CPSR_I))) {
                        env->exception_index = EXCP_IRQ;
                        do_interrupt(env);
                        cc->do_interrupt(cpu);
                        next_tb = 0;
                    }
#elif defined(TARGET_UNICORE32)
                    if (interrupt_request & CPU_INTERRUPT_HARD
                        && !(env->uncached_asr & ASR_I)) {
                        env->exception_index = UC32_EXCP_INTR;
                        do_interrupt(env);
                        cc->do_interrupt(cpu);
                        next_tb = 0;
                    }
#elif defined(TARGET_SH4)
                    if (interrupt_request & CPU_INTERRUPT_HARD) {
                        do_interrupt(env);
                        cc->do_interrupt(cpu);
                        next_tb = 0;
                    }
#elif defined(TARGET_ALPHA)
@@ -497,7 +501,7 @@ int cpu_exec(CPUArchState *env)
                        if (idx >= 0) {
                            env->exception_index = idx;
                            env->error_code = 0;
                            do_interrupt(env);
                            cc->do_interrupt(cpu);
                            next_tb = 0;
                        }
                    }
@@ -506,7 +510,7 @@ int cpu_exec(CPUArchState *env)
                        && (env->pregs[PR_CCS] & I_FLAG)
                        && !env->locked_irq) {
                        env->exception_index = EXCP_IRQ;
                        do_interrupt(env);
                        cc->do_interrupt(cpu);
                        next_tb = 0;
                    }
                    if (interrupt_request & CPU_INTERRUPT_NMI) {
@@ -518,7 +522,7 @@ int cpu_exec(CPUArchState *env)
                        }
                        if ((env->pregs[PR_CCS] & m_flag_archval)) {
                            env->exception_index = EXCP_NMI;
                            do_interrupt(env);
                            cc->do_interrupt(cpu);
                            next_tb = 0;
                        }
                    }
@@ -538,13 +542,13 @@ int cpu_exec(CPUArchState *env)
#elif defined(TARGET_S390X) && !defined(CONFIG_USER_ONLY)
                    if ((interrupt_request & CPU_INTERRUPT_HARD) &&
                        (env->psw.mask & PSW_MASK_EXT)) {
                        do_interrupt(env);
                        cc->do_interrupt(cpu);
                        next_tb = 0;
                    }
#elif defined(TARGET_XTENSA)
                    if (interrupt_request & CPU_INTERRUPT_HARD) {
                        env->exception_index = EXC_IRQ;
                        do_interrupt(env);
                        cc->do_interrupt(cpu);
                        next_tb = 0;
                    }
#endif
+2 −0
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ typedef struct CPUState CPUState;
 * @class_by_name: Callback to map -cpu command line model name to an
 * instantiatable CPU type.
 * @reset: Callback to reset the #CPUState to its initial state.
 * @do_interrupt: Callback for interrupt handling.
 * @vmsd: State description for migration.
 *
 * Represents a CPU family or model.
@@ -56,6 +57,7 @@ typedef struct CPUClass {
    ObjectClass *(*class_by_name)(const char *cpu_model);

    void (*reset)(CPUState *cpu);
    void (*do_interrupt)(CPUState *cpu);

    const struct VMStateDescription *vmsd;
} CPUClass;
+2 −0
Original line number Diff line number Diff line
@@ -74,4 +74,6 @@ static inline AlphaCPU *alpha_env_get_cpu(CPUAlphaState *env)

#define ENV_OFFSET offsetof(AlphaCPU, env)

void alpha_cpu_do_interrupt(CPUState *cpu);

#endif
+1 −0
Original line number Diff line number Diff line
@@ -263,6 +263,7 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data)
    dc->realize = alpha_cpu_realizefn;

    cc->class_by_name = alpha_cpu_class_by_name;
    cc->do_interrupt = alpha_cpu_do_interrupt;
}

static const TypeInfo alpha_cpu_type_info = {
+0 −1
Original line number Diff line number Diff line
@@ -449,7 +449,6 @@ int cpu_alpha_signal_handler(int host_signum, void *pinfo,
int cpu_alpha_handle_mmu_fault (CPUAlphaState *env, uint64_t address, int rw,
                                int mmu_idx);
#define cpu_handle_mmu_fault cpu_alpha_handle_mmu_fault
void do_interrupt (CPUAlphaState *env);
void do_restore_state(CPUAlphaState *, uintptr_t retaddr);
void QEMU_NORETURN dynamic_excp(CPUAlphaState *, uintptr_t, int, int);
void QEMU_NORETURN arith_excp(CPUAlphaState *, uintptr_t, int, uint64_t);
Loading