bmartini / zynq-xdma Goto Github PK
View Code? Open in Web Editor NEWLinux Driver for the Zynq FPGA DMA engine
Linux Driver for the Zynq FPGA DMA engine
Hello,
This project is currently broken.
And finally it won't load:
xdma: disagrees about version of symbol module_layout
insmod: can't insert 'xdma.ko': invalid module format
Maarten
-CC = gcc
-LDFLAGS := -lxdma
+CC = ${CROSS_COMPILE}gcc
+LDFLAGS := -L../lib -lxdma
CFLAGS := -c -Wall
-INCLUDES := -I. -I../dev
+INCLUDES := -I. -I../dev -I../lib
First of all, thanks for the driver and the library. Second, I'm having issues with the DMA not filling every cell of the buffer. It also seems to work every other time I run the program. I have a FIFO attached to a counter attached to AXI-DMA and when I run your program, I get the following:
[root@alarm demo]$ ./app
test: dst buffer before transmit:
0 0 0 0 0 0 0 0 0 0
test: dst buffer after transmit:
0 0 0 0 0 0 0 0 0 0
[root@alarm demo]$ ./app
test: dst buffer before transmit:
0 0 0 0 0 0 0 0 0 0
test: dst buffer after transmit:
-648555171 0 -648555169 0 -648555167 0 -648555165 0 -648555163 0
Hi,
I tried the xdma.c module with a loopback on AXI DMA IP and it generates a timeout when I use xdma-test.c :
file: open()
ioctl: XDMA_TEST_TRANSFER
test: rx buffer before transmit:
Y Y Y Y Y Y Y Y Y Y
test: xdma_start_transfer rx
test: xdma_start_transfer tx
test: time to prepare DMA channels [us]: 6432
Error: transfer timed out
test: DMA transfer time [us]: -6322
test: DMA bytes sent: 1048576
test: DMA speed in Mbytes/s: -165
test: rx buffer after transmit:
Y Y Y Y Y Y Y Y Y Y
ran driver test transition: use 'dmesg' to view results
file: close()
CMA is selected and I added cma=64M.
Thanks
Jo
Hello
I built your latest driver against 3.13 successfully. Upon insertion I got the problem that memory could not be allocated, although CMA is enabled and cma=64M in the device tree bootargs.
As a workaround I changed the allocated memory to 4M instead of 32M.
xdma.h
libxdma.h:
This allows the module to insert nicely:
root@zedboard-zynq7:~# insmod xdma.ko
init: registered
probe: number of devices found: 1
I am only using one S2MM channel, here is my device tree entry:
axi_dma_0: axidma@40400000 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "xlnx,axi-dma";
ranges = <0x40400000 0x40400000 0x10000>;
reg = <0x40400000 0x10000>;
//xlnx,include-sg ;
//xlnx,sg-include-stscntrl-strm ;
dma-channel@40400030 {
axistream-connected-slave = <&axi_dma_0>;
axistream-control-connected-slave = <&axi_dma_0>;
compatible = "xlnx,axi-dma-s2mm-channel";
interrupt-parent = <&ps7_scugic_0>;
interrupts = <0 59 4>;
xlnx,datawidth = <0x20>;
xlnx,device-id = <0x0>;
} ;
} ;
Connected to the DMA engine is a test counter acting as AXIS Master. DMA works by manually poking around in the DMA controller registers.
I changed xdma-app.c to only perform an S2MM transfer by setting srclen = 0 and src=NULL:
//xdma_perform_transaction(0, XDMA_WAIT_NONE, src, LENGTH, dst, LENGTH);
xdma_perform_transaction(0, XDMA_WAIT_NONE, NULL, 0, dst, LENGTH);
Upon running the app, the dst array is not changed, chipscope shows no activity on the DMA lines (TREADY stays low), and the kernel panics after xdma_exit due to a null pointer which I can't identify.
See below: (note: Panic happens few seconds after xdma_exit)
note: I added some debug printf's .
root@zedboard-zynq7:# cp libxdma.so /usr/lib# ldconfig
root@zedboard-zynq7:
croot@zedboard-zynq7:# chmod +x app# ./app
root@zedboard-zynq7:
file: open()
file: mmap()
file: memory size reserved: 4194304, mmap size requested: 4194304
ioctl: XDMA_GET_NUM_DEVICES
ioctl: XDMA_GET_DEV_INFO
ioctl: XDMA_DEVICE_CONTROL
ioctl: XDMA_DEVICE_CONTROL
test: dst buffer before transmit:
ioctl: XDMA_GET_NUM_DEVICES 65 65 65 65 65
libxdma.c @ 193 : xdma_perform_transaction : dst_used1
libxdma ioctl: XDMA_PREP_BUF
.c @ 200 : xdma_perform_transaction : dst_buf.buf_size 16384
l ioctl: XDMA_START_TRANSFER
ibxdma.c @ 220 : xdma_perform_transaction : dst_used2
libxdma.xilinx_dma_start_transfer::simple DMA mode
c @ 224 : xdma_perform_transaction : dst_trans.cookie 2
test: dst file: close()
buffer after transmit:
65 65 65 65 65 65 65 65 65 65
xdma_exit: map -1230393344 , FILESIZE 4194304
xdma_exit: fd 3
xdma_exit: exiting...
Unable to handle kernel NULL pointer dereference at virtual address 00000042
pgd = c0004000
[00000042] *pgd=00000000
Internal error: Oops: 817 [#1] PREEMPT SMP ARM
Modules linked in: xdma(O)
CPU: 1 PID: 320 Comm: kworker/1:1 Tainted: G O 3.13.0-xilinx #1
Workqueue: events cache_reap
task: de987c00 ti: de99a000 task.ti: de99a000
PC is at free_block+0x78/0x14c
LR is at drain_array+0x98/0xc4
pc : [] lr : [] psr: 40000093
sp : de99be88 ip : 00000042 fp : 00000000
r10: 00000018 r9 : c05a7184 r8 : de86744c
r7 : 0000000d r6 : de800a80 r5 : c0905c74 r4 : d87a74d0
r3 : c05f5ec0 r2 : 00100100 r1 : c09164e0 r0 : de826ec0
Flags: nZcv IRQs off FIQs on Mode SVC_32 ISA ARM Segment kernel
Control: 18c5387d Table: 1e8d404a DAC: 00000015
Process kworker/1:1 (pid: 320, stack limit = 0xde99a240)
Stack: (0xde99be88 to 0xde99c000)
be80: de800a80 de867414 00000018 de867400 00000018 de867414
bea0: de826ec0 00000000 de800a80 c05af948 00000000 c00aaedc 00000000 de800a80
bec0: de826ec0 00000000 de99a000 c059e0c0 c0a16e18 c00ab06c 00000000 00000002
bee0: de999f80 c0a16e18 c0a17540 de99a038 c0a1a600 00000000 de99a000 c0035a64
bf00: 00000000 de88beb8 de88beac 00000001 00000000 de999f80 c0a17540 c0a17540
bf20: de99a038 de99a000 de999f98 c0a17554 00000000 c003604c de999f80 de99bf6c
bf40: 00000000 de96f540 00000000 de999f80 c0035e20 00000000 00000000 00000000
bf60: 00000000 c003aee0 de9d6500 00000000 de99bf70 de999f80 00000000 00000000
bf80: de99bf80 de99bf80 00000000 00000000 de99bf90 de99bf90 de99bfac de96f540
bfa0: c003ae08 00000000 00000000 c000e5f8 00000000 00000000 00000000 00000000
bfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000
from
from
from
from
from
from
Code: e790000b e591c018 e5915014 e585c004 (e58c5000)
---[ end trace 30a84eb2acde8760 ]---
note: kworker/1:1[320] exited with preempt_count 1
Unable to handle kernel paging request at virtual address ffffffec
pgd = c0004000
[ffffffec] *pgd=1fffd821, *pte=00000000, *ppte=00000000
Internal error: Oops: 17 [#2] PREEMPT SMP ARM
Modules linked in: xdma(O)
CPU: 1 PID: 320 Comm: kworker/1:1 Tainted: G D O 3.13.0-xilinx #1
task: de987c00 ti: de99a000 task.ti: de99a000
PC is at kthread_data+0x4/0xc
LR is at wq_worker_sleeping+0xc/0xc0
pc : [] lr : [] psr: 20000193
sp : de99bbc0 ip : 00000528 fp : de99bc4c
r10: c05a4f20 r9 : 00000001 r8 : de99bc60
r7 : de987dc8 r6 : de99a008 r5 : de987c00 r4 : 00000001
r3 : 00000000 r2 : 0000000c r1 : 00000001 r0 : de987c00
Flags: nzCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment user
Control: 18c5387d Table: 1e8d404a DAC: 00000015
Process kworker/1:1 (pid: 320, stack limit = 0xde99a240)
Stack: (0xde99bbc0 to 0xde99c000)
bbc0: c0a179c0 c03f1864 0000000e de99bc00 3300001d 00000008 00000000 c059a9c0
bbe0: 00000001 c003800c de853640 00200200 c0a166b0 c005d4dc 00000000 de987c00
bc00: 00000000 c05992c0 00000001 c05d8158 de8aafc4 c0022984 de987c00 00000000
bc20: c05ad4f0 de99a010 de99bc60 de987c00 00000001 c05ad4f0 de99a000 de99bc60
bc40: de987d4c de84eb80 de987bf8 c00231a0 c05a8440 00000001 00000000 de987d94
bc60: de99bc60 de99bc60 acde8760 c05d7e84 0000000b c00aad72 de99a000 de99bcda
bc80: c05a8440 c00aad70 00000000 c0011864 de99a240 0000000b c04cf4cd 00000000
bca0: 00000008 60000193 65000000 30303937 20623030 31393565 38313063 39356520
bcc0: 31303531 35652034 30633538 28203430 63383565 30303035 00002029 c03ef560
bce0: c04cf746 00000042 00000817 00000000 de99be40 de987c00 00000000 00000817
bd00: 00000000 c03eee0c de99be40 c0019cc8 00000001 00000000 c059a9c0 00000000
bd20: 00000000 00000000 00000000 00000000 00000000 00000000 003c3962 00000000
bd40: 00000001 00000001 00000001 00000000 00000001 00000000 de8606c0 00000000
bd60: 007872be 00000000 00000000 00000000 00000000 00000000 00000000 00000817
bd80: c05a8fd0 00000042 de99be40 de86744c c05a7184 00000018 00000000 c00083a8
bda0: 00000000 003c395c 00000000 00000001 00000000 00000001 00000000 00000001
bdc0: 00000000 c0599498 de84a180 0047d000 c0a179c0 ffffc00b 00000001 de8606c0
bde0: 000004a0 c004aaf8 00000000 de863b80 00002e7b c0a16498 00000002 c059a9c0
be00: 00000000 a398e938 0000001b de84a180 00000000 00000000 00000001 c0a179c0
be20: 00000000 00000000 00000002 c00aad70 40000093 ffffffff de99be74 c0011fd8
be40: de826ec0 c09164e0 00100100 c05f5ec0 d87a74d0 c0905c74 de800a80 0000000d
be60: de86744c c05a7184 00000018 00000000 00000042 de99be88 c00aaedc c00aad70
be80: 40000093 ffffffff de800a80 de867414 00000018 de867400 00000018 de867414
bea0: de826ec0 00000000 de800a80 c05af948 00000000 c00aaedc 00000000 de800a80
bec0: de826ec0 00000000 de99a000 c059e0c0 c0a16e18 c00ab06c 00000000 00000002
bee0: de999f80 c0a16e18 c0a17540 de99a038 c0a1a600 00000000 de99a000 c0035a64
bf00: 00000000 de88beb8 de88beac 00000001 00000000 de999f80 c0a17540 c0a17540
bf20: de99a038 de99a000 de999f98 c0a17554 00000000 c003604c de999f80 de99bf6c
bf40: 00000000 de96f540 00000000 de999f80 c0035e20 00000000 00000000 00000000
bf60: 00000000 c003aee0 de9d6500 00000000 de99bf70 de999f80 00000000 00000000
bf80: de99bf80 de99bf80 00000001 00010001 de99bf90 de99bf90 de99bfac de96f540
bfa0: c003ae08 00000000 00000000 c000e5f8 00000000 00000000 00000000 00000000
bfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
bfe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000
from
from
from
from
from
from
from
from
Exception stack(0xde99be40 to 0xde99be88)
be40: de826ec0 c09164e0 00100100 c05f5ec0 d87a74d0 c0905c74 de800a80 0000000d
be60: de86744c c05a7184 00000018 00000000 00000042 de99be88 c00aaedc c00aad70
be80: 40000093 ffffffff
from
from
from
from
from
from
from
Code: e513001c e7e00150 e12fff1e e590319c (e5130014)
---[ end trace 30a84eb2acde8761 ]---
I have a feeling that the problem is connected to that I am only defining one channel, not two like your demos.
What also wonders me is that nothing happens on chipscope...
Do you have an idea what the null pointer might be or where to look?
Thanks
I have a simple loopthru design on a Zynq 7010 working. I am using a build out of petalinux 2014.4 with Linux kernel 3.17. I have the xdma driver installed in the build with the xdma test app. I have increased my AXI DMA logicore PL buffer lengths to max (256). When I run the xdma test app and look at the output using dmesg, the most throughput I can get is about 100 MB/s. I have tried also increasing the clock frequency that goes to the PL from 100 MHZ up to 150 MHZ. There was no difference in performance. Two questions: 1. What should I expect to see? 2. What can I do to increase it.
Also, SG is turned off with simple mode set in core.
Hello,
I tried ur code with a loopback AXI DMA on zc702 board. the relevant dts is
&ps7_axi_interconnect_0 {
ranges;
axi_dma_0: axi-dma@40400000 {
compatible = "xlnx,axi-dma";
interrupt-parent = <&ps7_scugic_0>;
interrupts = <0 30 4>, <0 29 4>;
reg = <0x40400000 0x10000>;
dma-channel@40400000 {
compatible = "xlnx,axi-dma-mm2s-channel";
interrupts = <0 30 4>;
xlnx,datawidth = <0x20>;
xlnx,device-id = <0x0>;
xlnx,include-dre ;
} ;
dma-channel@40400030 {
compatible = "xlnx,axi-dma-s2mm-channel";
interrupts = <0 29 4>;
xlnx,datawidth = <0x20>;
xlnx,device-id = <0x0>;
xlnx,include-dre ;
} ;
} ;
I am using the latest kernel 3.18 of linux-xlnx
the module is properly getting loaded but I am getting a following error in the dmesg listing below
<xdma> init: registered
<xdma> probe: number of devices found: 1
<xdma> file: open()
<xdma> ioctl: XDMA_TEST_TRANSFER
<xdma> test: rx buffer before transmit:
Y Y Y Y Y Y Y Y Y Y
<xdma> test: xdma_start_transfer rx
<xdma> test: xdma_start_transfer tx
<xdma> test: time to prepare DMA channels [us]: 30
irq 61: nobody cared (try booting with the "irqpoll" option)
CPU: 0 PID: 0 Comm: swapper/0 Tainted: G O 3.18.0-xilinx-06499-ge753fa3-dirty #7
[<400148b8>] (unwind_backtrace) from [<40010da4>] (show_stack+0x10/0x14)
[<40010da4>] (show_stack) from [<404697bc>] (dump_stack+0x90/0xd4)
[<404697bc>] (dump_stack) from [<40050bf0>] (__report_bad_irq+0x28/0xb8)
[<40050bf0>] (__report_bad_irq) from [<4005109c>] (note_interrupt+0x1ec/0x290)
[<4005109c>] (note_interrupt) from [<4004f258>] (handle_irq_event_percpu+0xd0/0xe0)
[<4004f258>] (handle_irq_event_percpu) from [<4004f2a4>] (handle_irq_event+0x3c/0x5c)
[<4004f2a4>] (handle_irq_event) from [<40051b38>] (handle_fasteoi_irq+0xa4/0x11c)
[<40051b38>] (handle_fasteoi_irq) from [<4004ea1c>] (generic_handle_irq+0x20/0x30)
[<4004ea1c>] (generic_handle_irq) from [<4004ecb0>] (__handle_domain_irq+0x7c/0xa0)
[<4004ecb0>] (__handle_domain_irq) from [<400085ac>] (gic_handle_irq+0x38/0x5c)
[<400085ac>] (gic_handle_irq) from [<40011740>] (__irq_svc+0x40/0x74)
Exception stack(0x40667e70 to 0x40667eb8)
7e60: 40667eb8 00000000 00000000 00000000
7e80: 00000040 40666038 00000000 7e002000 00000001 4069b238 00200000 406a3480
7ea0: 0000000a 40667eb8 40057ce0 400233ac 60070113 ffffffff
[<40011740>] (__irq_svc) from [<400233ac>] (__do_softirq+0x78/0x1c8)
[<400233ac>] (__do_softirq) from [<400236f0>] (irq_exit+0x58/0xac)
[<400236f0>] (irq_exit) from [<4004ecb4>] (__handle_domain_irq+0x80/0xa0)
[<4004ecb4>] (__handle_domain_irq) from [<400085ac>] (gic_handle_irq+0x38/0x5c)
[<400085ac>] (gic_handle_irq) from [<40011740>] (__irq_svc+0x40/0x74)
Exception stack(0x40667f30 to 0x40667f78)
7f20: a6990950 00000069 00000018 fffffff8
7f40: a6970ccd 00000069 00000000 7e7d0f30 4069b238 4069b238 4066e4d4 00000000
7f60: 00000008 40667f78 4005e07c 40362edc 90070013 ffffffff
[<40011740>] (__irq_svc) from [<40362edc>] (cpuidle_enter_state+0x4c/0xc0)
[<40362edc>] (cpuidle_enter_state) from [<40048170>] (cpu_startup_entry+0x17c/0x204)
[<40048170>] (cpu_startup_entry) from [<40631bc0>] (start_kernel+0x328/0x388)
handlers:
[<4020b000>] dma_intr_handler
Disabling IRQ #61
<xdma> Error: transfer timed out
<xdma> test: DMA transfer time [us]: -3682
<xdma> test: DMA bytes sent: 1024
<xdma> test: DMA speed in Mbytes/s: 0
<xdma> test: rx buffer after transmit:
Y Y Y Y Y Y Y Y Y Y
<xdma> file: close()
I could see a similar query on the net at link http://stackoverflow.com/questions/29213401/linux-interrupt-is-not-handled-by-the-wrapper-driver the gentleman is trying to implement similar wrapper as u have implemented.
I guess I must be missing out something, ur help in this regard will be greatly appreciated.
Thank you in advance.
Hi,
I am just wondering if your engine works on DMA direct more ?
I believe it makes difference if it is for scatter - gather or direct more.
BR
I can successfully run ./test from demos, but when I try to run ./demo
I have default values in my mapped memory.
Then I've changed xdma_ioctl to print bytes from xdma_addr - data there is valid,
but old(default) in my memory.
I'm having an issue with buffer to buffer transfer rates. When simply looping back through the FPGA I'm observing ~450 MB/s transfer rates for CPU -> FPGA -> CPU using the xdma-demo.c with minor alterations. This is awesome performance. However, when I do a memcpy call to transfer processed data from the memory mapped buffer to a new memory buffer (like if I'd want to pass the FPGA processed data on for further processing on the CPU and clear the mmap'd buffer to load more data) the transfer rate is only ~64 MB/s. I bench-marked just a simple buffer to buffer transfer of the same size using memcpy in the c-code and the Zedboard was able to do ~256 MB/s. This leads me to believe that something like 4 memory copies have to happen to pull data from the mmap'd buffer. So my questions:
Thanks,
-Austin
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.