mips: more fixes to the MIPS interrupt glue logic
authorAurelien Jarno <aurelien@aurel32.net>
Sun, 25 Jul 2010 14:51:29 +0000 (16:51 +0200)
committerAurelien Jarno <aurelien@aurel32.net>
Sun, 25 Jul 2010 14:54:02 +0000 (16:54 +0200)
Commit 36388314febad3d7675ab919287f03733a560ff6 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>
hw/mips_int.c
target-mips/cpu.h
target-mips/helper.h
target-mips/op_helper.c
target-mips/translate.c

index 80488baeba0b729a274ca0a638fbde9fa5742a8e..477f6abf950e8e3b2927257076e5b3541d0d3c2f 100644 (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);
+}
index 157885082a9031afc778625822de75e1a0c9cd6f..b8e6feefc2c2a092f01ef3d0cee96ab7e8e1f675 100644 (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);
index a6ba75dfbc5e7dbd1ae02561c0446499f26f4deb..cb13fb23528a22129215b9c6370dd89cb59f75e3 100644 (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)
index c9632248a083114153499ce064283021345384a6..a619b72610ad725152442da63729549657fc6285 100644 (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)
index 7168273381fb4741cf7f1e0bad41508381208989..6c72dee1ba7d0163f556eefdd7decb084b720cd9 100644 (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: