qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/9] hw/core: stream: Add end-of-packet flag
@ 2020-05-06  8:25 Edgar E. Iglesias
  2020-05-06  8:25 ` [PATCH v2 1/9] hw/net/xilinx_axienet: Auto-clear PHY Autoneg Edgar E. Iglesias
                   ` (8 more replies)
  0 siblings, 9 replies; 16+ messages in thread
From: Edgar E. Iglesias @ 2020-05-06  8:25 UTC (permalink / raw)
  To: qemu-devel
  Cc: damien.hedde, peter.maydell, sstabellini, edgar.iglesias,
	sai.pavan.boddu, frasse.iglesias, jasowang, alistair,
	frederic.konrad, qemu-arm, philmd, luc.michel, figlesia

From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>

Hi,

When modeling pipelines of processing nodes that communicate
through streaming interfaces (e.g AXI-Stream), some of these
nodes send packets while others may just stream unpacketized data.

The purpose of this series is to add an end-of-packet flag, e.g
what AXI-Stream calls tlast. This is in preparation for modeling
future nodes that may use huge packets that we wouldn't be able
to buffer and also to handle nodes that don't use packets.

Along the way I fixed a few things in the petalinux-ml605 eth setup.

Cheers,
Edgar

ChangeLog:

v1 -> v2:
* Check that packets fit c_txmem

Edgar E. Iglesias (9):
  hw/net/xilinx_axienet: Auto-clear PHY Autoneg
  hw/net/xilinx_axienet: Cleanup stream->push assignment
  hw/net/xilinx_axienet: Remove unncessary cast
  hw/dma/xilinx_axidma: Add DMA memory-region property
  hw/core: stream: Add an end-of-packet flag
  hw/net/xilinx_axienet: Handle fragmented packets from DMA
  hw/dma/xilinx_axidma: mm2s: Stream descriptor by descriptor
  hw/dma/xilinx_axidma: s2mm: Support stream fragments
  MAINTAINERS: Add myself as streams maintainer

 include/hw/stream.h     |  5 +--
 hw/core/stream.c        |  4 +--
 hw/dma/xilinx_axidma.c  | 75 ++++++++++++++++++++++++++---------------
 hw/net/xilinx_axienet.c | 70 ++++++++++++++++++++++++++++----------
 hw/ssi/xilinx_spips.c   |  2 +-
 MAINTAINERS             |  6 ++++
 6 files changed, 113 insertions(+), 49 deletions(-)

-- 
2.20.1



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

* [PATCH v2 1/9] hw/net/xilinx_axienet: Auto-clear PHY Autoneg
  2020-05-06  8:25 [PATCH v2 0/9] hw/core: stream: Add end-of-packet flag Edgar E. Iglesias
@ 2020-05-06  8:25 ` Edgar E. Iglesias
  2020-05-06  8:25 ` [PATCH v2 2/9] hw/net/xilinx_axienet: Cleanup stream->push assignment Edgar E. Iglesias
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 16+ messages in thread
From: Edgar E. Iglesias @ 2020-05-06  8:25 UTC (permalink / raw)
  To: qemu-devel
  Cc: damien.hedde, peter.maydell, sstabellini, edgar.iglesias,
	sai.pavan.boddu, frasse.iglesias, jasowang, alistair,
	frederic.konrad, qemu-arm, philmd, luc.michel, figlesia

From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>

Auto-clear PHY CR Autoneg bits. This makes this model
work with recent Linux kernels.

Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
---
 hw/net/xilinx_axienet.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/net/xilinx_axienet.c b/hw/net/xilinx_axienet.c
index 704788811a..0f97510d8a 100644
--- a/hw/net/xilinx_axienet.c
+++ b/hw/net/xilinx_axienet.c
@@ -149,8 +149,8 @@ tdk_write(struct PHY *phy, unsigned int req, unsigned int data)
             break;
     }
 
-    /* Unconditionally clear regs[BMCR][BMCR_RESET] */
-    phy->regs[0] &= ~0x8000;
+    /* Unconditionally clear regs[BMCR][BMCR_RESET] and auto-neg */
+    phy->regs[0] &= ~0x8200;
 }
 
 static void
-- 
2.20.1



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

* [PATCH v2 2/9] hw/net/xilinx_axienet: Cleanup stream->push assignment
  2020-05-06  8:25 [PATCH v2 0/9] hw/core: stream: Add end-of-packet flag Edgar E. Iglesias
  2020-05-06  8:25 ` [PATCH v2 1/9] hw/net/xilinx_axienet: Auto-clear PHY Autoneg Edgar E. Iglesias
@ 2020-05-06  8:25 ` Edgar E. Iglesias
  2020-05-06 11:38   ` Philippe Mathieu-Daudé
  2020-05-06  8:25 ` [PATCH v2 3/9] hw/net/xilinx_axienet: Remove unncessary cast Edgar E. Iglesias
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 16+ messages in thread
From: Edgar E. Iglesias @ 2020-05-06  8:25 UTC (permalink / raw)
  To: qemu-devel
  Cc: damien.hedde, peter.maydell, sstabellini, edgar.iglesias,
	sai.pavan.boddu, frasse.iglesias, jasowang, alistair,
	frederic.konrad, qemu-arm, philmd, luc.michel, figlesia

From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>

Split the shared stream_class_init function to assign
stream->push with better type-safety.

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
---
 hw/net/xilinx_axienet.c | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/hw/net/xilinx_axienet.c b/hw/net/xilinx_axienet.c
index 0f97510d8a..84073753d7 100644
--- a/hw/net/xilinx_axienet.c
+++ b/hw/net/xilinx_axienet.c
@@ -1029,11 +1029,19 @@ static void xilinx_enet_class_init(ObjectClass *klass, void *data)
     dc->reset = xilinx_axienet_reset;
 }
 
-static void xilinx_enet_stream_class_init(ObjectClass *klass, void *data)
+static void xilinx_enet_control_stream_class_init(ObjectClass *klass,
+                                                  void *data)
 {
     StreamSlaveClass *ssc = STREAM_SLAVE_CLASS(klass);
 
-    ssc->push = data;
+    ssc->push = xilinx_axienet_control_stream_push;
+}
+
+static void xilinx_enet_data_stream_class_init(ObjectClass *klass, void *data)
+{
+    StreamSlaveClass *ssc = STREAM_SLAVE_CLASS(klass);
+
+    ssc->push = xilinx_axienet_data_stream_push;
 }
 
 static const TypeInfo xilinx_enet_info = {
@@ -1048,8 +1056,7 @@ static const TypeInfo xilinx_enet_data_stream_info = {
     .name          = TYPE_XILINX_AXI_ENET_DATA_STREAM,
     .parent        = TYPE_OBJECT,
     .instance_size = sizeof(struct XilinxAXIEnetStreamSlave),
-    .class_init    = xilinx_enet_stream_class_init,
-    .class_data    = xilinx_axienet_data_stream_push,
+    .class_init    = xilinx_enet_data_stream_class_init,
     .interfaces = (InterfaceInfo[]) {
             { TYPE_STREAM_SLAVE },
             { }
@@ -1060,8 +1067,7 @@ static const TypeInfo xilinx_enet_control_stream_info = {
     .name          = TYPE_XILINX_AXI_ENET_CONTROL_STREAM,
     .parent        = TYPE_OBJECT,
     .instance_size = sizeof(struct XilinxAXIEnetStreamSlave),
-    .class_init    = xilinx_enet_stream_class_init,
-    .class_data    = xilinx_axienet_control_stream_push,
+    .class_init    = xilinx_enet_control_stream_class_init,
     .interfaces = (InterfaceInfo[]) {
             { TYPE_STREAM_SLAVE },
             { }
-- 
2.20.1



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

* [PATCH v2 3/9] hw/net/xilinx_axienet: Remove unncessary cast
  2020-05-06  8:25 [PATCH v2 0/9] hw/core: stream: Add end-of-packet flag Edgar E. Iglesias
  2020-05-06  8:25 ` [PATCH v2 1/9] hw/net/xilinx_axienet: Auto-clear PHY Autoneg Edgar E. Iglesias
  2020-05-06  8:25 ` [PATCH v2 2/9] hw/net/xilinx_axienet: Cleanup stream->push assignment Edgar E. Iglesias
@ 2020-05-06  8:25 ` Edgar E. Iglesias
  2020-05-06 11:39   ` Philippe Mathieu-Daudé
  2020-05-06  8:25 ` [PATCH v2 4/9] hw/dma/xilinx_axidma: Add DMA memory-region property Edgar E. Iglesias
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 16+ messages in thread
From: Edgar E. Iglesias @ 2020-05-06  8:25 UTC (permalink / raw)
  To: qemu-devel
  Cc: damien.hedde, peter.maydell, sstabellini, edgar.iglesias,
	sai.pavan.boddu, frasse.iglesias, jasowang, alistair,
	frederic.konrad, qemu-arm, philmd, luc.michel, figlesia

From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>

Remove unncessary cast, buf is already uint8_t *.
No functional change.

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
---
 hw/net/xilinx_axienet.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/net/xilinx_axienet.c b/hw/net/xilinx_axienet.c
index 84073753d7..c8dfcda3ee 100644
--- a/hw/net/xilinx_axienet.c
+++ b/hw/net/xilinx_axienet.c
@@ -918,7 +918,7 @@ xilinx_axienet_data_stream_push(StreamSlave *obj, uint8_t *buf, size_t size)
         uint16_t csum;
 
         tmp_csum = net_checksum_add(size - start_off,
-                                    (uint8_t *)buf + start_off);
+                                    buf + start_off);
         /* Accumulate the seed.  */
         tmp_csum += s->hdr[2] & 0xffff;
 
-- 
2.20.1



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

* [PATCH v2 4/9] hw/dma/xilinx_axidma: Add DMA memory-region property
  2020-05-06  8:25 [PATCH v2 0/9] hw/core: stream: Add end-of-packet flag Edgar E. Iglesias
                   ` (2 preceding siblings ...)
  2020-05-06  8:25 ` [PATCH v2 3/9] hw/net/xilinx_axienet: Remove unncessary cast Edgar E. Iglesias
@ 2020-05-06  8:25 ` Edgar E. Iglesias
  2020-05-06 11:42   ` Philippe Mathieu-Daudé
  2020-05-06  8:25 ` [PATCH v2 5/9] hw/core: stream: Add an end-of-packet flag Edgar E. Iglesias
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 16+ messages in thread
From: Edgar E. Iglesias @ 2020-05-06  8:25 UTC (permalink / raw)
  To: qemu-devel
  Cc: damien.hedde, peter.maydell, sstabellini, edgar.iglesias,
	sai.pavan.boddu, frasse.iglesias, jasowang, alistair,
	frederic.konrad, qemu-arm, philmd, luc.michel, figlesia

From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>

Add DMA memory-region property to externally control what
address-space this DMA operates on.

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
---
 hw/dma/xilinx_axidma.c | 30 +++++++++++++++++++++++-------
 1 file changed, 23 insertions(+), 7 deletions(-)

diff --git a/hw/dma/xilinx_axidma.c b/hw/dma/xilinx_axidma.c
index 018f36991b..4540051448 100644
--- a/hw/dma/xilinx_axidma.c
+++ b/hw/dma/xilinx_axidma.c
@@ -33,6 +33,7 @@
 #include "qemu/log.h"
 #include "qemu/module.h"
 
+#include "sysemu/dma.h"
 #include "hw/stream.h"
 
 #define D(x)
@@ -103,6 +104,7 @@ enum {
 };
 
 struct Stream {
+    struct XilinxAXIDMA *dma;
     ptimer_state *ptimer;
     qemu_irq irq;
 
@@ -125,6 +127,9 @@ struct XilinxAXIDMAStreamSlave {
 struct XilinxAXIDMA {
     SysBusDevice busdev;
     MemoryRegion iomem;
+    MemoryRegion *dma_mr;
+    AddressSpace as;
+
     uint32_t freqhz;
     StreamSlave *tx_data_dev;
     StreamSlave *tx_control_dev;
@@ -186,7 +191,7 @@ static void stream_desc_load(struct Stream *s, hwaddr addr)
 {
     struct SDesc *d = &s->desc;
 
-    cpu_physical_memory_read(addr, d, sizeof *d);
+    address_space_read(&s->dma->as, addr, MEMTXATTRS_UNSPECIFIED, d, sizeof *d);
 
     /* Convert from LE into host endianness.  */
     d->buffer_address = le64_to_cpu(d->buffer_address);
@@ -204,7 +209,8 @@ static void stream_desc_store(struct Stream *s, hwaddr addr)
     d->nxtdesc = cpu_to_le64(d->nxtdesc);
     d->control = cpu_to_le32(d->control);
     d->status = cpu_to_le32(d->status);
-    cpu_physical_memory_write(addr, d, sizeof *d);
+    address_space_write(&s->dma->as, addr, MEMTXATTRS_UNSPECIFIED,
+                        d, sizeof *d);
 }
 
 static void stream_update_irq(struct Stream *s)
@@ -286,8 +292,9 @@ static void stream_process_mem2s(struct Stream *s, StreamSlave *tx_data_dev,
                      txlen + s->pos);
         }
 
-        cpu_physical_memory_read(s->desc.buffer_address,
-                                 s->txbuf + s->pos, txlen);
+        address_space_read(&s->dma->as, s->desc.buffer_address,
+                           MEMTXATTRS_UNSPECIFIED,
+                           s->txbuf + s->pos, txlen);
         s->pos += txlen;
 
         if (stream_desc_eof(&s->desc)) {
@@ -336,7 +343,8 @@ static size_t stream_process_s2mem(struct Stream *s, unsigned char *buf,
             rxlen = len;
         }
 
-        cpu_physical_memory_write(s->desc.buffer_address, buf + pos, rxlen);
+        address_space_write(&s->dma->as, s->desc.buffer_address,
+                            MEMTXATTRS_UNSPECIFIED, buf + pos, rxlen);
         len -= rxlen;
         pos += rxlen;
 
@@ -525,6 +533,7 @@ static void xilinx_axidma_realize(DeviceState *dev, Error **errp)
     XilinxAXIDMAStreamSlave *cs = XILINX_AXI_DMA_CONTROL_STREAM(
                                                             &s->rx_control_dev);
     Error *local_err = NULL;
+    int i;
 
     object_property_add_link(OBJECT(ds), "dma", TYPE_XILINX_AXI_DMA,
                              (Object **)&ds->dma,
@@ -545,17 +554,19 @@ static void xilinx_axidma_realize(DeviceState *dev, Error **errp)
         goto xilinx_axidma_realize_fail;
     }
 
-    int i;
-
     for (i = 0; i < 2; i++) {
         struct Stream *st = &s->streams[i];
 
+        st->dma = s;
         st->nr = i;
         st->ptimer = ptimer_init(timer_hit, st, PTIMER_POLICY_DEFAULT);
         ptimer_transaction_begin(st->ptimer);
         ptimer_set_freq(st->ptimer, s->freqhz);
         ptimer_transaction_commit(st->ptimer);
     }
+
+    address_space_init(&s->as,
+                       s->dma_mr ? s->dma_mr : get_system_memory(), "dma");
     return;
 
 xilinx_axidma_realize_fail:
@@ -575,6 +586,11 @@ static void xilinx_axidma_init(Object *obj)
                             &s->rx_control_dev, sizeof(s->rx_control_dev),
                             TYPE_XILINX_AXI_DMA_CONTROL_STREAM, &error_abort,
                             NULL);
+    object_property_add_link(obj, "dma", TYPE_MEMORY_REGION,
+                             (Object **)&s->dma_mr,
+                             qdev_prop_allow_set_link_before_realize,
+                             OBJ_PROP_LINK_STRONG,
+                             &error_abort);
 
     sysbus_init_irq(sbd, &s->streams[0].irq);
     sysbus_init_irq(sbd, &s->streams[1].irq);
-- 
2.20.1



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

* [PATCH v2 5/9] hw/core: stream: Add an end-of-packet flag
  2020-05-06  8:25 [PATCH v2 0/9] hw/core: stream: Add end-of-packet flag Edgar E. Iglesias
                   ` (3 preceding siblings ...)
  2020-05-06  8:25 ` [PATCH v2 4/9] hw/dma/xilinx_axidma: Add DMA memory-region property Edgar E. Iglesias
@ 2020-05-06  8:25 ` Edgar E. Iglesias
  2020-05-06 11:53   ` Philippe Mathieu-Daudé
  2020-05-06  8:25 ` [PATCH v2 6/9] hw/net/xilinx_axienet: Handle fragmented packets from DMA Edgar E. Iglesias
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 16+ messages in thread
From: Edgar E. Iglesias @ 2020-05-06  8:25 UTC (permalink / raw)
  To: qemu-devel
  Cc: damien.hedde, peter.maydell, sstabellini, edgar.iglesias,
	sai.pavan.boddu, frasse.iglesias, jasowang, alistair,
	frederic.konrad, qemu-arm, philmd, luc.michel, figlesia

From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>

Some stream clients stream an endless stream of data while
other clients stream data in packets. Stream interfaces
usually have a way to signal the end of a packet or the
last beat of a transfer.

This adds an end-of-packet flag to the push interface.

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
---
 include/hw/stream.h     |  5 +++--
 hw/core/stream.c        |  4 ++--
 hw/dma/xilinx_axidma.c  | 10 ++++++----
 hw/net/xilinx_axienet.c | 14 ++++++++++----
 hw/ssi/xilinx_spips.c   |  2 +-
 5 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/include/hw/stream.h b/include/hw/stream.h
index d02f62ca89..ed09e83683 100644
--- a/include/hw/stream.h
+++ b/include/hw/stream.h
@@ -39,12 +39,13 @@ typedef struct StreamSlaveClass {
      * @obj: Stream slave to push to
      * @buf: Data to write
      * @len: Maximum number of bytes to write
+     * @eop: End of packet flag
      */
-    size_t (*push)(StreamSlave *obj, unsigned char *buf, size_t len);
+    size_t (*push)(StreamSlave *obj, unsigned char *buf, size_t len, bool eop);
 } StreamSlaveClass;
 
 size_t
-stream_push(StreamSlave *sink, uint8_t *buf, size_t len);
+stream_push(StreamSlave *sink, uint8_t *buf, size_t len, bool eop);
 
 bool
 stream_can_push(StreamSlave *sink, StreamCanPushNotifyFn notify,
diff --git a/hw/core/stream.c b/hw/core/stream.c
index 39b1e595cd..a65ad1208d 100644
--- a/hw/core/stream.c
+++ b/hw/core/stream.c
@@ -3,11 +3,11 @@
 #include "qemu/module.h"
 
 size_t
-stream_push(StreamSlave *sink, uint8_t *buf, size_t len)
+stream_push(StreamSlave *sink, uint8_t *buf, size_t len, bool eop)
 {
     StreamSlaveClass *k =  STREAM_SLAVE_GET_CLASS(sink);
 
-    return k->push(sink, buf, len);
+    return k->push(sink, buf, len, eop);
 }
 
 bool
diff --git a/hw/dma/xilinx_axidma.c b/hw/dma/xilinx_axidma.c
index 4540051448..a770e12c96 100644
--- a/hw/dma/xilinx_axidma.c
+++ b/hw/dma/xilinx_axidma.c
@@ -283,7 +283,7 @@ static void stream_process_mem2s(struct Stream *s, StreamSlave *tx_data_dev,
 
         if (stream_desc_sof(&s->desc)) {
             s->pos = 0;
-            stream_push(tx_control_dev, s->desc.app, sizeof(s->desc.app));
+            stream_push(tx_control_dev, s->desc.app, sizeof(s->desc.app), true);
         }
 
         txlen = s->desc.control & SDESC_CTRL_LEN_MASK;
@@ -298,7 +298,7 @@ static void stream_process_mem2s(struct Stream *s, StreamSlave *tx_data_dev,
         s->pos += txlen;
 
         if (stream_desc_eof(&s->desc)) {
-            stream_push(tx_data_dev, s->txbuf, s->pos);
+            stream_push(tx_data_dev, s->txbuf, s->pos, true);
             s->pos = 0;
             stream_complete(s);
         }
@@ -384,7 +384,7 @@ static void xilinx_axidma_reset(DeviceState *dev)
 
 static size_t
 xilinx_axidma_control_stream_push(StreamSlave *obj, unsigned char *buf,
-                                  size_t len)
+                                  size_t len, bool eop)
 {
     XilinxAXIDMAStreamSlave *cs = XILINX_AXI_DMA_CONTROL_STREAM(obj);
     struct Stream *s = &cs->dma->streams[1];
@@ -416,12 +416,14 @@ xilinx_axidma_data_stream_can_push(StreamSlave *obj,
 }
 
 static size_t
-xilinx_axidma_data_stream_push(StreamSlave *obj, unsigned char *buf, size_t len)
+xilinx_axidma_data_stream_push(StreamSlave *obj, unsigned char *buf, size_t len,
+                               bool eop)
 {
     XilinxAXIDMAStreamSlave *ds = XILINX_AXI_DMA_DATA_STREAM(obj);
     struct Stream *s = &ds->dma->streams[1];
     size_t ret;
 
+    assert(eop);
     ret = stream_process_s2mem(s, buf, len);
     stream_update_irq(s);
     return ret;
diff --git a/hw/net/xilinx_axienet.c b/hw/net/xilinx_axienet.c
index c8dfcda3ee..bd48305577 100644
--- a/hw/net/xilinx_axienet.c
+++ b/hw/net/xilinx_axienet.c
@@ -697,14 +697,14 @@ static void axienet_eth_rx_notify(void *opaque)
                                            axienet_eth_rx_notify, s)) {
         size_t ret = stream_push(s->tx_control_dev,
                                  (void *)s->rxapp + CONTROL_PAYLOAD_SIZE
-                                 - s->rxappsize, s->rxappsize);
+                                 - s->rxappsize, s->rxappsize, true);
         s->rxappsize -= ret;
     }
 
     while (s->rxsize && stream_can_push(s->tx_data_dev,
                                         axienet_eth_rx_notify, s)) {
         size_t ret = stream_push(s->tx_data_dev, (void *)s->rxmem + s->rxpos,
-                                 s->rxsize);
+                                 s->rxsize, true);
         s->rxsize -= ret;
         s->rxpos += ret;
         if (!s->rxsize) {
@@ -874,12 +874,14 @@ static ssize_t eth_rx(NetClientState *nc, const uint8_t *buf, size_t size)
 }
 
 static size_t
-xilinx_axienet_control_stream_push(StreamSlave *obj, uint8_t *buf, size_t len)
+xilinx_axienet_control_stream_push(StreamSlave *obj, uint8_t *buf, size_t len,
+                                   bool eop)
 {
     int i;
     XilinxAXIEnetStreamSlave *cs = XILINX_AXI_ENET_CONTROL_STREAM(obj);
     XilinxAXIEnet *s = cs->enet;
 
+    assert(eop);
     if (len != CONTROL_PAYLOAD_SIZE) {
         hw_error("AXI Enet requires %d byte control stream payload\n",
                  (int)CONTROL_PAYLOAD_SIZE);
@@ -894,11 +896,15 @@ xilinx_axienet_control_stream_push(StreamSlave *obj, uint8_t *buf, size_t len)
 }
 
 static size_t
-xilinx_axienet_data_stream_push(StreamSlave *obj, uint8_t *buf, size_t size)
+xilinx_axienet_data_stream_push(StreamSlave *obj, uint8_t *buf, size_t size,
+                                bool eop)
 {
     XilinxAXIEnetStreamSlave *ds = XILINX_AXI_ENET_DATA_STREAM(obj);
     XilinxAXIEnet *s = ds->enet;
 
+    /* We don't support fragmented packets yet.  */
+    assert(eop);
+
     /* TX enable ?  */
     if (!(s->tc & TC_TX)) {
         return size;
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
index c57850a505..4cfce882ab 100644
--- a/hw/ssi/xilinx_spips.c
+++ b/hw/ssi/xilinx_spips.c
@@ -868,7 +868,7 @@ static void xlnx_zynqmp_qspips_notify(void *opaque)
 
         memcpy(rq->dma_buf, rxd, num);
 
-        ret = stream_push(rq->dma, rq->dma_buf, num);
+        ret = stream_push(rq->dma, rq->dma_buf, num, false);
         assert(ret == num);
         xlnx_zynqmp_qspips_check_flush(rq);
     }
-- 
2.20.1



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

* [PATCH v2 6/9] hw/net/xilinx_axienet: Handle fragmented packets from DMA
  2020-05-06  8:25 [PATCH v2 0/9] hw/core: stream: Add end-of-packet flag Edgar E. Iglesias
                   ` (4 preceding siblings ...)
  2020-05-06  8:25 ` [PATCH v2 5/9] hw/core: stream: Add an end-of-packet flag Edgar E. Iglesias
@ 2020-05-06  8:25 ` Edgar E. Iglesias
  2020-05-06  8:25 ` [PATCH v2 7/9] hw/dma/xilinx_axidma: mm2s: Stream descriptor by descriptor Edgar E. Iglesias
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 16+ messages in thread
From: Edgar E. Iglesias @ 2020-05-06  8:25 UTC (permalink / raw)
  To: qemu-devel
  Cc: damien.hedde, peter.maydell, sstabellini, edgar.iglesias,
	sai.pavan.boddu, frasse.iglesias, jasowang, alistair,
	frederic.konrad, qemu-arm, philmd, luc.michel, figlesia

From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>

Add support for fragmented packets from the DMA.

Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
---
 hw/net/xilinx_axienet.c | 38 +++++++++++++++++++++++++++++++-------
 1 file changed, 31 insertions(+), 7 deletions(-)

diff --git a/hw/net/xilinx_axienet.c b/hw/net/xilinx_axienet.c
index bd48305577..498afe2f54 100644
--- a/hw/net/xilinx_axienet.c
+++ b/hw/net/xilinx_axienet.c
@@ -402,6 +402,9 @@ struct XilinxAXIEnet {
 
     uint32_t hdr[CONTROL_PAYLOAD_WORDS];
 
+    uint8_t *txmem;
+    uint32_t txpos;
+
     uint8_t *rxmem;
     uint32_t rxsize;
     uint32_t rxpos;
@@ -421,6 +424,7 @@ static void axienet_rx_reset(XilinxAXIEnet *s)
 static void axienet_tx_reset(XilinxAXIEnet *s)
 {
     s->tc = TC_JUM | TC_TX | TC_VLAN;
+    s->txpos = 0;
 }
 
 static inline int axienet_rx_resetting(XilinxAXIEnet *s)
@@ -902,17 +906,35 @@ xilinx_axienet_data_stream_push(StreamSlave *obj, uint8_t *buf, size_t size,
     XilinxAXIEnetStreamSlave *ds = XILINX_AXI_ENET_DATA_STREAM(obj);
     XilinxAXIEnet *s = ds->enet;
 
-    /* We don't support fragmented packets yet.  */
-    assert(eop);
-
     /* TX enable ?  */
     if (!(s->tc & TC_TX)) {
         return size;
     }
 
+    if (s->txpos + size > s->c_txmem) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: Packet larger than txmem\n",
+                      TYPE_XILINX_AXI_ENET);
+        s->txpos = 0;
+        return size;
+    }
+
+    if (s->txpos == 0 && eop) {
+        /* Fast path single fragment.  */
+        s->txpos = size;
+    } else {
+        memcpy(s->txmem + s->txpos, buf, size);
+        buf = s->txmem;
+        s->txpos += size;
+
+        if (!eop) {
+            return size;
+        }
+    }
+
     /* Jumbo or vlan sizes ?  */
     if (!(s->tc & TC_JUM)) {
-        if (size > 1518 && size <= 1522 && !(s->tc & TC_VLAN)) {
+        if (s->txpos > 1518 && s->txpos <= 1522 && !(s->tc & TC_VLAN)) {
+            s->txpos = 0;
             return size;
         }
     }
@@ -923,7 +945,7 @@ xilinx_axienet_data_stream_push(StreamSlave *obj, uint8_t *buf, size_t size,
         uint32_t tmp_csum;
         uint16_t csum;
 
-        tmp_csum = net_checksum_add(size - start_off,
+        tmp_csum = net_checksum_add(s->txpos - start_off,
                                     buf + start_off);
         /* Accumulate the seed.  */
         tmp_csum += s->hdr[2] & 0xffff;
@@ -936,12 +958,13 @@ xilinx_axienet_data_stream_push(StreamSlave *obj, uint8_t *buf, size_t size,
         buf[write_off + 1] = csum & 0xff;
     }
 
-    qemu_send_packet(qemu_get_queue(s->nic), buf, size);
+    qemu_send_packet(qemu_get_queue(s->nic), buf, s->txpos);
 
-    s->stats.tx_bytes += size;
+    s->stats.tx_bytes += s->txpos;
     s->regs[R_IS] |= IS_TX_COMPLETE;
     enet_update_irq(s);
 
+    s->txpos = 0;
     return size;
 }
 
@@ -989,6 +1012,7 @@ static void xilinx_enet_realize(DeviceState *dev, Error **errp)
     s->TEMAC.parent = s;
 
     s->rxmem = g_malloc(s->c_rxmem);
+    s->txmem = g_malloc(s->c_txmem);
     return;
 
 xilinx_enet_realize_fail:
-- 
2.20.1



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

* [PATCH v2 7/9] hw/dma/xilinx_axidma: mm2s: Stream descriptor by descriptor
  2020-05-06  8:25 [PATCH v2 0/9] hw/core: stream: Add end-of-packet flag Edgar E. Iglesias
                   ` (5 preceding siblings ...)
  2020-05-06  8:25 ` [PATCH v2 6/9] hw/net/xilinx_axienet: Handle fragmented packets from DMA Edgar E. Iglesias
@ 2020-05-06  8:25 ` Edgar E. Iglesias
  2020-05-06  8:25 ` [PATCH v2 8/9] hw/dma/xilinx_axidma: s2mm: Support stream fragments Edgar E. Iglesias
  2020-05-06  8:25 ` [PATCH v2 9/9] MAINTAINERS: Add myself as streams maintainer Edgar E. Iglesias
  8 siblings, 0 replies; 16+ messages in thread
From: Edgar E. Iglesias @ 2020-05-06  8:25 UTC (permalink / raw)
  To: qemu-devel
  Cc: damien.hedde, peter.maydell, sstabellini, edgar.iglesias,
	sai.pavan.boddu, frasse.iglesias, jasowang, alistair,
	frederic.konrad, qemu-arm, philmd, luc.michel, figlesia

From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>

Stream descriptor by descriptor from memory instead of
buffering entire packets before pushing. This enables
non-packet streaming clients to work and also lifts the
limitation that our internal DMA buffer needs to be able
to hold entire packets.

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
---
 hw/dma/xilinx_axidma.c | 31 +++++++++++++++++--------------
 1 file changed, 17 insertions(+), 14 deletions(-)

diff --git a/hw/dma/xilinx_axidma.c b/hw/dma/xilinx_axidma.c
index a770e12c96..101d32a965 100644
--- a/hw/dma/xilinx_axidma.c
+++ b/hw/dma/xilinx_axidma.c
@@ -111,7 +111,6 @@ struct Stream {
     int nr;
 
     struct SDesc desc;
-    int pos;
     unsigned int complete_cnt;
     uint32_t regs[R_MAX];
     uint8_t app[20];
@@ -267,7 +266,9 @@ static void stream_process_mem2s(struct Stream *s, StreamSlave *tx_data_dev,
                                  StreamSlave *tx_control_dev)
 {
     uint32_t prev_d;
-    unsigned int txlen;
+    uint32_t txlen;
+    uint64_t addr;
+    bool eop;
 
     if (!stream_running(s) || stream_idle(s)) {
         return;
@@ -282,24 +283,26 @@ static void stream_process_mem2s(struct Stream *s, StreamSlave *tx_data_dev,
         }
 
         if (stream_desc_sof(&s->desc)) {
-            s->pos = 0;
             stream_push(tx_control_dev, s->desc.app, sizeof(s->desc.app), true);
         }
 
         txlen = s->desc.control & SDESC_CTRL_LEN_MASK;
-        if ((txlen + s->pos) > sizeof s->txbuf) {
-            hw_error("%s: too small internal txbuf! %d\n", __func__,
-                     txlen + s->pos);
-        }
 
-        address_space_read(&s->dma->as, s->desc.buffer_address,
-                           MEMTXATTRS_UNSPECIFIED,
-                           s->txbuf + s->pos, txlen);
-        s->pos += txlen;
+        eop = stream_desc_eof(&s->desc);
+        addr = s->desc.buffer_address;
+        while (txlen) {
+            unsigned int len;
+
+            len = txlen > sizeof s->txbuf ? sizeof s->txbuf : txlen;
+            address_space_read(&s->dma->as, addr,
+                               MEMTXATTRS_UNSPECIFIED,
+                               s->txbuf, len);
+            stream_push(tx_data_dev, s->txbuf, len, eop && len == txlen);
+            txlen -= len;
+            addr += len;
+        }
 
-        if (stream_desc_eof(&s->desc)) {
-            stream_push(tx_data_dev, s->txbuf, s->pos, true);
-            s->pos = 0;
+        if (eop) {
             stream_complete(s);
         }
 
-- 
2.20.1



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

* [PATCH v2 8/9] hw/dma/xilinx_axidma: s2mm: Support stream fragments
  2020-05-06  8:25 [PATCH v2 0/9] hw/core: stream: Add end-of-packet flag Edgar E. Iglesias
                   ` (6 preceding siblings ...)
  2020-05-06  8:25 ` [PATCH v2 7/9] hw/dma/xilinx_axidma: mm2s: Stream descriptor by descriptor Edgar E. Iglesias
@ 2020-05-06  8:25 ` Edgar E. Iglesias
  2020-05-06  8:25 ` [PATCH v2 9/9] MAINTAINERS: Add myself as streams maintainer Edgar E. Iglesias
  8 siblings, 0 replies; 16+ messages in thread
From: Edgar E. Iglesias @ 2020-05-06  8:25 UTC (permalink / raw)
  To: qemu-devel
  Cc: damien.hedde, peter.maydell, sstabellini, edgar.iglesias,
	sai.pavan.boddu, frasse.iglesias, jasowang, alistair,
	frederic.konrad, qemu-arm, philmd, luc.michel, figlesia

From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>

Add support for stream fragments.

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
---
 hw/dma/xilinx_axidma.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/hw/dma/xilinx_axidma.c b/hw/dma/xilinx_axidma.c
index 101d32a965..87be9cade7 100644
--- a/hw/dma/xilinx_axidma.c
+++ b/hw/dma/xilinx_axidma.c
@@ -110,6 +110,7 @@ struct Stream {
 
     int nr;
 
+    bool sof;
     struct SDesc desc;
     unsigned int complete_cnt;
     uint32_t regs[R_MAX];
@@ -174,6 +175,7 @@ static void stream_reset(struct Stream *s)
 {
     s->regs[R_DMASR] = DMASR_HALTED;  /* starts up halted.  */
     s->regs[R_DMACR] = 1 << 16; /* Starts with one in compl threshold.  */
+    s->sof = true;
 }
 
 /* Map an offset addr into a channel index.  */
@@ -321,12 +323,11 @@ static void stream_process_mem2s(struct Stream *s, StreamSlave *tx_data_dev,
 }
 
 static size_t stream_process_s2mem(struct Stream *s, unsigned char *buf,
-                                   size_t len)
+                                   size_t len, bool eop)
 {
     uint32_t prev_d;
     unsigned int rxlen;
     size_t pos = 0;
-    int sof = 1;
 
     if (!stream_running(s) || stream_idle(s)) {
         return 0;
@@ -352,16 +353,16 @@ static size_t stream_process_s2mem(struct Stream *s, unsigned char *buf,
         pos += rxlen;
 
         /* Update the descriptor.  */
-        if (!len) {
+        if (eop) {
             stream_complete(s);
             memcpy(s->desc.app, s->app, sizeof(s->desc.app));
             s->desc.status |= SDESC_STATUS_EOF;
         }
 
-        s->desc.status |= sof << SDESC_STATUS_SOF_BIT;
+        s->desc.status |= s->sof << SDESC_STATUS_SOF_BIT;
         s->desc.status |= SDESC_STATUS_COMPLETE;
         stream_desc_store(s, s->regs[R_CURDESC]);
-        sof = 0;
+        s->sof = eop;
 
         /* Advance.  */
         prev_d = s->regs[R_CURDESC];
@@ -426,8 +427,7 @@ xilinx_axidma_data_stream_push(StreamSlave *obj, unsigned char *buf, size_t len,
     struct Stream *s = &ds->dma->streams[1];
     size_t ret;
 
-    assert(eop);
-    ret = stream_process_s2mem(s, buf, len);
+    ret = stream_process_s2mem(s, buf, len, eop);
     stream_update_irq(s);
     return ret;
 }
-- 
2.20.1



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

* [PATCH v2 9/9] MAINTAINERS: Add myself as streams maintainer
  2020-05-06  8:25 [PATCH v2 0/9] hw/core: stream: Add end-of-packet flag Edgar E. Iglesias
                   ` (7 preceding siblings ...)
  2020-05-06  8:25 ` [PATCH v2 8/9] hw/dma/xilinx_axidma: s2mm: Support stream fragments Edgar E. Iglesias
@ 2020-05-06  8:25 ` Edgar E. Iglesias
  2020-05-06 11:54   ` Philippe Mathieu-Daudé
  8 siblings, 1 reply; 16+ messages in thread
From: Edgar E. Iglesias @ 2020-05-06  8:25 UTC (permalink / raw)
  To: qemu-devel
  Cc: damien.hedde, peter.maydell, sstabellini, edgar.iglesias,
	sai.pavan.boddu, frasse.iglesias, jasowang, alistair,
	frederic.konrad, qemu-arm, philmd, luc.michel, figlesia

From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>

Since we're missing a maintainer, add myself.

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
---
 MAINTAINERS | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 1f84e3ae2c..d3663d6c9a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2315,6 +2315,12 @@ F: net/slirp.c
 F: include/net/slirp.h
 T: git https://people.debian.org/~sthibault/qemu.git slirp
 
+Streams
+M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
+S: Maintained
+F: hw/core/stream.c
+F: include/hw/stream.h
+
 Stubs
 M: Paolo Bonzini <pbonzini@redhat.com>
 S: Maintained
-- 
2.20.1



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

* Re: [PATCH v2 2/9] hw/net/xilinx_axienet: Cleanup stream->push assignment
  2020-05-06  8:25 ` [PATCH v2 2/9] hw/net/xilinx_axienet: Cleanup stream->push assignment Edgar E. Iglesias
@ 2020-05-06 11:38   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 16+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-05-06 11:38 UTC (permalink / raw)
  To: Edgar E. Iglesias, qemu-devel
  Cc: damien.hedde, peter.maydell, sstabellini, edgar.iglesias,
	sai.pavan.boddu, frasse.iglesias, jasowang, alistair,
	frederic.konrad, qemu-arm, figlesia, luc.michel

On 5/6/20 10:25 AM, Edgar E. Iglesias wrote:
> From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
> 
> Split the shared stream_class_init function to assign
> stream->push with better type-safety.
> 
> Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
> Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
> Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

> ---
>   hw/net/xilinx_axienet.c | 18 ++++++++++++------
>   1 file changed, 12 insertions(+), 6 deletions(-)
> 
> diff --git a/hw/net/xilinx_axienet.c b/hw/net/xilinx_axienet.c
> index 0f97510d8a..84073753d7 100644
> --- a/hw/net/xilinx_axienet.c
> +++ b/hw/net/xilinx_axienet.c
> @@ -1029,11 +1029,19 @@ static void xilinx_enet_class_init(ObjectClass *klass, void *data)
>       dc->reset = xilinx_axienet_reset;
>   }
>   
> -static void xilinx_enet_stream_class_init(ObjectClass *klass, void *data)
> +static void xilinx_enet_control_stream_class_init(ObjectClass *klass,
> +                                                  void *data)
>   {
>       StreamSlaveClass *ssc = STREAM_SLAVE_CLASS(klass);
>   
> -    ssc->push = data;
> +    ssc->push = xilinx_axienet_control_stream_push;
> +}
> +
> +static void xilinx_enet_data_stream_class_init(ObjectClass *klass, void *data)
> +{
> +    StreamSlaveClass *ssc = STREAM_SLAVE_CLASS(klass);
> +
> +    ssc->push = xilinx_axienet_data_stream_push;
>   }
>   
>   static const TypeInfo xilinx_enet_info = {
> @@ -1048,8 +1056,7 @@ static const TypeInfo xilinx_enet_data_stream_info = {
>       .name          = TYPE_XILINX_AXI_ENET_DATA_STREAM,
>       .parent        = TYPE_OBJECT,
>       .instance_size = sizeof(struct XilinxAXIEnetStreamSlave),
> -    .class_init    = xilinx_enet_stream_class_init,
> -    .class_data    = xilinx_axienet_data_stream_push,
> +    .class_init    = xilinx_enet_data_stream_class_init,
>       .interfaces = (InterfaceInfo[]) {
>               { TYPE_STREAM_SLAVE },
>               { }
> @@ -1060,8 +1067,7 @@ static const TypeInfo xilinx_enet_control_stream_info = {
>       .name          = TYPE_XILINX_AXI_ENET_CONTROL_STREAM,
>       .parent        = TYPE_OBJECT,
>       .instance_size = sizeof(struct XilinxAXIEnetStreamSlave),
> -    .class_init    = xilinx_enet_stream_class_init,
> -    .class_data    = xilinx_axienet_control_stream_push,
> +    .class_init    = xilinx_enet_control_stream_class_init,
>       .interfaces = (InterfaceInfo[]) {
>               { TYPE_STREAM_SLAVE },
>               { }
> 


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

* Re: [PATCH v2 3/9] hw/net/xilinx_axienet: Remove unncessary cast
  2020-05-06  8:25 ` [PATCH v2 3/9] hw/net/xilinx_axienet: Remove unncessary cast Edgar E. Iglesias
@ 2020-05-06 11:39   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 16+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-05-06 11:39 UTC (permalink / raw)
  To: Edgar E. Iglesias, qemu-devel
  Cc: damien.hedde, peter.maydell, sstabellini, edgar.iglesias,
	sai.pavan.boddu, frasse.iglesias, jasowang, alistair,
	frederic.konrad, qemu-arm, figlesia, luc.michel

On 5/6/20 10:25 AM, Edgar E. Iglesias wrote:
> From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
> 
> Remove unncessary cast, buf is already uint8_t *.

Typo "unnecessary" here and in patch subject.
Otherwise:
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

> No functional change.
> 
> Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
> Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
> Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
> ---
>   hw/net/xilinx_axienet.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/hw/net/xilinx_axienet.c b/hw/net/xilinx_axienet.c
> index 84073753d7..c8dfcda3ee 100644
> --- a/hw/net/xilinx_axienet.c
> +++ b/hw/net/xilinx_axienet.c
> @@ -918,7 +918,7 @@ xilinx_axienet_data_stream_push(StreamSlave *obj, uint8_t *buf, size_t size)
>           uint16_t csum;
>   
>           tmp_csum = net_checksum_add(size - start_off,
> -                                    (uint8_t *)buf + start_off);
> +                                    buf + start_off);
>           /* Accumulate the seed.  */
>           tmp_csum += s->hdr[2] & 0xffff;
>   
> 


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

* Re: [PATCH v2 4/9] hw/dma/xilinx_axidma: Add DMA memory-region property
  2020-05-06  8:25 ` [PATCH v2 4/9] hw/dma/xilinx_axidma: Add DMA memory-region property Edgar E. Iglesias
@ 2020-05-06 11:42   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 16+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-05-06 11:42 UTC (permalink / raw)
  To: Edgar E. Iglesias, qemu-devel
  Cc: damien.hedde, peter.maydell, sstabellini, edgar.iglesias,
	sai.pavan.boddu, frasse.iglesias, jasowang, alistair,
	frederic.konrad, qemu-arm, figlesia, luc.michel

Hi Edgar,

On 5/6/20 10:25 AM, Edgar E. Iglesias wrote:
> From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
> 
> Add DMA memory-region property to externally control what
> address-space this DMA operates on.
> 
> Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
> Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
> Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
> ---
>   hw/dma/xilinx_axidma.c | 30 +++++++++++++++++++++++-------
>   1 file changed, 23 insertions(+), 7 deletions(-)
> 
> diff --git a/hw/dma/xilinx_axidma.c b/hw/dma/xilinx_axidma.c
> index 018f36991b..4540051448 100644
> --- a/hw/dma/xilinx_axidma.c
> +++ b/hw/dma/xilinx_axidma.c
> @@ -33,6 +33,7 @@
>   #include "qemu/log.h"
>   #include "qemu/module.h"
>   
> +#include "sysemu/dma.h"
>   #include "hw/stream.h"
>   
>   #define D(x)
> @@ -103,6 +104,7 @@ enum {
>   };
>   
>   struct Stream {
> +    struct XilinxAXIDMA *dma;
>       ptimer_state *ptimer;
>       qemu_irq irq;
>   
> @@ -125,6 +127,9 @@ struct XilinxAXIDMAStreamSlave {
>   struct XilinxAXIDMA {
>       SysBusDevice busdev;
>       MemoryRegion iomem;
> +    MemoryRegion *dma_mr;
> +    AddressSpace as;
> +
>       uint32_t freqhz;
>       StreamSlave *tx_data_dev;
>       StreamSlave *tx_control_dev;
> @@ -186,7 +191,7 @@ static void stream_desc_load(struct Stream *s, hwaddr addr)
>   {
>       struct SDesc *d = &s->desc;
>   
> -    cpu_physical_memory_read(addr, d, sizeof *d);
> +    address_space_read(&s->dma->as, addr, MEMTXATTRS_UNSPECIFIED, d, sizeof *d);
>   
>       /* Convert from LE into host endianness.  */
>       d->buffer_address = le64_to_cpu(d->buffer_address);
> @@ -204,7 +209,8 @@ static void stream_desc_store(struct Stream *s, hwaddr addr)
>       d->nxtdesc = cpu_to_le64(d->nxtdesc);
>       d->control = cpu_to_le32(d->control);
>       d->status = cpu_to_le32(d->status);
> -    cpu_physical_memory_write(addr, d, sizeof *d);
> +    address_space_write(&s->dma->as, addr, MEMTXATTRS_UNSPECIFIED,
> +                        d, sizeof *d);
>   }
>   
>   static void stream_update_irq(struct Stream *s)
> @@ -286,8 +292,9 @@ static void stream_process_mem2s(struct Stream *s, StreamSlave *tx_data_dev,
>                        txlen + s->pos);
>           }
>   
> -        cpu_physical_memory_read(s->desc.buffer_address,
> -                                 s->txbuf + s->pos, txlen);
> +        address_space_read(&s->dma->as, s->desc.buffer_address,
> +                           MEMTXATTRS_UNSPECIFIED,
> +                           s->txbuf + s->pos, txlen);
>           s->pos += txlen;
>   
>           if (stream_desc_eof(&s->desc)) {
> @@ -336,7 +343,8 @@ static size_t stream_process_s2mem(struct Stream *s, unsigned char *buf,
>               rxlen = len;
>           }
>   
> -        cpu_physical_memory_write(s->desc.buffer_address, buf + pos, rxlen);
> +        address_space_write(&s->dma->as, s->desc.buffer_address,
> +                            MEMTXATTRS_UNSPECIFIED, buf + pos, rxlen);
>           len -= rxlen;
>           pos += rxlen;
>   
> @@ -525,6 +533,7 @@ static void xilinx_axidma_realize(DeviceState *dev, Error **errp)
>       XilinxAXIDMAStreamSlave *cs = XILINX_AXI_DMA_CONTROL_STREAM(
>                                                               &s->rx_control_dev);
>       Error *local_err = NULL;
> +    int i;
>   
>       object_property_add_link(OBJECT(ds), "dma", TYPE_XILINX_AXI_DMA,
>                                (Object **)&ds->dma,
> @@ -545,17 +554,19 @@ static void xilinx_axidma_realize(DeviceState *dev, Error **errp)
>           goto xilinx_axidma_realize_fail;
>       }
>   
> -    int i;
> -
>       for (i = 0; i < 2; i++) {
>           struct Stream *st = &s->streams[i];
>   
> +        st->dma = s;
>           st->nr = i;
>           st->ptimer = ptimer_init(timer_hit, st, PTIMER_POLICY_DEFAULT);
>           ptimer_transaction_begin(st->ptimer);
>           ptimer_set_freq(st->ptimer, s->freqhz);
>           ptimer_transaction_commit(st->ptimer);
>       }
> +
> +    address_space_init(&s->as,
> +                       s->dma_mr ? s->dma_mr : get_system_memory(), "dma");

I'd instead return an error (earlier in this function) if dma_mr 
property is not set. If you ever respin...

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


>       return;
>   
>   xilinx_axidma_realize_fail:
> @@ -575,6 +586,11 @@ static void xilinx_axidma_init(Object *obj)
>                               &s->rx_control_dev, sizeof(s->rx_control_dev),
>                               TYPE_XILINX_AXI_DMA_CONTROL_STREAM, &error_abort,
>                               NULL);
> +    object_property_add_link(obj, "dma", TYPE_MEMORY_REGION,
> +                             (Object **)&s->dma_mr,
> +                             qdev_prop_allow_set_link_before_realize,
> +                             OBJ_PROP_LINK_STRONG,
> +                             &error_abort);
>   
>       sysbus_init_irq(sbd, &s->streams[0].irq);
>       sysbus_init_irq(sbd, &s->streams[1].irq);
> 


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

* Re: [PATCH v2 5/9] hw/core: stream: Add an end-of-packet flag
  2020-05-06  8:25 ` [PATCH v2 5/9] hw/core: stream: Add an end-of-packet flag Edgar E. Iglesias
@ 2020-05-06 11:53   ` Philippe Mathieu-Daudé
  2020-05-06 12:42     ` Edgar E. Iglesias
  0 siblings, 1 reply; 16+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-05-06 11:53 UTC (permalink / raw)
  To: Edgar E. Iglesias, qemu-devel
  Cc: damien.hedde, peter.maydell, sstabellini, edgar.iglesias,
	sai.pavan.boddu, frasse.iglesias, jasowang, alistair,
	frederic.konrad, qemu-arm, figlesia, luc.michel

Hi Edgar,

On 5/6/20 10:25 AM, Edgar E. Iglesias wrote:
> From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
> 
> Some stream clients stream an endless stream of data while
> other clients stream data in packets. Stream interfaces
> usually have a way to signal the end of a packet or the
> last beat of a transfer.
> 
> This adds an end-of-packet flag to the push interface.
> 
> Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
> Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
> Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
> ---
>   include/hw/stream.h     |  5 +++--
>   hw/core/stream.c        |  4 ++--
>   hw/dma/xilinx_axidma.c  | 10 ++++++----
>   hw/net/xilinx_axienet.c | 14 ++++++++++----
>   hw/ssi/xilinx_spips.c   |  2 +-
>   5 files changed, 22 insertions(+), 13 deletions(-)
> 
> diff --git a/include/hw/stream.h b/include/hw/stream.h
> index d02f62ca89..ed09e83683 100644
> --- a/include/hw/stream.h
> +++ b/include/hw/stream.h
> @@ -39,12 +39,13 @@ typedef struct StreamSlaveClass {
>        * @obj: Stream slave to push to
>        * @buf: Data to write
>        * @len: Maximum number of bytes to write
> +     * @eop: End of packet flag
>        */
> -    size_t (*push)(StreamSlave *obj, unsigned char *buf, size_t len);
> +    size_t (*push)(StreamSlave *obj, unsigned char *buf, size_t len, bool eop);

I'd split this patch, first add EOP in the push handler, keeping current 
code working, then the following patches (implementing the feature in 
the backend handlers), then ...

>   } StreamSlaveClass;
>   
>   size_t
> -stream_push(StreamSlave *sink, uint8_t *buf, size_t len);
> +stream_push(StreamSlave *sink, uint8_t *buf, size_t len, bool eop);

... this final patch, enable the feature and let the frontends use it.

>   
>   bool
>   stream_can_push(StreamSlave *sink, StreamCanPushNotifyFn notify,
> diff --git a/hw/core/stream.c b/hw/core/stream.c
> index 39b1e595cd..a65ad1208d 100644
> --- a/hw/core/stream.c
> +++ b/hw/core/stream.c
> @@ -3,11 +3,11 @@
>   #include "qemu/module.h"
>   
>   size_t
> -stream_push(StreamSlave *sink, uint8_t *buf, size_t len)
> +stream_push(StreamSlave *sink, uint8_t *buf, size_t len, bool eop)
>   {
>       StreamSlaveClass *k =  STREAM_SLAVE_GET_CLASS(sink);
>   
> -    return k->push(sink, buf, len);
> +    return k->push(sink, buf, len, eop);

So in this first part patch I'd use 'false' here, and update by 'eop' in 
the other part (last patch in series). Does it make sense?

Regards,

Phil.

>   }
>   
>   bool
> diff --git a/hw/dma/xilinx_axidma.c b/hw/dma/xilinx_axidma.c
> index 4540051448..a770e12c96 100644
> --- a/hw/dma/xilinx_axidma.c
> +++ b/hw/dma/xilinx_axidma.c
> @@ -283,7 +283,7 @@ static void stream_process_mem2s(struct Stream *s, StreamSlave *tx_data_dev,
>   
>           if (stream_desc_sof(&s->desc)) {
>               s->pos = 0;
> -            stream_push(tx_control_dev, s->desc.app, sizeof(s->desc.app));
> +            stream_push(tx_control_dev, s->desc.app, sizeof(s->desc.app), true);
>           }
>   
>           txlen = s->desc.control & SDESC_CTRL_LEN_MASK;
> @@ -298,7 +298,7 @@ static void stream_process_mem2s(struct Stream *s, StreamSlave *tx_data_dev,
>           s->pos += txlen;
>   
>           if (stream_desc_eof(&s->desc)) {
> -            stream_push(tx_data_dev, s->txbuf, s->pos);
> +            stream_push(tx_data_dev, s->txbuf, s->pos, true);
>               s->pos = 0;
>               stream_complete(s);
>           }
> @@ -384,7 +384,7 @@ static void xilinx_axidma_reset(DeviceState *dev)
>   
>   static size_t
>   xilinx_axidma_control_stream_push(StreamSlave *obj, unsigned char *buf,
> -                                  size_t len)
> +                                  size_t len, bool eop)
>   {
>       XilinxAXIDMAStreamSlave *cs = XILINX_AXI_DMA_CONTROL_STREAM(obj);
>       struct Stream *s = &cs->dma->streams[1];
> @@ -416,12 +416,14 @@ xilinx_axidma_data_stream_can_push(StreamSlave *obj,
>   }
>   
>   static size_t
> -xilinx_axidma_data_stream_push(StreamSlave *obj, unsigned char *buf, size_t len)
> +xilinx_axidma_data_stream_push(StreamSlave *obj, unsigned char *buf, size_t len,
> +                               bool eop)
>   {
>       XilinxAXIDMAStreamSlave *ds = XILINX_AXI_DMA_DATA_STREAM(obj);
>       struct Stream *s = &ds->dma->streams[1];
>       size_t ret;
>   
> +    assert(eop);
>       ret = stream_process_s2mem(s, buf, len);
>       stream_update_irq(s);
>       return ret;
> diff --git a/hw/net/xilinx_axienet.c b/hw/net/xilinx_axienet.c
> index c8dfcda3ee..bd48305577 100644
> --- a/hw/net/xilinx_axienet.c
> +++ b/hw/net/xilinx_axienet.c
> @@ -697,14 +697,14 @@ static void axienet_eth_rx_notify(void *opaque)
>                                              axienet_eth_rx_notify, s)) {
>           size_t ret = stream_push(s->tx_control_dev,
>                                    (void *)s->rxapp + CONTROL_PAYLOAD_SIZE
> -                                 - s->rxappsize, s->rxappsize);
> +                                 - s->rxappsize, s->rxappsize, true);
>           s->rxappsize -= ret;
>       }
>   
>       while (s->rxsize && stream_can_push(s->tx_data_dev,
>                                           axienet_eth_rx_notify, s)) {
>           size_t ret = stream_push(s->tx_data_dev, (void *)s->rxmem + s->rxpos,
> -                                 s->rxsize);
> +                                 s->rxsize, true);
>           s->rxsize -= ret;
>           s->rxpos += ret;
>           if (!s->rxsize) {
> @@ -874,12 +874,14 @@ static ssize_t eth_rx(NetClientState *nc, const uint8_t *buf, size_t size)
>   }
>   
>   static size_t
> -xilinx_axienet_control_stream_push(StreamSlave *obj, uint8_t *buf, size_t len)
> +xilinx_axienet_control_stream_push(StreamSlave *obj, uint8_t *buf, size_t len,
> +                                   bool eop)
>   {
>       int i;
>       XilinxAXIEnetStreamSlave *cs = XILINX_AXI_ENET_CONTROL_STREAM(obj);
>       XilinxAXIEnet *s = cs->enet;
>   
> +    assert(eop);
>       if (len != CONTROL_PAYLOAD_SIZE) {
>           hw_error("AXI Enet requires %d byte control stream payload\n",
>                    (int)CONTROL_PAYLOAD_SIZE);
> @@ -894,11 +896,15 @@ xilinx_axienet_control_stream_push(StreamSlave *obj, uint8_t *buf, size_t len)
>   }
>   
>   static size_t
> -xilinx_axienet_data_stream_push(StreamSlave *obj, uint8_t *buf, size_t size)
> +xilinx_axienet_data_stream_push(StreamSlave *obj, uint8_t *buf, size_t size,
> +                                bool eop)
>   {
>       XilinxAXIEnetStreamSlave *ds = XILINX_AXI_ENET_DATA_STREAM(obj);
>       XilinxAXIEnet *s = ds->enet;
>   
> +    /* We don't support fragmented packets yet.  */
> +    assert(eop);
> +
>       /* TX enable ?  */
>       if (!(s->tc & TC_TX)) {
>           return size;
> diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
> index c57850a505..4cfce882ab 100644
> --- a/hw/ssi/xilinx_spips.c
> +++ b/hw/ssi/xilinx_spips.c
> @@ -868,7 +868,7 @@ static void xlnx_zynqmp_qspips_notify(void *opaque)
>   
>           memcpy(rq->dma_buf, rxd, num);
>   
> -        ret = stream_push(rq->dma, rq->dma_buf, num);
> +        ret = stream_push(rq->dma, rq->dma_buf, num, false);
>           assert(ret == num);
>           xlnx_zynqmp_qspips_check_flush(rq);
>       }
> 


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

* Re: [PATCH v2 9/9] MAINTAINERS: Add myself as streams maintainer
  2020-05-06  8:25 ` [PATCH v2 9/9] MAINTAINERS: Add myself as streams maintainer Edgar E. Iglesias
@ 2020-05-06 11:54   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 16+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-05-06 11:54 UTC (permalink / raw)
  To: Edgar E. Iglesias, qemu-devel
  Cc: damien.hedde, peter.maydell, sstabellini, edgar.iglesias,
	sai.pavan.boddu, frasse.iglesias, jasowang, alistair,
	frederic.konrad, qemu-arm, figlesia, luc.michel

On 5/6/20 10:25 AM, Edgar E. Iglesias wrote:
> From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
> 
> Since we're missing a maintainer, add myself.
> 
> Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
> Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
> ---
>   MAINTAINERS | 6 ++++++
>   1 file changed, 6 insertions(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 1f84e3ae2c..d3663d6c9a 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2315,6 +2315,12 @@ F: net/slirp.c
>   F: include/net/slirp.h
>   T: git https://people.debian.org/~sthibault/qemu.git slirp
>   
> +Streams
> +M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
> +S: Maintained
> +F: hw/core/stream.c
> +F: include/hw/stream.h
> +
>   Stubs
>   M: Paolo Bonzini <pbonzini@redhat.com>
>   S: Maintained
> 

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


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

* Re: [PATCH v2 5/9] hw/core: stream: Add an end-of-packet flag
  2020-05-06 11:53   ` Philippe Mathieu-Daudé
@ 2020-05-06 12:42     ` Edgar E. Iglesias
  0 siblings, 0 replies; 16+ messages in thread
From: Edgar E. Iglesias @ 2020-05-06 12:42 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé
  Cc: damien.hedde, peter.maydell, sstabellini, edgar.iglesias,
	sai.pavan.boddu, frasse.iglesias, jasowang, alistair, qemu-devel,
	frederic.konrad, qemu-arm, figlesia, luc.michel

On Wed, May 06, 2020 at 01:53:33PM +0200, Philippe Mathieu-Daudé wrote:
> Hi Edgar,

Hi Philippe,



> 
> On 5/6/20 10:25 AM, Edgar E. Iglesias wrote:
> > From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
> > 
> > Some stream clients stream an endless stream of data while
> > other clients stream data in packets. Stream interfaces
> > usually have a way to signal the end of a packet or the
> > last beat of a transfer.
> > 
> > This adds an end-of-packet flag to the push interface.
> > 
> > Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
> > Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
> > Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
> > ---
> >   include/hw/stream.h     |  5 +++--
> >   hw/core/stream.c        |  4 ++--
> >   hw/dma/xilinx_axidma.c  | 10 ++++++----
> >   hw/net/xilinx_axienet.c | 14 ++++++++++----
> >   hw/ssi/xilinx_spips.c   |  2 +-
> >   5 files changed, 22 insertions(+), 13 deletions(-)
> > 
> > diff --git a/include/hw/stream.h b/include/hw/stream.h
> > index d02f62ca89..ed09e83683 100644
> > --- a/include/hw/stream.h
> > +++ b/include/hw/stream.h
> > @@ -39,12 +39,13 @@ typedef struct StreamSlaveClass {
> >        * @obj: Stream slave to push to
> >        * @buf: Data to write
> >        * @len: Maximum number of bytes to write
> > +     * @eop: End of packet flag
> >        */
> > -    size_t (*push)(StreamSlave *obj, unsigned char *buf, size_t len);
> > +    size_t (*push)(StreamSlave *obj, unsigned char *buf, size_t len, bool eop);
> 
> I'd split this patch, first add EOP in the push handler, keeping current
> code working, then the following patches (implementing the feature in the
> backend handlers), then ...
> 
> >   } StreamSlaveClass;
> >   size_t
> > -stream_push(StreamSlave *sink, uint8_t *buf, size_t len);
> > +stream_push(StreamSlave *sink, uint8_t *buf, size_t len, bool eop);
> 
> ... this final patch, enable the feature and let the frontends use it.
> 
> >   bool
> >   stream_can_push(StreamSlave *sink, StreamCanPushNotifyFn notify,
> > diff --git a/hw/core/stream.c b/hw/core/stream.c
> > index 39b1e595cd..a65ad1208d 100644
> > --- a/hw/core/stream.c
> > +++ b/hw/core/stream.c
> > @@ -3,11 +3,11 @@
> >   #include "qemu/module.h"
> >   size_t
> > -stream_push(StreamSlave *sink, uint8_t *buf, size_t len)
> > +stream_push(StreamSlave *sink, uint8_t *buf, size_t len, bool eop)
> >   {
> >       StreamSlaveClass *k =  STREAM_SLAVE_GET_CLASS(sink);
> > -    return k->push(sink, buf, len);
> > +    return k->push(sink, buf, len, eop);
> 
> So in this first part patch I'd use 'false' here, and update by 'eop' in the
> other part (last patch in series). Does it make sense?

Current code implicitly assumes eop = true, so this patch keeps things
working as before. It just makes the assumption explicit and guarding
backends with asserts. The support for eop = false is then added
(where relevant) in future patches, roughly the way you describe it.

I can add something to the commit message to clarify that.

Best regards,
Edgar


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

end of thread, other threads:[~2020-05-06 12:43 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-06  8:25 [PATCH v2 0/9] hw/core: stream: Add end-of-packet flag Edgar E. Iglesias
2020-05-06  8:25 ` [PATCH v2 1/9] hw/net/xilinx_axienet: Auto-clear PHY Autoneg Edgar E. Iglesias
2020-05-06  8:25 ` [PATCH v2 2/9] hw/net/xilinx_axienet: Cleanup stream->push assignment Edgar E. Iglesias
2020-05-06 11:38   ` Philippe Mathieu-Daudé
2020-05-06  8:25 ` [PATCH v2 3/9] hw/net/xilinx_axienet: Remove unncessary cast Edgar E. Iglesias
2020-05-06 11:39   ` Philippe Mathieu-Daudé
2020-05-06  8:25 ` [PATCH v2 4/9] hw/dma/xilinx_axidma: Add DMA memory-region property Edgar E. Iglesias
2020-05-06 11:42   ` Philippe Mathieu-Daudé
2020-05-06  8:25 ` [PATCH v2 5/9] hw/core: stream: Add an end-of-packet flag Edgar E. Iglesias
2020-05-06 11:53   ` Philippe Mathieu-Daudé
2020-05-06 12:42     ` Edgar E. Iglesias
2020-05-06  8:25 ` [PATCH v2 6/9] hw/net/xilinx_axienet: Handle fragmented packets from DMA Edgar E. Iglesias
2020-05-06  8:25 ` [PATCH v2 7/9] hw/dma/xilinx_axidma: mm2s: Stream descriptor by descriptor Edgar E. Iglesias
2020-05-06  8:25 ` [PATCH v2 8/9] hw/dma/xilinx_axidma: s2mm: Support stream fragments Edgar E. Iglesias
2020-05-06  8:25 ` [PATCH v2 9/9] MAINTAINERS: Add myself as streams maintainer Edgar E. Iglesias
2020-05-06 11:54   ` Philippe Mathieu-Daudé

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).