qemu-commits
[Top][All Lists]
Advanced

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

[Qemu-commits] [COMMIT a1961a4] Sparc32: convert slavio interrupt contro


From: Anthony Liguori
Subject: [Qemu-commits] [COMMIT a1961a4] Sparc32: convert slavio interrupt controller to qdev
Date: Thu, 16 Jul 2009 14:24:01 -0000

From: Blue Swirl <address@hidden>

Also increase QDEV_MAX_IRQ.

Signed-off-by: Blue Swirl <address@hidden>

diff --git a/hw/slavio_intctl.c b/hw/slavio_intctl.c
index a46d926..235e8c3 100644
--- a/hw/slavio_intctl.c
+++ b/hw/slavio_intctl.c
@@ -21,9 +21,10 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-#include "hw.h"
+
 #include "sun4m.h"
 #include "monitor.h"
+#include "sysbus.h"
 
 //#define DEBUG_IRQ_COUNT
 //#define DEBUG_IRQ
@@ -49,28 +50,29 @@
 #define MAX_CPUS 16
 #define MAX_PILS 16
 
-struct SLAVIO_CPUINTCTLState;
+struct SLAVIO_INTCTLState;
+
+typedef struct SLAVIO_CPUINTCTLState {
+    uint32_t intreg_pending;
+    struct SLAVIO_INTCTLState *master;
+    uint32_t cpu;
+} SLAVIO_CPUINTCTLState;
 
 typedef struct SLAVIO_INTCTLState {
+    SysBusDevice busdev;
     uint32_t intregm_pending;
     uint32_t intregm_disabled;
     uint32_t target_cpu;
 #ifdef DEBUG_IRQ_COUNT
     uint64_t irq_count[32];
 #endif
-    qemu_irq *cpu_irqs[MAX_CPUS];
+    qemu_irq cpu_irqs[MAX_CPUS][MAX_PILS];
     const uint32_t *intbit_to_level;
     uint32_t cputimer_lbit, cputimer_mbit;
     uint32_t pil_out[MAX_CPUS];
-    struct SLAVIO_CPUINTCTLState *slaves[MAX_CPUS];
+    SLAVIO_CPUINTCTLState slaves[MAX_CPUS];
 } SLAVIO_INTCTLState;
 
-typedef struct SLAVIO_CPUINTCTLState {
-    uint32_t intreg_pending;
-    SLAVIO_INTCTLState *master;
-    uint32_t cpu;
-} SLAVIO_CPUINTCTLState;
-
 #define INTCTL_MAXADDR 0xf
 #define INTCTL_SIZE (INTCTL_MAXADDR + 1)
 #define INTCTLM_SIZE 0x14
@@ -225,7 +227,7 @@ void slavio_pic_info(Monitor *mon, void *opaque)
 
     for (i = 0; i < MAX_CPUS; i++) {
         monitor_printf(mon, "per-cpu %d: pending 0x%08x\n", i,
-                       s->slaves[i]->intreg_pending);
+                       s->slaves[i].intreg_pending);
     }
     monitor_printf(mon, "master: pending 0x%08x, disabled 0x%08x\n",
                    s->intregm_pending, s->intregm_disabled);
@@ -266,7 +268,7 @@ static void slavio_check_interrupts(SLAVIO_INTCTLState *s, 
int set_irqs)
                     pil_pending |= 1 << s->intbit_to_level[j];
             }
         }
-        pil_pending |= (s->slaves[i]->intreg_pending & CPU_SOFTIRQ_MASK) >> 16;
+        pil_pending |= (s->slaves[i].intreg_pending & CPU_SOFTIRQ_MASK) >> 16;
 
         if (set_irqs) {
             for (j = 0; j < MAX_PILS; j++) {
@@ -303,10 +305,10 @@ static void slavio_set_irq(void *opaque, int irq, int 
level)
             s->irq_count[pil]++;
 #endif
             s->intregm_pending |= mask;
-            s->slaves[s->target_cpu]->intreg_pending |= 1 << pil;
+            s->slaves[s->target_cpu].intreg_pending |= 1 << pil;
         } else {
             s->intregm_pending &= ~mask;
-            s->slaves[s->target_cpu]->intreg_pending &= ~(1 << pil);
+            s->slaves[s->target_cpu].intreg_pending &= ~(1 << pil);
         }
         slavio_check_interrupts(s, 1);
     }
@@ -320,22 +322,31 @@ static void slavio_set_timer_irq_cpu(void *opaque, int 
cpu, int level)
 
     if (level) {
         s->intregm_pending |= s->cputimer_mbit;
-        s->slaves[cpu]->intreg_pending |= s->cputimer_lbit;
+        s->slaves[cpu].intreg_pending |= s->cputimer_lbit;
     } else {
         s->intregm_pending &= ~s->cputimer_mbit;
-        s->slaves[cpu]->intreg_pending &= ~s->cputimer_lbit;
+        s->slaves[cpu].intreg_pending &= ~s->cputimer_lbit;
     }
 
     slavio_check_interrupts(s, 1);
 }
 
+static void slavio_set_irq_all(void *opaque, int irq, int level)
+{
+    if (irq < 32) {
+        slavio_set_irq(opaque, irq, level);
+    } else {
+        slavio_set_timer_irq_cpu(opaque, irq - 32, level);
+    }
+}
+
 static void slavio_intctl_save(QEMUFile *f, void *opaque)
 {
     SLAVIO_INTCTLState *s = opaque;
     int i;
 
     for (i = 0; i < MAX_CPUS; i++) {
-        qemu_put_be32s(f, &s->slaves[i]->intreg_pending);
+        qemu_put_be32s(f, &s->slaves[i].intreg_pending);
     }
     qemu_put_be32s(f, &s->intregm_pending);
     qemu_put_be32s(f, &s->intregm_disabled);
@@ -351,7 +362,7 @@ static int slavio_intctl_load(QEMUFile *f, void *opaque, 
int version_id)
         return -EINVAL;
 
     for (i = 0; i < MAX_CPUS; i++) {
-        qemu_get_be32s(f, &s->slaves[i]->intreg_pending);
+        qemu_get_be32s(f, &s->slaves[i].intreg_pending);
     }
     qemu_get_be32s(f, &s->intregm_pending);
     qemu_get_be32s(f, &s->intregm_disabled);
@@ -366,7 +377,7 @@ static void slavio_intctl_reset(void *opaque)
     int i;
 
     for (i = 0; i < MAX_CPUS; i++) {
-        s->slaves[i]->intreg_pending = 0;
+        s->slaves[i].intreg_pending = 0;
     }
     s->intregm_disabled = ~MASTER_IRQ_MASK;
     s->intregm_pending = 0;
@@ -374,47 +385,81 @@ static void slavio_intctl_reset(void *opaque)
     slavio_check_interrupts(s, 0);
 }
 
-void *slavio_intctl_init(target_phys_addr_t addr, target_phys_addr_t addrg,
-                         const uint32_t *intbit_to_level,
-                         qemu_irq **irq, qemu_irq **cpu_irq,
-                         qemu_irq **parent_irq, unsigned int cputimer)
+static void slavio_intctl_init1(SysBusDevice *dev)
 {
-    int slavio_intctl_io_memory, slavio_intctlm_io_memory, i;
-    SLAVIO_INTCTLState *s;
-    SLAVIO_CPUINTCTLState *slave;
+    SLAVIO_INTCTLState *s = FROM_SYSBUS(SLAVIO_INTCTLState, dev);
+    int io_memory, cputimer;
+    unsigned int i, j;
 
-    s = qemu_mallocz(sizeof(SLAVIO_INTCTLState));
+    qdev_init_gpio_in(&dev->qdev, slavio_set_irq_all, 32 + MAX_CPUS);
+    io_memory = cpu_register_io_memory(slavio_intctlm_mem_read,
+                                       slavio_intctlm_mem_write, s);
+    sysbus_init_mmio(dev, INTCTLM_SIZE, io_memory);
+    s->intbit_to_level = qdev_get_prop_ptr(&dev->qdev, "intbit_to_level");
+    cputimer = qdev_get_prop_int(&dev->qdev, "cputimer_bit", -1);
+    s->cputimer_mbit = 1 << cputimer;
+    s->cputimer_lbit = 1 << s->intbit_to_level[cputimer];
 
-    s->intbit_to_level = intbit_to_level;
     for (i = 0; i < MAX_CPUS; i++) {
-        slave = qemu_mallocz(sizeof(SLAVIO_CPUINTCTLState));
+        for (j = 0; j < MAX_PILS; j++) {
+            sysbus_init_irq(dev, &s->cpu_irqs[i][j]);
+        }
+        io_memory = cpu_register_io_memory(slavio_intctl_mem_read,
+                                           slavio_intctl_mem_write,
+                                           &s->slaves[i]);
+        sysbus_init_mmio(dev, INTCTL_SIZE, io_memory);
+        s->slaves[i].cpu = i;
+        s->slaves[i].master = s;
+    }
+    register_savevm("slavio_intctl", -1, 1, slavio_intctl_save,
+                    slavio_intctl_load, s);
+    qemu_register_reset(slavio_intctl_reset, s);
+    slavio_intctl_reset(s);
+}
+
+DeviceState *slavio_intctl_init(target_phys_addr_t addr,
+                                target_phys_addr_t addrg,
+                                const uint32_t *intbit_to_level,
+                                qemu_irq **parent_irq, unsigned int cputimer)
+{
+    DeviceState *dev;
+    SysBusDevice *s;
+    unsigned int i, j;
 
-        slave->cpu = i;
-        slave->master = s;
+    dev = qdev_create(NULL, "slavio_intctl");
+    qdev_set_prop_ptr(dev, "intbit_to_level", (void *)intbit_to_level);
+    qdev_set_prop_int(dev, "cputimer_bit", cputimer);
+    qdev_init(dev);
 
-        slavio_intctl_io_memory = 
cpu_register_io_memory(slavio_intctl_mem_read,
-                                                         
slavio_intctl_mem_write,
-                                                         slave);
-        cpu_register_physical_memory(addr + i * TARGET_PAGE_SIZE, INTCTL_SIZE,
-                                     slavio_intctl_io_memory);
+    s = sysbus_from_qdev(dev);
 
-        s->slaves[i] = slave;
-        s->cpu_irqs[i] = parent_irq[i];
+    for (i = 0; i < MAX_CPUS; i++) {
+        for (j = 0; j < MAX_PILS; j++) {
+            sysbus_connect_irq(s, i * MAX_PILS + j, parent_irq[i][j]);
+        }
+    }
+    sysbus_mmio_map(s, 0, addrg);
+    for (i = 0; i < MAX_CPUS; i++) {
+        sysbus_mmio_map(s, i + 1, addr + i * TARGET_PAGE_SIZE);
     }
 
-    slavio_intctlm_io_memory = cpu_register_io_memory(slavio_intctlm_mem_read,
-                                                      slavio_intctlm_mem_write,
-                                                      s);
-    cpu_register_physical_memory(addrg, INTCTLM_SIZE, 
slavio_intctlm_io_memory);
+    return dev;
+}
 
-    register_savevm("slavio_intctl", addr, 1, slavio_intctl_save,
-                    slavio_intctl_load, s);
-    qemu_register_reset(slavio_intctl_reset, s);
-    *irq = qemu_allocate_irqs(slavio_set_irq, s, 32);
+static SysBusDeviceInfo slavio_intctl_info = {
+    .init = slavio_intctl_init1,
+    .qdev.name  = "slavio_intctl",
+    .qdev.size  = sizeof(SLAVIO_INTCTLState),
+    .qdev.props = (DevicePropList[]) {
+        {.name = "intbit_to_level", .type = PROP_TYPE_PTR},
+        {.name = "cputimer_bit", .type = PROP_TYPE_INT},
+        {.name = NULL}
+    }
+};
 
-    *cpu_irq = qemu_allocate_irqs(slavio_set_timer_irq_cpu, s, MAX_CPUS);
-    s->cputimer_mbit = 1 << cputimer;
-    s->cputimer_lbit = 1 << intbit_to_level[cputimer];
-    slavio_intctl_reset(s);
-    return s;
+static void slavio_intctl_register_devices(void)
+{
+    sysbus_register_withprop(&slavio_intctl_info);
 }
+
+device_init(slavio_intctl_register_devices)
diff --git a/hw/sun4m.c b/hw/sun4m.c
index f348a9c..220eaae 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -563,7 +563,7 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, 
ram_addr_t RAM_size,
     CPUState *envs[MAX_CPUS];
     unsigned int i;
     void *iommu, *espdma, *ledma, *nvram;
-    qemu_irq *cpu_irqs[MAX_CPUS], *slavio_irq, *slavio_cpu_irq,
+    qemu_irq *cpu_irqs[MAX_CPUS], slavio_irq[32], slavio_cpu_irq[MAX_CPUS],
         espdma_irq, ledma_irq;
     qemu_irq *esp_reset, *le_reset;
     qemu_irq fdc_tc;
@@ -572,6 +572,7 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, 
ram_addr_t RAM_size,
     BlockDriverState *fd[MAX_FD];
     int drive_index;
     void *fw_cfg;
+    DeviceState *dev;
 
     /* init CPUs */
     if (!cpu_model)
@@ -590,12 +591,18 @@ static void sun4m_hw_init(const struct sun4m_hwdef 
*hwdef, ram_addr_t RAM_size,
 
     prom_init(hwdef->slavio_base, bios_name);
 
-    slavio_intctl = slavio_intctl_init(hwdef->intctl_base,
-                                       hwdef->intctl_base + 0x10000ULL,
-                                       &hwdef->intbit_to_level[0],
-                                       &slavio_irq, &slavio_cpu_irq,
-                                       cpu_irqs,
-                                       hwdef->clock_irq);
+    dev = slavio_intctl_init(hwdef->intctl_base,
+                             hwdef->intctl_base + 0x10000ULL,
+                             &hwdef->intbit_to_level[0],
+                             cpu_irqs,
+                             hwdef->clock_irq);
+
+    for (i = 0; i < 32; i++) {
+        slavio_irq[i] = qdev_get_gpio_in(dev, i);
+    }
+    for (i = 0; i < MAX_CPUS; i++) {
+        slavio_cpu_irq[i] = qdev_get_gpio_in(dev, 32 + i);
+    }
 
     if (hwdef->idreg_base) {
         idreg_init(hwdef->idreg_base);
diff --git a/hw/sun4m.h b/hw/sun4m.h
index 510c6bc..d818fb1 100644
--- a/hw/sun4m.h
+++ b/hw/sun4m.h
@@ -28,10 +28,10 @@ void tcx_init(target_phys_addr_t addr, int vram_size, int 
width, int height,
               int depth);
 
 /* slavio_intctl.c */
-void *slavio_intctl_init(target_phys_addr_t addr, target_phys_addr_t addrg,
-                         const uint32_t *intbit_to_level,
-                         qemu_irq **irq, qemu_irq **cpu_irq,
-                         qemu_irq **parent_irq, unsigned int cputimer);
+DeviceState *slavio_intctl_init(target_phys_addr_t addr,
+                                target_phys_addr_t addrg,
+                                const uint32_t *intbit_to_level,
+                                qemu_irq **parent_irq, unsigned int cputimer);
 void slavio_pic_info(Monitor *mon, void *opaque);
 void slavio_irq_info(Monitor *mon, void *opaque);
 
diff --git a/hw/sysbus.h b/hw/sysbus.h
index 9b2553d..d48ca8c 100644
--- a/hw/sysbus.h
+++ b/hw/sysbus.h
@@ -6,7 +6,7 @@
 #include "qdev.h"
 
 #define QDEV_MAX_MMIO 32
-#define QDEV_MAX_IRQ 32
+#define QDEV_MAX_IRQ 256
 
 typedef struct SysBusDevice SysBusDevice;
 typedef void (*mmio_mapfunc)(SysBusDevice *dev, target_phys_addr_t addr);




reply via email to

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