qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

hw/core: stream: Add an end-of-packet flag

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>
Message-Id: <20200506082513.18751-6-edgar.iglesias@gmail.com>

+22 -13
+2 -2
hw/core/stream.c
··· 3 3 #include "qemu/module.h" 4 4 5 5 size_t 6 - stream_push(StreamSlave *sink, uint8_t *buf, size_t len) 6 + stream_push(StreamSlave *sink, uint8_t *buf, size_t len, bool eop) 7 7 { 8 8 StreamSlaveClass *k = STREAM_SLAVE_GET_CLASS(sink); 9 9 10 - return k->push(sink, buf, len); 10 + return k->push(sink, buf, len, eop); 11 11 } 12 12 13 13 bool
+6 -4
hw/dma/xilinx_axidma.c
··· 283 283 284 284 if (stream_desc_sof(&s->desc)) { 285 285 s->pos = 0; 286 - stream_push(tx_control_dev, s->desc.app, sizeof(s->desc.app)); 286 + stream_push(tx_control_dev, s->desc.app, sizeof(s->desc.app), true); 287 287 } 288 288 289 289 txlen = s->desc.control & SDESC_CTRL_LEN_MASK; ··· 298 298 s->pos += txlen; 299 299 300 300 if (stream_desc_eof(&s->desc)) { 301 - stream_push(tx_data_dev, s->txbuf, s->pos); 301 + stream_push(tx_data_dev, s->txbuf, s->pos, true); 302 302 s->pos = 0; 303 303 stream_complete(s); 304 304 } ··· 384 384 385 385 static size_t 386 386 xilinx_axidma_control_stream_push(StreamSlave *obj, unsigned char *buf, 387 - size_t len) 387 + size_t len, bool eop) 388 388 { 389 389 XilinxAXIDMAStreamSlave *cs = XILINX_AXI_DMA_CONTROL_STREAM(obj); 390 390 struct Stream *s = &cs->dma->streams[1]; ··· 416 416 } 417 417 418 418 static size_t 419 - xilinx_axidma_data_stream_push(StreamSlave *obj, unsigned char *buf, size_t len) 419 + xilinx_axidma_data_stream_push(StreamSlave *obj, unsigned char *buf, size_t len, 420 + bool eop) 420 421 { 421 422 XilinxAXIDMAStreamSlave *ds = XILINX_AXI_DMA_DATA_STREAM(obj); 422 423 struct Stream *s = &ds->dma->streams[1]; 423 424 size_t ret; 424 425 426 + assert(eop); 425 427 ret = stream_process_s2mem(s, buf, len); 426 428 stream_update_irq(s); 427 429 return ret;
+10 -4
hw/net/xilinx_axienet.c
··· 697 697 axienet_eth_rx_notify, s)) { 698 698 size_t ret = stream_push(s->tx_control_dev, 699 699 (void *)s->rxapp + CONTROL_PAYLOAD_SIZE 700 - - s->rxappsize, s->rxappsize); 700 + - s->rxappsize, s->rxappsize, true); 701 701 s->rxappsize -= ret; 702 702 } 703 703 704 704 while (s->rxsize && stream_can_push(s->tx_data_dev, 705 705 axienet_eth_rx_notify, s)) { 706 706 size_t ret = stream_push(s->tx_data_dev, (void *)s->rxmem + s->rxpos, 707 - s->rxsize); 707 + s->rxsize, true); 708 708 s->rxsize -= ret; 709 709 s->rxpos += ret; 710 710 if (!s->rxsize) { ··· 874 874 } 875 875 876 876 static size_t 877 - xilinx_axienet_control_stream_push(StreamSlave *obj, uint8_t *buf, size_t len) 877 + xilinx_axienet_control_stream_push(StreamSlave *obj, uint8_t *buf, size_t len, 878 + bool eop) 878 879 { 879 880 int i; 880 881 XilinxAXIEnetStreamSlave *cs = XILINX_AXI_ENET_CONTROL_STREAM(obj); 881 882 XilinxAXIEnet *s = cs->enet; 882 883 884 + assert(eop); 883 885 if (len != CONTROL_PAYLOAD_SIZE) { 884 886 hw_error("AXI Enet requires %d byte control stream payload\n", 885 887 (int)CONTROL_PAYLOAD_SIZE); ··· 894 896 } 895 897 896 898 static size_t 897 - xilinx_axienet_data_stream_push(StreamSlave *obj, uint8_t *buf, size_t size) 899 + xilinx_axienet_data_stream_push(StreamSlave *obj, uint8_t *buf, size_t size, 900 + bool eop) 898 901 { 899 902 XilinxAXIEnetStreamSlave *ds = XILINX_AXI_ENET_DATA_STREAM(obj); 900 903 XilinxAXIEnet *s = ds->enet; 904 + 905 + /* We don't support fragmented packets yet. */ 906 + assert(eop); 901 907 902 908 /* TX enable ? */ 903 909 if (!(s->tc & TC_TX)) {
+1 -1
hw/ssi/xilinx_spips.c
··· 868 868 869 869 memcpy(rq->dma_buf, rxd, num); 870 870 871 - ret = stream_push(rq->dma, rq->dma_buf, num); 871 + ret = stream_push(rq->dma, rq->dma_buf, num, false); 872 872 assert(ret == num); 873 873 xlnx_zynqmp_qspips_check_flush(rq); 874 874 }
+3 -2
include/hw/stream.h
··· 39 39 * @obj: Stream slave to push to 40 40 * @buf: Data to write 41 41 * @len: Maximum number of bytes to write 42 + * @eop: End of packet flag 42 43 */ 43 - size_t (*push)(StreamSlave *obj, unsigned char *buf, size_t len); 44 + size_t (*push)(StreamSlave *obj, unsigned char *buf, size_t len, bool eop); 44 45 } StreamSlaveClass; 45 46 46 47 size_t 47 - stream_push(StreamSlave *sink, uint8_t *buf, size_t len); 48 + stream_push(StreamSlave *sink, uint8_t *buf, size_t len, bool eop); 48 49 49 50 bool 50 51 stream_can_push(StreamSlave *sink, StreamCanPushNotifyFn notify,