diff mbox

[RFC,v0,2/8] xilinx: remove PROP_PTR properties

Message ID c99cecf596f18d4a7ded9caff8c96c12273f150c.1339578989.git.peter.crosthwaite@petalogix.com
State New
Headers show

Commit Message

Peter A. G. Crosthwaite June 13, 2012, 9:38 a.m. UTC
From: Paolo Bonzini <pbonzini@redhat.com>

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/petalogix_ml605_mmu.c |   17 +++++++--------
 hw/xilinx.h              |   22 ++++++++-----------
 hw/xilinx_axidma.c       |   39 +++++++++++++++++++++++-----------
 hw/xilinx_axidma.h       |   52 ++++++++++++++++++++-------------------------
 hw/xilinx_axienet.c      |   35 +++++++++++++++++++++---------
 5 files changed, 90 insertions(+), 75 deletions(-)
diff mbox

Patch

diff --git a/hw/petalogix_ml605_mmu.c b/hw/petalogix_ml605_mmu.c
index bff63e3..37866f4 100644
--- a/hw/petalogix_ml605_mmu.c
+++ b/hw/petalogix_ml605_mmu.c
@@ -125,15 +125,14 @@  petalogix_ml605_init(ram_addr_t ram_size,
     /* 2 timers at irq 2 @ 100 Mhz.  */
     xilinx_timer_create(TIMER_BASEADDR, irq[2], 2, 100 * 1000000);
 
-    /* axi ethernet and dma initialization. TODO: Dynamically connect them.  */
-    {
-        static struct XilinxDMAConnection dmach;
-
-        xilinx_axiethernet_create(&dmach, &nd_table[0], 0x82780000,
-                                  irq[3], 0x1000, 0x1000);
-        xilinx_axiethernetdma_create(&dmach, 0x84600000,
-                                     irq[1], irq[0], 100 * 1000000);
-    }
+    /* axi ethernet and dma initialization. */
+    DeviceState *dma = qdev_create(NULL, "xilinx-axidma");
+    DeviceState *eth0;
+
+    eth0 = xilinx_axiethernet_create(&nd_table[0], XILINX_AXIDMA_PEER(dma),
+                                     0x82780000, irq[3], 0x1000, 0x1000);
+    xilinx_axiethernetdma_init(dma, XILINX_AXIDMA_PEER(eth0),
+                               0x84600000, irq[1], irq[0], 100 * 1000000);
 
     microblaze_load_kernel(cpu, ddr_base, ram_size, BINARY_DEVICE_TREE_FILE,
                                                             machine_cpu_reset);
diff --git a/hw/xilinx.h b/hw/xilinx.h
index 35f35bd..5ccf3fa 100644
--- a/hw/xilinx.h
+++ b/hw/xilinx.h
@@ -1,3 +1,4 @@ 
+#include "xilinx_axidma.h"
 #include "qemu-common.h"
 #include "net.h"
 
@@ -49,8 +50,8 @@  xilinx_ethlite_create(NICInfo *nd, target_phys_addr_t base, qemu_irq irq,
 }
 
 static inline DeviceState *
-xilinx_axiethernet_create(void *dmach,
-                          NICInfo *nd, target_phys_addr_t base, qemu_irq irq,
+xilinx_axiethernet_create(NICInfo *nd, XilinxAXIDMAPeer *peer,
+                          target_phys_addr_t base, qemu_irq irq,
                           int txmem, int rxmem)
 {
     DeviceState *dev;
@@ -60,7 +61,7 @@  xilinx_axiethernet_create(void *dmach,
     qdev_set_nic_properties(dev, nd);
     qdev_prop_set_uint32(dev, "c_rxmem", rxmem);
     qdev_prop_set_uint32(dev, "c_txmem", txmem);
-    qdev_prop_set_ptr(dev, "dmach", dmach);
+    object_property_set_link(OBJECT(dev), OBJECT(peer), "peer", NULL);
     qdev_init_nofail(dev);
     sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
     sysbus_connect_irq(sysbus_from_qdev(dev), 0, irq);
@@ -68,21 +69,16 @@  xilinx_axiethernet_create(void *dmach,
     return dev;
 }
 
-static inline DeviceState *
-xilinx_axiethernetdma_create(void *dmach,
-                             target_phys_addr_t base, qemu_irq irq,
-                             qemu_irq irq2, int freqhz)
+static inline void
+xilinx_axiethernetdma_init(DeviceState *dev, XilinxAXIDMAPeer *peer,
+                           target_phys_addr_t base, qemu_irq irq,
+                           qemu_irq irq2, int freqhz)
 {
-    DeviceState *dev = NULL;
-
-    dev = qdev_create(NULL, "xilinx,axidma");
     qdev_prop_set_uint32(dev, "freqhz", freqhz);
-    qdev_prop_set_ptr(dev, "dmach", dmach);
+    object_property_set_link(OBJECT(dev), OBJECT(peer), "peer", NULL);
     qdev_init_nofail(dev);
 
     sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
     sysbus_connect_irq(sysbus_from_qdev(dev), 0, irq2);
     sysbus_connect_irq(sysbus_from_qdev(dev), 1, irq);
-
-    return dev;
 }
diff --git a/hw/xilinx_axidma.c b/hw/xilinx_axidma.c
index 85dfcbf..b82c02e 100644
--- a/hw/xilinx_axidma.c
+++ b/hw/xilinx_axidma.c
@@ -94,7 +94,7 @@  struct XilinxAXIDMA {
     SysBusDevice busdev;
     MemoryRegion iomem;
     uint32_t freqhz;
-    void *dmach;
+    XilinxAXIDMAPeer *peer;
 
     struct AXIStream streams[2];
 };
@@ -241,7 +241,7 @@  static void stream_complete(struct AXIStream *s)
 }
 
 static void stream_process_mem2s(struct AXIStream *s,
-                                 struct XilinxDMAConnection *dmach)
+                                 XilinxAXIDMAPeer *peer)
 {
     uint32_t prev_d;
     unsigned char txbuf[16 * 1024];
@@ -276,7 +276,7 @@  static void stream_process_mem2s(struct AXIStream *s,
         s->pos += txlen;
 
         if (stream_desc_eof(&s->desc)) {
-            xlx_dma_push_to_client(dmach, txbuf, s->pos, app);
+            xlx_dma_push(peer, txbuf, s->pos, app);
             s->pos = 0;
             stream_complete(s);
         }
@@ -352,9 +352,9 @@  static void stream_process_s2mem(struct AXIStream *s,
 }
 
 static
-void axidma_push(void *opaque, unsigned char *buf, size_t len, uint32_t *app)
+void axidma_push(Object *obj, unsigned char *buf, size_t len, uint32_t *app)
 {
-    struct XilinxAXIDMA *d = opaque;
+    struct XilinxAXIDMA *d = FROM_SYSBUS(typeof(*d), SYS_BUS_DEVICE(obj));
     struct AXIStream *s = &d->streams[1];
 
     if (!app) {
@@ -440,7 +440,7 @@  static void axidma_write(void *opaque, target_phys_addr_t addr,
             s->regs[addr] = value;
             s->regs[R_DMASR] &= ~DMASR_IDLE; /* Not idle.  */
             if (!sid) {
-                stream_process_mem2s(s, d->dmach);
+                stream_process_mem2s(s, d->peer);
             }
             break;
         default:
@@ -466,12 +466,6 @@  static int xilinx_axidma_init(SysBusDevice *dev)
     sysbus_init_irq(dev, &s->streams[1].irq);
     sysbus_init_irq(dev, &s->streams[0].irq);
 
-    if (!s->dmach) {
-        hw_error("Unconnected DMA channel.\n");
-    }
-
-    xlx_dma_connect_dma(s->dmach, s, axidma_push);
-
     memory_region_init_io(&s->iomem, &axidma_ops, s,
                           "axidma", R_MAX * 4 * 2);
     sysbus_init_mmio(dev, &s->iomem);
@@ -486,9 +480,23 @@  static int xilinx_axidma_init(SysBusDevice *dev)
     return 0;
 }
 
+static void xilinx_axidma_initfn(Object *obj)
+{
+    struct XilinxAXIDMA *s = FROM_SYSBUS(typeof(*s), SYS_BUS_DEVICE(obj));
+
+    object_property_add_link(obj, "peer", TYPE_XILINX_AXIDMA_PEER, 
+                             (Object **) &s->peer, NULL);
+}
+
+static void xilinx_axidma_peer_initfn(ObjectClass *klass, void *data)
+{
+    XilinxAXIDMAPeerIface *k = XILINX_AXIDMA_PEER_IFACE(klass);
+
+    k->push = axidma_push;
+}
+
 static Property axidma_properties[] = {
     DEFINE_PROP_UINT32("freqhz", struct XilinxAXIDMA, freqhz, 50000000),
-    DEFINE_PROP_PTR("dmach", struct XilinxAXIDMA, dmach),
     DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -506,6 +514,11 @@  static TypeInfo axidma_info = {
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(struct XilinxAXIDMA),
     .class_init    = axidma_class_init,
+    .instance_init = xilinx_axidma_initfn,
+    .interfaces = (InterfaceInfo[]) {
+	    { TYPE_XILINX_AXIDMA_PEER, xilinx_axidma_peer_initfn },
+	    { }
+    }
 };
 
 static void xilinx_axidma_register_types(void)
diff --git a/hw/xilinx_axidma.h b/hw/xilinx_axidma.h
index 37cb6f0..99c8371 100644
--- a/hw/xilinx_axidma.h
+++ b/hw/xilinx_axidma.h
@@ -1,39 +1,33 @@ 
+#ifndef XILINX_AXIDMA_H
+#define XILINX_AXIDMA_H 1
+
 /* AXI DMA connection. Used until qdev provides a generic way.  */
-typedef void (*DMAPushFn)(void *opaque,
-                            unsigned char *buf, size_t len, uint32_t *app);
+#define TYPE_XILINX_AXIDMA_PEER "xilinx-axidma-peer"
 
-struct XilinxDMAConnection {
-    void *dma;
-    void *client;
+#define XILINX_AXIDMA_PEER_IFACE(klass) \
+     OBJECT_CLASS_CHECK(XilinxAXIDMAPeerIface, klass, TYPE_XILINX_AXIDMA_PEER)
 
-    DMAPushFn to_dma;
-    DMAPushFn to_client;
-};
+/* This is usually done implicitly by object_set_link_property.  */
+#define XILINX_AXIDMA_PEER(obj) \
+     OBJECT_CHECK(XilinxAXIDMAPeer, obj, TYPE_XILINX_AXIDMA_PEER)
 
-static inline void xlx_dma_connect_client(struct XilinxDMAConnection *dmach,
-                                          void *c, DMAPushFn f)
-{
-    dmach->client = c;
-    dmach->to_client = f;
-}
+typedef Interface XilinxAXIDMAPeer;
+typedef struct XilinxAXIDMAPeerIface XilinxAXIDMAPeerIface;
 
-static inline void xlx_dma_connect_dma(struct XilinxDMAConnection *dmach,
-                                       void *d, DMAPushFn f)
-{
-    dmach->dma = d;
-    dmach->to_dma = f;
-}
+struct XilinxAXIDMAPeerIface {
+    InterfaceClass parent;
+
+    void (*push)(Object *obj, unsigned char *buf, size_t len, uint32_t *app);
+};
 
 static inline
-void xlx_dma_push_to_dma(struct XilinxDMAConnection *dmach,
-                         uint8_t *buf, size_t len, uint32_t *app)
-{
-    dmach->to_dma(dmach->dma, buf, len, app);
-}
-static inline
-void xlx_dma_push_to_client(struct XilinxDMAConnection *dmach,
-                            uint8_t *buf, size_t len, uint32_t *app)
+void xlx_dma_push(XilinxAXIDMAPeer *peer,
+                  uint8_t *buf, size_t len, uint32_t *app)
 {
-    dmach->to_client(dmach->client, buf, len, app);
+    XilinxAXIDMAPeerIface *iface = container_of(INTERFACE_GET_CLASS(peer),
+                                                XilinxAXIDMAPeerIface,
+                                                parent);
+    iface->push(INTERFACE_OBJECT(peer), buf, len, app);
 }
 
+#endif
diff --git a/hw/xilinx_axienet.c b/hw/xilinx_axienet.c
index a25949b..a340cf2 100644
--- a/hw/xilinx_axienet.c
+++ b/hw/xilinx_axienet.c
@@ -310,7 +310,7 @@  struct XilinxAXIEnet {
     SysBusDevice busdev;
     MemoryRegion iomem;
     qemu_irq irq;
-    void *dmach;
+    XilinxAXIDMAPeer *peer;
     NICState *nic;
     NICConf conf;
 
@@ -773,7 +773,7 @@  static ssize_t eth_rx(VLANClientState *nc, const uint8_t *buf, size_t size)
     /* Good frame.  */
     app[2] |= 1 << 6;
 
-    xlx_dma_push_to_dma(s->dmach, (void *)s->rxmem, size, app);
+    xlx_dma_push(s->peer, (void *)s->rxmem, size, app);
 
     s->regs[R_IS] |= IS_RX_COMPLETE;
     enet_update_irq(s);
@@ -789,9 +789,9 @@  static void eth_cleanup(VLANClientState *nc)
 }
 
 static void
-axienet_stream_push(void *opaque, uint8_t *buf, size_t size, uint32_t *hdr)
+axienet_stream_push(Object *obj, uint8_t *buf, size_t size, uint32_t *hdr)
 {
-    struct XilinxAXIEnet *s = opaque;
+    struct XilinxAXIEnet *s = FROM_SYSBUS(typeof(*s), SYS_BUS_DEVICE(obj));
 
     /* TX enable ?  */
     if (!(s->tc & TC_TX)) {
@@ -845,12 +845,6 @@  static int xilinx_enet_init(SysBusDevice *dev)
 
     sysbus_init_irq(dev, &s->irq);
 
-    if (!s->dmach) {
-        hw_error("Unconnected Xilinx Ethernet MAC.\n");
-    }
-
-    xlx_dma_connect_client(s->dmach, s, axienet_stream_push);
-
     memory_region_init_io(&s->iomem, &enet_ops, s, "enet", 0x40000);
     sysbus_init_mmio(dev, &s->iomem);
 
@@ -870,11 +864,25 @@  static int xilinx_enet_init(SysBusDevice *dev)
     return 0;
 }
 
+static void xilinx_enet_initfn(Object *obj)
+{
+    struct XilinxAXIEnet *s = FROM_SYSBUS(typeof(*s), SYS_BUS_DEVICE(obj));
+
+    object_property_add_link(obj, "peer", TYPE_XILINX_AXIDMA_PEER,
+                             (Object **) &s->peer, NULL);
+}
+
+static void xilinx_enet_peer_initfn(ObjectClass *klass, void *data)
+{
+    XilinxAXIDMAPeerIface *k = XILINX_AXIDMA_PEER_IFACE(klass);
+
+    k->push = axienet_stream_push;
+}
+
 static Property xilinx_enet_properties[] = {
     DEFINE_PROP_UINT32("phyaddr", struct XilinxAXIEnet, c_phyaddr, 7),
     DEFINE_PROP_UINT32("c_rxmem", struct XilinxAXIEnet, c_rxmem, 0x1000),
     DEFINE_PROP_UINT32("c_txmem", struct XilinxAXIEnet, c_txmem, 0x1000),
-    DEFINE_PROP_PTR("dmach", struct XilinxAXIEnet, dmach),
     DEFINE_NIC_PROPERTIES(struct XilinxAXIEnet, conf),
     DEFINE_PROP_END_OF_LIST(),
 };
@@ -893,6 +901,11 @@  static TypeInfo xilinx_enet_info = {
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(struct XilinxAXIEnet),
     .class_init    = xilinx_enet_class_init,
+    .instance_init = xilinx_enet_initfn,
+    .interfaces = (InterfaceInfo[]) {
+            { TYPE_XILINX_AXIDMA_PEER, xilinx_enet_peer_initfn },
+            { }
+    }
 };
 
 static void xilinx_enet_register_types(void)