08-03-2020 01:37 PM - edited 08-04-2020 10:08 AM
Hello, I have been having a problem with the Xilinx DMA core, and have spent several months trying to fix it, but it appears to be an issue either with the XDMA core or the Xilinx drivers. I have built a very simple AXI stream device that continuously outputs data to the XDMA core. The core works fine in "loop-back" mode, but when I continuously stream data to it, I get random errors and missing data coming from the software drivers.
I issue a command like this:
./dma_from_device -c 1 -s 64 -f output.dat
It hangs, or complains the 0xFFFFFFF != 0x00000040
If I try and stop the transfer I get errors like this:
[ 874.849003] pci 0000:01:00.0: [10ee:9018] type 00 class 0x0f0400 [ 874.849028] pci 0000:01:00.0: reg 0x10: [mem 0xf7110000-0xf7110fff] [ 874.849038] pci 0000:01:00.0: reg 0x14: [mem 0xf7100000-0xf710ffff] [ 874.869191] pci 0000:01:00.0: BAR 1: assigned [mem 0xf7100000-0xf710ffff] [ 874.869197] pci 0000:01:00.0: BAR 0: assigned [mem 0xf7110000-0xf7110fff] [ 874.869205] pci 0000:00:1e.0: PCI bridge to [bus 04] [ 874.874630] xdma:xdma_mod_init: Xilinx XDMA Reference Driver xdma v2018.3.50 [ 874.874633] xdma:xdma_mod_init: desc_blen_max: 0xfffffff/268435455, sgdma_timeout: 10 sec. [ 874.874672] xdma:xdma_device_open: xdma device 0000:01:00.0, 0x00000000651a5e31. [ 874.874792] xdma:map_single_bar: BAR0 at 0xf7110000 mapped at 0x00000000e63cdaef, length=4096(/4096) [ 874.874824] xdma:map_single_bar: BAR1 at 0xf7100000 mapped at 0x00000000b616d24f, length=65536(/65536) [ 874.874827] xdma:map_bars: config bar 1, pos 1. [ 874.874828] xdma:identify_bars: 2 BARs: config 1, user 0, bypass -1. [ 874.874881] xdma:probe_one: 0000:01:00.0 xdma0, pdev 0x00000000651a5e31, xdev 0x0000000085fe03e8, 0x00000000af3208ae, usr 16, ch 1,1. [ 874.877507] xdma:cdev_xvc_init: xcdev 0x00000000c17ec15a, bar 0, offset 0x40000. [ 918.126328] xdma:cyclic_shutdown_interrupt: 0-C2H0-ST still running?!, -512 [ 918.126411] xdma:engine_service_final_transfer: 0-C2H0-ST, xfer 0x000000008f879274, stopped half-way, 0/256.
If I used dd command in Linux:
dd if=/dev/xdma0_c2h_0 of=/dev/stdout
I get garbled data and random amounts.
I am doing everything to the word boundary, and I don't use TKEEP, TLAST etc. so it should be really simple. Sometimes it works, sometimes it doesn't! The AXI device is a simple counter that passes all Xilinx VIP tests. Anyone else seen issues like this? I have also inserted a Xilinx FIFO between my data source and the XDMA core, and it only improves things a little bit. All help appreciated.
(I am using Vivado 19.2, KCU116 eval board which is a Ultrascale+ device. The XDMA is the Xilinx DMA/Bridge Subsystem for PCI Express v4.1. Machine running the driver is Linux 4.19.0-6-amd64 #1 SMP Debian 4.19.67-2+deb10u2 (2019-11-11) x86_64 )
08-04-2020 10:07 AM
Here are the issues:
First I use the AXI lite bus to write a value into a register that determines my transfer size. This is read back, along with the magic ABADCAFE
( echo -en '\x0\x0\x0\x0\x0\x0\x0\x0\x08\x0\x0\x0\x0\x0\x0\x0'|dd of=/dev/xdma0_user if=/dev/stdin ) && ( dd if=/dev/xdma0_user of=/dev/stdout bs=1 count=4 | od -t x4 ) 0+1 records in 0+1 records out 16 bytes copied, 0.000125051 s, 128 kB/s 4+0 records in 0+4 records out 16 bytes copied, 0.000115693 s, 138 kB/s 0000000 0b35945b abadcafe 00000008 00000000 0000020
This works just fine
Then I put the board into loop back mode (c2h0 <-> h2c0) by selecting the multiplexer. This is tested and works just fine.
Next I connect my counter by switching the multiplexer over (same bitfile). Now I run the code.
./dma_from_device -c 1 -s 64 -f output.dat /dev/xdma0_c2h_0, R off 0x0, 0x1 != 0x40. read file: Success ./dma_from_device -c 1 -s 8 -f output.dat /dev/xdma0_c2h_0, R off 0x0, 0x1 != 0x8. read file: Success ./dma_from_device -c 1 -s 1 -f output.dat ** Average BW = 1, 0.005997 ./dma_from_device -c 1 -s 1 -f output.dat ** Average BW = 1, 0.000003 hexdump output.dat 0000000 0080 0000001 ./dma_from_device -c 1 -s 1 -f output.dat ** Average BW = 1, 0.000002 hexdump output.dat 0000000 0080 0000001
Instead of the size of transfer I selected, it is giving me 1 byte or a random number of bytes. If I don't ask for the correct number, the driver hangs. A reset puts it back to one byte. The data looks correct and is consistent. My guess is something to do with timing on TLAST. Anyone have experience of this, and know how to time the AXIS input bus to work correctly?