mips: more fixes to the MIPS interrupt glue logic
Commit 36388314fe
moved most of the
interrupt logic to cpu-exec.c. Remove the remaining useless code
and fix software interrupts.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Acked-by: Edgar E. Iglesias <edgar@axis.com>
Tested-by: Edgar E. Iglesias <edgar@axis.com>
This commit is contained in:
parent
a5efa6441c
commit
5dc5d9f055
|
@ -54,3 +54,12 @@ void cpu_mips_irq_init_cpu(CPUState *env)
|
|||
env->irq[i] = qi[i];
|
||||
}
|
||||
}
|
||||
|
||||
void cpu_mips_soft_irq(CPUState *env, int irq, int level)
|
||||
{
|
||||
if (irq < 0 || irq > 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
qemu_set_irq(env->irq[irq], level);
|
||||
}
|
||||
|
|
|
@ -597,6 +597,9 @@ void cpu_mips_store_compare (CPUState *env, uint32_t value);
|
|||
void cpu_mips_start_count(CPUState *env);
|
||||
void cpu_mips_stop_count(CPUState *env);
|
||||
|
||||
/* mips_int.c */
|
||||
void cpu_mips_soft_irq(CPUState *env, int irq, int level);
|
||||
|
||||
/* helper.c */
|
||||
int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
|
||||
int mmu_idx, int is_softmmu);
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
DEF_HELPER_2(raise_exception_err, void, i32, int)
|
||||
DEF_HELPER_1(raise_exception, void, i32)
|
||||
DEF_HELPER_0(interrupt_restart, void)
|
||||
|
||||
#ifdef TARGET_MIPS64
|
||||
DEF_HELPER_3(ldl, tl, tl, tl, int)
|
||||
|
|
|
@ -46,18 +46,6 @@ void helper_raise_exception (uint32_t exception)
|
|||
helper_raise_exception_err(exception, 0);
|
||||
}
|
||||
|
||||
void helper_interrupt_restart (void)
|
||||
{
|
||||
if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
|
||||
!(env->CP0_Status & (1 << CP0St_ERL)) &&
|
||||
!(env->hflags & MIPS_HFLAG_DM) &&
|
||||
(env->CP0_Status & (1 << CP0St_IE)) &&
|
||||
(env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask)) {
|
||||
env->CP0_Cause &= ~(0x1f << CP0Ca_EC);
|
||||
helper_raise_exception(EXCP_EXT_INTERRUPT);
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
static void do_restore_state (void *pc_ptr)
|
||||
{
|
||||
|
@ -1346,6 +1334,7 @@ void helper_mtc0_cause (target_ulong arg1)
|
|||
{
|
||||
uint32_t mask = 0x00C00300;
|
||||
uint32_t old = env->CP0_Cause;
|
||||
int i;
|
||||
|
||||
if (env->insn_flags & ISA_MIPS32R2)
|
||||
mask |= 1 << CP0Ca_DC;
|
||||
|
@ -1358,6 +1347,13 @@ void helper_mtc0_cause (target_ulong arg1)
|
|||
else
|
||||
cpu_mips_start_count(env);
|
||||
}
|
||||
|
||||
/* Set/reset software interrupts */
|
||||
for (i = 0 ; i < 2 ; i++) {
|
||||
if ((old ^ env->CP0_Cause) & (1 << (CP0Ca_IP + i))) {
|
||||
cpu_mips_soft_irq(env, i, env->CP0_Cause & (1 << (CP0Ca_IP + i)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void helper_mtc0_ebase (target_ulong arg1)
|
||||
|
|
|
@ -5190,7 +5190,17 @@ static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int
|
|||
switch (sel) {
|
||||
case 0:
|
||||
save_cpu_state(ctx, 1);
|
||||
/* Mark as an IO operation because we may trigger a software
|
||||
interrupt. */
|
||||
if (use_icount) {
|
||||
gen_io_start();
|
||||
}
|
||||
gen_helper_mtc0_cause(arg);
|
||||
if (use_icount) {
|
||||
gen_io_end();
|
||||
}
|
||||
/* Stop translation as we may have triggered an intetrupt */
|
||||
ctx->bstate = BS_STOP;
|
||||
rn = "Cause";
|
||||
break;
|
||||
default:
|
||||
|
@ -12365,7 +12375,6 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
|
|||
} else {
|
||||
switch (ctx.bstate) {
|
||||
case BS_STOP:
|
||||
gen_helper_interrupt_restart();
|
||||
gen_goto_tb(&ctx, 0, ctx.pc);
|
||||
break;
|
||||
case BS_NONE:
|
||||
|
@ -12373,7 +12382,6 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
|
|||
gen_goto_tb(&ctx, 0, ctx.pc);
|
||||
break;
|
||||
case BS_EXCP:
|
||||
gen_helper_interrupt_restart();
|
||||
tcg_gen_exit_tb(0);
|
||||
break;
|
||||
case BS_BRANCH:
|
||||
|
|
Loading…
Reference in a new issue