From patchwork Wed Jun 13 09:38:31 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Peter A. G. Crosthwaite" X-Patchwork-Id: 164580 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 246CBB6FA8 for ; Wed, 13 Jun 2012 19:30:01 +1000 (EST) Received: from localhost ([::1]:33293 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Sejtm-0005At-N6 for incoming@patchwork.ozlabs.org; Wed, 13 Jun 2012 05:29:58 -0400 Received: from eggs.gnu.org ([208.118.235.92]:43339) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SejtT-0004ko-O3 for qemu-devel@nongnu.org; Wed, 13 Jun 2012 05:29:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SejtQ-0002v2-UE for qemu-devel@nongnu.org; Wed, 13 Jun 2012 05:29:39 -0400 Received: from mail-pz0-f47.google.com ([209.85.210.47]:64204) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SejtQ-0002um-K4 for qemu-devel@nongnu.org; Wed, 13 Jun 2012 05:29:36 -0400 Received: by dalh21 with SMTP id h21so817971dal.34 for ; Wed, 13 Jun 2012 02:29:34 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :in-reply-to:references:x-gm-message-state; bh=QuA7OJO1wwYEN0w8ZkG8oHFBpiiuT4qWrkCC1z05LTc=; b=O/v/hU/ilqbz/sGCMn3zeUntjm51eBGc+LMfckIW8PGxMYkGTClfleUyvA2QGOs4ia T/jNS+R+iq91gFZU1B8uIypIBGSfBRNPpwYMK3/LBnIgorFLyWLv/LFUsItj8A1HPumm Eg/uYaM4oRF1R5hMfC3Zq9XVJf64uKOGGsL8CI1heVf0118Ig2jXPAf7ZnzP1Kc88Zuj uq3cocXyFay5G/dlJLlP2UTqJqDTj1V5VgaTLb4UgOpYt98wh7jNXF35Wc97q1vHH04x m6AqNWJB5axXsizoSgzXHA8uHuqGEEonbnq/faZs70L+RVWbXj51wrsrLuu9C5iKe+ir 6syw== Received: by 10.68.223.129 with SMTP id qu1mr48228538pbc.165.1339579774034; Wed, 13 Jun 2012 02:29:34 -0700 (PDT) Received: from localhost ([124.148.20.9]) by mx.google.com with ESMTPS id ph1sm5156878pbb.45.2012.06.13.02.29.28 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 13 Jun 2012 02:29:33 -0700 (PDT) From: "Peter A. G. Crosthwaite" To: qemu-devel@nongnu.org, aliguori@us.ibm.com, pbonzini@redhat.com Date: Wed, 13 Jun 2012 19:38:31 +1000 Message-Id: X-Mailer: git-send-email 1.7.3.2 In-Reply-To: References: In-Reply-To: References: X-Gm-Message-State: ALoCoQnO25/pK2hwYNPc6kJPSGhAIjSkim9aXVLpd8XhCgmvkRA8403OvHY0zcmQEznEPDDSv/5n X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.210.47 Cc: peter.maydell@linaro.org, peter.crosthwaite@petalogix.com, paul@codesourcery.com, edgar.iglesias@gmail.com, afaerber@suse.de, john.williams@petalogix.com, avi@redhat.com Subject: [Qemu-devel] [RFC v0 2/8] xilinx: remove PROP_PTR properties X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Paolo Bonzini Signed-off-by: Paolo Bonzini --- 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 --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)