* [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.