All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/10] pxa2xx: work on switching to qdev/vmstate
@ 2011-02-20 13:50 Dmitry Eremin-Solenikov
  2011-02-20 13:50 ` [Qemu-devel] [PATCH 01/10] arm-pic: add one extra interrupt to support EXITTB interrupts Dmitry Eremin-Solenikov
                   ` (9 more replies)
  0 siblings, 10 replies; 14+ messages in thread
From: Dmitry Eremin-Solenikov @ 2011-02-20 13:50 UTC (permalink / raw)
  To: qemu-devel

This series introduces another partial rework of pxa2xx to use qdev/vmstate
to handle subdevices.

Dmitry Eremin-Solenikov (10):
      arm-pic: add one extra interrupt to support EXITTB interrupts
      pxa2xx_pic: update to use qdev and arm-pic
      pxa2xx_gpio: simplify by reusing wake irq from arm_pic
      vmstate: add VMSTATE_STRUCT_ARRAY_TEST
      pxa2xx_timer: change info struct name to comply with guidelines
      pxa2xx_timer: switch to using qdev/vmstate
      vmstate: move VMSTATE_PCIE_AER_ERRS to hw/hw.h
      pxa2xx_dma: drop unused pxa2xx_dma_handler_t/handler field
      pxa2xx_dma: port to qdev/vmstate
      pxa2xx: port pxa2xx_rtc to using qdev/vmstate

 hw/arm-misc.h     |    1 +
 hw/arm_pic.c      |    6 +-
 hw/hw.h           |   27 +++++-
 hw/mainstone.c    |    2 +-
 hw/pcie_aer.c     |   12 +--
 hw/pxa.h          |   51 ++-------
 hw/pxa2xx.c       |  313 +++++++++++++++++++++++++++++++++--------------------
 hw/pxa2xx_dma.c   |  189 ++++++++++++++++++--------------
 hw/pxa2xx_gpio.c  |   23 ++--
 hw/pxa2xx_mmci.c  |   16 ++--
 hw/pxa2xx_pic.c   |  126 +++++++++++----------
 hw/pxa2xx_timer.c |  262 +++++++++++++++++++++++++-------------------
 12 files changed, 582 insertions(+), 446 deletions(-)

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 01/10] arm-pic: add one extra interrupt to support EXITTB interrupts
  2011-02-20 13:50 [Qemu-devel] [PATCH 0/10] pxa2xx: work on switching to qdev/vmstate Dmitry Eremin-Solenikov
@ 2011-02-20 13:50 ` Dmitry Eremin-Solenikov
  2011-02-20 13:50 ` [Qemu-devel] [PATCH 02/10] pxa2xx_pic: update to use qdev and arm-pic Dmitry Eremin-Solenikov
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Dmitry Eremin-Solenikov @ 2011-02-20 13:50 UTC (permalink / raw)
  To: qemu-devel

Some ARM processors (consider PXA2xx, Omap1, etc.) want to be able to send
CPU_INTERRUPT_EXITTB to the cpu. Support doing that through common arm_pic.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 hw/arm-misc.h |    1 +
 hw/arm_pic.c  |    6 +++++-
 2 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/hw/arm-misc.h b/hw/arm-misc.h
index 010acb4..f2e45ee 100644
--- a/hw/arm-misc.h
+++ b/hw/arm-misc.h
@@ -14,6 +14,7 @@
 /* The CPU is also modeled as an interrupt controller.  */
 #define ARM_PIC_CPU_IRQ 0
 #define ARM_PIC_CPU_FIQ 1
+#define ARM_PIC_CPU_WAKE 2
 qemu_irq *arm_pic_init_cpu(CPUState *env);
 
 /* armv7m.c */
diff --git a/hw/arm_pic.c b/hw/arm_pic.c
index f44568c..9865a29 100644
--- a/hw/arm_pic.c
+++ b/hw/arm_pic.c
@@ -38,6 +38,10 @@ static void arm_pic_cpu_handler(void *opaque, int irq, int level)
         else
             cpu_reset_interrupt(env, CPU_INTERRUPT_FIQ);
         break;
+    case ARM_PIC_CPU_WAKE:
+        if (env->halted && level)
+            cpu_interrupt(env, CPU_INTERRUPT_EXITTB);
+        break;
     default:
         hw_error("arm_pic_cpu_handler: Bad interrput line %d\n", irq);
     }
@@ -45,5 +49,5 @@ static void arm_pic_cpu_handler(void *opaque, int irq, int level)
 
 qemu_irq *arm_pic_init_cpu(CPUState *env)
 {
-    return qemu_allocate_irqs(arm_pic_cpu_handler, env, 2);
+    return qemu_allocate_irqs(arm_pic_cpu_handler, env, 3);
 }
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 02/10] pxa2xx_pic: update to use qdev and arm-pic
  2011-02-20 13:50 [Qemu-devel] [PATCH 0/10] pxa2xx: work on switching to qdev/vmstate Dmitry Eremin-Solenikov
  2011-02-20 13:50 ` [Qemu-devel] [PATCH 01/10] arm-pic: add one extra interrupt to support EXITTB interrupts Dmitry Eremin-Solenikov
@ 2011-02-20 13:50 ` Dmitry Eremin-Solenikov
  2011-02-25 11:51   ` andrzej zaborowski
  2011-02-20 13:50 ` [Qemu-devel] [PATCH 03/10] pxa2xx_gpio: simplify by reusing wake irq from arm_pic Dmitry Eremin-Solenikov
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 14+ messages in thread
From: Dmitry Eremin-Solenikov @ 2011-02-20 13:50 UTC (permalink / raw)
  To: qemu-devel

Use qdev/sysbus framework to handle pxa2xx-pic. Instead of exposing IRQs
via array, reference them via qdev_get_gpio_in(). Also pxa2xx_pic duplicated
some code from arm-pic. Drop it, replacing with references to arm-pic,
as all other ARM SoCs do for their PIC code.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 hw/mainstone.c    |    2 +-
 hw/pxa.h          |   12 +++--
 hw/pxa2xx.c       |   84 +++++++++++++++++++++++------------
 hw/pxa2xx_gpio.c  |   11 +++--
 hw/pxa2xx_pic.c   |  126 ++++++++++++++++++++++++++++-------------------------
 hw/pxa2xx_timer.c |   16 +++---
 6 files changed, 144 insertions(+), 107 deletions(-)

diff --git a/hw/mainstone.c b/hw/mainstone.c
index aec8d34..4eabdb9 100644
--- a/hw/mainstone.c
+++ b/hw/mainstone.c
@@ -140,7 +140,7 @@ static void mainstone_common_init(ram_addr_t ram_size,
     }
 
     mst_irq = sysbus_create_simple("mainstone-fpga", MST_FPGA_PHYS,
-                    cpu->pic[PXA2XX_PIC_GPIO_0]);
+                    qdev_get_gpio_in(cpu->pic, PXA2XX_PIC_GPIO_0));
 
     /* setup keypad */
     printf("map addr %p\n", &map);
diff --git a/hw/pxa.h b/hw/pxa.h
index f73d33b..7c6fd44 100644
--- a/hw/pxa.h
+++ b/hw/pxa.h
@@ -63,15 +63,16 @@
 # define PXA2XX_INTERNAL_SIZE	0x40000
 
 /* pxa2xx_pic.c */
-qemu_irq *pxa2xx_pic_init(target_phys_addr_t base, CPUState *env);
+DeviceState *pxa2xx_pic_init(target_phys_addr_t base, CPUState *env,
+        qemu_irq *arm_pic);
 
 /* pxa2xx_timer.c */
-void pxa25x_timer_init(target_phys_addr_t base, qemu_irq *irqs);
-void pxa27x_timer_init(target_phys_addr_t base, qemu_irq *irqs, qemu_irq irq4);
+void pxa25x_timer_init(target_phys_addr_t base, DeviceState *pic);
+void pxa27x_timer_init(target_phys_addr_t base, DeviceState *pic);
 
 /* pxa2xx_gpio.c */
 DeviceState *pxa2xx_gpio_init(target_phys_addr_t base,
-                CPUState *env, qemu_irq *pic, int lines);
+                CPUState *env, DeviceState *pic, int lines);
 void pxa2xx_gpio_read_notifier(DeviceState *dev, qemu_irq handler);
 
 /* pxa2xx_dma.c */
@@ -125,7 +126,7 @@ typedef struct PXA2xxFIrState PXA2xxFIrState;
 
 typedef struct {
     CPUState *env;
-    qemu_irq *pic;
+    DeviceState *pic;
     qemu_irq reset;
     PXA2xxDMAState *dma;
     DeviceState *gpio;
@@ -180,6 +181,7 @@ typedef struct {
     QEMUTimer *rtc_swal1;
     QEMUTimer *rtc_swal2;
     QEMUTimer *rtc_pi;
+    qemu_irq rtc_irq;
 } PXA2xxState;
 
 struct PXA2xxI2SState {
diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
index 9ebbce6..58e6e7b 100644
--- a/hw/pxa2xx.c
+++ b/hw/pxa2xx.c
@@ -16,6 +16,7 @@
 #include "qemu-timer.h"
 #include "qemu-char.h"
 #include "blockdev.h"
+#include "arm-misc.h"
 
 static struct {
     target_phys_addr_t io_base;
@@ -888,7 +889,7 @@ static int pxa2xx_ssp_init(SysBusDevice *dev)
 
 static inline void pxa2xx_rtc_int_update(PXA2xxState *s)
 {
-    qemu_set_irq(s->pic[PXA2XX_PIC_RTCALARM], !!(s->rtsr & 0x2553));
+    qemu_set_irq(s->rtc_irq, !!(s->rtsr & 0x2553));
 }
 
 static void pxa2xx_rtc_hzupdate(PXA2xxState *s)
@@ -1197,6 +1198,8 @@ static void pxa2xx_rtc_init(PXA2xxState *s)
     s->rtc_swal1 = qemu_new_timer(rt_clock, pxa2xx_rtc_swal1_tick, s);
     s->rtc_swal2 = qemu_new_timer(rt_clock, pxa2xx_rtc_swal2_tick, s);
     s->rtc_pi    = qemu_new_timer(rt_clock, pxa2xx_rtc_pi_tick,    s);
+
+    s->rtc_irq = qdev_get_gpio_in(s->pic, PXA2XX_PIC_RTCALARM);
 }
 
 static void pxa2xx_rtc_save(QEMUFile *f, void *opaque)
@@ -2069,6 +2072,8 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision)
     PXA2xxState *s;
     int iomemtype, i;
     DriveInfo *dinfo;
+    qemu_irq *arm_pic;
+
     s = (PXA2xxState *) qemu_mallocz(sizeof(PXA2xxState));
 
     if (revision && strncmp(revision, "pxa27", 5)) {
@@ -2093,12 +2098,13 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision)
                     0x40000, qemu_ram_alloc(NULL, "pxa270.internal",
                                             0x40000) | IO_MEM_RAM);
 
-    s->pic = pxa2xx_pic_init(0x40d00000, s->env);
+    arm_pic = arm_pic_init_cpu(s->env);
+    s->pic = pxa2xx_pic_init(0x40d00000, s->env, arm_pic);
 
-    s->dma = pxa27x_dma_init(0x40000000, s->pic[PXA2XX_PIC_DMA]);
+    s->dma = pxa27x_dma_init(0x40000000,
+            qdev_get_gpio_in(s->pic, PXA2XX_PIC_DMA));
 
-    pxa27x_timer_init(0x40a00000, &s->pic[PXA2XX_PIC_OST_0],
-                    s->pic[PXA27X_PIC_OST_4_11]);
+    pxa27x_timer_init(0x40a00000, s->pic);
 
     s->gpio = pxa2xx_gpio_init(0x40e00000, s->env, s->pic, 121);
 
@@ -2108,26 +2114,30 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision)
         exit(1);
     }
     s->mmc = pxa2xx_mmci_init(0x41100000, dinfo->bdrv,
-                              s->pic[PXA2XX_PIC_MMC], s->dma);
+                              qdev_get_gpio_in(s->pic, PXA2XX_PIC_MMC), s->dma);
 
     for (i = 0; pxa270_serial[i].io_base; i ++)
         if (serial_hds[i])
 #ifdef TARGET_WORDS_BIGENDIAN
             serial_mm_init(pxa270_serial[i].io_base, 2,
-                           s->pic[pxa270_serial[i].irqn], 14857000/16,
+                           qdev_get_gpio_in(s->pic, pxa270_serial[i].irqn),
+                           14857000/16,
                            serial_hds[i], 1, 1);
 #else
             serial_mm_init(pxa270_serial[i].io_base, 2,
-                           s->pic[pxa270_serial[i].irqn], 14857000/16,
+                           qdev_get_gpio_in(s->pic, pxa270_serial[i].irqn),
+                           14857000/16,
                            serial_hds[i], 1, 0);
 #endif
         else
             break;
     if (serial_hds[i])
-        s->fir = pxa2xx_fir_init(0x40800000, s->pic[PXA2XX_PIC_ICP],
+        s->fir = pxa2xx_fir_init(0x40800000,
+                        qdev_get_gpio_in(s->pic, PXA2XX_PIC_ICP),
                         s->dma, serial_hds[i]);
 
-    s->lcd = pxa2xx_lcdc_init(0x44000000, s->pic[PXA2XX_PIC_LCD]);
+    s->lcd = pxa2xx_lcdc_init(0x44000000,
+                        qdev_get_gpio_in(s->pic, PXA2XX_PIC_LCD));
 
     s->cm_base = 0x41300000;
     s->cm_regs[CCCR >> 2] = 0x02000210;	/* 416.0 MHz */
@@ -2159,13 +2169,13 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision)
     for (i = 0; pxa27x_ssp[i].io_base; i ++) {
         DeviceState *dev;
         dev = sysbus_create_simple("pxa2xx-ssp", pxa27x_ssp[i].io_base,
-                                   s->pic[pxa27x_ssp[i].irqn]);
+                               qdev_get_gpio_in(s->pic, pxa27x_ssp[i].irqn));
         s->ssp[i] = (SSIBus *)qdev_get_child_bus(dev, "ssi");
     }
 
     if (usb_enabled) {
         sysbus_create_simple("sysbus-ohci", 0x4c000000,
-                             s->pic[PXA2XX_PIC_USBH1]);
+                             qdev_get_gpio_in(s->pic, PXA2XX_PIC_USBH1));
     }
 
     s->pcmcia[0] = pxa2xx_pcmcia_init(0x20000000);
@@ -2179,12 +2189,17 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision)
     register_savevm(NULL, "pxa2xx_rtc", 0, 0, pxa2xx_rtc_save,
                     pxa2xx_rtc_load, s);
 
-    s->i2c[0] = pxa2xx_i2c_init(0x40301600, s->pic[PXA2XX_PIC_I2C], 0xffff);
-    s->i2c[1] = pxa2xx_i2c_init(0x40f00100, s->pic[PXA2XX_PIC_PWRI2C], 0xff);
+    s->i2c[0] = pxa2xx_i2c_init(0x40301600,
+            qdev_get_gpio_in(s->pic, PXA2XX_PIC_I2C), 0xffff);
+    s->i2c[1] = pxa2xx_i2c_init(0x40f00100,
+            qdev_get_gpio_in(s->pic, PXA2XX_PIC_PWRI2C), 0xff);
 
-    s->i2s = pxa2xx_i2s_init(0x40400000, s->pic[PXA2XX_PIC_I2S], s->dma);
+    s->i2s = pxa2xx_i2s_init(0x40400000,
+            qdev_get_gpio_in(s->pic, PXA2XX_PIC_I2S),
+            s->dma);
 
-    s->kp = pxa27x_keypad_init(0x41500000, s->pic[PXA2XX_PIC_KEYPAD]);
+    s->kp = pxa27x_keypad_init(0x41500000,
+            qdev_get_gpio_in(s->pic, PXA2XX_PIC_KEYPAD));
 
     /* GPIO1 resets the processor */
     /* The handler can be overridden by board-specific code */
@@ -2198,6 +2213,7 @@ PXA2xxState *pxa255_init(unsigned int sdram_size)
     PXA2xxState *s;
     int iomemtype, i;
     DriveInfo *dinfo;
+    qemu_irq *arm_pic;
 
     s = (PXA2xxState *) qemu_mallocz(sizeof(PXA2xxState));
 
@@ -2216,11 +2232,13 @@ PXA2xxState *pxa255_init(unsigned int sdram_size)
                     qemu_ram_alloc(NULL, "pxa255.internal",
                                    PXA2XX_INTERNAL_SIZE) | IO_MEM_RAM);
 
-    s->pic = pxa2xx_pic_init(0x40d00000, s->env);
+    arm_pic = arm_pic_init_cpu(s->env);
+    s->pic = pxa2xx_pic_init(0x40d00000, s->env, arm_pic);
 
-    s->dma = pxa255_dma_init(0x40000000, s->pic[PXA2XX_PIC_DMA]);
+    s->dma = pxa255_dma_init(0x40000000,
+            qdev_get_gpio_in(s->pic, PXA2XX_PIC_DMA));
 
-    pxa25x_timer_init(0x40a00000, &s->pic[PXA2XX_PIC_OST_0]);
+    pxa25x_timer_init(0x40a00000, s->pic);
 
     s->gpio = pxa2xx_gpio_init(0x40e00000, s->env, s->pic, 85);
 
@@ -2230,27 +2248,31 @@ PXA2xxState *pxa255_init(unsigned int sdram_size)
         exit(1);
     }
     s->mmc = pxa2xx_mmci_init(0x41100000, dinfo->bdrv,
-                              s->pic[PXA2XX_PIC_MMC], s->dma);
+                              qdev_get_gpio_in(s->pic, PXA2XX_PIC_MMC), s->dma);
 
     for (i = 0; pxa255_serial[i].io_base; i ++)
         if (serial_hds[i]) {
 #ifdef TARGET_WORDS_BIGENDIAN
             serial_mm_init(pxa255_serial[i].io_base, 2,
-                           s->pic[pxa255_serial[i].irqn], 14745600/16,
+                           qdev_get_gpio_in(s->pic, pxa255_serial[i].irqn),
+                           14745600/16,
                            serial_hds[i], 1, 1);
 #else
             serial_mm_init(pxa255_serial[i].io_base, 2,
-                           s->pic[pxa255_serial[i].irqn], 14745600/16,
+                           qdev_get_gpio_in(s->pic, pxa255_serial[i].irqn),
+                           14745600/16,
                            serial_hds[i], 1, 0);
 #endif
         } else {
             break;
         }
     if (serial_hds[i])
-        s->fir = pxa2xx_fir_init(0x40800000, s->pic[PXA2XX_PIC_ICP],
+        s->fir = pxa2xx_fir_init(0x40800000,
+                        qdev_get_gpio_in(s->pic, PXA2XX_PIC_ICP),
                         s->dma, serial_hds[i]);
 
-    s->lcd = pxa2xx_lcdc_init(0x44000000, s->pic[PXA2XX_PIC_LCD]);
+    s->lcd = pxa2xx_lcdc_init(0x44000000,
+            qdev_get_gpio_in(s->pic, PXA2XX_PIC_LCD));
 
     s->cm_base = 0x41300000;
     s->cm_regs[CCCR >> 2] = 0x02000210;	/* 416.0 MHz */
@@ -2282,13 +2304,13 @@ PXA2xxState *pxa255_init(unsigned int sdram_size)
     for (i = 0; pxa255_ssp[i].io_base; i ++) {
         DeviceState *dev;
         dev = sysbus_create_simple("pxa2xx-ssp", pxa255_ssp[i].io_base,
-                                   s->pic[pxa255_ssp[i].irqn]);
+                               qdev_get_gpio_in(s->pic, pxa255_ssp[i].irqn));
         s->ssp[i] = (SSIBus *)qdev_get_child_bus(dev, "ssi");
     }
 
     if (usb_enabled) {
         sysbus_create_simple("sysbus-ohci", 0x4c000000,
-                             s->pic[PXA2XX_PIC_USBH1]);
+                             qdev_get_gpio_in(s->pic, PXA2XX_PIC_USBH1));
     }
 
     s->pcmcia[0] = pxa2xx_pcmcia_init(0x20000000);
@@ -2302,10 +2324,14 @@ PXA2xxState *pxa255_init(unsigned int sdram_size)
     register_savevm(NULL, "pxa2xx_rtc", 0, 0, pxa2xx_rtc_save,
                     pxa2xx_rtc_load, s);
 
-    s->i2c[0] = pxa2xx_i2c_init(0x40301600, s->pic[PXA2XX_PIC_I2C], 0xffff);
-    s->i2c[1] = pxa2xx_i2c_init(0x40f00100, s->pic[PXA2XX_PIC_PWRI2C], 0xff);
+    s->i2c[0] = pxa2xx_i2c_init(0x40301600,
+            qdev_get_gpio_in(s->pic, PXA2XX_PIC_I2C), 0xffff);
+    s->i2c[1] = pxa2xx_i2c_init(0x40f00100,
+            qdev_get_gpio_in(s->pic, PXA2XX_PIC_PWRI2C), 0xff);
 
-    s->i2s = pxa2xx_i2s_init(0x40400000, s->pic[PXA2XX_PIC_I2S], s->dma);
+    s->i2s = pxa2xx_i2s_init(0x40400000,
+            qdev_get_gpio_in(s->pic, PXA2XX_PIC_I2S),
+            s->dma);
 
     /* GPIO1 resets the processor */
     /* The handler can be overridden by board-specific code */
diff --git a/hw/pxa2xx_gpio.c b/hw/pxa2xx_gpio.c
index 789965d..16a8865 100644
--- a/hw/pxa2xx_gpio.c
+++ b/hw/pxa2xx_gpio.c
@@ -253,7 +253,7 @@ static CPUWriteMemoryFunc * const pxa2xx_gpio_writefn[] = {
 };
 
 DeviceState *pxa2xx_gpio_init(target_phys_addr_t base,
-                CPUState *env, qemu_irq *pic, int lines)
+                CPUState *env, DeviceState *pic, int lines)
 {
     DeviceState *dev;
 
@@ -263,9 +263,12 @@ DeviceState *pxa2xx_gpio_init(target_phys_addr_t base,
     qdev_init_nofail(dev);
 
     sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
-    sysbus_connect_irq(sysbus_from_qdev(dev), 0, pic[PXA2XX_PIC_GPIO_0]);
-    sysbus_connect_irq(sysbus_from_qdev(dev), 1, pic[PXA2XX_PIC_GPIO_1]);
-    sysbus_connect_irq(sysbus_from_qdev(dev), 2, pic[PXA2XX_PIC_GPIO_X]);
+    sysbus_connect_irq(sysbus_from_qdev(dev), 0,
+            qdev_get_gpio_in(pic, PXA2XX_PIC_GPIO_0));
+    sysbus_connect_irq(sysbus_from_qdev(dev), 1,
+            qdev_get_gpio_in(pic, PXA2XX_PIC_GPIO_1));
+    sysbus_connect_irq(sysbus_from_qdev(dev), 2,
+            qdev_get_gpio_in(pic, PXA2XX_PIC_GPIO_X));
 
     return dev;
 }
diff --git a/hw/pxa2xx_pic.c b/hw/pxa2xx_pic.c
index a36da23..1053b92 100644
--- a/hw/pxa2xx_pic.c
+++ b/hw/pxa2xx_pic.c
@@ -10,6 +10,8 @@
 
 #include "hw.h"
 #include "pxa.h"
+#include "arm-misc.h"
+#include "sysbus.h"
 
 #define ICIP	0x00	/* Interrupt Controller IRQ Pending register */
 #define ICMR	0x04	/* Interrupt Controller Mask register */
@@ -31,7 +33,10 @@
 #define PXA2XX_PIC_SRCS	40
 
 typedef struct {
-    CPUState *cpu_env;
+    SysBusDevice busdev;
+    qemu_irq hard_irq;
+    qemu_irq fiq_irq;
+    qemu_irq wake_irq;
     uint32_t int_enabled[2];
     uint32_t int_pending[2];
     uint32_t is_fiq[2];
@@ -44,25 +49,18 @@ static void pxa2xx_pic_update(void *opaque)
     uint32_t mask[2];
     PXA2xxPICState *s = (PXA2xxPICState *) opaque;
 
-    if (s->cpu_env->halted) {
-        mask[0] = s->int_pending[0] & (s->int_enabled[0] | s->int_idle);
-        mask[1] = s->int_pending[1] & (s->int_enabled[1] | s->int_idle);
-        if (mask[0] || mask[1])
-            cpu_interrupt(s->cpu_env, CPU_INTERRUPT_EXITTB);
-    }
+    mask[0] = s->int_pending[0] & (s->int_enabled[0] | s->int_idle);
+    mask[1] = s->int_pending[1] & (s->int_enabled[1] | s->int_idle);
+    qemu_set_irq(s->wake_irq, mask[0] || mask[1]);
 
     mask[0] = s->int_pending[0] & s->int_enabled[0];
     mask[1] = s->int_pending[1] & s->int_enabled[1];
 
-    if ((mask[0] & s->is_fiq[0]) || (mask[1] & s->is_fiq[1]))
-        cpu_interrupt(s->cpu_env, CPU_INTERRUPT_FIQ);
-    else
-        cpu_reset_interrupt(s->cpu_env, CPU_INTERRUPT_FIQ);
+    qemu_set_irq(s->fiq_irq,
+            ((mask[0] & s->is_fiq[0]) || (mask[1] & s->is_fiq[1])));
 
-    if ((mask[0] & ~s->is_fiq[0]) || (mask[1] & ~s->is_fiq[1]))
-        cpu_interrupt(s->cpu_env, CPU_INTERRUPT_HARD);
-    else
-        cpu_reset_interrupt(s->cpu_env, CPU_INTERRUPT_HARD);
+    qemu_set_irq(s->hard_irq,
+            ((mask[0] & ~s->is_fiq[0]) || (mask[1] & ~s->is_fiq[1])));
 }
 
 /* Note: Here level means state of the signal on a pin, not
@@ -241,53 +239,33 @@ static CPUWriteMemoryFunc * const pxa2xx_pic_writefn[] = {
     pxa2xx_pic_mem_write,
 };
 
-static void pxa2xx_pic_save(QEMUFile *f, void *opaque)
+static int pxa2xx_pic_post_load(void *opaque, int version_id)
 {
-    PXA2xxPICState *s = (PXA2xxPICState *) opaque;
-    int i;
-
-    for (i = 0; i < 2; i ++)
-        qemu_put_be32s(f, &s->int_enabled[i]);
-    for (i = 0; i < 2; i ++)
-        qemu_put_be32s(f, &s->int_pending[i]);
-    for (i = 0; i < 2; i ++)
-        qemu_put_be32s(f, &s->is_fiq[i]);
-    qemu_put_be32s(f, &s->int_idle);
-    for (i = 0; i < PXA2XX_PIC_SRCS; i ++)
-        qemu_put_be32s(f, &s->priority[i]);
+    pxa2xx_pic_update(opaque);
+    return 0;
 }
 
-static int pxa2xx_pic_load(QEMUFile *f, void *opaque, int version_id)
+DeviceState *pxa2xx_pic_init(target_phys_addr_t base, CPUState *env,
+        qemu_irq *arm_pic)
 {
-    PXA2xxPICState *s = (PXA2xxPICState *) opaque;
-    int i;
-
-    for (i = 0; i < 2; i ++)
-        qemu_get_be32s(f, &s->int_enabled[i]);
-    for (i = 0; i < 2; i ++)
-        qemu_get_be32s(f, &s->int_pending[i]);
-    for (i = 0; i < 2; i ++)
-        qemu_get_be32s(f, &s->is_fiq[i]);
-    qemu_get_be32s(f, &s->int_idle);
-    for (i = 0; i < PXA2XX_PIC_SRCS; i ++)
-        qemu_get_be32s(f, &s->priority[i]);
+    DeviceState *dev;
 
-    pxa2xx_pic_update(opaque);
-    return 0;
+    dev = sysbus_create_varargs("pxa2xx_pic", base,
+            arm_pic[ARM_PIC_CPU_IRQ],
+            arm_pic[ARM_PIC_CPU_FIQ],
+            arm_pic[ARM_PIC_CPU_WAKE],
+            NULL);
+
+    /* Enable IC coprocessor access.  */
+    cpu_arm_set_cp_io(env, 6, pxa2xx_pic_cp_read, pxa2xx_pic_cp_write, dev);
+
+    return dev;
 }
 
-qemu_irq *pxa2xx_pic_init(target_phys_addr_t base, CPUState *env)
+static int pxa2xx_pic_initfn(SysBusDevice *dev)
 {
-    PXA2xxPICState *s;
+    PXA2xxPICState *s = FROM_SYSBUS(PXA2xxPICState, dev);
     int iomemtype;
-    qemu_irq *qi;
-
-    s = (PXA2xxPICState *)
-            qemu_mallocz(sizeof(PXA2xxPICState));
-    if (!s)
-        return NULL;
-
-    s->cpu_env = env;
 
     s->int_pending[0] = 0;
     s->int_pending[1] = 0;
@@ -296,18 +274,46 @@ qemu_irq *pxa2xx_pic_init(target_phys_addr_t base, CPUState *env)
     s->is_fiq[0] = 0;
     s->is_fiq[1] = 0;
 
-    qi = qemu_allocate_irqs(pxa2xx_pic_set_irq, s, PXA2XX_PIC_SRCS);
+    sysbus_init_irq(dev, &s->hard_irq);
+    sysbus_init_irq(dev, &s->fiq_irq);
+    sysbus_init_irq(dev, &s->wake_irq);
+
+    qdev_init_gpio_in(&dev->qdev, pxa2xx_pic_set_irq, PXA2XX_PIC_SRCS);
 
     /* Enable IC memory-mapped registers access.  */
     iomemtype = cpu_register_io_memory(pxa2xx_pic_readfn,
                     pxa2xx_pic_writefn, s, DEVICE_NATIVE_ENDIAN);
-    cpu_register_physical_memory(base, 0x00100000, iomemtype);
+    sysbus_init_mmio(dev, 0x00100000, iomemtype);
 
-    /* Enable IC coprocessor access.  */
-    cpu_arm_set_cp_io(env, 6, pxa2xx_pic_cp_read, pxa2xx_pic_cp_write, s);
+    return 0;
+}
 
-    register_savevm(NULL, "pxa2xx_pic", 0, 0, pxa2xx_pic_save,
-                    pxa2xx_pic_load, s);
+static VMStateDescription vmstate_pxa2xx_pic_regs = {
+    .name = "pxa2xx_pic",
+    .version_id = 0,
+    .minimum_version_id = 0,
+    .minimum_version_id_old = 0,
+    .post_load = pxa2xx_pic_post_load,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32_ARRAY(int_enabled, PXA2xxPICState, 2),
+        VMSTATE_UINT32_ARRAY(int_pending, PXA2xxPICState, 2),
+        VMSTATE_UINT32_ARRAY(is_fiq, PXA2xxPICState, 2),
+        VMSTATE_UINT32(int_idle, PXA2xxPICState),
+        VMSTATE_UINT32_ARRAY(priority, PXA2xxPICState, PXA2XX_PIC_SRCS),
+        VMSTATE_END_OF_LIST(),
+    },
+};
 
-    return qi;
+static SysBusDeviceInfo pxa2xx_pic_info = {
+    .init       = pxa2xx_pic_initfn,
+    .qdev.name  = "pxa2xx_pic",
+    .qdev.desc  = "PXA2xx PIC",
+    .qdev.size  = sizeof(PXA2xxPICState),
+    .qdev.vmsd  = &vmstate_pxa2xx_pic_regs,
+};
+
+static void pxa2xx_pic_register(void)
+{
+    sysbus_register_withprop(&pxa2xx_pic_info);
 }
+device_init(pxa2xx_pic_register);
diff --git a/hw/pxa2xx_timer.c b/hw/pxa2xx_timer.c
index b556d11..7ab2cc3 100644
--- a/hw/pxa2xx_timer.c
+++ b/hw/pxa2xx_timer.c
@@ -10,6 +10,7 @@
 #include "hw.h"
 #include "qemu-timer.h"
 #include "sysemu.h"
+#include "qdev.h"
 #include "pxa.h"
 
 #define OSMR0	0x00
@@ -428,7 +429,7 @@ static int pxa2xx_timer_load(QEMUFile *f, void *opaque, int version_id)
 }
 
 static pxa2xx_timer_info *pxa2xx_timer_init(target_phys_addr_t base,
-                qemu_irq *irqs)
+                DeviceState *pic)
 {
     int i;
     int iomemtype;
@@ -443,7 +444,7 @@ static pxa2xx_timer_info *pxa2xx_timer_init(target_phys_addr_t base,
 
     for (i = 0; i < 4; i ++) {
         s->timer[i].value = 0;
-        s->timer[i].irq = irqs[i];
+        s->timer[i].irq = qdev_get_gpio_in(pic, PXA2XX_PIC_OST_0 + i);
         s->timer[i].info = s;
         s->timer[i].num = i;
         s->timer[i].level = 0;
@@ -461,24 +462,23 @@ static pxa2xx_timer_info *pxa2xx_timer_init(target_phys_addr_t base,
     return s;
 }
 
-void pxa25x_timer_init(target_phys_addr_t base, qemu_irq *irqs)
+void pxa25x_timer_init(target_phys_addr_t base, DeviceState *pic)
 {
-    pxa2xx_timer_info *s = pxa2xx_timer_init(base, irqs);
+    pxa2xx_timer_info *s = pxa2xx_timer_init(base, pic);
     s->freq = PXA25X_FREQ;
     s->tm4 = NULL;
 }
 
-void pxa27x_timer_init(target_phys_addr_t base,
-                qemu_irq *irqs, qemu_irq irq4)
+void pxa27x_timer_init(target_phys_addr_t base, DeviceState *pic)
 {
-    pxa2xx_timer_info *s = pxa2xx_timer_init(base, irqs);
+    pxa2xx_timer_info *s = pxa2xx_timer_init(base, pic);
     int i;
     s->freq = PXA27X_FREQ;
     s->tm4 = (PXA2xxTimer4 *) qemu_mallocz(8 *
                     sizeof(PXA2xxTimer4));
     for (i = 0; i < 8; i ++) {
         s->tm4[i].tm.value = 0;
-        s->tm4[i].tm.irq = irq4;
+        s->tm4[i].tm.irq = qdev_get_gpio_in(pic, PXA27X_PIC_OST_4_11);
         s->tm4[i].tm.info = s;
         s->tm4[i].tm.num = i + 4;
         s->tm4[i].tm.level = 0;
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 03/10] pxa2xx_gpio: simplify by reusing wake irq from arm_pic
  2011-02-20 13:50 [Qemu-devel] [PATCH 0/10] pxa2xx: work on switching to qdev/vmstate Dmitry Eremin-Solenikov
  2011-02-20 13:50 ` [Qemu-devel] [PATCH 01/10] arm-pic: add one extra interrupt to support EXITTB interrupts Dmitry Eremin-Solenikov
  2011-02-20 13:50 ` [Qemu-devel] [PATCH 02/10] pxa2xx_pic: update to use qdev and arm-pic Dmitry Eremin-Solenikov
@ 2011-02-20 13:50 ` Dmitry Eremin-Solenikov
  2011-02-20 13:50 ` [Qemu-devel] [PATCH 04/10] vmstate: add VMSTATE_STRUCT_ARRAY_TEST Dmitry Eremin-Solenikov
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Dmitry Eremin-Solenikov @ 2011-02-20 13:50 UTC (permalink / raw)
  To: qemu-devel

We can stop messing with CPUState directly, as we have special irq in arm_pic

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 hw/pxa.h         |    2 +-
 hw/pxa2xx.c      |    6 ++++--
 hw/pxa2xx_gpio.c |   14 +++++---------
 3 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/hw/pxa.h b/hw/pxa.h
index 7c6fd44..c2dede2 100644
--- a/hw/pxa.h
+++ b/hw/pxa.h
@@ -72,7 +72,7 @@ void pxa27x_timer_init(target_phys_addr_t base, DeviceState *pic);
 
 /* pxa2xx_gpio.c */
 DeviceState *pxa2xx_gpio_init(target_phys_addr_t base,
-                CPUState *env, DeviceState *pic, int lines);
+                qemu_irq wake_irq, DeviceState *pic, int lines);
 void pxa2xx_gpio_read_notifier(DeviceState *dev, qemu_irq handler);
 
 /* pxa2xx_dma.c */
diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
index 58e6e7b..bc9542e 100644
--- a/hw/pxa2xx.c
+++ b/hw/pxa2xx.c
@@ -2106,7 +2106,8 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision)
 
     pxa27x_timer_init(0x40a00000, s->pic);
 
-    s->gpio = pxa2xx_gpio_init(0x40e00000, s->env, s->pic, 121);
+    s->gpio = pxa2xx_gpio_init(0x40e00000, arm_pic[ARM_PIC_CPU_WAKE],
+            s->pic, 121);
 
     dinfo = drive_get(IF_SD, 0, 0);
     if (!dinfo) {
@@ -2240,7 +2241,8 @@ PXA2xxState *pxa255_init(unsigned int sdram_size)
 
     pxa25x_timer_init(0x40a00000, s->pic);
 
-    s->gpio = pxa2xx_gpio_init(0x40e00000, s->env, s->pic, 85);
+    s->gpio = pxa2xx_gpio_init(0x40e00000, arm_pic[ARM_PIC_CPU_WAKE],
+            s->pic, 85);
 
     dinfo = drive_get(IF_SD, 0, 0);
     if (!dinfo) {
diff --git a/hw/pxa2xx_gpio.c b/hw/pxa2xx_gpio.c
index 16a8865..61d556b 100644
--- a/hw/pxa2xx_gpio.c
+++ b/hw/pxa2xx_gpio.c
@@ -17,9 +17,8 @@ typedef struct PXA2xxGPIOInfo PXA2xxGPIOInfo;
 struct PXA2xxGPIOInfo {
     SysBusDevice busdev;
     qemu_irq irq0, irq1, irqX;
+    qemu_irq wake_irq;
     int lines;
-    int ncpu;
-    CPUState *cpu_env;
 
     /* XXX: GNU C vectors are more suitable */
     uint32_t ilevel[PXA2XX_GPIO_BANKS];
@@ -117,8 +116,7 @@ static void pxa2xx_gpio_set(void *opaque, int line, int level)
         pxa2xx_gpio_irq_update(s);
 
     /* Wake-up GPIOs */
-    if (s->cpu_env->halted && (mask & ~s->dir[bank] & pxa2xx_gpio_wake[bank]))
-        cpu_interrupt(s->cpu_env, CPU_INTERRUPT_EXITTB);
+    qemu_set_irq(s->wake_irq, (mask & ~s->dir[bank] & pxa2xx_gpio_wake[bank]));
 }
 
 static void pxa2xx_gpio_handler_update(PXA2xxGPIOInfo *s) {
@@ -253,13 +251,12 @@ static CPUWriteMemoryFunc * const pxa2xx_gpio_writefn[] = {
 };
 
 DeviceState *pxa2xx_gpio_init(target_phys_addr_t base,
-                CPUState *env, DeviceState *pic, int lines)
+                qemu_irq wake_irq, DeviceState *pic, int lines)
 {
     DeviceState *dev;
 
     dev = qdev_create(NULL, "pxa2xx-gpio");
     qdev_prop_set_int32(dev, "lines", lines);
-    qdev_prop_set_int32(dev, "ncpu", env->cpu_index);
     qdev_init_nofail(dev);
 
     sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
@@ -269,6 +266,7 @@ DeviceState *pxa2xx_gpio_init(target_phys_addr_t base,
             qdev_get_gpio_in(pic, PXA2XX_PIC_GPIO_1));
     sysbus_connect_irq(sysbus_from_qdev(dev), 2,
             qdev_get_gpio_in(pic, PXA2XX_PIC_GPIO_X));
+    sysbus_connect_irq(sysbus_from_qdev(dev), 3, wake_irq);
 
     return dev;
 }
@@ -280,8 +278,6 @@ static int pxa2xx_gpio_initfn(SysBusDevice *dev)
 
     s = FROM_SYSBUS(PXA2xxGPIOInfo, dev);
 
-    s->cpu_env = qemu_get_cpu(s->ncpu);
-
     qdev_init_gpio_in(&dev->qdev, pxa2xx_gpio_set, s->lines);
     qdev_init_gpio_out(&dev->qdev, s->handler, s->lines);
 
@@ -292,6 +288,7 @@ static int pxa2xx_gpio_initfn(SysBusDevice *dev)
     sysbus_init_irq(dev, &s->irq0);
     sysbus_init_irq(dev, &s->irq1);
     sysbus_init_irq(dev, &s->irqX);
+    sysbus_init_irq(dev, &s->wake_irq);
 
     return 0;
 }
@@ -331,7 +328,6 @@ static SysBusDeviceInfo pxa2xx_gpio_info = {
     .qdev.size  = sizeof(PXA2xxGPIOInfo),
     .qdev.props = (Property []) {
         DEFINE_PROP_INT32("lines", PXA2xxGPIOInfo, lines, 0),
-        DEFINE_PROP_INT32("ncpu", PXA2xxGPIOInfo, ncpu, 0),
         DEFINE_PROP_END_OF_LIST(),
     }
 };
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 04/10] vmstate: add VMSTATE_STRUCT_ARRAY_TEST
  2011-02-20 13:50 [Qemu-devel] [PATCH 0/10] pxa2xx: work on switching to qdev/vmstate Dmitry Eremin-Solenikov
                   ` (2 preceding siblings ...)
  2011-02-20 13:50 ` [Qemu-devel] [PATCH 03/10] pxa2xx_gpio: simplify by reusing wake irq from arm_pic Dmitry Eremin-Solenikov
@ 2011-02-20 13:50 ` Dmitry Eremin-Solenikov
  2011-02-20 13:50 ` [Qemu-devel] [PATCH 05/10] pxa2xx_timer: change info struct name to comply with guidelines Dmitry Eremin-Solenikov
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Dmitry Eremin-Solenikov @ 2011-02-20 13:50 UTC (permalink / raw)
  To: qemu-devel

This is a _TEST variant of VMSTATE_STRUCT_ARRAY, necessary e.g.
for future patch changing pxa2xx_timer to use vmstate.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 hw/hw.h |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/hw/hw.h b/hw/hw.h
index 5e24329..b47a7c8 100644
--- a/hw/hw.h
+++ b/hw/hw.h
@@ -475,9 +475,10 @@ extern const VMStateInfo vmstate_info_unused_buffer;
     .offset     = vmstate_offset_array(_state, _field, _type, _num), \
 }
 
-#define VMSTATE_STRUCT_ARRAY(_field, _state, _num, _version, _vmsd, _type) { \
+#define VMSTATE_STRUCT_ARRAY_TEST(_field, _state, _num, _test, _version, _vmsd, _type) { \
     .name       = (stringify(_field)),                               \
     .num        = (_num),                                            \
+    .field_exists = (_test),                                         \
     .version_id = (_version),                                        \
     .vmsd       = &(_vmsd),                                          \
     .size       = sizeof(_type),                                     \
@@ -485,6 +486,9 @@ extern const VMStateInfo vmstate_info_unused_buffer;
     .offset     = vmstate_offset_array(_state, _field, _type, _num), \
 }
 
+#define VMSTATE_STRUCT_ARRAY(_field, _state, _num, _version, _vmsd, _type) \
+    VMSTATE_STRUCT_ARRAY_TEST(_field, _state, _num, NULL, _version, _vmsd, _type)
+
 #define VMSTATE_STRUCT_VARRAY_UINT8(_field, _state, _field_num, _version, _vmsd, _type) { \
     .name       = (stringify(_field)),                               \
     .num_offset = vmstate_offset_value(_state, _field_num, uint8_t),  \
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 05/10] pxa2xx_timer: change info struct name to comply with guidelines
  2011-02-20 13:50 [Qemu-devel] [PATCH 0/10] pxa2xx: work on switching to qdev/vmstate Dmitry Eremin-Solenikov
                   ` (3 preceding siblings ...)
  2011-02-20 13:50 ` [Qemu-devel] [PATCH 04/10] vmstate: add VMSTATE_STRUCT_ARRAY_TEST Dmitry Eremin-Solenikov
@ 2011-02-20 13:50 ` Dmitry Eremin-Solenikov
  2011-02-20 13:50 ` [Qemu-devel] [PATCH 06/10] pxa2xx_timer: switch to using qdev/vmstate Dmitry Eremin-Solenikov
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Dmitry Eremin-Solenikov @ 2011-02-20 13:50 UTC (permalink / raw)
  To: qemu-devel

It should be PXA2xxTimerInfo, not pxa2xx_timer_info. Replace all occurencies of old name
with the new one.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 hw/pxa2xx_timer.c |   28 ++++++++++++++--------------
 1 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/hw/pxa2xx_timer.c b/hw/pxa2xx_timer.c
index 7ab2cc3..08141a2 100644
--- a/hw/pxa2xx_timer.c
+++ b/hw/pxa2xx_timer.c
@@ -89,11 +89,11 @@ typedef struct {
     uint32_t irq_enabled;
     uint32_t reset3;
     uint32_t snapshot;
-} pxa2xx_timer_info;
+} PXA2xxTimerInfo;
 
 static void pxa2xx_timer_update(void *opaque, uint64_t now_qemu)
 {
-    pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque;
+    PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
     int i;
     uint32_t now_vm;
     uint64_t new_qemu;
@@ -110,7 +110,7 @@ static void pxa2xx_timer_update(void *opaque, uint64_t now_qemu)
 
 static void pxa2xx_timer_update4(void *opaque, uint64_t now_qemu, int n)
 {
-    pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque;
+    PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
     uint32_t now_vm;
     uint64_t new_qemu;
     static const int counters[8] = { 0, 0, 0, 0, 4, 4, 6, 6 };
@@ -137,7 +137,7 @@ static void pxa2xx_timer_update4(void *opaque, uint64_t now_qemu, int n)
 
 static uint32_t pxa2xx_timer_read(void *opaque, target_phys_addr_t offset)
 {
-    pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque;
+    PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
     int tm = 0;
 
     switch (offset) {
@@ -216,7 +216,7 @@ static void pxa2xx_timer_write(void *opaque, target_phys_addr_t offset,
                 uint32_t value)
 {
     int i, tm = 0;
-    pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque;
+    PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
 
     switch (offset) {
     case OSMR3:  tm ++;
@@ -334,7 +334,7 @@ static CPUWriteMemoryFunc * const pxa2xx_timer_writefn[] = {
 static void pxa2xx_timer_tick(void *opaque)
 {
     PXA2xxTimer0 *t = (PXA2xxTimer0 *) opaque;
-    pxa2xx_timer_info *i = (pxa2xx_timer_info *) t->info;
+    PXA2xxTimerInfo *i = (PXA2xxTimerInfo *) t->info;
 
     if (i->irq_enabled & (1 << t->num)) {
         t->level = 1;
@@ -352,7 +352,7 @@ static void pxa2xx_timer_tick(void *opaque)
 static void pxa2xx_timer_tick4(void *opaque)
 {
     PXA2xxTimer4 *t = (PXA2xxTimer4 *) opaque;
-    pxa2xx_timer_info *i = (pxa2xx_timer_info *) t->tm.info;
+    PXA2xxTimerInfo *i = (PXA2xxTimerInfo *) t->tm.info;
 
     pxa2xx_timer_tick(&t->tm);
     if (t->control & (1 << 3))
@@ -363,7 +363,7 @@ static void pxa2xx_timer_tick4(void *opaque)
 
 static void pxa2xx_timer_save(QEMUFile *f, void *opaque)
 {
-    pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque;
+    PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
     int i;
 
     qemu_put_be32s(f, (uint32_t *) &s->clock);
@@ -393,7 +393,7 @@ static void pxa2xx_timer_save(QEMUFile *f, void *opaque)
 
 static int pxa2xx_timer_load(QEMUFile *f, void *opaque, int version_id)
 {
-    pxa2xx_timer_info *s = (pxa2xx_timer_info *) opaque;
+    PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
     int64_t now;
     int i;
 
@@ -428,14 +428,14 @@ static int pxa2xx_timer_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static pxa2xx_timer_info *pxa2xx_timer_init(target_phys_addr_t base,
+static PXA2xxTimerInfo *pxa2xx_timer_init(target_phys_addr_t base,
                 DeviceState *pic)
 {
     int i;
     int iomemtype;
-    pxa2xx_timer_info *s;
+    PXA2xxTimerInfo *s;
 
-    s = (pxa2xx_timer_info *) qemu_mallocz(sizeof(pxa2xx_timer_info));
+    s = (PXA2xxTimerInfo *) qemu_mallocz(sizeof(PXA2xxTimerInfo));
     s->irq_enabled = 0;
     s->oldclock = 0;
     s->clock = 0;
@@ -464,14 +464,14 @@ static pxa2xx_timer_info *pxa2xx_timer_init(target_phys_addr_t base,
 
 void pxa25x_timer_init(target_phys_addr_t base, DeviceState *pic)
 {
-    pxa2xx_timer_info *s = pxa2xx_timer_init(base, pic);
+    PXA2xxTimerInfo *s = pxa2xx_timer_init(base, pic);
     s->freq = PXA25X_FREQ;
     s->tm4 = NULL;
 }
 
 void pxa27x_timer_init(target_phys_addr_t base, DeviceState *pic)
 {
-    pxa2xx_timer_info *s = pxa2xx_timer_init(base, pic);
+    PXA2xxTimerInfo *s = pxa2xx_timer_init(base, pic);
     int i;
     s->freq = PXA27X_FREQ;
     s->tm4 = (PXA2xxTimer4 *) qemu_mallocz(8 *
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 06/10] pxa2xx_timer: switch to using qdev/vmstate
  2011-02-20 13:50 [Qemu-devel] [PATCH 0/10] pxa2xx: work on switching to qdev/vmstate Dmitry Eremin-Solenikov
                   ` (4 preceding siblings ...)
  2011-02-20 13:50 ` [Qemu-devel] [PATCH 05/10] pxa2xx_timer: change info struct name to comply with guidelines Dmitry Eremin-Solenikov
@ 2011-02-20 13:50 ` Dmitry Eremin-Solenikov
  2011-02-20 13:50 ` [Qemu-devel] [PATCH 07/10] vmstate: move VMSTATE_PCIE_AER_ERRS to hw/hw.h Dmitry Eremin-Solenikov
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Dmitry Eremin-Solenikov @ 2011-02-20 13:50 UTC (permalink / raw)
  To: qemu-devel

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 hw/pxa.h          |    4 -
 hw/pxa2xx.c       |   15 +++-
 hw/pxa2xx_timer.c |  248 ++++++++++++++++++++++++++++++-----------------------
 3 files changed, 155 insertions(+), 112 deletions(-)

diff --git a/hw/pxa.h b/hw/pxa.h
index c2dede2..142f094 100644
--- a/hw/pxa.h
+++ b/hw/pxa.h
@@ -66,10 +66,6 @@
 DeviceState *pxa2xx_pic_init(target_phys_addr_t base, CPUState *env,
         qemu_irq *arm_pic);
 
-/* pxa2xx_timer.c */
-void pxa25x_timer_init(target_phys_addr_t base, DeviceState *pic);
-void pxa27x_timer_init(target_phys_addr_t base, DeviceState *pic);
-
 /* pxa2xx_gpio.c */
 DeviceState *pxa2xx_gpio_init(target_phys_addr_t base,
                 qemu_irq wake_irq, DeviceState *pic, int lines);
diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
index bc9542e..a2604f1 100644
--- a/hw/pxa2xx.c
+++ b/hw/pxa2xx.c
@@ -2104,7 +2104,13 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision)
     s->dma = pxa27x_dma_init(0x40000000,
             qdev_get_gpio_in(s->pic, PXA2XX_PIC_DMA));
 
-    pxa27x_timer_init(0x40a00000, s->pic);
+    sysbus_create_varargs("pxa27x-timer", 0x40a00000,
+            qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 0),
+            qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 1),
+            qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 2),
+            qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 3),
+            qdev_get_gpio_in(s->pic, PXA27X_PIC_OST_4_11),
+            NULL);
 
     s->gpio = pxa2xx_gpio_init(0x40e00000, arm_pic[ARM_PIC_CPU_WAKE],
             s->pic, 121);
@@ -2239,7 +2245,12 @@ PXA2xxState *pxa255_init(unsigned int sdram_size)
     s->dma = pxa255_dma_init(0x40000000,
             qdev_get_gpio_in(s->pic, PXA2XX_PIC_DMA));
 
-    pxa25x_timer_init(0x40a00000, s->pic);
+    sysbus_create_varargs("pxa25x-timer", 0x40a00000,
+            qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 0),
+            qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 1),
+            qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 2),
+            qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 3),
+            NULL);
 
     s->gpio = pxa2xx_gpio_init(0x40e00000, arm_pic[ARM_PIC_CPU_WAKE],
             s->pic, 85);
diff --git a/hw/pxa2xx_timer.c b/hw/pxa2xx_timer.c
index 08141a2..d30c45c 100644
--- a/hw/pxa2xx_timer.c
+++ b/hw/pxa2xx_timer.c
@@ -10,8 +10,8 @@
 #include "hw.h"
 #include "qemu-timer.h"
 #include "sysemu.h"
-#include "qdev.h"
 #include "pxa.h"
+#include "sysbus.h"
 
 #define OSMR0	0x00
 #define OSMR1	0x04
@@ -60,13 +60,14 @@ static int pxa2xx_timer4_freq[8] = {
     [5 ... 7] = 0,
 };
 
+typedef struct PXA2xxTimerInfo PXA2xxTimerInfo;
+
 typedef struct {
     uint32_t value;
     int level;
-    qemu_irq irq;
     QEMUTimer *qtimer;
     int num;
-    void *info;
+    PXA2xxTimerInfo *info;
 } PXA2xxTimer0;
 
 typedef struct {
@@ -78,18 +79,31 @@ typedef struct {
     uint32_t control;
 } PXA2xxTimer4;
 
-typedef struct {
+struct PXA2xxTimerInfo {
+    SysBusDevice busdev;
+    uint32_t flags;
+
     int32_t clock;
     int32_t oldclock;
     uint64_t lastload;
     uint32_t freq;
     PXA2xxTimer0 timer[4];
-    PXA2xxTimer4 *tm4;
+    qemu_irq irqs[5];
     uint32_t events;
     uint32_t irq_enabled;
     uint32_t reset3;
     uint32_t snapshot;
-} PXA2xxTimerInfo;
+
+    PXA2xxTimer4 tm4[8];
+    qemu_irq irq4;
+};
+
+#define PXA2XX_TIMER_HAVE_TM4   0
+
+static bool pxa2xx_timer_has_tm4(PXA2xxTimerInfo *s)
+{
+    return !!(s->flags & (1 << PXA2XX_TIMER_HAVE_TM4));
+}
 
 static void pxa2xx_timer_update(void *opaque, uint64_t now_qemu)
 {
@@ -101,7 +115,7 @@ static void pxa2xx_timer_update(void *opaque, uint64_t now_qemu)
     now_vm = s->clock +
             muldiv64(now_qemu - s->lastload, s->freq, get_ticks_per_sec());
 
-    for (i = 0; i < 4; i ++) {
+    for (i = 0; i < 4; i++) {
         new_qemu = now_qemu + muldiv64((uint32_t) (s->timer[i].value - now_vm),
                         get_ticks_per_sec(), s->freq);
         qemu_mod_timer(s->timer[i].qtimer, new_qemu);
@@ -154,7 +168,7 @@ static uint32_t pxa2xx_timer_read(void *opaque, target_phys_addr_t offset)
     case OSMR6:  tm ++;
     case OSMR5:  tm ++;
     case OSMR4:
-        if (!s->tm4)
+        if (!pxa2xx_timer_has_tm4(s))
             goto badreg;
         return s->tm4[tm].tm.value;
     case OSCR:
@@ -168,7 +182,7 @@ static uint32_t pxa2xx_timer_read(void *opaque, target_phys_addr_t offset)
     case OSCR6:  tm ++;
     case OSCR5:  tm ++;
     case OSCR4:
-        if (!s->tm4)
+        if (!pxa2xx_timer_has_tm4(s))
             goto badreg;
 
         if ((tm == 9 - 4 || tm == 11 - 4) && (s->tm4[tm].control & (1 << 9))) {
@@ -184,7 +198,8 @@ static uint32_t pxa2xx_timer_read(void *opaque, target_phys_addr_t offset)
         if (!s->tm4[tm].freq)
             return s->tm4[tm].clock;
         return s->tm4[tm].clock + muldiv64(qemu_get_clock(vm_clock) -
-                        s->tm4[tm].lastload, s->tm4[tm].freq, get_ticks_per_sec());
+                        s->tm4[tm].lastload, s->tm4[tm].freq,
+                        get_ticks_per_sec());
     case OIER:
         return s->irq_enabled;
     case OSSR:	/* Status register */
@@ -199,7 +214,7 @@ static uint32_t pxa2xx_timer_read(void *opaque, target_phys_addr_t offset)
     case OMCR6:  tm ++;
     case OMCR5:  tm ++;
     case OMCR4:
-        if (!s->tm4)
+        if (!pxa2xx_timer_has_tm4(s))
             goto badreg;
         return s->tm4[tm].control;
     case OSNR:
@@ -217,7 +232,6 @@ static void pxa2xx_timer_write(void *opaque, target_phys_addr_t offset,
 {
     int i, tm = 0;
     PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
-
     switch (offset) {
     case OSMR3:  tm ++;
     case OSMR2:  tm ++;
@@ -234,7 +248,7 @@ static void pxa2xx_timer_write(void *opaque, target_phys_addr_t offset,
     case OSMR6:  tm ++;
     case OSMR5:  tm ++;
     case OSMR4:
-        if (!s->tm4)
+        if (!pxa2xx_timer_has_tm4(s))
             goto badreg;
         s->tm4[tm].tm.value = value;
         pxa2xx_timer_update4(s, qemu_get_clock(vm_clock), tm);
@@ -253,7 +267,7 @@ static void pxa2xx_timer_write(void *opaque, target_phys_addr_t offset,
     case OSCR6:  tm ++;
     case OSCR5:  tm ++;
     case OSCR4:
-        if (!s->tm4)
+        if (!pxa2xx_timer_has_tm4(s))
             goto badreg;
         s->tm4[tm].oldclock = s->tm4[tm].clock;
         s->tm4[tm].lastload = qemu_get_clock(vm_clock);
@@ -268,15 +282,15 @@ static void pxa2xx_timer_write(void *opaque, target_phys_addr_t offset,
         for (i = 0; i < 4; i ++, value >>= 1) {
             if (s->timer[i].level && (value & 1)) {
                 s->timer[i].level = 0;
-                qemu_irq_lower(s->timer[i].irq);
+                qemu_irq_lower(s->irqs[i]);
             }
         }
-        if (s->tm4) {
+        if (pxa2xx_timer_has_tm4(s)) {
             for (i = 0; i < 8; i ++, value >>= 1)
                 if (s->tm4[i].tm.level && (value & 1))
                     s->tm4[i].tm.level = 0;
             if (!(s->events & 0xff0))
-                qemu_irq_lower(s->tm4->tm.irq);
+                qemu_irq_lower(s->irq4);
         }
         break;
     case OWER:	/* XXX: Reset on OSMR3 match? */
@@ -286,7 +300,7 @@ static void pxa2xx_timer_write(void *opaque, target_phys_addr_t offset,
     case OMCR6:  tm ++;
     case OMCR5:  tm ++;
     case OMCR4:
-        if (!s->tm4)
+        if (!pxa2xx_timer_has_tm4(s))
             goto badreg;
         s->tm4[tm].control = value & 0x0ff;
         /* XXX Stop if running (shouldn't happen) */
@@ -301,7 +315,7 @@ static void pxa2xx_timer_write(void *opaque, target_phys_addr_t offset,
     case OMCR10: tm ++;
     case OMCR9:  tm ++;
     case OMCR8:  tm += 4;
-        if (!s->tm4)
+        if (!pxa2xx_timer_has_tm4(s))
             goto badreg;
         s->tm4[tm].control = value & 0x3ff;
         /* XXX Stop if running (shouldn't happen) */
@@ -334,12 +348,12 @@ static CPUWriteMemoryFunc * const pxa2xx_timer_writefn[] = {
 static void pxa2xx_timer_tick(void *opaque)
 {
     PXA2xxTimer0 *t = (PXA2xxTimer0 *) opaque;
-    PXA2xxTimerInfo *i = (PXA2xxTimerInfo *) t->info;
+    PXA2xxTimerInfo *i = t->info;
 
     if (i->irq_enabled & (1 << t->num)) {
         t->level = 1;
         i->events |= 1 << t->num;
-        qemu_irq_raise(t->irq);
+        qemu_irq_raise(t->num < 4 ? i->irqs[t->num] : i->irq4);
     }
 
     if (t->num == 3)
@@ -361,130 +375,152 @@ static void pxa2xx_timer_tick4(void *opaque)
         pxa2xx_timer_update4(i, qemu_get_clock(vm_clock), t->tm.num - 4);
 }
 
-static void pxa2xx_timer_save(QEMUFile *f, void *opaque)
-{
-    PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
-    int i;
-
-    qemu_put_be32s(f, (uint32_t *) &s->clock);
-    qemu_put_be32s(f, (uint32_t *) &s->oldclock);
-    qemu_put_be64s(f, &s->lastload);
-
-    for (i = 0; i < 4; i ++) {
-        qemu_put_be32s(f, &s->timer[i].value);
-        qemu_put_be32(f, s->timer[i].level);
-    }
-    if (s->tm4)
-        for (i = 0; i < 8; i ++) {
-            qemu_put_be32s(f, &s->tm4[i].tm.value);
-            qemu_put_be32(f, s->tm4[i].tm.level);
-            qemu_put_sbe32s(f, &s->tm4[i].oldclock);
-            qemu_put_sbe32s(f, &s->tm4[i].clock);
-            qemu_put_be64s(f, &s->tm4[i].lastload);
-            qemu_put_be32s(f, &s->tm4[i].freq);
-            qemu_put_be32s(f, &s->tm4[i].control);
-        }
-
-    qemu_put_be32s(f, &s->events);
-    qemu_put_be32s(f, &s->irq_enabled);
-    qemu_put_be32s(f, &s->reset3);
-    qemu_put_be32s(f, &s->snapshot);
-}
-
-static int pxa2xx_timer_load(QEMUFile *f, void *opaque, int version_id)
+static int pxa25x_timer_post_load(void *opaque, int version_id)
 {
     PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
     int64_t now;
     int i;
 
-    qemu_get_be32s(f, (uint32_t *) &s->clock);
-    qemu_get_be32s(f, (uint32_t *) &s->oldclock);
-    qemu_get_be64s(f, &s->lastload);
-
     now = qemu_get_clock(vm_clock);
-    for (i = 0; i < 4; i ++) {
-        qemu_get_be32s(f, &s->timer[i].value);
-        s->timer[i].level = qemu_get_be32(f);
-    }
     pxa2xx_timer_update(s, now);
 
-    if (s->tm4)
-        for (i = 0; i < 8; i ++) {
-            qemu_get_be32s(f, &s->tm4[i].tm.value);
-            s->tm4[i].tm.level = qemu_get_be32(f);
-            qemu_get_sbe32s(f, &s->tm4[i].oldclock);
-            qemu_get_sbe32s(f, &s->tm4[i].clock);
-            qemu_get_be64s(f, &s->tm4[i].lastload);
-            qemu_get_be32s(f, &s->tm4[i].freq);
-            qemu_get_be32s(f, &s->tm4[i].control);
+    if (pxa2xx_timer_has_tm4(s))
+        for (i = 0; i < 8; i++) {
             pxa2xx_timer_update4(s, now, i);
         }
 
-    qemu_get_be32s(f, &s->events);
-    qemu_get_be32s(f, &s->irq_enabled);
-    qemu_get_be32s(f, &s->reset3);
-    qemu_get_be32s(f, &s->snapshot);
-
     return 0;
 }
 
-static PXA2xxTimerInfo *pxa2xx_timer_init(target_phys_addr_t base,
-                DeviceState *pic)
+static int pxa2xx_timer_init(SysBusDevice *dev)
 {
     int i;
     int iomemtype;
     PXA2xxTimerInfo *s;
 
-    s = (PXA2xxTimerInfo *) qemu_mallocz(sizeof(PXA2xxTimerInfo));
+    s = FROM_SYSBUS(PXA2xxTimerInfo, dev);
     s->irq_enabled = 0;
     s->oldclock = 0;
     s->clock = 0;
     s->lastload = qemu_get_clock(vm_clock);
     s->reset3 = 0;
 
-    for (i = 0; i < 4; i ++) {
+    for (i = 0; i < 4; i++) {
         s->timer[i].value = 0;
-        s->timer[i].irq = qdev_get_gpio_in(pic, PXA2XX_PIC_OST_0 + i);
+        sysbus_init_irq(dev, &s->irqs[i]);
         s->timer[i].info = s;
         s->timer[i].num = i;
         s->timer[i].level = 0;
         s->timer[i].qtimer = qemu_new_timer(vm_clock,
                         pxa2xx_timer_tick, &s->timer[i]);
     }
+    if (s->flags & (1 << PXA2XX_TIMER_HAVE_TM4)) {
+        sysbus_init_irq(dev, &s->irq4);
+
+        for (i = 0; i < 8; i++) {
+            s->tm4[i].tm.value = 0;
+            s->tm4[i].tm.info = s;
+            s->tm4[i].tm.num = i + 4;
+            s->tm4[i].tm.level = 0;
+            s->tm4[i].freq = 0;
+            s->tm4[i].control = 0x0;
+            s->tm4[i].tm.qtimer = qemu_new_timer(vm_clock,
+                        pxa2xx_timer_tick4, &s->tm4[i]);
+        }
+    }
 
     iomemtype = cpu_register_io_memory(pxa2xx_timer_readfn,
                     pxa2xx_timer_writefn, s, DEVICE_NATIVE_ENDIAN);
-    cpu_register_physical_memory(base, 0x00001000, iomemtype);
-
-    register_savevm(NULL, "pxa2xx_timer", 0, 0,
-                    pxa2xx_timer_save, pxa2xx_timer_load, s);
+    sysbus_init_mmio(dev, 0x00001000, iomemtype);
 
-    return s;
+    return 0;
 }
 
-void pxa25x_timer_init(target_phys_addr_t base, DeviceState *pic)
+static const VMStateDescription vmstate_pxa2xx_timer0_regs = {
+    .name = "pxa2xx_timer0",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(value, PXA2xxTimer0),
+        VMSTATE_INT32(level, PXA2xxTimer0),
+        VMSTATE_END_OF_LIST(),
+    },
+};
+
+static const VMStateDescription vmstate_pxa2xx_timer4_regs = {
+    .name = "pxa2xx_timer4",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_STRUCT(tm, PXA2xxTimer4, 1, vmstate_pxa2xx_timer0_regs, PXA2xxTimer0),
+        VMSTATE_INT32(oldclock, PXA2xxTimer4),
+        VMSTATE_INT32(clock, PXA2xxTimer4),
+        VMSTATE_UINT64(lastload, PXA2xxTimer4),
+        VMSTATE_UINT32(freq, PXA2xxTimer4),
+        VMSTATE_UINT32(control, PXA2xxTimer4),
+        VMSTATE_END_OF_LIST(),
+    },
+};
+
+static bool pxa2xx_timer_has_tm4_test(void *opaque, int version_id)
 {
-    PXA2xxTimerInfo *s = pxa2xx_timer_init(base, pic);
-    s->freq = PXA25X_FREQ;
-    s->tm4 = NULL;
+    return pxa2xx_timer_has_tm4(opaque);
 }
 
-void pxa27x_timer_init(target_phys_addr_t base, DeviceState *pic)
-{
-    PXA2xxTimerInfo *s = pxa2xx_timer_init(base, pic);
-    int i;
-    s->freq = PXA27X_FREQ;
-    s->tm4 = (PXA2xxTimer4 *) qemu_mallocz(8 *
-                    sizeof(PXA2xxTimer4));
-    for (i = 0; i < 8; i ++) {
-        s->tm4[i].tm.value = 0;
-        s->tm4[i].tm.irq = qdev_get_gpio_in(pic, PXA27X_PIC_OST_4_11);
-        s->tm4[i].tm.info = s;
-        s->tm4[i].tm.num = i + 4;
-        s->tm4[i].tm.level = 0;
-        s->tm4[i].freq = 0;
-        s->tm4[i].control = 0x0;
-        s->tm4[i].tm.qtimer = qemu_new_timer(vm_clock,
-                        pxa2xx_timer_tick4, &s->tm4[i]);
+static const VMStateDescription vmstate_pxa2xx_timer_regs = {
+    .name = "pxa2xx_timer",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .post_load = pxa25x_timer_post_load,
+    .fields = (VMStateField[]) {
+        VMSTATE_INT32(clock, PXA2xxTimerInfo),
+        VMSTATE_INT32(oldclock, PXA2xxTimerInfo),
+        VMSTATE_UINT64(lastload, PXA2xxTimerInfo),
+        VMSTATE_STRUCT_ARRAY(timer, PXA2xxTimerInfo, 4, 1,
+                    vmstate_pxa2xx_timer0_regs, PXA2xxTimer0),
+        VMSTATE_UINT32(events, PXA2xxTimerInfo),
+        VMSTATE_UINT32(irq_enabled, PXA2xxTimerInfo),
+        VMSTATE_UINT32(reset3, PXA2xxTimerInfo),
+        VMSTATE_UINT32(snapshot, PXA2xxTimerInfo),
+        VMSTATE_STRUCT_ARRAY_TEST(tm4, PXA2xxTimerInfo, 8,
+                    pxa2xx_timer_has_tm4_test, 0,
+                    vmstate_pxa2xx_timer4_regs, PXA2xxTimer4),
+        VMSTATE_END_OF_LIST(),
     }
-}
+};
+
+static SysBusDeviceInfo pxa25x_timer_dev_info = {
+    .init       = pxa2xx_timer_init,
+    .qdev.name  = "pxa25x-timer",
+    .qdev.desc  = "PXA25x timer",
+    .qdev.size  = sizeof(PXA2xxTimerInfo),
+    .qdev.vmsd  = &vmstate_pxa2xx_timer_regs,
+    .qdev.props = (Property[]) {
+        DEFINE_PROP_UINT32("freq", PXA2xxTimerInfo, freq, PXA25X_FREQ),
+        DEFINE_PROP_BIT("tm4", PXA2xxTimerInfo, flags, PXA2XX_TIMER_HAVE_TM4, false),
+        DEFINE_PROP_END_OF_LIST(),
+    },
+};
+
+static SysBusDeviceInfo pxa27x_timer_dev_info = {
+    .init       = pxa2xx_timer_init,
+    .qdev.name  = "pxa27x-timer",
+    .qdev.desc  = "PXA27x timer",
+    .qdev.size  = sizeof(PXA2xxTimerInfo),
+    .qdev.vmsd  = &vmstate_pxa2xx_timer_regs,
+    .qdev.props = (Property[]) {
+        DEFINE_PROP_UINT32("freq", PXA2xxTimerInfo, freq, PXA27X_FREQ),
+        DEFINE_PROP_BIT("tm4", PXA2xxTimerInfo, flags, PXA2XX_TIMER_HAVE_TM4, true),
+        DEFINE_PROP_END_OF_LIST(),
+    },
+};
+
+static void pxa2xx_timer_register(void)
+{
+    sysbus_register_withprop(&pxa25x_timer_dev_info);
+    sysbus_register_withprop(&pxa27x_timer_dev_info);
+};
+device_init(pxa2xx_timer_register);
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 07/10] vmstate: move VMSTATE_PCIE_AER_ERRS to hw/hw.h
  2011-02-20 13:50 [Qemu-devel] [PATCH 0/10] pxa2xx: work on switching to qdev/vmstate Dmitry Eremin-Solenikov
                   ` (5 preceding siblings ...)
  2011-02-20 13:50 ` [Qemu-devel] [PATCH 06/10] pxa2xx_timer: switch to using qdev/vmstate Dmitry Eremin-Solenikov
@ 2011-02-20 13:50 ` Dmitry Eremin-Solenikov
  2011-02-20 13:50 ` [Qemu-devel] [PATCH 08/10] pxa2xx_dma: drop unused pxa2xx_dma_handler_t/handler field Dmitry Eremin-Solenikov
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 14+ messages in thread
From: Dmitry Eremin-Solenikov @ 2011-02-20 13:50 UTC (permalink / raw)
  To: qemu-devel

VMSTATE_PCIE_AER_ERRS is indeed useful for other emulation drivers.
Move it to hw/hw.h under the name of VMSTATE_STRUCT_VARRAY_POINTER_UINT16.
Also add VMSTATE_STRUCT_VARRAY_POINTER_INT32 which is more or less
the same as _UINT16 macro, except the fact it uses int32_t internally.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 hw/hw.h       |   21 +++++++++++++++++++++
 hw/pcie_aer.c |   12 +-----------
 2 files changed, 22 insertions(+), 11 deletions(-)

diff --git a/hw/hw.h b/hw/hw.h
index b47a7c8..eec9c6b 100644
--- a/hw/hw.h
+++ b/hw/hw.h
@@ -499,6 +499,27 @@ extern const VMStateInfo vmstate_info_unused_buffer;
     .offset     = offsetof(_state, _field),                          \
 }
 
+#define VMSTATE_STRUCT_VARRAY_POINTER_INT32(_field, _state, _field_num, _vmsd, _type) { \
+    .name       = (stringify(_field)),                                    \
+    .version_id = 0,                                                      \
+    .num_offset = vmstate_offset_value(_state, _field_num, int32_t),     \
+    .size       = sizeof(_type),                                          \
+    .vmsd       = &(_vmsd),                                               \
+    .flags      = VMS_POINTER | VMS_VARRAY_INT32 | VMS_STRUCT,           \
+    .offset     = vmstate_offset_pointer(_state, _field, _type),          \
+}
+
+#define VMSTATE_STRUCT_VARRAY_POINTER_UINT16(_field, _state, _field_num, _vmsd, _type) { \
+    .name       = (stringify(_field)),                                    \
+    .version_id = 0,                                                      \
+    .num_offset = vmstate_offset_value(_state, _field_num, uint16_t),     \
+    .size       = sizeof(_type),                                          \
+    .vmsd       = &(_vmsd),                                               \
+    .flags      = VMS_POINTER | VMS_VARRAY_UINT16 | VMS_STRUCT,           \
+    .offset     = vmstate_offset_pointer(_state, _field, _type),          \
+}
+
+
 #define VMSTATE_STATIC_BUFFER(_field, _state, _version, _test, _start, _size) { \
     .name         = (stringify(_field)),                             \
     .version_id   = (_version),                                      \
diff --git a/hw/pcie_aer.c b/hw/pcie_aer.c
index 6e653dd..0c4e8a5 100644
--- a/hw/pcie_aer.c
+++ b/hw/pcie_aer.c
@@ -785,16 +785,6 @@ static const VMStateDescription vmstate_pcie_aer_err = {
     }
 };
 
-#define VMSTATE_PCIE_AER_ERRS(_field, _state, _field_num, _vmsd, _type) { \
-    .name       = (stringify(_field)),                                    \
-    .version_id = 0,                                                      \
-    .num_offset = vmstate_offset_value(_state, _field_num, uint16_t),     \
-    .size       = sizeof(_type),                                          \
-    .vmsd       = &(_vmsd),                                               \
-    .flags      = VMS_POINTER | VMS_VARRAY_UINT16 | VMS_STRUCT,           \
-    .offset     = vmstate_offset_pointer(_state, _field, _type),          \
-}
-
 const VMStateDescription vmstate_pcie_aer_log = {
     .name = "PCIE_AER_ERROR_LOG",
     .version_id = 1,
@@ -803,7 +793,7 @@ const VMStateDescription vmstate_pcie_aer_log = {
     .fields     = (VMStateField[]) {
         VMSTATE_UINT16(log_num, PCIEAERLog),
         VMSTATE_UINT16(log_max, PCIEAERLog),
-        VMSTATE_PCIE_AER_ERRS(log, PCIEAERLog, log_num,
+        VMSTATE_STRUCT_VARRAY_POINTER_UINT16(log, PCIEAERLog, log_num,
                               vmstate_pcie_aer_err, PCIEAERErr),
         VMSTATE_END_OF_LIST()
     }
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 08/10] pxa2xx_dma: drop unused pxa2xx_dma_handler_t/handler field
  2011-02-20 13:50 [Qemu-devel] [PATCH 0/10] pxa2xx: work on switching to qdev/vmstate Dmitry Eremin-Solenikov
                   ` (6 preceding siblings ...)
  2011-02-20 13:50 ` [Qemu-devel] [PATCH 07/10] vmstate: move VMSTATE_PCIE_AER_ERRS to hw/hw.h Dmitry Eremin-Solenikov
@ 2011-02-20 13:50 ` Dmitry Eremin-Solenikov
  2011-02-20 13:50 ` [Qemu-devel] [PATCH 09/10] pxa2xx_dma: port to qdev/vmstate Dmitry Eremin-Solenikov
  2011-02-20 13:50 ` [Qemu-devel] [PATCH 10/10] pxa2xx: port pxa2xx_rtc to using qdev/vmstate Dmitry Eremin-Solenikov
  9 siblings, 0 replies; 14+ messages in thread
From: Dmitry Eremin-Solenikov @ 2011-02-20 13:50 UTC (permalink / raw)
  To: qemu-devel

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 hw/pxa2xx_dma.c |    5 -----
 1 files changed, 0 insertions(+), 5 deletions(-)

diff --git a/hw/pxa2xx_dma.c b/hw/pxa2xx_dma.c
index b512d34..92c3e1e 100644
--- a/hw/pxa2xx_dma.c
+++ b/hw/pxa2xx_dma.c
@@ -20,11 +20,7 @@ typedef struct {
     int request;
 } PXA2xxDMAChannel;
 
-/* Allow the DMA to be used as a PIC.  */
-typedef void (*pxa2xx_dma_handler_t)(void *opaque, int irq, int level);
-
 struct PXA2xxDMAState {
-    pxa2xx_dma_handler_t handler;
     qemu_irq irq;
 
     uint32_t stopintr;
@@ -494,7 +490,6 @@ static PXA2xxDMAState *pxa2xx_dma_init(target_phys_addr_t base,
     s->channels = channels;
     s->chan = qemu_mallocz(sizeof(PXA2xxDMAChannel) * s->channels);
     s->irq = irq;
-    s->handler = (pxa2xx_dma_handler_t) pxa2xx_dma_request;
     s->req = qemu_mallocz(sizeof(uint8_t) * PXA2XX_DMA_NUM_REQUESTS);
 
     memset(s->chan, 0, sizeof(PXA2xxDMAChannel) * s->channels);
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 09/10] pxa2xx_dma: port to qdev/vmstate
  2011-02-20 13:50 [Qemu-devel] [PATCH 0/10] pxa2xx: work on switching to qdev/vmstate Dmitry Eremin-Solenikov
                   ` (7 preceding siblings ...)
  2011-02-20 13:50 ` [Qemu-devel] [PATCH 08/10] pxa2xx_dma: drop unused pxa2xx_dma_handler_t/handler field Dmitry Eremin-Solenikov
@ 2011-02-20 13:50 ` Dmitry Eremin-Solenikov
  2011-02-20 13:50 ` [Qemu-devel] [PATCH 10/10] pxa2xx: port pxa2xx_rtc to using qdev/vmstate Dmitry Eremin-Solenikov
  9 siblings, 0 replies; 14+ messages in thread
From: Dmitry Eremin-Solenikov @ 2011-02-20 13:50 UTC (permalink / raw)
  To: qemu-devel

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 hw/pxa.h         |   14 ++--
 hw/pxa2xx.c      |   43 ++++++++-----
 hw/pxa2xx_dma.c  |  184 +++++++++++++++++++++++++++++++-----------------------
 hw/pxa2xx_mmci.c |   16 +++--
 4 files changed, 150 insertions(+), 107 deletions(-)

diff --git a/hw/pxa.h b/hw/pxa.h
index 142f094..bad0556 100644
--- a/hw/pxa.h
+++ b/hw/pxa.h
@@ -72,12 +72,10 @@ DeviceState *pxa2xx_gpio_init(target_phys_addr_t base,
 void pxa2xx_gpio_read_notifier(DeviceState *dev, qemu_irq handler);
 
 /* pxa2xx_dma.c */
-typedef struct PXA2xxDMAState PXA2xxDMAState;
-PXA2xxDMAState *pxa255_dma_init(target_phys_addr_t base,
+DeviceState *pxa255_dma_init(target_phys_addr_t base,
                 qemu_irq irq);
-PXA2xxDMAState *pxa27x_dma_init(target_phys_addr_t base,
+DeviceState *pxa27x_dma_init(target_phys_addr_t base,
                 qemu_irq irq);
-void pxa2xx_dma_request(PXA2xxDMAState *s, int req_num, int on);
 
 /* pxa2xx_lcd.c */
 typedef struct PXA2xxLCDState PXA2xxLCDState;
@@ -89,7 +87,8 @@ void pxa2xx_lcdc_oritentation(void *opaque, int angle);
 /* pxa2xx_mmci.c */
 typedef struct PXA2xxMMCIState PXA2xxMMCIState;
 PXA2xxMMCIState *pxa2xx_mmci_init(target_phys_addr_t base,
-                BlockDriverState *bd, qemu_irq irq, void *dma);
+                BlockDriverState *bd, qemu_irq irq,
+                qemu_irq rx_dma, qemu_irq tx_dma);
 void pxa2xx_mmci_handlers(PXA2xxMMCIState *s, qemu_irq readonly,
                 qemu_irq coverswitch);
 
@@ -124,7 +123,7 @@ typedef struct {
     CPUState *env;
     DeviceState *pic;
     qemu_irq reset;
-    PXA2xxDMAState *dma;
+    DeviceState *dma;
     DeviceState *gpio;
     PXA2xxLCDState *lcd;
     SSIBus **ssp;
@@ -182,7 +181,8 @@ typedef struct {
 
 struct PXA2xxI2SState {
     qemu_irq irq;
-    PXA2xxDMAState *dma;
+    qemu_irq rx_dma;
+    qemu_irq tx_dma;
     void (*data_req)(void *, int, int);
 
     uint32_t control[2];
diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
index a2604f1..f9ada1c 100644
--- a/hw/pxa2xx.c
+++ b/hw/pxa2xx.c
@@ -1586,8 +1586,8 @@ static inline void pxa2xx_i2s_update(PXA2xxI2SState *i2s)
     tfs = (i2s->tx_len || i2s->fifo_len < SACR_TFTH(i2s->control[0])) &&
             i2s->enable && !SACR_DPRL(i2s->control[1]);
 
-    pxa2xx_dma_request(i2s->dma, PXA2XX_RX_RQ_I2S, rfs);
-    pxa2xx_dma_request(i2s->dma, PXA2XX_TX_RQ_I2S, tfs);
+    qemu_set_irq(i2s->rx_dma, rfs);
+    qemu_set_irq(i2s->tx_dma, tfs);
 
     i2s->status &= 0xe0;
     if (i2s->fifo_len < 16 || !i2s->enable)
@@ -1770,14 +1770,15 @@ static void pxa2xx_i2s_data_req(void *opaque, int tx, int rx)
 }
 
 static PXA2xxI2SState *pxa2xx_i2s_init(target_phys_addr_t base,
-                qemu_irq irq, PXA2xxDMAState *dma)
+                qemu_irq irq, qemu_irq rx_dma, qemu_irq tx_dma)
 {
     int iomemtype;
     PXA2xxI2SState *s = (PXA2xxI2SState *)
             qemu_mallocz(sizeof(PXA2xxI2SState));
 
     s->irq = irq;
-    s->dma = dma;
+    s->rx_dma = rx_dma;
+    s->tx_dma = tx_dma;
     s->data_req = pxa2xx_i2s_data_req;
 
     pxa2xx_i2s_reset(s);
@@ -1795,7 +1796,8 @@ static PXA2xxI2SState *pxa2xx_i2s_init(target_phys_addr_t base,
 /* PXA Fast Infra-red Communications Port */
 struct PXA2xxFIrState {
     qemu_irq irq;
-    PXA2xxDMAState *dma;
+    qemu_irq rx_dma;
+    qemu_irq tx_dma;
     int enable;
     CharDriverState *chr;
 
@@ -1849,8 +1851,8 @@ static inline void pxa2xx_fir_update(PXA2xxFIrState *s)
             (s->status[0] & (1 << 1));			/* TUR */
     intr |= s->status[0] & 0x25;			/* FRE, RAB, EIF */
 
-    pxa2xx_dma_request(s->dma, PXA2XX_RX_RQ_ICP, (s->status[0] >> 4) & 1);
-    pxa2xx_dma_request(s->dma, PXA2XX_TX_RQ_ICP, (s->status[0] >> 3) & 1);
+    qemu_set_irq(s->rx_dma, (s->status[0] >> 4) & 1);
+    qemu_set_irq(s->tx_dma, (s->status[0] >> 3) & 1);
 
     qemu_set_irq(s->irq, intr && s->enable);
 }
@@ -2029,7 +2031,7 @@ static int pxa2xx_fir_load(QEMUFile *f, void *opaque, int version_id)
 }
 
 static PXA2xxFIrState *pxa2xx_fir_init(target_phys_addr_t base,
-                qemu_irq irq, PXA2xxDMAState *dma,
+                qemu_irq irq, qemu_irq rx_dma, qemu_irq tx_dma,
                 CharDriverState *chr)
 {
     int iomemtype;
@@ -2037,7 +2039,8 @@ static PXA2xxFIrState *pxa2xx_fir_init(target_phys_addr_t base,
             qemu_mallocz(sizeof(PXA2xxFIrState));
 
     s->irq = irq;
-    s->dma = dma;
+    s->rx_dma = rx_dma;
+    s->tx_dma = tx_dma;
     s->chr = chr;
 
     pxa2xx_fir_reset(s);
@@ -2121,7 +2124,9 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision)
         exit(1);
     }
     s->mmc = pxa2xx_mmci_init(0x41100000, dinfo->bdrv,
-                              qdev_get_gpio_in(s->pic, PXA2XX_PIC_MMC), s->dma);
+                              qdev_get_gpio_in(s->pic, PXA2XX_PIC_MMC),
+                              qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_MMCI),
+                              qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_MMCI));
 
     for (i = 0; pxa270_serial[i].io_base; i ++)
         if (serial_hds[i])
@@ -2141,7 +2146,9 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision)
     if (serial_hds[i])
         s->fir = pxa2xx_fir_init(0x40800000,
                         qdev_get_gpio_in(s->pic, PXA2XX_PIC_ICP),
-                        s->dma, serial_hds[i]);
+                        qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_ICP),
+                        qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_ICP),
+                        serial_hds[i]);
 
     s->lcd = pxa2xx_lcdc_init(0x44000000,
                         qdev_get_gpio_in(s->pic, PXA2XX_PIC_LCD));
@@ -2203,7 +2210,8 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision)
 
     s->i2s = pxa2xx_i2s_init(0x40400000,
             qdev_get_gpio_in(s->pic, PXA2XX_PIC_I2S),
-            s->dma);
+            qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_I2S),
+            qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_I2S));
 
     s->kp = pxa27x_keypad_init(0x41500000,
             qdev_get_gpio_in(s->pic, PXA2XX_PIC_KEYPAD));
@@ -2261,7 +2269,9 @@ PXA2xxState *pxa255_init(unsigned int sdram_size)
         exit(1);
     }
     s->mmc = pxa2xx_mmci_init(0x41100000, dinfo->bdrv,
-                              qdev_get_gpio_in(s->pic, PXA2XX_PIC_MMC), s->dma);
+                              qdev_get_gpio_in(s->pic, PXA2XX_PIC_MMC),
+                              qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_MMCI),
+                              qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_MMCI));
 
     for (i = 0; pxa255_serial[i].io_base; i ++)
         if (serial_hds[i]) {
@@ -2282,7 +2292,9 @@ PXA2xxState *pxa255_init(unsigned int sdram_size)
     if (serial_hds[i])
         s->fir = pxa2xx_fir_init(0x40800000,
                         qdev_get_gpio_in(s->pic, PXA2XX_PIC_ICP),
-                        s->dma, serial_hds[i]);
+                        qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_ICP),
+                        qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_ICP),
+                        serial_hds[i]);
 
     s->lcd = pxa2xx_lcdc_init(0x44000000,
             qdev_get_gpio_in(s->pic, PXA2XX_PIC_LCD));
@@ -2344,7 +2356,8 @@ PXA2xxState *pxa255_init(unsigned int sdram_size)
 
     s->i2s = pxa2xx_i2s_init(0x40400000,
             qdev_get_gpio_in(s->pic, PXA2XX_PIC_I2S),
-            s->dma);
+            qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_I2S),
+            qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_I2S));
 
     /* GPIO1 resets the processor */
     /* The handler can be overridden by board-specific code */
diff --git a/hw/pxa2xx_dma.c b/hw/pxa2xx_dma.c
index 92c3e1e..4e03472 100644
--- a/hw/pxa2xx_dma.c
+++ b/hw/pxa2xx_dma.c
@@ -10,6 +10,12 @@
 
 #include "hw.h"
 #include "pxa.h"
+#include "sysbus.h"
+
+#define PXA255_DMA_NUM_CHANNELS 16
+#define PXA27X_DMA_NUM_CHANNELS 32
+
+#define PXA2XX_DMA_NUM_REQUESTS 75
 
 typedef struct {
     target_phys_addr_t descr;
@@ -20,7 +26,8 @@ typedef struct {
     int request;
 } PXA2xxDMAChannel;
 
-struct PXA2xxDMAState {
+typedef struct PXA2xxDMAState {
+    SysBusDevice busdev;
     qemu_irq irq;
 
     uint32_t stopintr;
@@ -35,16 +42,11 @@ struct PXA2xxDMAState {
     int channels;
     PXA2xxDMAChannel *chan;
 
-    uint8_t *req;
+    uint8_t req[PXA2XX_DMA_NUM_REQUESTS];
 
     /* Flag to avoid recursive DMA invocations.  */
     int running;
-};
-
-#define PXA255_DMA_NUM_CHANNELS	16
-#define PXA27X_DMA_NUM_CHANNELS	32
-
-#define PXA2XX_DMA_NUM_REQUESTS	75
+} PXA2xxDMAState;
 
 #define DCSR0	0x0000	/* DMA Control / Status register for Channel 0 */
 #define DCSR31	0x007c	/* DMA Control / Status register for Channel 31 */
@@ -424,73 +426,19 @@ static CPUWriteMemoryFunc * const pxa2xx_dma_writefn[] = {
     pxa2xx_dma_write
 };
 
-static void pxa2xx_dma_save(QEMUFile *f, void *opaque)
-{
-    PXA2xxDMAState *s = (PXA2xxDMAState *) opaque;
-    int i;
-
-    qemu_put_be32(f, s->channels);
-
-    qemu_put_be32s(f, &s->stopintr);
-    qemu_put_be32s(f, &s->eorintr);
-    qemu_put_be32s(f, &s->rasintr);
-    qemu_put_be32s(f, &s->startintr);
-    qemu_put_be32s(f, &s->endintr);
-    qemu_put_be32s(f, &s->align);
-    qemu_put_be32s(f, &s->pio);
-
-    qemu_put_buffer(f, s->req, PXA2XX_DMA_NUM_REQUESTS);
-    for (i = 0; i < s->channels; i ++) {
-        qemu_put_betl(f, s->chan[i].descr);
-        qemu_put_betl(f, s->chan[i].src);
-        qemu_put_betl(f, s->chan[i].dest);
-        qemu_put_be32s(f, &s->chan[i].cmd);
-        qemu_put_be32s(f, &s->chan[i].state);
-        qemu_put_be32(f, s->chan[i].request);
-    };
-}
+static void pxa2xx_dma_request(void *opaque, int req_num, int on);
 
-static int pxa2xx_dma_load(QEMUFile *f, void *opaque, int version_id)
-{
-    PXA2xxDMAState *s = (PXA2xxDMAState *) opaque;
-    int i;
-
-    if (qemu_get_be32(f) != s->channels)
-        return -EINVAL;
-
-    qemu_get_be32s(f, &s->stopintr);
-    qemu_get_be32s(f, &s->eorintr);
-    qemu_get_be32s(f, &s->rasintr);
-    qemu_get_be32s(f, &s->startintr);
-    qemu_get_be32s(f, &s->endintr);
-    qemu_get_be32s(f, &s->align);
-    qemu_get_be32s(f, &s->pio);
-
-    qemu_get_buffer(f, s->req, PXA2XX_DMA_NUM_REQUESTS);
-    for (i = 0; i < s->channels; i ++) {
-        s->chan[i].descr = qemu_get_betl(f);
-        s->chan[i].src = qemu_get_betl(f);
-        s->chan[i].dest = qemu_get_betl(f);
-        qemu_get_be32s(f, &s->chan[i].cmd);
-        qemu_get_be32s(f, &s->chan[i].state);
-        s->chan[i].request = qemu_get_be32(f);
-    };
-
-    return 0;
-}
-
-static PXA2xxDMAState *pxa2xx_dma_init(target_phys_addr_t base,
-                qemu_irq irq, int channels)
+static int pxa2xx_dma_init(SysBusDevice *dev)
 {
     int i, iomemtype;
     PXA2xxDMAState *s;
-    s = (PXA2xxDMAState *)
-            qemu_mallocz(sizeof(PXA2xxDMAState));
+    s = FROM_SYSBUS(PXA2xxDMAState, dev);
+
+    if (s->channels <= 0) {
+        return -1;
+    }
 
-    s->channels = channels;
     s->chan = qemu_mallocz(sizeof(PXA2xxDMAChannel) * s->channels);
-    s->irq = irq;
-    s->req = qemu_mallocz(sizeof(uint8_t) * PXA2XX_DMA_NUM_REQUESTS);
 
     memset(s->chan, 0, sizeof(PXA2xxDMAChannel) * s->channels);
     for (i = 0; i < s->channels; i ++)
@@ -498,29 +446,49 @@ static PXA2xxDMAState *pxa2xx_dma_init(target_phys_addr_t base,
 
     memset(s->req, 0, sizeof(uint8_t) * PXA2XX_DMA_NUM_REQUESTS);
 
+    qdev_init_gpio_in(&dev->qdev, pxa2xx_dma_request, PXA2XX_DMA_NUM_REQUESTS);
+
     iomemtype = cpu_register_io_memory(pxa2xx_dma_readfn,
                     pxa2xx_dma_writefn, s, DEVICE_NATIVE_ENDIAN);
-    cpu_register_physical_memory(base, 0x00010000, iomemtype);
+    sysbus_init_mmio(dev, 0x00010000, iomemtype);
+    sysbus_init_irq(dev, &s->irq);
 
-    register_savevm(NULL, "pxa2xx_dma", 0, 0, pxa2xx_dma_save, pxa2xx_dma_load, s);
-
-    return s;
+    return 0;
 }
 
-PXA2xxDMAState *pxa27x_dma_init(target_phys_addr_t base,
+DeviceState *pxa27x_dma_init(target_phys_addr_t base,
                 qemu_irq irq)
 {
-    return pxa2xx_dma_init(base, irq, PXA27X_DMA_NUM_CHANNELS);
+    DeviceState *dev;
+
+    dev = qdev_create(NULL, "pxa2xx-dma");
+    qdev_prop_set_int32(dev, "channels", PXA27X_DMA_NUM_CHANNELS);
+    qdev_init_nofail(dev);
+
+    sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
+    sysbus_connect_irq(sysbus_from_qdev(dev), 0, irq);
+
+    return dev;
 }
 
-PXA2xxDMAState *pxa255_dma_init(target_phys_addr_t base,
+DeviceState *pxa255_dma_init(target_phys_addr_t base,
                 qemu_irq irq)
 {
-    return pxa2xx_dma_init(base, irq, PXA255_DMA_NUM_CHANNELS);
+    DeviceState *dev;
+
+    dev = qdev_create(NULL, "pxa2xx-dma");
+    qdev_prop_set_int32(dev, "channels", PXA27X_DMA_NUM_CHANNELS);
+    qdev_init_nofail(dev);
+
+    sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
+    sysbus_connect_irq(sysbus_from_qdev(dev), 0, irq);
+
+    return dev;
 }
 
-void pxa2xx_dma_request(PXA2xxDMAState *s, int req_num, int on)
+static void pxa2xx_dma_request(void *opaque, int req_num, int on)
 {
+    PXA2xxDMAState *s = opaque;
     int ch;
     if (req_num < 0 || req_num >= PXA2XX_DMA_NUM_REQUESTS)
         hw_error("%s: Bad DMA request %i\n", __FUNCTION__, req_num);
@@ -542,3 +510,63 @@ void pxa2xx_dma_request(PXA2xxDMAState *s, int req_num, int on)
         pxa2xx_dma_update(s, ch);
     }
 }
+
+static bool is_version_0(void *opaque, int version_id)
+{
+    return version_id == 0;
+}
+
+static VMStateDescription vmstate_pxa2xx_dma_chan = {
+    .name = "pxa2xx_dma_chan",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINTTL(descr, PXA2xxDMAChannel),
+        VMSTATE_UINTTL(src, PXA2xxDMAChannel),
+        VMSTATE_UINTTL(dest, PXA2xxDMAChannel),
+        VMSTATE_UINT32(cmd, PXA2xxDMAChannel),
+        VMSTATE_UINT32(state, PXA2xxDMAChannel),
+        VMSTATE_INT32(request, PXA2xxDMAChannel),
+        VMSTATE_END_OF_LIST(),
+    },
+};
+
+static VMStateDescription vmstate_pxa2xx_dma = {
+    .name = "pxa2xx_dma",
+    .version_id = 1,
+    .minimum_version_id = 0,
+    .minimum_version_id_old = 0,
+    .fields = (VMStateField[]) {
+        VMSTATE_UNUSED_TEST(is_version_0, 4),
+        VMSTATE_UINT32(stopintr, PXA2xxDMAState),
+        VMSTATE_UINT32(eorintr, PXA2xxDMAState),
+        VMSTATE_UINT32(rasintr, PXA2xxDMAState),
+        VMSTATE_UINT32(startintr, PXA2xxDMAState),
+        VMSTATE_UINT32(endintr, PXA2xxDMAState),
+        VMSTATE_UINT32(align, PXA2xxDMAState),
+        VMSTATE_UINT32(pio, PXA2xxDMAState),
+        VMSTATE_BUFFER(req, PXA2xxDMAState),
+        VMSTATE_STRUCT_VARRAY_POINTER_INT32(chan, PXA2xxDMAState, channels,
+                vmstate_pxa2xx_dma_chan, PXA2xxDMAChannel),
+        VMSTATE_END_OF_LIST(),
+    },
+};
+
+static SysBusDeviceInfo pxa2xx_dma_info = {
+    .init       = pxa2xx_dma_init,
+    .qdev.name  = "pxa2xx-dma",
+    .qdev.desc  = "PXA2xx DMA controller",
+    .qdev.size  = sizeof(PXA2xxDMAState),
+    .qdev.vmsd  = &vmstate_pxa2xx_dma,
+    .qdev.props = (Property[]) {
+        DEFINE_PROP_INT32("channels", PXA2xxDMAState, channels, -1),
+        DEFINE_PROP_END_OF_LIST(),
+    },
+};
+
+static void pxa2xx_dma_register(void)
+{
+    sysbus_register_withprop(&pxa2xx_dma_info);
+}
+device_init(pxa2xx_dma_register);
diff --git a/hw/pxa2xx_mmci.c b/hw/pxa2xx_mmci.c
index 24d409d..d86f735 100644
--- a/hw/pxa2xx_mmci.c
+++ b/hw/pxa2xx_mmci.c
@@ -10,10 +10,12 @@
 #include "hw.h"
 #include "pxa.h"
 #include "sd.h"
+#include "qdev.h"
 
 struct PXA2xxMMCIState {
     qemu_irq irq;
-    void *dma;
+    qemu_irq rx_dma;
+    qemu_irq tx_dma;
 
     SDState *card;
 
@@ -102,10 +104,8 @@ static void pxa2xx_mmci_int_update(PXA2xxMMCIState *s)
     if (s->cmdat & CMDAT_DMA_EN) {
         mask |= INT_RXFIFO_REQ | INT_TXFIFO_REQ;
 
-        pxa2xx_dma_request(s->dma,
-                        PXA2XX_RX_RQ_MMCI, !!(s->intreq & INT_RXFIFO_REQ));
-        pxa2xx_dma_request(s->dma,
-                        PXA2XX_TX_RQ_MMCI, !!(s->intreq & INT_TXFIFO_REQ));
+        qemu_set_irq(s->rx_dma, !!(s->intreq & INT_RXFIFO_REQ));
+        qemu_set_irq(s->tx_dma, !!(s->intreq & INT_TXFIFO_REQ));
     }
 
     qemu_set_irq(s->irq, !!(s->intreq & ~mask));
@@ -518,14 +518,16 @@ static int pxa2xx_mmci_load(QEMUFile *f, void *opaque, int version_id)
 }
 
 PXA2xxMMCIState *pxa2xx_mmci_init(target_phys_addr_t base,
-                BlockDriverState *bd, qemu_irq irq, void *dma)
+                BlockDriverState *bd, qemu_irq irq,
+                qemu_irq rx_dma, qemu_irq tx_dma)
 {
     int iomemtype;
     PXA2xxMMCIState *s;
 
     s = (PXA2xxMMCIState *) qemu_mallocz(sizeof(PXA2xxMMCIState));
     s->irq = irq;
-    s->dma = dma;
+    s->rx_dma = rx_dma;
+    s->tx_dma = tx_dma;
 
     iomemtype = cpu_register_io_memory(pxa2xx_mmci_readfn,
                     pxa2xx_mmci_writefn, s, DEVICE_NATIVE_ENDIAN);
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [Qemu-devel] [PATCH 10/10] pxa2xx: port pxa2xx_rtc to using qdev/vmstate
  2011-02-20 13:50 [Qemu-devel] [PATCH 0/10] pxa2xx: work on switching to qdev/vmstate Dmitry Eremin-Solenikov
                   ` (8 preceding siblings ...)
  2011-02-20 13:50 ` [Qemu-devel] [PATCH 09/10] pxa2xx_dma: port to qdev/vmstate Dmitry Eremin-Solenikov
@ 2011-02-20 13:50 ` Dmitry Eremin-Solenikov
  9 siblings, 0 replies; 14+ messages in thread
From: Dmitry Eremin-Solenikov @ 2011-02-20 13:50 UTC (permalink / raw)
  To: qemu-devel

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 hw/pxa.h    |   27 ---------
 hw/pxa2xx.c |  173 ++++++++++++++++++++++++++++++++++-------------------------
 2 files changed, 100 insertions(+), 100 deletions(-)

diff --git a/hw/pxa.h b/hw/pxa.h
index bad0556..6e2509a 100644
--- a/hw/pxa.h
+++ b/hw/pxa.h
@@ -150,33 +150,6 @@ typedef struct {
     /* Performance monitoring */
     uint32_t pmnc;
 
-    /* Real-Time clock */
-    target_phys_addr_t rtc_base;
-    uint32_t rttr;
-    uint32_t rtsr;
-    uint32_t rtar;
-    uint32_t rdar1;
-    uint32_t rdar2;
-    uint32_t ryar1;
-    uint32_t ryar2;
-    uint32_t swar1;
-    uint32_t swar2;
-    uint32_t piar;
-    uint32_t last_rcnr;
-    uint32_t last_rdcr;
-    uint32_t last_rycr;
-    uint32_t last_swcr;
-    uint32_t last_rtcpicr;
-    int64_t last_hz;
-    int64_t last_sw;
-    int64_t last_pi;
-    QEMUTimer *rtc_hz;
-    QEMUTimer *rtc_rdal1;
-    QEMUTimer *rtc_rdal2;
-    QEMUTimer *rtc_swal1;
-    QEMUTimer *rtc_swal2;
-    QEMUTimer *rtc_pi;
-    qemu_irq rtc_irq;
 } PXA2xxState;
 
 struct PXA2xxI2SState {
diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
index f9ada1c..3607f27 100644
--- a/hw/pxa2xx.c
+++ b/hw/pxa2xx.c
@@ -13,7 +13,6 @@
 #include "pc.h"
 #include "i2c.h"
 #include "ssi.h"
-#include "qemu-timer.h"
 #include "qemu-char.h"
 #include "blockdev.h"
 #include "arm-misc.h"
@@ -887,12 +886,41 @@ static int pxa2xx_ssp_init(SysBusDevice *dev)
 #define RTCPICR		0x34	/* RTC Periodic Interrupt Counter register */
 #define PIAR		0x38	/* RTC Periodic Interrupt Alarm register */
 
-static inline void pxa2xx_rtc_int_update(PXA2xxState *s)
+typedef struct {
+    SysBusDevice busdev;
+    uint32_t rttr;
+    uint32_t rtsr;
+    uint32_t rtar;
+    uint32_t rdar1;
+    uint32_t rdar2;
+    uint32_t ryar1;
+    uint32_t ryar2;
+    uint32_t swar1;
+    uint32_t swar2;
+    uint32_t piar;
+    uint32_t last_rcnr;
+    uint32_t last_rdcr;
+    uint32_t last_rycr;
+    uint32_t last_swcr;
+    uint32_t last_rtcpicr;
+    int64_t last_hz;
+    int64_t last_sw;
+    int64_t last_pi;
+    QEMUTimer *rtc_hz;
+    QEMUTimer *rtc_rdal1;
+    QEMUTimer *rtc_rdal2;
+    QEMUTimer *rtc_swal1;
+    QEMUTimer *rtc_swal2;
+    QEMUTimer *rtc_pi;
+    qemu_irq rtc_irq;
+} PXA2xxRTCState;
+
+static inline void pxa2xx_rtc_int_update(PXA2xxRTCState *s)
 {
     qemu_set_irq(s->rtc_irq, !!(s->rtsr & 0x2553));
 }
 
-static void pxa2xx_rtc_hzupdate(PXA2xxState *s)
+static void pxa2xx_rtc_hzupdate(PXA2xxRTCState *s)
 {
     int64_t rt = qemu_get_clock(rt_clock);
     s->last_rcnr += ((rt - s->last_hz) << 15) /
@@ -902,7 +930,7 @@ static void pxa2xx_rtc_hzupdate(PXA2xxState *s)
     s->last_hz = rt;
 }
 
-static void pxa2xx_rtc_swupdate(PXA2xxState *s)
+static void pxa2xx_rtc_swupdate(PXA2xxRTCState *s)
 {
     int64_t rt = qemu_get_clock(rt_clock);
     if (s->rtsr & (1 << 12))
@@ -910,7 +938,7 @@ static void pxa2xx_rtc_swupdate(PXA2xxState *s)
     s->last_sw = rt;
 }
 
-static void pxa2xx_rtc_piupdate(PXA2xxState *s)
+static void pxa2xx_rtc_piupdate(PXA2xxRTCState *s)
 {
     int64_t rt = qemu_get_clock(rt_clock);
     if (s->rtsr & (1 << 15))
@@ -918,7 +946,7 @@ static void pxa2xx_rtc_piupdate(PXA2xxState *s)
     s->last_pi = rt;
 }
 
-static inline void pxa2xx_rtc_alarm_update(PXA2xxState *s,
+static inline void pxa2xx_rtc_alarm_update(PXA2xxRTCState *s,
                 uint32_t rtsr)
 {
     if ((rtsr & (1 << 2)) && !(rtsr & (1 << 0)))
@@ -963,7 +991,7 @@ static inline void pxa2xx_rtc_alarm_update(PXA2xxState *s,
 
 static inline void pxa2xx_rtc_hz_tick(void *opaque)
 {
-    PXA2xxState *s = (PXA2xxState *) opaque;
+    PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
     s->rtsr |= (1 << 0);
     pxa2xx_rtc_alarm_update(s, s->rtsr);
     pxa2xx_rtc_int_update(s);
@@ -971,7 +999,7 @@ static inline void pxa2xx_rtc_hz_tick(void *opaque)
 
 static inline void pxa2xx_rtc_rdal1_tick(void *opaque)
 {
-    PXA2xxState *s = (PXA2xxState *) opaque;
+    PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
     s->rtsr |= (1 << 4);
     pxa2xx_rtc_alarm_update(s, s->rtsr);
     pxa2xx_rtc_int_update(s);
@@ -979,7 +1007,7 @@ static inline void pxa2xx_rtc_rdal1_tick(void *opaque)
 
 static inline void pxa2xx_rtc_rdal2_tick(void *opaque)
 {
-    PXA2xxState *s = (PXA2xxState *) opaque;
+    PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
     s->rtsr |= (1 << 6);
     pxa2xx_rtc_alarm_update(s, s->rtsr);
     pxa2xx_rtc_int_update(s);
@@ -987,7 +1015,7 @@ static inline void pxa2xx_rtc_rdal2_tick(void *opaque)
 
 static inline void pxa2xx_rtc_swal1_tick(void *opaque)
 {
-    PXA2xxState *s = (PXA2xxState *) opaque;
+    PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
     s->rtsr |= (1 << 8);
     pxa2xx_rtc_alarm_update(s, s->rtsr);
     pxa2xx_rtc_int_update(s);
@@ -995,7 +1023,7 @@ static inline void pxa2xx_rtc_swal1_tick(void *opaque)
 
 static inline void pxa2xx_rtc_swal2_tick(void *opaque)
 {
-    PXA2xxState *s = (PXA2xxState *) opaque;
+    PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
     s->rtsr |= (1 << 10);
     pxa2xx_rtc_alarm_update(s, s->rtsr);
     pxa2xx_rtc_int_update(s);
@@ -1003,7 +1031,7 @@ static inline void pxa2xx_rtc_swal2_tick(void *opaque)
 
 static inline void pxa2xx_rtc_pi_tick(void *opaque)
 {
-    PXA2xxState *s = (PXA2xxState *) opaque;
+    PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
     s->rtsr |= (1 << 13);
     pxa2xx_rtc_piupdate(s);
     s->last_rtcpicr = 0;
@@ -1013,7 +1041,7 @@ static inline void pxa2xx_rtc_pi_tick(void *opaque)
 
 static uint32_t pxa2xx_rtc_read(void *opaque, target_phys_addr_t addr)
 {
-    PXA2xxState *s = (PXA2xxState *) opaque;
+    PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
 
     switch (addr) {
     case RTTR:
@@ -1059,7 +1087,7 @@ static uint32_t pxa2xx_rtc_read(void *opaque, target_phys_addr_t addr)
 static void pxa2xx_rtc_write(void *opaque, target_phys_addr_t addr,
                 uint32_t value)
 {
-    PXA2xxState *s = (PXA2xxState *) opaque;
+    PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
 
     switch (addr) {
     case RTTR:
@@ -1171,10 +1199,12 @@ static CPUWriteMemoryFunc * const pxa2xx_rtc_writefn[] = {
     pxa2xx_rtc_write,
 };
 
-static void pxa2xx_rtc_init(PXA2xxState *s)
+static int pxa2xx_rtc_init(SysBusDevice *dev)
 {
+    PXA2xxRTCState *s = FROM_SYSBUS(PXA2xxRTCState, dev);
     struct tm tm;
     int wom;
+    int iomemtype;
 
     s->rttr = 0x7fff;
     s->rtsr = 0;
@@ -1199,65 +1229,71 @@ static void pxa2xx_rtc_init(PXA2xxState *s)
     s->rtc_swal2 = qemu_new_timer(rt_clock, pxa2xx_rtc_swal2_tick, s);
     s->rtc_pi    = qemu_new_timer(rt_clock, pxa2xx_rtc_pi_tick,    s);
 
-    s->rtc_irq = qdev_get_gpio_in(s->pic, PXA2XX_PIC_RTCALARM);
+    sysbus_init_irq(dev, &s->rtc_irq);
+
+    iomemtype = cpu_register_io_memory(pxa2xx_rtc_readfn,
+                    pxa2xx_rtc_writefn, s, DEVICE_NATIVE_ENDIAN);
+    sysbus_init_mmio(dev, 0x10000, iomemtype);
+
+    return 0;
 }
 
-static void pxa2xx_rtc_save(QEMUFile *f, void *opaque)
+static void pxa2xx_rtc_pre_save(void *opaque)
 {
-    PXA2xxState *s = (PXA2xxState *) opaque;
+    PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
 
     pxa2xx_rtc_hzupdate(s);
     pxa2xx_rtc_piupdate(s);
     pxa2xx_rtc_swupdate(s);
+}
 
-    qemu_put_be32s(f, &s->rttr);
-    qemu_put_be32s(f, &s->rtsr);
-    qemu_put_be32s(f, &s->rtar);
-    qemu_put_be32s(f, &s->rdar1);
-    qemu_put_be32s(f, &s->rdar2);
-    qemu_put_be32s(f, &s->ryar1);
-    qemu_put_be32s(f, &s->ryar2);
-    qemu_put_be32s(f, &s->swar1);
-    qemu_put_be32s(f, &s->swar2);
-    qemu_put_be32s(f, &s->piar);
-    qemu_put_be32s(f, &s->last_rcnr);
-    qemu_put_be32s(f, &s->last_rdcr);
-    qemu_put_be32s(f, &s->last_rycr);
-    qemu_put_be32s(f, &s->last_swcr);
-    qemu_put_be32s(f, &s->last_rtcpicr);
-    qemu_put_sbe64s(f, &s->last_hz);
-    qemu_put_sbe64s(f, &s->last_sw);
-    qemu_put_sbe64s(f, &s->last_pi);
-}
-
-static int pxa2xx_rtc_load(QEMUFile *f, void *opaque, int version_id)
+static int pxa2xx_rtc_post_load(void *opaque, int version_id)
 {
-    PXA2xxState *s = (PXA2xxState *) opaque;
-
-    qemu_get_be32s(f, &s->rttr);
-    qemu_get_be32s(f, &s->rtsr);
-    qemu_get_be32s(f, &s->rtar);
-    qemu_get_be32s(f, &s->rdar1);
-    qemu_get_be32s(f, &s->rdar2);
-    qemu_get_be32s(f, &s->ryar1);
-    qemu_get_be32s(f, &s->ryar2);
-    qemu_get_be32s(f, &s->swar1);
-    qemu_get_be32s(f, &s->swar2);
-    qemu_get_be32s(f, &s->piar);
-    qemu_get_be32s(f, &s->last_rcnr);
-    qemu_get_be32s(f, &s->last_rdcr);
-    qemu_get_be32s(f, &s->last_rycr);
-    qemu_get_be32s(f, &s->last_swcr);
-    qemu_get_be32s(f, &s->last_rtcpicr);
-    qemu_get_sbe64s(f, &s->last_hz);
-    qemu_get_sbe64s(f, &s->last_sw);
-    qemu_get_sbe64s(f, &s->last_pi);
+    PXA2xxRTCState *s = (PXA2xxRTCState *) opaque;
 
     pxa2xx_rtc_alarm_update(s, s->rtsr);
 
     return 0;
 }
 
+static const VMStateDescription vmstate_pxa2xx_rtc_regs = {
+    .name = "pxa2xx_rtc",
+    .version_id = 0,
+    .minimum_version_id = 0,
+    .minimum_version_id_old = 0,
+    .pre_save = pxa2xx_rtc_pre_save,
+    .post_load = pxa2xx_rtc_post_load,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(rttr, PXA2xxRTCState),
+        VMSTATE_UINT32(rtsr, PXA2xxRTCState),
+        VMSTATE_UINT32(rtar, PXA2xxRTCState),
+        VMSTATE_UINT32(rdar1, PXA2xxRTCState),
+        VMSTATE_UINT32(rdar2, PXA2xxRTCState),
+        VMSTATE_UINT32(ryar1, PXA2xxRTCState),
+        VMSTATE_UINT32(ryar2, PXA2xxRTCState),
+        VMSTATE_UINT32(swar1, PXA2xxRTCState),
+        VMSTATE_UINT32(swar2, PXA2xxRTCState),
+        VMSTATE_UINT32(piar, PXA2xxRTCState),
+        VMSTATE_UINT32(last_rcnr, PXA2xxRTCState),
+        VMSTATE_UINT32(last_rdcr, PXA2xxRTCState),
+        VMSTATE_UINT32(last_rycr, PXA2xxRTCState),
+        VMSTATE_UINT32(last_swcr, PXA2xxRTCState),
+        VMSTATE_UINT32(last_rtcpicr, PXA2xxRTCState),
+        VMSTATE_INT64(last_hz, PXA2xxRTCState),
+        VMSTATE_INT64(last_sw, PXA2xxRTCState),
+        VMSTATE_INT64(last_pi, PXA2xxRTCState),
+        VMSTATE_END_OF_LIST(),
+    },
+};
+
+static SysBusDeviceInfo pxa2xx_rtc_sysbus_info = {
+    .init       = pxa2xx_rtc_init,
+    .qdev.name  = "pxa2xx_rtc",
+    .qdev.desc  = "PXA2xx RTC Controller",
+    .qdev.size  = sizeof(PXA2xxRTCState),
+    .qdev.vmsd  = &vmstate_pxa2xx_rtc_regs,
+};
+
 /* I2C Interface */
 typedef struct {
     i2c_slave i2c;
@@ -2195,13 +2231,8 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision)
     s->pcmcia[0] = pxa2xx_pcmcia_init(0x20000000);
     s->pcmcia[1] = pxa2xx_pcmcia_init(0x30000000);
 
-    s->rtc_base = 0x40900000;
-    iomemtype = cpu_register_io_memory(pxa2xx_rtc_readfn,
-                    pxa2xx_rtc_writefn, s, DEVICE_NATIVE_ENDIAN);
-    cpu_register_physical_memory(s->rtc_base, 0x1000, iomemtype);
-    pxa2xx_rtc_init(s);
-    register_savevm(NULL, "pxa2xx_rtc", 0, 0, pxa2xx_rtc_save,
-                    pxa2xx_rtc_load, s);
+    sysbus_create_simple("pxa2xx_rtc", 0x40900000,
+            qdev_get_gpio_in(s->pic, PXA2XX_PIC_RTCALARM));
 
     s->i2c[0] = pxa2xx_i2c_init(0x40301600,
             qdev_get_gpio_in(s->pic, PXA2XX_PIC_I2C), 0xffff);
@@ -2341,13 +2372,8 @@ PXA2xxState *pxa255_init(unsigned int sdram_size)
     s->pcmcia[0] = pxa2xx_pcmcia_init(0x20000000);
     s->pcmcia[1] = pxa2xx_pcmcia_init(0x30000000);
 
-    s->rtc_base = 0x40900000;
-    iomemtype = cpu_register_io_memory(pxa2xx_rtc_readfn,
-                    pxa2xx_rtc_writefn, s, DEVICE_NATIVE_ENDIAN);
-    cpu_register_physical_memory(s->rtc_base, 0x1000, iomemtype);
-    pxa2xx_rtc_init(s);
-    register_savevm(NULL, "pxa2xx_rtc", 0, 0, pxa2xx_rtc_save,
-                    pxa2xx_rtc_load, s);
+    sysbus_create_simple("pxa2xx_rtc", 0x40900000,
+            qdev_get_gpio_in(s->pic, PXA2XX_PIC_RTCALARM));
 
     s->i2c[0] = pxa2xx_i2c_init(0x40301600,
             qdev_get_gpio_in(s->pic, PXA2XX_PIC_I2C), 0xffff);
@@ -2370,6 +2396,7 @@ static void pxa2xx_register_devices(void)
     i2c_register_slave(&pxa2xx_i2c_slave_info);
     sysbus_register_dev("pxa2xx-ssp", sizeof(PXA2xxSSPState), pxa2xx_ssp_init);
     sysbus_register_withprop(&pxa2xx_i2c_info);
+    sysbus_register_withprop(&pxa2xx_rtc_sysbus_info);
 }
 
 device_init(pxa2xx_register_devices)
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH 02/10] pxa2xx_pic: update to use qdev and arm-pic
  2011-02-20 13:50 ` [Qemu-devel] [PATCH 02/10] pxa2xx_pic: update to use qdev and arm-pic Dmitry Eremin-Solenikov
@ 2011-02-25 11:51   ` andrzej zaborowski
  2011-02-25 13:50     ` Dmitry Eremin-Solenikov
  0 siblings, 1 reply; 14+ messages in thread
From: andrzej zaborowski @ 2011-02-25 11:51 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov; +Cc: qemu-devel

Hi Dmitry,

On 20 February 2011 14:50, Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> wrote:
> Use qdev/sysbus framework to handle pxa2xx-pic. Instead of exposing IRQs
> via array, reference them via qdev_get_gpio_in(). Also pxa2xx_pic duplicated
> some code from arm-pic. Drop it, replacing with references to arm-pic,
> as all other ARM SoCs do for their PIC code.

As I said earlier not using arm-pic was deliberate (and I also asked
what the gain was from converting the pic to a separate sysbus device
from the CPU) so I skipped this part of the patch and pushed the rest
of it, please check that everything works.

>
> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> ---
>  hw/mainstone.c    |    2 +-
>  hw/pxa.h          |   12 +++--
>  hw/pxa2xx.c       |   84 +++++++++++++++++++++++------------
>  hw/pxa2xx_gpio.c  |   11 +++--
>  hw/pxa2xx_pic.c   |  126 ++++++++++++++++++++++++++++-------------------------
>  hw/pxa2xx_timer.c |   16 +++---
>  6 files changed, 144 insertions(+), 107 deletions(-)
>
> diff --git a/hw/mainstone.c b/hw/mainstone.c
> index aec8d34..4eabdb9 100644
> --- a/hw/mainstone.c
> +++ b/hw/mainstone.c
> @@ -140,7 +140,7 @@ static void mainstone_common_init(ram_addr_t ram_size,
>     }
>
>     mst_irq = sysbus_create_simple("mainstone-fpga", MST_FPGA_PHYS,
> -                    cpu->pic[PXA2XX_PIC_GPIO_0]);
> +                    qdev_get_gpio_in(cpu->pic, PXA2XX_PIC_GPIO_0));

I'm also wondering if this device should really use the interrupt line
instead of using a GPIO.  It seems wrong that both the fpga and the
gpio module are connected to the same line.

>
>     /* setup keypad */
>     printf("map addr %p\n", &map);
> diff --git a/hw/pxa.h b/hw/pxa.h
> index f73d33b..7c6fd44 100644
> --- a/hw/pxa.h
> +++ b/hw/pxa.h
> @@ -63,15 +63,16 @@
>  # define PXA2XX_INTERNAL_SIZE  0x40000
>
>  /* pxa2xx_pic.c */
> -qemu_irq *pxa2xx_pic_init(target_phys_addr_t base, CPUState *env);
> +DeviceState *pxa2xx_pic_init(target_phys_addr_t base, CPUState *env,
> +        qemu_irq *arm_pic);
>
>  /* pxa2xx_timer.c */
> -void pxa25x_timer_init(target_phys_addr_t base, qemu_irq *irqs);
> -void pxa27x_timer_init(target_phys_addr_t base, qemu_irq *irqs, qemu_irq irq4);
> +void pxa25x_timer_init(target_phys_addr_t base, DeviceState *pic);
> +void pxa27x_timer_init(target_phys_addr_t base, DeviceState *pic);
>
>  /* pxa2xx_gpio.c */
>  DeviceState *pxa2xx_gpio_init(target_phys_addr_t base,
> -                CPUState *env, qemu_irq *pic, int lines);
> +                CPUState *env, DeviceState *pic, int lines);
>  void pxa2xx_gpio_read_notifier(DeviceState *dev, qemu_irq handler);
>
>  /* pxa2xx_dma.c */
> @@ -125,7 +126,7 @@ typedef struct PXA2xxFIrState PXA2xxFIrState;
>
>  typedef struct {
>     CPUState *env;
> -    qemu_irq *pic;
> +    DeviceState *pic;
>     qemu_irq reset;
>     PXA2xxDMAState *dma;
>     DeviceState *gpio;
> @@ -180,6 +181,7 @@ typedef struct {
>     QEMUTimer *rtc_swal1;
>     QEMUTimer *rtc_swal2;
>     QEMUTimer *rtc_pi;
> +    qemu_irq rtc_irq;
>  } PXA2xxState;
>
>  struct PXA2xxI2SState {
> diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
> index 9ebbce6..58e6e7b 100644
> --- a/hw/pxa2xx.c
> +++ b/hw/pxa2xx.c
> @@ -16,6 +16,7 @@
>  #include "qemu-timer.h"
>  #include "qemu-char.h"
>  #include "blockdev.h"
> +#include "arm-misc.h"
>
>  static struct {
>     target_phys_addr_t io_base;
> @@ -888,7 +889,7 @@ static int pxa2xx_ssp_init(SysBusDevice *dev)
>
>  static inline void pxa2xx_rtc_int_update(PXA2xxState *s)
>  {
> -    qemu_set_irq(s->pic[PXA2XX_PIC_RTCALARM], !!(s->rtsr & 0x2553));
> +    qemu_set_irq(s->rtc_irq, !!(s->rtsr & 0x2553));
>  }
>
>  static void pxa2xx_rtc_hzupdate(PXA2xxState *s)
> @@ -1197,6 +1198,8 @@ static void pxa2xx_rtc_init(PXA2xxState *s)
>     s->rtc_swal1 = qemu_new_timer(rt_clock, pxa2xx_rtc_swal1_tick, s);
>     s->rtc_swal2 = qemu_new_timer(rt_clock, pxa2xx_rtc_swal2_tick, s);
>     s->rtc_pi    = qemu_new_timer(rt_clock, pxa2xx_rtc_pi_tick,    s);
> +
> +    s->rtc_irq = qdev_get_gpio_in(s->pic, PXA2XX_PIC_RTCALARM);
>  }
>
>  static void pxa2xx_rtc_save(QEMUFile *f, void *opaque)
> @@ -2069,6 +2072,8 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision)
>     PXA2xxState *s;
>     int iomemtype, i;
>     DriveInfo *dinfo;
> +    qemu_irq *arm_pic;
> +
>     s = (PXA2xxState *) qemu_mallocz(sizeof(PXA2xxState));
>
>     if (revision && strncmp(revision, "pxa27", 5)) {
> @@ -2093,12 +2098,13 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision)
>                     0x40000, qemu_ram_alloc(NULL, "pxa270.internal",
>                                             0x40000) | IO_MEM_RAM);
>
> -    s->pic = pxa2xx_pic_init(0x40d00000, s->env);
> +    arm_pic = arm_pic_init_cpu(s->env);
> +    s->pic = pxa2xx_pic_init(0x40d00000, s->env, arm_pic);
>
> -    s->dma = pxa27x_dma_init(0x40000000, s->pic[PXA2XX_PIC_DMA]);
> +    s->dma = pxa27x_dma_init(0x40000000,
> +            qdev_get_gpio_in(s->pic, PXA2XX_PIC_DMA));
>
> -    pxa27x_timer_init(0x40a00000, &s->pic[PXA2XX_PIC_OST_0],
> -                    s->pic[PXA27X_PIC_OST_4_11]);
> +    pxa27x_timer_init(0x40a00000, s->pic);
>
>     s->gpio = pxa2xx_gpio_init(0x40e00000, s->env, s->pic, 121);
>
> @@ -2108,26 +2114,30 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision)
>         exit(1);
>     }
>     s->mmc = pxa2xx_mmci_init(0x41100000, dinfo->bdrv,
> -                              s->pic[PXA2XX_PIC_MMC], s->dma);
> +                              qdev_get_gpio_in(s->pic, PXA2XX_PIC_MMC), s->dma);
>
>     for (i = 0; pxa270_serial[i].io_base; i ++)
>         if (serial_hds[i])
>  #ifdef TARGET_WORDS_BIGENDIAN
>             serial_mm_init(pxa270_serial[i].io_base, 2,
> -                           s->pic[pxa270_serial[i].irqn], 14857000/16,
> +                           qdev_get_gpio_in(s->pic, pxa270_serial[i].irqn),
> +                           14857000/16,
>                            serial_hds[i], 1, 1);
>  #else
>             serial_mm_init(pxa270_serial[i].io_base, 2,
> -                           s->pic[pxa270_serial[i].irqn], 14857000/16,
> +                           qdev_get_gpio_in(s->pic, pxa270_serial[i].irqn),
> +                           14857000/16,
>                            serial_hds[i], 1, 0);
>  #endif
>         else
>             break;
>     if (serial_hds[i])
> -        s->fir = pxa2xx_fir_init(0x40800000, s->pic[PXA2XX_PIC_ICP],
> +        s->fir = pxa2xx_fir_init(0x40800000,
> +                        qdev_get_gpio_in(s->pic, PXA2XX_PIC_ICP),
>                         s->dma, serial_hds[i]);
>
> -    s->lcd = pxa2xx_lcdc_init(0x44000000, s->pic[PXA2XX_PIC_LCD]);
> +    s->lcd = pxa2xx_lcdc_init(0x44000000,
> +                        qdev_get_gpio_in(s->pic, PXA2XX_PIC_LCD));
>
>     s->cm_base = 0x41300000;
>     s->cm_regs[CCCR >> 2] = 0x02000210;        /* 416.0 MHz */
> @@ -2159,13 +2169,13 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision)
>     for (i = 0; pxa27x_ssp[i].io_base; i ++) {
>         DeviceState *dev;
>         dev = sysbus_create_simple("pxa2xx-ssp", pxa27x_ssp[i].io_base,
> -                                   s->pic[pxa27x_ssp[i].irqn]);
> +                               qdev_get_gpio_in(s->pic, pxa27x_ssp[i].irqn));
>         s->ssp[i] = (SSIBus *)qdev_get_child_bus(dev, "ssi");
>     }
>
>     if (usb_enabled) {
>         sysbus_create_simple("sysbus-ohci", 0x4c000000,
> -                             s->pic[PXA2XX_PIC_USBH1]);
> +                             qdev_get_gpio_in(s->pic, PXA2XX_PIC_USBH1));
>     }
>
>     s->pcmcia[0] = pxa2xx_pcmcia_init(0x20000000);
> @@ -2179,12 +2189,17 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision)
>     register_savevm(NULL, "pxa2xx_rtc", 0, 0, pxa2xx_rtc_save,
>                     pxa2xx_rtc_load, s);
>
> -    s->i2c[0] = pxa2xx_i2c_init(0x40301600, s->pic[PXA2XX_PIC_I2C], 0xffff);
> -    s->i2c[1] = pxa2xx_i2c_init(0x40f00100, s->pic[PXA2XX_PIC_PWRI2C], 0xff);
> +    s->i2c[0] = pxa2xx_i2c_init(0x40301600,
> +            qdev_get_gpio_in(s->pic, PXA2XX_PIC_I2C), 0xffff);
> +    s->i2c[1] = pxa2xx_i2c_init(0x40f00100,
> +            qdev_get_gpio_in(s->pic, PXA2XX_PIC_PWRI2C), 0xff);
>
> -    s->i2s = pxa2xx_i2s_init(0x40400000, s->pic[PXA2XX_PIC_I2S], s->dma);
> +    s->i2s = pxa2xx_i2s_init(0x40400000,
> +            qdev_get_gpio_in(s->pic, PXA2XX_PIC_I2S),
> +            s->dma);
>
> -    s->kp = pxa27x_keypad_init(0x41500000, s->pic[PXA2XX_PIC_KEYPAD]);
> +    s->kp = pxa27x_keypad_init(0x41500000,
> +            qdev_get_gpio_in(s->pic, PXA2XX_PIC_KEYPAD));
>
>     /* GPIO1 resets the processor */
>     /* The handler can be overridden by board-specific code */
> @@ -2198,6 +2213,7 @@ PXA2xxState *pxa255_init(unsigned int sdram_size)
>     PXA2xxState *s;
>     int iomemtype, i;
>     DriveInfo *dinfo;
> +    qemu_irq *arm_pic;
>
>     s = (PXA2xxState *) qemu_mallocz(sizeof(PXA2xxState));
>
> @@ -2216,11 +2232,13 @@ PXA2xxState *pxa255_init(unsigned int sdram_size)
>                     qemu_ram_alloc(NULL, "pxa255.internal",
>                                    PXA2XX_INTERNAL_SIZE) | IO_MEM_RAM);
>
> -    s->pic = pxa2xx_pic_init(0x40d00000, s->env);
> +    arm_pic = arm_pic_init_cpu(s->env);
> +    s->pic = pxa2xx_pic_init(0x40d00000, s->env, arm_pic);
>
> -    s->dma = pxa255_dma_init(0x40000000, s->pic[PXA2XX_PIC_DMA]);
> +    s->dma = pxa255_dma_init(0x40000000,
> +            qdev_get_gpio_in(s->pic, PXA2XX_PIC_DMA));
>
> -    pxa25x_timer_init(0x40a00000, &s->pic[PXA2XX_PIC_OST_0]);
> +    pxa25x_timer_init(0x40a00000, s->pic);
>
>     s->gpio = pxa2xx_gpio_init(0x40e00000, s->env, s->pic, 85);
>
> @@ -2230,27 +2248,31 @@ PXA2xxState *pxa255_init(unsigned int sdram_size)
>         exit(1);
>     }
>     s->mmc = pxa2xx_mmci_init(0x41100000, dinfo->bdrv,
> -                              s->pic[PXA2XX_PIC_MMC], s->dma);
> +                              qdev_get_gpio_in(s->pic, PXA2XX_PIC_MMC), s->dma);
>
>     for (i = 0; pxa255_serial[i].io_base; i ++)
>         if (serial_hds[i]) {
>  #ifdef TARGET_WORDS_BIGENDIAN
>             serial_mm_init(pxa255_serial[i].io_base, 2,
> -                           s->pic[pxa255_serial[i].irqn], 14745600/16,
> +                           qdev_get_gpio_in(s->pic, pxa255_serial[i].irqn),
> +                           14745600/16,
>                            serial_hds[i], 1, 1);
>  #else
>             serial_mm_init(pxa255_serial[i].io_base, 2,
> -                           s->pic[pxa255_serial[i].irqn], 14745600/16,
> +                           qdev_get_gpio_in(s->pic, pxa255_serial[i].irqn),
> +                           14745600/16,
>                            serial_hds[i], 1, 0);
>  #endif
>         } else {
>             break;
>         }
>     if (serial_hds[i])
> -        s->fir = pxa2xx_fir_init(0x40800000, s->pic[PXA2XX_PIC_ICP],
> +        s->fir = pxa2xx_fir_init(0x40800000,
> +                        qdev_get_gpio_in(s->pic, PXA2XX_PIC_ICP),
>                         s->dma, serial_hds[i]);
>
> -    s->lcd = pxa2xx_lcdc_init(0x44000000, s->pic[PXA2XX_PIC_LCD]);
> +    s->lcd = pxa2xx_lcdc_init(0x44000000,
> +            qdev_get_gpio_in(s->pic, PXA2XX_PIC_LCD));
>
>     s->cm_base = 0x41300000;
>     s->cm_regs[CCCR >> 2] = 0x02000210;        /* 416.0 MHz */
> @@ -2282,13 +2304,13 @@ PXA2xxState *pxa255_init(unsigned int sdram_size)
>     for (i = 0; pxa255_ssp[i].io_base; i ++) {
>         DeviceState *dev;
>         dev = sysbus_create_simple("pxa2xx-ssp", pxa255_ssp[i].io_base,
> -                                   s->pic[pxa255_ssp[i].irqn]);
> +                               qdev_get_gpio_in(s->pic, pxa255_ssp[i].irqn));
>         s->ssp[i] = (SSIBus *)qdev_get_child_bus(dev, "ssi");
>     }
>
>     if (usb_enabled) {
>         sysbus_create_simple("sysbus-ohci", 0x4c000000,
> -                             s->pic[PXA2XX_PIC_USBH1]);
> +                             qdev_get_gpio_in(s->pic, PXA2XX_PIC_USBH1));
>     }
>
>     s->pcmcia[0] = pxa2xx_pcmcia_init(0x20000000);
> @@ -2302,10 +2324,14 @@ PXA2xxState *pxa255_init(unsigned int sdram_size)
>     register_savevm(NULL, "pxa2xx_rtc", 0, 0, pxa2xx_rtc_save,
>                     pxa2xx_rtc_load, s);
>
> -    s->i2c[0] = pxa2xx_i2c_init(0x40301600, s->pic[PXA2XX_PIC_I2C], 0xffff);
> -    s->i2c[1] = pxa2xx_i2c_init(0x40f00100, s->pic[PXA2XX_PIC_PWRI2C], 0xff);
> +    s->i2c[0] = pxa2xx_i2c_init(0x40301600,
> +            qdev_get_gpio_in(s->pic, PXA2XX_PIC_I2C), 0xffff);
> +    s->i2c[1] = pxa2xx_i2c_init(0x40f00100,
> +            qdev_get_gpio_in(s->pic, PXA2XX_PIC_PWRI2C), 0xff);
>
> -    s->i2s = pxa2xx_i2s_init(0x40400000, s->pic[PXA2XX_PIC_I2S], s->dma);
> +    s->i2s = pxa2xx_i2s_init(0x40400000,
> +            qdev_get_gpio_in(s->pic, PXA2XX_PIC_I2S),
> +            s->dma);
>
>     /* GPIO1 resets the processor */
>     /* The handler can be overridden by board-specific code */
> diff --git a/hw/pxa2xx_gpio.c b/hw/pxa2xx_gpio.c
> index 789965d..16a8865 100644
> --- a/hw/pxa2xx_gpio.c
> +++ b/hw/pxa2xx_gpio.c
> @@ -253,7 +253,7 @@ static CPUWriteMemoryFunc * const pxa2xx_gpio_writefn[] = {
>  };
>
>  DeviceState *pxa2xx_gpio_init(target_phys_addr_t base,
> -                CPUState *env, qemu_irq *pic, int lines)
> +                CPUState *env, DeviceState *pic, int lines)
>  {
>     DeviceState *dev;
>
> @@ -263,9 +263,12 @@ DeviceState *pxa2xx_gpio_init(target_phys_addr_t base,
>     qdev_init_nofail(dev);
>
>     sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
> -    sysbus_connect_irq(sysbus_from_qdev(dev), 0, pic[PXA2XX_PIC_GPIO_0]);
> -    sysbus_connect_irq(sysbus_from_qdev(dev), 1, pic[PXA2XX_PIC_GPIO_1]);
> -    sysbus_connect_irq(sysbus_from_qdev(dev), 2, pic[PXA2XX_PIC_GPIO_X]);
> +    sysbus_connect_irq(sysbus_from_qdev(dev), 0,
> +            qdev_get_gpio_in(pic, PXA2XX_PIC_GPIO_0));
> +    sysbus_connect_irq(sysbus_from_qdev(dev), 1,
> +            qdev_get_gpio_in(pic, PXA2XX_PIC_GPIO_1));
> +    sysbus_connect_irq(sysbus_from_qdev(dev), 2,
> +            qdev_get_gpio_in(pic, PXA2XX_PIC_GPIO_X));
>
>     return dev;
>  }
> diff --git a/hw/pxa2xx_pic.c b/hw/pxa2xx_pic.c
> index a36da23..1053b92 100644
> --- a/hw/pxa2xx_pic.c
> +++ b/hw/pxa2xx_pic.c
> @@ -10,6 +10,8 @@
>
>  #include "hw.h"
>  #include "pxa.h"
> +#include "arm-misc.h"
> +#include "sysbus.h"
>
>  #define ICIP   0x00    /* Interrupt Controller IRQ Pending register */
>  #define ICMR   0x04    /* Interrupt Controller Mask register */
> @@ -31,7 +33,10 @@
>  #define PXA2XX_PIC_SRCS        40
>
>  typedef struct {
> -    CPUState *cpu_env;
> +    SysBusDevice busdev;
> +    qemu_irq hard_irq;
> +    qemu_irq fiq_irq;
> +    qemu_irq wake_irq;
>     uint32_t int_enabled[2];
>     uint32_t int_pending[2];
>     uint32_t is_fiq[2];
> @@ -44,25 +49,18 @@ static void pxa2xx_pic_update(void *opaque)
>     uint32_t mask[2];
>     PXA2xxPICState *s = (PXA2xxPICState *) opaque;
>
> -    if (s->cpu_env->halted) {
> -        mask[0] = s->int_pending[0] & (s->int_enabled[0] | s->int_idle);
> -        mask[1] = s->int_pending[1] & (s->int_enabled[1] | s->int_idle);
> -        if (mask[0] || mask[1])
> -            cpu_interrupt(s->cpu_env, CPU_INTERRUPT_EXITTB);
> -    }
> +    mask[0] = s->int_pending[0] & (s->int_enabled[0] | s->int_idle);
> +    mask[1] = s->int_pending[1] & (s->int_enabled[1] | s->int_idle);
> +    qemu_set_irq(s->wake_irq, mask[0] || mask[1]);
>
>     mask[0] = s->int_pending[0] & s->int_enabled[0];
>     mask[1] = s->int_pending[1] & s->int_enabled[1];
>
> -    if ((mask[0] & s->is_fiq[0]) || (mask[1] & s->is_fiq[1]))
> -        cpu_interrupt(s->cpu_env, CPU_INTERRUPT_FIQ);
> -    else
> -        cpu_reset_interrupt(s->cpu_env, CPU_INTERRUPT_FIQ);
> +    qemu_set_irq(s->fiq_irq,
> +            ((mask[0] & s->is_fiq[0]) || (mask[1] & s->is_fiq[1])));
>
> -    if ((mask[0] & ~s->is_fiq[0]) || (mask[1] & ~s->is_fiq[1]))
> -        cpu_interrupt(s->cpu_env, CPU_INTERRUPT_HARD);
> -    else
> -        cpu_reset_interrupt(s->cpu_env, CPU_INTERRUPT_HARD);
> +    qemu_set_irq(s->hard_irq,
> +            ((mask[0] & ~s->is_fiq[0]) || (mask[1] & ~s->is_fiq[1])));
>  }
>
>  /* Note: Here level means state of the signal on a pin, not
> @@ -241,53 +239,33 @@ static CPUWriteMemoryFunc * const pxa2xx_pic_writefn[] = {
>     pxa2xx_pic_mem_write,
>  };
>
> -static void pxa2xx_pic_save(QEMUFile *f, void *opaque)
> +static int pxa2xx_pic_post_load(void *opaque, int version_id)
>  {
> -    PXA2xxPICState *s = (PXA2xxPICState *) opaque;
> -    int i;
> -
> -    for (i = 0; i < 2; i ++)
> -        qemu_put_be32s(f, &s->int_enabled[i]);
> -    for (i = 0; i < 2; i ++)
> -        qemu_put_be32s(f, &s->int_pending[i]);
> -    for (i = 0; i < 2; i ++)
> -        qemu_put_be32s(f, &s->is_fiq[i]);
> -    qemu_put_be32s(f, &s->int_idle);
> -    for (i = 0; i < PXA2XX_PIC_SRCS; i ++)
> -        qemu_put_be32s(f, &s->priority[i]);
> +    pxa2xx_pic_update(opaque);
> +    return 0;
>  }
>
> -static int pxa2xx_pic_load(QEMUFile *f, void *opaque, int version_id)
> +DeviceState *pxa2xx_pic_init(target_phys_addr_t base, CPUState *env,
> +        qemu_irq *arm_pic)
>  {
> -    PXA2xxPICState *s = (PXA2xxPICState *) opaque;
> -    int i;
> -
> -    for (i = 0; i < 2; i ++)
> -        qemu_get_be32s(f, &s->int_enabled[i]);
> -    for (i = 0; i < 2; i ++)
> -        qemu_get_be32s(f, &s->int_pending[i]);
> -    for (i = 0; i < 2; i ++)
> -        qemu_get_be32s(f, &s->is_fiq[i]);
> -    qemu_get_be32s(f, &s->int_idle);
> -    for (i = 0; i < PXA2XX_PIC_SRCS; i ++)
> -        qemu_get_be32s(f, &s->priority[i]);
> +    DeviceState *dev;
>
> -    pxa2xx_pic_update(opaque);
> -    return 0;
> +    dev = sysbus_create_varargs("pxa2xx_pic", base,
> +            arm_pic[ARM_PIC_CPU_IRQ],
> +            arm_pic[ARM_PIC_CPU_FIQ],
> +            arm_pic[ARM_PIC_CPU_WAKE],
> +            NULL);
> +
> +    /* Enable IC coprocessor access.  */
> +    cpu_arm_set_cp_io(env, 6, pxa2xx_pic_cp_read, pxa2xx_pic_cp_write, dev);

I changed the last parameter to "s" as passing dev here was hacky.

Cheers

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH 02/10] pxa2xx_pic: update to use qdev and arm-pic
  2011-02-25 11:51   ` andrzej zaborowski
@ 2011-02-25 13:50     ` Dmitry Eremin-Solenikov
  2011-03-03 14:35       ` andrzej zaborowski
  0 siblings, 1 reply; 14+ messages in thread
From: Dmitry Eremin-Solenikov @ 2011-02-25 13:50 UTC (permalink / raw)
  To: andrzej zaborowski; +Cc: qemu-devel

On 2/25/11, andrzej zaborowski <balrogg@gmail.com> wrote:
> Hi Dmitry,
>
> On 20 February 2011 14:50, Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> wrote:
>> Use qdev/sysbus framework to handle pxa2xx-pic. Instead of exposing IRQs
>> via array, reference them via qdev_get_gpio_in(). Also pxa2xx_pic
>> duplicated
>> some code from arm-pic. Drop it, replacing with references to arm-pic,
>> as all other ARM SoCs do for their PIC code.
>
> As I said earlier not using arm-pic was deliberate (and I also asked
> what the gain was from converting the pic to a separate sysbus device
> from the CPU) so I skipped this part of the patch and pushed the rest
> of it, please check that everything works.

The primary goal was using arm-pic IRQs in pxa2xx-gpio and not having to
mess with passing CPUEnv around. Moreover all other ARM SoCs use
arm-pic w/o any references to performance gains/loses.

I can still provide a patch that will use arm-pic only for
pxa2xx-gpio, will that
be suitable for you?

BTW: it seems that your version won't work: using of sysbus_init_mmio()
is hackish and there is no place where that mmio region will be mapped to base.

About mapping pic to a separate device from CPU. Initially I wanted to reuse
somehow pxa2xx-pic for sa-11[0-1]0 emulation. It doesn't seem reasonable
for me anymore anyway. Second, the pic is already in separate
module, so I didn't want to disturb main pxa2xx.c with it.
I might still later use pxa2xx-pic for allocating main CPU structure and
making all other device hang on ot.

>> diff --git a/hw/mainstone.c b/hw/mainstone.c
>> index aec8d34..4eabdb9 100644
>> --- a/hw/mainstone.c
>> +++ b/hw/mainstone.c
>> @@ -140,7 +140,7 @@ static void mainstone_common_init(ram_addr_t ram_size,
>>     }
>>
>>     mst_irq = sysbus_create_simple("mainstone-fpga", MST_FPGA_PHYS,
>> -                    cpu->pic[PXA2XX_PIC_GPIO_0]);
>> +                    qdev_get_gpio_in(cpu->pic, PXA2XX_PIC_GPIO_0));
>
> I'm also wondering if this device should really use the interrupt line
> instead of using a GPIO.  It seems wrong that both the fpga and the
> gpio module are connected to the same line.

Fixed, will submit a fix soon.

>> @@ -241,53 +239,33 @@ static CPUWriteMemoryFunc * const
>> pxa2xx_pic_writefn[] = {
>>     pxa2xx_pic_mem_write,
>>  };
>>
>> -static void pxa2xx_pic_save(QEMUFile *f, void *opaque)
>> +static int pxa2xx_pic_post_load(void *opaque, int version_id)
>>  {
>> -    PXA2xxPICState *s = (PXA2xxPICState *) opaque;
>> -    int i;
>> -
>> -    for (i = 0; i < 2; i ++)
>> -        qemu_put_be32s(f, &s->int_enabled[i]);
>> -    for (i = 0; i < 2; i ++)
>> -        qemu_put_be32s(f, &s->int_pending[i]);
>> -    for (i = 0; i < 2; i ++)
>> -        qemu_put_be32s(f, &s->is_fiq[i]);
>> -    qemu_put_be32s(f, &s->int_idle);
>> -    for (i = 0; i < PXA2XX_PIC_SRCS; i ++)
>> -        qemu_put_be32s(f, &s->priority[i]);
>> +    pxa2xx_pic_update(opaque);
>> +    return 0;
>>  }
>>
>> -static int pxa2xx_pic_load(QEMUFile *f, void *opaque, int version_id)
>> +DeviceState *pxa2xx_pic_init(target_phys_addr_t base, CPUState *env,
>> +        qemu_irq *arm_pic)
>>  {
>> -    PXA2xxPICState *s = (PXA2xxPICState *) opaque;
>> -    int i;
>> -
>> -    for (i = 0; i < 2; i ++)
>> -        qemu_get_be32s(f, &s->int_enabled[i]);
>> -    for (i = 0; i < 2; i ++)
>> -        qemu_get_be32s(f, &s->int_pending[i]);
>> -    for (i = 0; i < 2; i ++)
>> -        qemu_get_be32s(f, &s->is_fiq[i]);
>> -    qemu_get_be32s(f, &s->int_idle);
>> -    for (i = 0; i < PXA2XX_PIC_SRCS; i ++)
>> -        qemu_get_be32s(f, &s->priority[i]);
>> +    DeviceState *dev;
>>
>> -    pxa2xx_pic_update(opaque);
>> -    return 0;
>> +    dev = sysbus_create_varargs("pxa2xx_pic", base,
>> +            arm_pic[ARM_PIC_CPU_IRQ],
>> +            arm_pic[ARM_PIC_CPU_FIQ],
>> +            arm_pic[ARM_PIC_CPU_WAKE],
>> +            NULL);
>> +
>> +    /* Enable IC coprocessor access.  */
>> +    cpu_arm_set_cp_io(env, 6, pxa2xx_pic_cp_read, pxa2xx_pic_cp_write,
>> dev);
>
> I changed the last parameter to "s" as passing dev here was hacky.


Fine with me.


BTW: what about all other patches?

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [Qemu-devel] [PATCH 02/10] pxa2xx_pic: update to use qdev and arm-pic
  2011-02-25 13:50     ` Dmitry Eremin-Solenikov
@ 2011-03-03 14:35       ` andrzej zaborowski
  0 siblings, 0 replies; 14+ messages in thread
From: andrzej zaborowski @ 2011-03-03 14:35 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov; +Cc: qemu-devel

On 25 February 2011 14:50, Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> wrote:
> On 2/25/11, andrzej zaborowski <balrogg@gmail.com> wrote:
>> Hi Dmitry,
>>
>> On 20 February 2011 14:50, Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>> wrote:
>>> Use qdev/sysbus framework to handle pxa2xx-pic. Instead of exposing IRQs
>>> via array, reference them via qdev_get_gpio_in(). Also pxa2xx_pic
>>> duplicated
>>> some code from arm-pic. Drop it, replacing with references to arm-pic,
>>> as all other ARM SoCs do for their PIC code.
>>
>> As I said earlier not using arm-pic was deliberate (and I also asked
>> what the gain was from converting the pic to a separate sysbus device
>> from the CPU) so I skipped this part of the patch and pushed the rest
>> of it, please check that everything works.
>
> The primary goal was using arm-pic IRQs in pxa2xx-gpio and not having to
> mess with passing CPUEnv around. Moreover all other ARM SoCs use
> arm-pic w/o any references to performance gains/loses.
>
> I can still provide a patch that will use arm-pic only for
> pxa2xx-gpio, will that
> be suitable for you?

Well my take on it is that it adds an additional level indirection.
More levels of indirection / abstraction are only good if they enable
some new feature or make a big difference in the code and it's not the
case here.  Otherwise they make bloat and more levels of function
calls which add up to small overheads.  And I don't see using CPUEnv
as a hack anyway.

I pushed the remaining patches with small adjustments.

Cheers

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2011-03-03 14:35 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-02-20 13:50 [Qemu-devel] [PATCH 0/10] pxa2xx: work on switching to qdev/vmstate Dmitry Eremin-Solenikov
2011-02-20 13:50 ` [Qemu-devel] [PATCH 01/10] arm-pic: add one extra interrupt to support EXITTB interrupts Dmitry Eremin-Solenikov
2011-02-20 13:50 ` [Qemu-devel] [PATCH 02/10] pxa2xx_pic: update to use qdev and arm-pic Dmitry Eremin-Solenikov
2011-02-25 11:51   ` andrzej zaborowski
2011-02-25 13:50     ` Dmitry Eremin-Solenikov
2011-03-03 14:35       ` andrzej zaborowski
2011-02-20 13:50 ` [Qemu-devel] [PATCH 03/10] pxa2xx_gpio: simplify by reusing wake irq from arm_pic Dmitry Eremin-Solenikov
2011-02-20 13:50 ` [Qemu-devel] [PATCH 04/10] vmstate: add VMSTATE_STRUCT_ARRAY_TEST Dmitry Eremin-Solenikov
2011-02-20 13:50 ` [Qemu-devel] [PATCH 05/10] pxa2xx_timer: change info struct name to comply with guidelines Dmitry Eremin-Solenikov
2011-02-20 13:50 ` [Qemu-devel] [PATCH 06/10] pxa2xx_timer: switch to using qdev/vmstate Dmitry Eremin-Solenikov
2011-02-20 13:50 ` [Qemu-devel] [PATCH 07/10] vmstate: move VMSTATE_PCIE_AER_ERRS to hw/hw.h Dmitry Eremin-Solenikov
2011-02-20 13:50 ` [Qemu-devel] [PATCH 08/10] pxa2xx_dma: drop unused pxa2xx_dma_handler_t/handler field Dmitry Eremin-Solenikov
2011-02-20 13:50 ` [Qemu-devel] [PATCH 09/10] pxa2xx_dma: port to qdev/vmstate Dmitry Eremin-Solenikov
2011-02-20 13:50 ` [Qemu-devel] [PATCH 10/10] pxa2xx: port pxa2xx_rtc to using qdev/vmstate Dmitry Eremin-Solenikov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.