From patchwork Wed Apr 3 05:17:12 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Crosthwaite X-Patchwork-Id: 233247 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 2B9212C0150 for ; Wed, 3 Apr 2013 16:25:31 +1100 (EST) Received: from localhost ([::1]:57016 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UNGCP-0001Gv-AW for incoming@patchwork.ozlabs.org; Wed, 03 Apr 2013 01:25:29 -0400 Received: from eggs.gnu.org ([208.118.235.92]:39963) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UNGBs-00015q-5f for qemu-devel@nongnu.org; Wed, 03 Apr 2013 01:24:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UNGBq-0004Po-L8 for qemu-devel@nongnu.org; Wed, 03 Apr 2013 01:24:56 -0400 Received: from mail-pb0-f46.google.com ([209.85.160.46]:48214) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UNGBq-0004Pe-Cc for qemu-devel@nongnu.org; Wed, 03 Apr 2013 01:24:54 -0400 Received: by mail-pb0-f46.google.com with SMTP id rp8so643180pbb.33 for ; Tue, 02 Apr 2013 22:24:53 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:sender:from:to:cc:subject:date:message-id:x-mailer :in-reply-to:references:in-reply-to:references:x-gm-message-state; bh=3BS+P3BlAMF2WrpnEGr2XtKs4nHRnWbRfTEiBTKVrGs=; b=IM7XuWh3GIqoOp2WxsWSCv7XYp/GhDvthrVMe1WGr/Jmqj5vdmtgshKC5flwZFLfym 3Uvzmf3xIH7ZccD3+9dd6ICAo9qQSy6ORqGV36YUX84w2/N+ilJgqxtdeZHTu7WPTVOr 7KQPaLbCkrGJhuBSVfSO68SASYWu1QjzLx7Ek6vhx7C4ioNukmSKUqV+yQfz8jAjThIK 7d0bx3AduzUG0VuQBlzO1i+TBU5N5/rLn73wpXL3X47pViPCyan3LOUbzJ1961cMMyL3 OkdAnkUbqih5gkdCKY6BGJ05c6oetqM4z+8xTvwPjE9PjQ7KSDNuJCAlh+fwaUtwT2ZH zNXw== X-Received: by 10.68.204.68 with SMTP id kw4mr442019pbc.76.1364966693599; Tue, 02 Apr 2013 22:24:53 -0700 (PDT) Received: from localhost ([149.199.62.254]) by mx.google.com with ESMTPS id 4sm4495722pbn.23.2013.04.02.22.24.50 (version=TLSv1.1 cipher=RC4-SHA bits=128/128); Tue, 02 Apr 2013 22:24:52 -0700 (PDT) From: Peter Crosthwaite To: qemu-devel@nongnu.org, edgar.iglesias@gmail.com Date: Wed, 3 Apr 2013 15:17:12 +1000 Message-Id: X-Mailer: git-send-email 1.7.0.4 In-Reply-To: References: In-Reply-To: References: X-Gm-Message-State: ALoCoQmIinvawg5gd0RLnf1RqBRIXuqvQWMc0f/eLemqqMISJbOVZIA4emQ1vEW6KFnLl+XiqhkB X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 209.85.160.46 Cc: Peter Crosthwaite Subject: [Qemu-devel] [PATCH v5 12/16] xilinx_axidma: Create Proxy object for stream 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 Create a separate child object to proxy the stream slave connection. This is setup for future work where a second stream slave connection is needed. The new child object is created at qdev init time and is linked back to the parent (the ethernet device itself) automatically. Stream slave masters differentiate which slave connection they are connected to by linking to the proxy object rather than the parent. Signed-off-by: Peter Crosthwaite --- changed since v3: Rebased to occur before flow control patches hw/microblaze/petalogix_ml605_mmu.c | 6 ++- hw/xilinx_axidma.c | 63 ++++++++++++++++++++++++++++++++--- 2 files changed, 62 insertions(+), 7 deletions(-) diff --git a/hw/microblaze/petalogix_ml605_mmu.c b/hw/microblaze/petalogix_ml605_mmu.c index 9240660..7581275 100644 --- a/hw/microblaze/petalogix_ml605_mmu.c +++ b/hw/microblaze/petalogix_ml605_mmu.c @@ -140,8 +140,10 @@ petalogix_ml605_init(QEMUMachineInitArgs *args) object_property_add_child(qdev_get_machine(), "xilinx-dma", OBJECT(dma), NULL); - xilinx_axiethernet_init(eth0, &nd_table[0], STREAM_SLAVE(dma), - 0x82780000, irq[3], 0x1000, 0x1000); + peer = object_property_get_link(OBJECT(dma), + "axistream-connected-target", NULL); + xilinx_axiethernet_init(eth0, &nd_table[0], STREAM_SLAVE(peer), + 0x82780000, irq[3], 0x1000, 0x1000); peer = object_property_get_link(OBJECT(eth0), "axistream-connected-target", NULL); diff --git a/hw/xilinx_axidma.c b/hw/xilinx_axidma.c index 2c95765..02700ea 100644 --- a/hw/xilinx_axidma.c +++ b/hw/xilinx_axidma.c @@ -34,10 +34,15 @@ #define D(x) #define TYPE_XILINX_AXI_DMA "xlnx.axi-dma" +#define TYPE_XILINX_AXI_DMA_DATA_STREAM "xilinx-axi-dma-data-stream" #define XILINX_AXI_DMA(obj) \ OBJECT_CHECK(XilinxAXIDMA, (obj), TYPE_XILINX_AXI_DMA) +#define XILINX_AXI_DMA_DATA_STREAM(obj) \ + OBJECT_CHECK(XilinxAXIDMAStreamSlave, (obj),\ + TYPE_XILINX_AXI_DMA_DATA_STREAM) + #define R_DMACR (0x00 / 4) #define R_DMASR (0x04 / 4) #define R_CURDESC (0x08 / 4) @@ -45,6 +50,7 @@ #define R_MAX (0x30 / 4) typedef struct XilinxAXIDMA XilinxAXIDMA; +typedef struct XilinxAXIDMAStreamSlave XilinxAXIDMAStreamSlave; enum { DMACR_RUNSTOP = 1, @@ -97,11 +103,18 @@ struct Stream { uint32_t regs[R_MAX]; }; +struct XilinxAXIDMAStreamSlave { + Object parent; + + struct XilinxAXIDMA *dma; +}; + struct XilinxAXIDMA { SysBusDevice busdev; MemoryRegion iomem; uint32_t freqhz; StreamSlave *tx_dev; + XilinxAXIDMAStreamSlave rx_data_dev; struct Stream streams[2]; }; @@ -369,10 +382,11 @@ static void xilinx_axidma_reset(DeviceState *dev) } static void -axidma_push(StreamSlave *obj, unsigned char *buf, size_t len, uint32_t *app) +xilinx_axidma_data_stream_push(StreamSlave *obj, unsigned char *buf, size_t len, + uint32_t *app) { - XilinxAXIDMA *d = XILINX_AXI_DMA(obj); - struct Stream *s = &d->streams[1]; + XilinxAXIDMAStreamSlave *ds = XILINX_AXI_DMA_DATA_STREAM(obj); + struct Stream *s = &ds->dma->streams[1]; if (!app) { hw_error("No stream app data!\n"); @@ -478,6 +492,19 @@ static const MemoryRegionOps axidma_ops = { static void xilinx_axidma_realize(DeviceState *dev, Error **errp) { XilinxAXIDMA *s = XILINX_AXI_DMA(dev); + XilinxAXIDMAStreamSlave *ds = XILINX_AXI_DMA_DATA_STREAM(&s->rx_data_dev); + Error *local_errp = NULL; + + object_property_add_link(OBJECT(ds), "dma", TYPE_XILINX_AXI_DMA, + (Object **)&ds->dma, &local_errp); + if (local_errp) { + goto xilinx_axidma_realize_fail; + } + object_property_set_link(OBJECT(ds), OBJECT(s), "dma", &local_errp); + if (local_errp) { + goto xilinx_axidma_realize_fail; + } + int i; for (i = 0; i < 2; i++) { @@ -486,16 +513,28 @@ static void xilinx_axidma_realize(DeviceState *dev, Error **errp) s->streams[i].ptimer = ptimer_init(s->streams[i].bh); ptimer_set_freq(s->streams[i].ptimer, s->freqhz); } + return; + +xilinx_axidma_realize_fail: + if (!*errp) { + *errp = local_errp; + } } static void xilinx_axidma_init(Object *obj) { XilinxAXIDMA *s = XILINX_AXI_DMA(obj); SysBusDevice *sbd = SYS_BUS_DEVICE(obj); + Error *errp = NULL; object_property_add_link(obj, "axistream-connected", TYPE_STREAM_SLAVE, (Object **) &s->tx_dev, NULL); + object_initialize(&s->rx_data_dev, TYPE_XILINX_AXI_DMA_DATA_STREAM); + object_property_add_child(OBJECT(s), "axistream-connected-target", + (Object *)&s->rx_data_dev, &errp); + assert_no_error(errp); + sysbus_init_irq(sbd, &s->streams[0].irq); sysbus_init_irq(sbd, &s->streams[1].irq); @@ -512,12 +551,17 @@ static Property axidma_properties[] = { static void axidma_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - StreamSlaveClass *ssc = STREAM_SLAVE_CLASS(klass); dc->realize = xilinx_axidma_realize, dc->reset = xilinx_axidma_reset; dc->props = axidma_properties; - ssc->push = axidma_push; +} + +static void xilinx_axidma_stream_class_init(ObjectClass *klass, void *data) +{ + StreamSlaveClass *ssc = STREAM_SLAVE_CLASS(klass); + + ssc->push = data; } static const TypeInfo axidma_info = { @@ -526,6 +570,14 @@ static const TypeInfo axidma_info = { .instance_size = sizeof(XilinxAXIDMA), .class_init = axidma_class_init, .instance_init = xilinx_axidma_init, +}; + +static const TypeInfo xilinx_axidma_data_stream_info = { + .name = TYPE_XILINX_AXI_DMA_DATA_STREAM, + .parent = TYPE_OBJECT, + .instance_size = sizeof(struct XilinxAXIDMAStreamSlave), + .class_init = xilinx_axidma_stream_class_init, + .class_data = xilinx_axidma_data_stream_push, .interfaces = (InterfaceInfo[]) { { TYPE_STREAM_SLAVE }, { } @@ -535,6 +587,7 @@ static const TypeInfo axidma_info = { static void xilinx_axidma_register_types(void) { type_register_static(&axidma_info); + type_register_static(&xilinx_axidma_data_stream_info); } type_init(xilinx_axidma_register_types)