Patchwork [7/8,MIPS] qdev: convert jazz irq controller to sysbus device

login
register
mail settings
Submitter Hervé Poussineau
Date Sept. 8, 2010, 8:39 p.m.
Message ID <1283978392-6313-8-git-send-email-hpoussin@reactos.org>
Download mbox | patch
Permalink /patch/64215/
State New
Headers show

Comments

Hervé Poussineau - Sept. 8, 2010, 8:39 p.m.
Use it in Jazz emulation

Signed-off-by: Hervé Poussineau <hpoussin@reactos.org>
---
 hw/mips.h      |    3 +-
 hw/mips_jazz.c |   10 +++-
 hw/rc4030.c    |  145 +++++++++++++++++++++++++++++++++++++++-----------------
 3 files changed, 111 insertions(+), 47 deletions(-)

Patch

diff --git a/hw/mips.h b/hw/mips.h
index 75b7c3d..2897ea6 100644
--- a/hw/mips.h
+++ b/hw/mips.h
@@ -17,8 +17,7 @@  void rc4030_dma_memory_rw(void *opaque, target_phys_addr_t addr, uint8_t *buf, i
 void rc4030_dma_read(void *dma, uint8_t *buf, int len);
 void rc4030_dma_write(void *dma, uint8_t *buf, int len);
 
-void *rc4030_init(qemu_irq timer, qemu_irq jazz_bus,
-                  qemu_irq **irqs, rc4030_dma **dmas);
+void *rc4030_init(qemu_irq timer, rc4030_dma **dmas);
 
 /* dp8393x.c */
 void dp83932_init(NICInfo *nd, target_phys_addr_t base, int it_shift,
diff --git a/hw/mips_jazz.c b/hw/mips_jazz.c
index f24b5eb..56739db 100644
--- a/hw/mips_jazz.c
+++ b/hw/mips_jazz.c
@@ -131,7 +131,8 @@  void mips_jazz_init (ram_addr_t ram_size,
     char *filename;
     int bios_size, n;
     CPUState *env;
-    qemu_irq *rc4030, *i8259;
+    DeviceState *dev;
+    qemu_irq rc4030[16], *i8259;
     rc4030_dma *dmas;
     void* rc4030_opaque;
     int s_rtc, s_dma_dummy;
@@ -190,7 +191,12 @@  void mips_jazz_init (ram_addr_t ram_size,
     cpu_mips_clock_init(env);
 
     /* Chipset */
-    rc4030_opaque = rc4030_init(env->irq[6], env->irq[3], &rc4030, &dmas);
+    dev = sysbus_create_simple("jazzio", 0xf0000000, env->irq[3]);
+    for (n = 0; n < 16; n++) {
+        rc4030[n] = qdev_get_gpio_in(dev, n);
+    }
+
+    rc4030_opaque = rc4030_init(env->irq[6], &dmas);
     s_dma_dummy = cpu_register_io_memory(dma_dummy_read, dma_dummy_write, NULL);
     cpu_register_physical_memory(0x8000d000, 0x00001000, s_dma_dummy);
 
diff --git a/hw/rc4030.c b/hw/rc4030.c
index 2231373..811d12d 100644
--- a/hw/rc4030.c
+++ b/hw/rc4030.c
@@ -25,6 +25,7 @@ 
 #include "hw.h"
 #include "mips.h"
 #include "qemu-timer.h"
+#include "sysbus.h"
 
 /********************************************************/
 /* debug rc4030 */
@@ -63,6 +64,13 @@  typedef struct dma_pagetable_entry {
 #define DMA_FLAG_MEM_INTR   0x0200
 #define DMA_FLAG_ADDR_INTR  0x0400
 
+typedef struct JazzIoState
+{
+    uint32_t mask; /* Local bus int enable mask */
+    uint32_t source; /* Local bus int source */
+    qemu_irq irq;
+} JazzIoState;
+
 typedef struct rc4030State
 {
     uint32_t config; /* 0x0000: RC4030 config register */
@@ -86,15 +94,12 @@  typedef struct rc4030State
     uint32_t offset210;
     uint32_t nvram_protect; /* 0x0220: NV ram protect register */
     uint32_t rem_speed[16];
-    uint32_t imr_jazz; /* Local bus int enable mask */
-    uint32_t isr_jazz; /* Local bus int source */
 
     /* timer */
     QEMUTimer *periodic_timer;
     uint32_t itr; /* Interval timer reload */
 
     qemu_irq timer_irq;
-    qemu_irq jazz_bus_irq;
 } rc4030State;
 
 static void set_next_tick(rc4030State *s)
@@ -431,20 +436,20 @@  static CPUWriteMemoryFunc * const rc4030_write[3] = {
     rc4030_writel,
 };
 
-static void update_jazz_irq(rc4030State *s)
+static void update_jazz_irq(JazzIoState *s)
 {
     uint16_t pending;
 
-    pending = s->isr_jazz & s->imr_jazz;
+    pending = s->source & s->mask;
 
 #ifdef DEBUG_RC4030
-    if (s->isr_jazz != 0) {
+    if (s->source != 0) {
         uint32_t irq = 0;
         DPRINTF("pending irqs:");
         for (irq = 0; irq < ARRAY_SIZE(irq_names); irq++) {
-            if (s->isr_jazz & (1 << irq)) {
+            if (s->source & (1 << irq)) {
                 printf(" %s", irq_names[irq]);
-                if (!(s->imr_jazz & (1 << irq))) {
+                if (!(s->mask & (1 << irq))) {
                     printf("(ignored)");
                 }
             }
@@ -454,22 +459,9 @@  static void update_jazz_irq(rc4030State *s)
 #endif
 
     if (pending != 0)
-        qemu_irq_raise(s->jazz_bus_irq);
+        qemu_irq_raise(s->irq);
     else
-        qemu_irq_lower(s->jazz_bus_irq);
-}
-
-static void rc4030_irq_jazz_request(void *opaque, int irq, int level)
-{
-    rc4030State *s = opaque;
-
-    if (level) {
-        s->isr_jazz |= 1 << irq;
-    } else {
-        s->isr_jazz &= ~(1 << irq);
-    }
-
-    update_jazz_irq(s);
+        qemu_irq_lower(s->irq);
 }
 
 static void rc4030_periodic_timer(void *opaque)
@@ -482,7 +474,7 @@  static void rc4030_periodic_timer(void *opaque)
 
 static uint32_t jazzio_readw(void *opaque, target_phys_addr_t addr)
 {
-    rc4030State *s = opaque;
+    JazzIoState *s = opaque;
     uint32_t val;
     uint32_t irq;
     addr &= 0xfff;
@@ -490,7 +482,7 @@  static uint32_t jazzio_readw(void *opaque, target_phys_addr_t addr)
     switch (addr) {
     /* Local bus int source */
     case 0x00: {
-        uint32_t pending = s->isr_jazz & s->imr_jazz;
+        uint32_t pending = s->source & s->mask;
         val = 0;
         irq = 0;
         while (pending) {
@@ -506,7 +498,7 @@  static uint32_t jazzio_readw(void *opaque, target_phys_addr_t addr)
     }
     /* Local bus int enable mask */
     case 0x02:
-        val = s->imr_jazz;
+        val = s->mask;
         break;
     default:
         RC4030_ERROR("(jazz io controller) invalid read [" TARGET_FMT_plx "]\n", addr);
@@ -535,7 +527,7 @@  static uint32_t jazzio_readl(void *opaque, target_phys_addr_t addr)
 
 static void jazzio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
 {
-    rc4030State *s = opaque;
+    JazzIoState *s = opaque;
     addr &= 0xfff;
 
     DPRINTF("(jazz io controller) write 0x%04x at " TARGET_FMT_plx "\n", val, addr);
@@ -543,7 +535,7 @@  static void jazzio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
     switch (addr) {
     /* Local bus int enable mask */
     case 0x02:
-        s->imr_jazz = val;
+        s->mask = val;
         update_jazz_irq(s);
         break;
     default:
@@ -585,6 +577,13 @@  static CPUWriteMemoryFunc * const jazzio_write[3] = {
     jazzio_writel,
 };
 
+static void jazzio_reset(JazzIoState* s)
+{
+    s->mask = 0x10; /* XXX: required by firmware, but why? */
+    s->source = 0;
+    qemu_irq_lower(s->irq);
+}
+
 static void rc4030_reset(void *opaque)
 {
     rc4030State *s = opaque;
@@ -606,13 +605,10 @@  static void rc4030_reset(void *opaque)
     s->nvram_protect = 7;
     for (i = 0; i < 15; i++)
         s->rem_speed[i] = 7;
-    s->imr_jazz = 0x10; /* XXX: required by firmware, but why? */
-    s->isr_jazz = 0;
 
     s->itr = 0;
 
     qemu_irq_lower(s->timer_irq);
-    qemu_irq_lower(s->jazz_bus_irq);
 }
 
 static int rc4030_load(QEMUFile *f, void *opaque, int version_id)
@@ -640,12 +636,9 @@  static int rc4030_load(QEMUFile *f, void *opaque, int version_id)
     s->nvram_protect = qemu_get_be32(f);
     for (i = 0; i < 15; i++)
         s->rem_speed[i] = qemu_get_be32(f);
-    s->imr_jazz = qemu_get_be32(f);
-    s->isr_jazz = qemu_get_be32(f);
     s->itr = qemu_get_be32(f);
 
     set_next_tick(s);
-    update_jazz_irq(s);
 
     return 0;
 }
@@ -672,8 +665,6 @@  static void rc4030_save(QEMUFile *f, void *opaque)
     qemu_put_be32(f, s->nvram_protect);
     for (i = 0; i < 15; i++)
         qemu_put_be32(f, s->rem_speed[i]);
-    qemu_put_be32(f, s->imr_jazz);
-    qemu_put_be32(f, s->isr_jazz);
     qemu_put_be32(f, s->itr);
 }
 
@@ -797,20 +788,17 @@  static rc4030_dma *rc4030_allocate_dmas(void *opaque, int n)
     return s;
 }
 
-void *rc4030_init(qemu_irq timer, qemu_irq jazz_bus,
-                  qemu_irq **irqs, rc4030_dma **dmas)
+void *rc4030_init(qemu_irq timer, rc4030_dma **dmas)
 {
     rc4030State *s;
-    int s_chipset, s_jazzio;
+    int s_chipset;
 
     s = qemu_mallocz(sizeof(rc4030State));
 
-    *irqs = qemu_allocate_irqs(rc4030_irq_jazz_request, s, 16);
     *dmas = rc4030_allocate_dmas(s, 4);
 
     s->periodic_timer = qemu_new_timer(vm_clock, rc4030_periodic_timer, s);
     s->timer_irq = timer;
-    s->jazz_bus_irq = jazz_bus;
 
     qemu_register_reset(rc4030_reset, s);
     register_savevm(NULL, "rc4030", 0, 2, rc4030_save, rc4030_load, s);
@@ -818,8 +806,79 @@  void *rc4030_init(qemu_irq timer, qemu_irq jazz_bus,
 
     s_chipset = cpu_register_io_memory(rc4030_read, rc4030_write, s);
     cpu_register_physical_memory(0x80000000, 0x300, s_chipset);
-    s_jazzio = cpu_register_io_memory(jazzio_read, jazzio_write, s);
-    cpu_register_physical_memory(0xf0000000, 0x00001000, s_jazzio);
 
     return s;
 }
+
+static int jazzio_post_load(void *opaque, int version_id)
+{
+    JazzIoState *s = opaque;
+    update_jazz_irq(s);
+    return 0;
+}
+
+static const VMStateDescription vmstate_jazzio = {
+    .name = "jazzio",
+    .version_id = 0,
+    .minimum_version_id = 0,
+    .minimum_version_id_old = 0,
+    .post_load = jazzio_post_load,
+    .fields = (VMStateField []) {
+        VMSTATE_UINT32(mask, JazzIoState),
+        VMSTATE_UINT32(source, JazzIoState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+typedef struct {
+    SysBusDevice busdev;
+    JazzIoState jazzio;
+} SysBusJazzIoState;
+
+static void jazzio_sysbus_reset(DeviceState *d)
+{
+    JazzIoState *s = &container_of(d, SysBusJazzIoState, busdev.qdev)->jazzio;
+    jazzio_reset(s);
+}
+
+static void jazzio_set_irq(void *opaque, int irq, int level)
+{
+    JazzIoState *s = &container_of(opaque, SysBusJazzIoState, busdev.qdev)->jazzio;
+
+    if (level) {
+        s->source |= 1 << irq;
+    } else {
+        s->source &= ~(1 << irq);
+    }
+
+    update_jazz_irq(s);
+}
+
+static int jazzio_sysbus_initfn(SysBusDevice *dev)
+{
+    JazzIoState *s = &FROM_SYSBUS(SysBusJazzIoState, dev)->jazzio;
+    int s_jazzio;
+
+    qdev_init_gpio_in(&dev->qdev, jazzio_set_irq, 16);
+
+    s_jazzio = cpu_register_io_memory(jazzio_read, jazzio_write, s);
+    sysbus_init_mmio(dev, 0x00001000, s_jazzio);
+    sysbus_init_irq(dev, &s->irq);
+
+    return 0;
+}
+
+static SysBusDeviceInfo jazzio_sysbus_info = {
+    .qdev.name  = "jazzio",
+    .qdev.size  = sizeof(SysBusJazzIoState),
+    .qdev.vmsd  = &vmstate_jazzio,
+    .qdev.reset = jazzio_sysbus_reset,
+    .init       = jazzio_sysbus_initfn,
+};
+
+static void jazz_register(void)
+{
+    sysbus_register_withprop(&jazzio_sysbus_info);
+}
+
+device_init(jazz_register)