qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [5299] Add software and timer interrupt support


From: Blue Swirl
Subject: [Qemu-devel] [5299] Add software and timer interrupt support
Date: Mon, 22 Sep 2008 19:50:29 +0000

Revision: 5299
          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=5299
Author:   blueswir1
Date:     2008-09-22 19:50:28 +0000 (Mon, 22 Sep 2008)

Log Message:
-----------
Add software and timer interrupt support

Modified Paths:
--------------
    trunk/hw/sun4u.c
    trunk/target-sparc/cpu.h
    trunk/target-sparc/helper.h
    trunk/target-sparc/op_helper.c
    trunk/target-sparc/translate.c

Modified: trunk/hw/sun4u.c
===================================================================
--- trunk/hw/sun4u.c    2008-09-22 19:45:36 UTC (rev 5298)
+++ trunk/hw/sun4u.c    2008-09-22 19:50:28 UTC (rev 5299)
@@ -33,6 +33,15 @@
 #include "firmware_abi.h"
 #include "fw_cfg.h"
 
+//#define DEBUG_IRQ
+
+#ifdef DEBUG_IRQ
+#define DPRINTF(fmt, args...)                           \
+    do { printf("CPUIRQ: " fmt , ##args); } while (0)
+#else
+#define DPRINTF(fmt, args...)
+#endif
+
 #define KERNEL_LOAD_ADDR     0x00404000
 #define CMDLINE_ADDR         0x003ff000
 #define INITRD_LOAD_ADDR     0x00300000
@@ -47,6 +56,8 @@
 #define MAX_IDE_BUS          2
 #define BIOS_CFG_IOPORT      0x510
 
+#define MAX_PILS 16
+
 struct hwdef {
     const char * const default_cpu_model;
     uint16_t machine_id;
@@ -201,6 +212,50 @@
 {
 }
 
+void cpu_check_irqs(CPUState *env)
+{
+    uint32_t pil = env->pil_in | (env->softint & ~SOFTINT_TIMER) |
+        ((env->softint & SOFTINT_TIMER) << 14);
+
+    if (pil && (env->interrupt_index == 0 ||
+                (env->interrupt_index & ~15) == TT_EXTINT)) {
+        unsigned int i;
+
+        for (i = 15; i > 0; i--) {
+            if (pil & (1 << i)) {
+                int old_interrupt = env->interrupt_index;
+
+                env->interrupt_index = TT_EXTINT | i;
+                if (old_interrupt != env->interrupt_index) {
+                    DPRINTF("Set CPU IRQ %d\n", i);
+                    cpu_interrupt(env, CPU_INTERRUPT_HARD);
+                }
+                break;
+            }
+        }
+    } else if (!pil && (env->interrupt_index & ~15) == TT_EXTINT) {
+        DPRINTF("Reset CPU IRQ %d\n", env->interrupt_index & 15);
+        env->interrupt_index = 0;
+        cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
+    }
+}
+
+static void cpu_set_irq(void *opaque, int irq, int level)
+{
+    CPUState *env = opaque;
+
+    if (level) {
+        DPRINTF("Raise CPU IRQ %d\n", irq);
+        env->halted = 0;
+        env->pil_in |= 1 << irq;
+        cpu_check_irqs(env);
+    } else {
+        DPRINTF("Lower CPU IRQ %d\n", irq);
+        env->pil_in &= ~(1 << irq);
+        cpu_check_irqs(env);
+    }
+}
+
 void qemu_system_powerdown(void)
 {
 }
@@ -222,6 +277,7 @@
 {
     CPUState *env = opaque;
 
+    env->softint |= SOFTINT_TIMER;
     cpu_interrupt(env, CPU_INTERRUPT_TIMER);
 }
 
@@ -229,6 +285,7 @@
 {
     CPUState *env = opaque;
 
+    env->softint |= SOFTINT_TIMER;
     cpu_interrupt(env, CPU_INTERRUPT_TIMER);
 }
 
@@ -236,13 +293,10 @@
 {
     CPUState *env = opaque;
 
+    env->softint |= SOFTINT_TIMER;
     cpu_interrupt(env, CPU_INTERRUPT_TIMER);
 }
 
-static void dummy_cpu_set_irq(void *opaque, int irq, int level)
-{
-}
-
 static const int ide_iobase[2] = { 0x1f0, 0x170 };
 static const int ide_iobase2[2] = { 0x3f6, 0x376 };
 static const int ide_irq[2] = { 14, 15 };
@@ -383,7 +437,7 @@
         pci_nic_init(pci_bus, &nd_table[i], -1);
     }
 
-    irq = qemu_allocate_irqs(dummy_cpu_set_irq, NULL, 32);
+    irq = qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS);
     if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) {
         fprintf(stderr, "qemu: too many IDE bus\n");
         exit(1);

Modified: trunk/target-sparc/cpu.h
===================================================================
--- trunk/target-sparc/cpu.h    2008-09-22 19:45:36 UTC (rev 5298)
+++ trunk/target-sparc/cpu.h    2008-09-22 19:50:28 UTC (rev 5299)
@@ -329,6 +329,8 @@
     /* UA 2005 hyperprivileged registers */
     uint64_t hpstate, htstate[MAXTL_MAX], hintp, htba, hver, hstick_cmpr, ssr;
     void *hstick; // UA 2005
+    uint32_t softint;
+#define SOFTINT_TIMER 1
 #endif
     sparc_def_t *def;
 } CPUSPARCState;

Modified: trunk/target-sparc/helper.h
===================================================================
--- trunk/target-sparc/helper.h 2008-09-22 19:45:36 UTC (rev 5298)
+++ trunk/target-sparc/helper.h 2008-09-22 19:50:28 UTC (rev 5299)
@@ -31,6 +31,9 @@
 DEF_HELPER(target_ulong, helper_casx_asi, (target_ulong addr, \
                                            target_ulong val1, \
                                            target_ulong val2, uint32_t asi))
+DEF_HELPER(void, helper_set_softint, (uint64_t value))
+DEF_HELPER(void, helper_clear_softint, (uint64_t value))
+DEF_HELPER(void, helper_write_softint, (uint64_t value))
 DEF_HELPER(void, helper_tick_set_count, (void *opaque, uint64_t count))
 DEF_HELPER(uint64_t, helper_tick_get_count, (void *opaque))
 DEF_HELPER(void, helper_tick_set_limit, (void *opaque, uint64_t limit))

Modified: trunk/target-sparc/op_helper.c
===================================================================
--- trunk/target-sparc/op_helper.c      2008-09-22 19:45:36 UTC (rev 5298)
+++ trunk/target-sparc/op_helper.c      2008-09-22 19:50:28 UTC (rev 5299)
@@ -2671,6 +2671,21 @@
     env->tl--;
     env->tsptr = &env->ts[env->tl & MAXTL_MASK];
 }
+
+void helper_set_softint(uint64_t value)
+{
+    env->softint |= (uint32_t)value;
+}
+
+void helper_clear_softint(uint64_t value)
+{
+    env->softint &= (uint32_t)~value;
+}
+
+void helper_write_softint(uint64_t value)
+{
+    env->softint = (uint32_t)value;
+}
 #endif
 
 void helper_flush(target_ulong addr)

Modified: trunk/target-sparc/translate.c
===================================================================
--- trunk/target-sparc/translate.c      2008-09-22 19:45:36 UTC (rev 5298)
+++ trunk/target-sparc/translate.c      2008-09-22 19:50:28 UTC (rev 5299)
@@ -49,7 +49,7 @@
 #ifdef TARGET_SPARC64
 static TCGv cpu_xcc, cpu_asi, cpu_fprs, cpu_gsr;
 static TCGv cpu_tick_cmpr, cpu_stick_cmpr, cpu_hstick_cmpr;
-static TCGv cpu_hintp, cpu_htba, cpu_hver, cpu_ssr, cpu_ver;
+static TCGv cpu_hintp, cpu_htba, cpu_hver, cpu_ssr, cpu_ver, cpu_softint;
 #else
 static TCGv cpu_wim;
 #endif
@@ -2102,6 +2102,10 @@
                         goto jmp_insn;
                     gen_movl_TN_reg(rd, cpu_gsr);
                     break;
+                case 0x16: /* Softint */
+                    tcg_gen_ext_i32_tl(cpu_dst, cpu_softint);
+                    gen_movl_TN_reg(rd, cpu_dst);
+                    break;
                 case 0x17: /* Tick compare */
                     gen_movl_TN_reg(rd, cpu_tick_cmpr);
                     break;
@@ -2126,7 +2130,6 @@
                 case 0x12: /* Dispatch Control */
                 case 0x14: /* Softint set, WO */
                 case 0x15: /* Softint clear, WO */
-                case 0x16: /* Softint write */
 #endif
                 default:
                     goto illegal_insn;
@@ -3233,6 +3236,27 @@
                                     goto jmp_insn;
                                 tcg_gen_xor_tl(cpu_gsr, cpu_src1, cpu_src2);
                                 break;
+                            case 0x14: /* Softint set */
+                                if (!supervisor(dc))
+                                    goto illegal_insn;
+                                tcg_gen_xor_tl(cpu_tmp64, cpu_src1, cpu_src2);
+                                tcg_gen_helper_0_1(helper_set_softint,
+                                                   cpu_tmp64);
+                                break;
+                            case 0x15: /* Softint clear */
+                                if (!supervisor(dc))
+                                    goto illegal_insn;
+                                tcg_gen_xor_tl(cpu_tmp64, cpu_src1, cpu_src2);
+                                tcg_gen_helper_0_1(helper_clear_softint,
+                                                   cpu_tmp64);
+                                break;
+                            case 0x16: /* Softint write */
+                                if (!supervisor(dc))
+                                    goto illegal_insn;
+                                tcg_gen_xor_tl(cpu_tmp64, cpu_src1, cpu_src2);
+                                tcg_gen_helper_0_1(helper_write_softint,
+                                                   cpu_tmp64);
+                                break;
                             case 0x17: /* Tick compare */
 #if !defined(CONFIG_USER_ONLY)
                                 if (!supervisor(dc))
@@ -3292,9 +3316,6 @@
                             case 0x11: /* Performance Instrumentation
                                           Counter */
                             case 0x12: /* Dispatch Control */
-                            case 0x14: /* Softint set */
-                            case 0x15: /* Softint clear */
-                            case 0x16: /* Softint write */
 #endif
                             default:
                                 goto illegal_insn;
@@ -4952,6 +4973,9 @@
                                      offsetof(CPUState, ssr), "ssr");
         cpu_ver = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
                                      offsetof(CPUState, version), "ver");
+        cpu_softint = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
+                                         offsetof(CPUState, softint),
+                                         "softint");
 #else
         cpu_wim = tcg_global_mem_new(TCG_TYPE_I32,
                                      TCG_AREG0, offsetof(CPUState, wim),






reply via email to

[Prev in Thread] Current Thread [Next in Thread]