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:
Aurelien Jarno 2010-07-25 16:51:29 +02:00
parent a5efa6441c
commit 5dc5d9f055
5 changed files with 30 additions and 15 deletions

View File

@ -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);
}

View File

@ -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);

View File

@ -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)

View File

@ -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)

View File

@ -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: