12-27-2019 06:51 AM - edited 12-28-2019 07:41 AM
I am trying to use AXI DMA in Scatter Gather mode with only S2MM channel enabled, but I am experiencing some issues and I don't know the exact reasons..
The whole block scheme is the following
Block Design
AXI DMA SG configuration
Memory Map
The bootargs string passed to the Linux kernel is:
bootargs = "earlycon console=ttyPS0,115200 clk_ignore_unused root=/dev/mmcblk0p2 rw rootwait uio_pdrv_genirq.of_id=generic-uio";
UIO driver is also enabled:
The system-user.dtsi file is modified as fdllows (according to what is shown at Testing UIO with Interrupt on Zynq Ultrascale - Create the Linux Image in Petalinux (Tutorial) for axi_gpio_0 node)
/include/ "system-conf.dtsi" / { chosen { bootargs = "earlycon console=ttyPS0,115200 clk_ignore_unused root=/dev/mmcblk0p2 rw rootwait uio_pdrv_genirq.of_id=generic-uio"; stdout-path = "serial0:115200n8"; }; }; /* axi_dma_0 is declared in components/plnx_workspace/device-tree/device-tree/pl.dtsi */ &axi_dma_0 { compatible = "xlnx,axi-dma-7.1", "xlnx,axi-dma-1.00.a", "generic-uio"; }
The inclusion of axi_dma_0 generates the following error executing petalinux-build -c device-tree
device-tree-xilinx-v2019.2+gitAUTOINC+a8b39cf536-r0 do_compile: Error executing a python function in exec_python_func() autogenerated: The stack trace of python calls that resulted in this exception/failure was: File: 'exec_python_func() autogenerated', lineno: 2, function: <module> 0001: *** 0002:devicetree_do_compile(d) 0003: File: '/opt/Xilinx/PetaLinux/2019.2/components/yocto/source/aarch64/layers/core/meta/classes/devicetree.bbclass', lineno: 131, function: devicetree_do_compile 0127: if not(os.path.isfile(dtspath)) or not(dts.endswith(".dts") or devicetree_source_is_overlay(dtspath)): 0128: continue # skip non-.dts files and non-overlay files 0129: except: 0130: continue # skip if can't determine if overlay *** 0131: devicetree_compile(dtspath, includes, d) 0132:} 0133: 0134:devicetree_do_install() { 0135: for DTB_FILE in `ls *.dtb *.dtbo`; do File: '/opt/Xilinx/PetaLinux/2019.2/components/yocto/source/aarch64/layers/core/meta/classes/devicetree.bbclass', lineno: 119, function: devicetree_compile 0115: dtcargs += ["-i", i] 0116: dtcargs += ["-o", "{0}.{1}".format(dtname, "dtbo" if isoverlay else "dtb")] 0117: dtcargs += ["-I", "dts", "-O", "dtb", "{0}.pp".format(dts)] 0118: bb.note("Running {0}".format(" ".join(dtcargs))) *** 0119: subprocess.run(dtcargs, check = True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 0120: 0121:python devicetree_do_compile() { 0122: includes = expand_includes("DT_INCLUDE", d) 0123: listpath = d.getVar("DT_FILES_PATH") File: '/opt/Xilinx/PetaLinux/2019.2/components/yocto/source/aarch64/buildtools/sysroots/x86_64-petalinux-linux/usr/lib/python3.5/subprocess.py', lineno: 398, function: run 0394: raise 0395: retcode = process.poll() 0396: if check and retcode: 0397: raise CalledProcessError(retcode, process.args, *** 0398: output=stdout, stderr=stderr) 0399: return CompletedProcess(process.args, retcode, stdout, stderr) 0400: 0401: 0402:def list2cmdline(seq): Exception: subprocess.CalledProcessError: Command '['dtc', '-R', '8', '-b', '0', '-@', '-p', '0x1000', '-i', '/path/to/petalinux-prj/uzed_eg_dma_2_usb_2019.2/uzed_eg_dma_2_usb_2019.2.petalinux/uzed_2019_2/build/tmp/work-shared/plnx-zynqmp/kernel-source/arch/arm64/boot/dts/amd', '-i', '/path/to/petalinux-prj/uzed_eg_dma_2_usb_2019.2/uzed_eg_dma_2_usb_2019.2.petalinux/uzed_2019_2/build/tmp/work-shared/plnx-zynqmp/kernel-source/scripts/dtc/include-prefixes', '-i', '/path/to/petalinux-prj/uzed_eg_dma_2_usb_2019.2/uzed_eg_dma_2_usb_2019.2.petalinux/uzed_2019_2/build/tmp/work-shared/plnx-zynqmp/kernel-source/arch/arm64/boot/dts/marvell', '-i', '/path/to/petalinux-prj/uzed_eg_dma_2_usb_2019.2/uzed_eg_dma_2_usb_2019.2.petalinux/uzed_2019_2/build/tmp/work-shared/plnx-zynqmp/kernel-source/arch/arm64/boot/dts/freescale', '-i', '/path/to/petalinux-prj/uzed_eg_dma_2_usb_2019.2/uzed_eg_dma_2_usb_2019.2.petalinux/uzed_2019_2/build/tmp/work-shared/plnx-zynqmp/kernel-source/arch/arm64/boot/dts/socionext', '-i', '/path/to/petalinux-prj/uzed_eg_dma_2_usb_2019.2/uzed_eg_dma_2_usb_2019.2.petalinux/uzed_2019_2/build/tmp/work-shared/plnx-zynqmp/kernel-source/arch/arm64/boot/dts/mediatek', '-i', '/path/to/petalinux-prj/uzed_eg_dma_2_usb_2019.2/uzed_eg_dma_2_usb_2019.2.petalinux/uzed_2019_2/build/tmp/work-shared/plnx-zynqmp/kernel-source/arch/arm64/boot/dts/sprd', '-i', '/path/to/petalinux-prj/uzed_eg_dma_2_usb_2019.2/uzed_eg_dma_2_usb_2019.2.petalinux/uzed_2019_2/build/tmp/work-shared/plnx-zynqmp/kernel-source/arch/arm64/boot/dts/lg', '-i', '/path/to/petalinux-prj/uzed_eg_dma_2_usb_2019.2/uzed_eg_dma_2_usb_2019.2.petalinux/uzed_2019_2/build/tmp/work-shared/plnx-zynqmp/kernel-source/arch/arm64/boot/dts/renesas', '-i', '/path/to/petalinux-prj/uzed_eg_dma_2_usb_2019.2/uzed_eg_dma_2_usb_2019.2.petalinux/uzed_2019_2/build/tmp/work-shared/plnx-zynqmp/kernel-source/arch/arm64/boot/dts/realtek', '-i', '/path/to/petalinux-prj/uzed_eg_dma_2_usb_2019.2/uzed_eg_dma_2_usb_2019.2.petalinux/uzed_2019_2/build/tmp/work-shared/plnx-zynqmp/kernel-source/include', '-i', '/path/to/petalinux-prj/uzed_eg_dma_2_usb_2019.2/uzed_eg_dma_2_usb_2019.2.petalinux/uzed_2019_2/build/tmp/work-shared/plnx-zynqmp/kernel-source/arch/arm64/boot/dts/qcom', '-i', '/path/to/petalinux-prj/uzed_eg_dma_2_usb_2019.2/uzed_eg_dma_2_usb_2019.2.petalinux/uzed_2019_2/build/tmp/work-shared/plnx-zynqmp/kernel-source/arch/arm64/boot/dts/exynos', '-i', '/path/to/petalinux-prj/uzed_eg_dma_2_usb_2019.2/uzed_eg_dma_2_usb_2019.2.petalinux/uzed_2019_2/build/tmp/work-shared/plnx-zynqmp/kernel-source/arch/arm64/boot/dts', '-i', '/path/to/petalinux-prj/uzed_eg_dma_2_usb_2019.2/uzed_eg_dma_2_usb_2019.2.petalinux/uzed_2019_2/build/tmp/work-shared/plnx-zynqmp/kernel-source/arch/arm64/boot/dts/xilinx', '-i', '/path/to/petalinux-prj/uzed_eg_dma_2_usb_2019.2/uzed_eg_dma_2_usb_2019.2.petalinux/uzed_2019_2/build/tmp/work-shared/plnx-zynqmp/kernel-source/arch/arm64/boot/dts/al', '-i', '/path/to/petalinux-prj/uzed_eg_dma_2_usb_2019.2/uzed_eg_dma_2_usb_2019.2.petalinux/uzed_2019_2/build/tmp/work-shared/plnx-zynqmp/kernel-source/arch/arm64/boot/dts/altera', '-i', '/path/to/petalinux-prj/uzed_eg_dma_2_usb_2019.2/uzed_eg_dma_2_usb_2019.2.petalinux/uzed_2019_2/build/tmp/work-shared/plnx-zynqmp/kernel-source/arch/arm64/boot/dts/nvidia', '-i', '/path/to/petalinux-prj/uzed_eg_dma_2_usb_2019.2/uzed_eg_dma_2_usb_2019.2.petalinux/uzed_2019_2/build/tmp/work-shared/plnx-zynqmp/kernel-source/arch/arm64/boot/dts/arm', '-i', '/path/to/petalinux-prj/uzed_eg_dma_2_usb_2019.2/uzed_eg_dma_2_usb_2019.2.petalinux/uzed_2019_2/build/tmp/work-shared/plnx-zynqmp/kernel-source/arch/arm64/boot/dts/apm', '-i', '/path/to/petalinux-prj/uzed_eg_dma_2_usb_2019.2/uzed_eg_dma_2_usb_2019.2.petalinux/uzed_2019_2/build/tmp/work/plnx_zynqmp-xilinx-linux/device-tree/xilinx-v2019.2+gitAUTOINC+a8b39cf536-r0', '-i', '/path/to/petalinux-prj/uzed_eg_dma_2_usb_2019.2/uzed_eg_dma_2_usb_2019.2.petalinux/uzed_2019_2/build/tmp/work-shared/plnx-zynqmp/kernel-source/arch/arm64/boot/dts/amlogic', '-i', '/path/to/petalinux-prj/uzed_eg_dma_2_usb_2019.2/uzed_eg_dma_2_usb_2019.2.petalinux/uzed_2019_2/build/tmp/work-shared/plnx-zynqmp/kernel-source/arch/arm64/boot/dts/allwinner', '-i', '/path/to/petalinux-prj/uzed_eg_dma_2_usb_2019.2/uzed_eg_dma_2_usb_2019.2.petalinux/uzed_2019_2/build/tmp/work-shared/plnx-zynqmp/kernel-source/arch/arm64/boot/dts/cavium', '-i', '/path/to/petalinux-prj/uzed_eg_dma_2_usb_2019.2/uzed_eg_dma_2_usb_2019.2.petalinux/uzed_2019_2/build/tmp/work-shared/plnx-zynqmp/kernel-source/arch/arm64/boot/dts/broadcom', '-i', '/path/to/petalinux-prj/uzed_eg_dma_2_usb_2019.2/uzed_eg_dma_2_usb_2019.2.petalinux/uzed_2019_2/build/tmp/work-shared/plnx-zynqmp/kernel-source/arch/arm64/boot/dts/zte', '-i', '/path/to/petalinux-prj/uzed_eg_dma_2_usb_2019.2/uzed_eg_dma_2_usb_2019.2.petalinux/uzed_2019_2/build/../components/plnx_workspace/device-tree/device-tree', '-i', '/path/to/petalinux-prj/uzed_eg_dma_2_usb_2019.2/uzed_eg_dma_2_usb_2019.2.petalinux/uzed_2019_2/build/tmp/work-shared/plnx-zynqmp/kernel-source/arch/arm64/boot/dts/rockchip', '-i', '/path/to/petalinux-prj/uzed_eg_dma_2_usb_2019.2/uzed_eg_dma_2_usb_2019.2.petalinux/uzed_2019_2/build/tmp/work-shared/plnx-zynqmp/kernel-source/arch/arm64/boot/dts/synaptics', '-i', '/path/to/petalinux-prj/uzed_eg_dma_2_usb_2019.2/uzed_eg_dma_2_usb_2019.2.petalinux/uzed_2019_2/build/tmp/work-shared/plnx-zynqmp/kernel-source/arch/arm64/boot/dts/ti', '-i', '/path/to/petalinux-prj/uzed_eg_dma_2_usb_2019.2/uzed_eg_dma_2_usb_2019.2.petalinux/uzed_2019_2/build/tmp/work-shared/plnx-zynqmp/kernel-source/arch/arm64/boot/dts/actions', '-i', '/path/to/petalinux-prj/uzed_eg_dma_2_usb_2019.2/uzed_eg_dma_2_usb_2019.2.petalinux/uzed_2019_2/build/tmp/work-shared/plnx-zynqmp/kernel-source/arch/arm64/boot/dts/hisilicon', '-o', 'system-top.dtb', '-I', 'dts', '-O', 'dtb', 'system-top.dts.pp']' returned non-zero exit status 1 Subprocess output: Error: /path/to/petalinux-prj/uzed_eg_dma_2_usb_2019.2/uzed_eg_dma_2_usb_2019.2.petalinux/uzed_2019_2/build/../components/plnx_workspace/device-tree/device-tree/system-top.dts:28.194-29.1 syntax error FATAL ERROR: Unable to parse input tree ERROR: device-tree-xilinx-v2019.2+gitAUTOINC+a8b39cf536-r0 do_compile: Function failed: devicetree_do_compile ERROR: Logfile of failure stored in: /path/to/petalinux-prj/uzed_eg_dma_2_usb_2019.2/uzed_eg_dma_2_usb_2019.2.petalinux/uzed_2019_2/build/tmp/work/plnx_zynqmp-xilinx-linux/device-tree/xilinx-v2019.2+gitAUTOINC+a8b39cf536-r0/temp/log.do_compile.29493 ERROR: Task (/opt/Xilinx/PetaLinux/2019.2/components/yocto/source
In addition, the following simple code (I cannot attach txt or C files) which uses mmap with /dev/uio0,
#ifndef _DEFAULT_SOURCE #define _DEFAULT_SOURCE #endif #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include <stdio.h> #include <stdint.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/mman.h> #define DDR_MEM_BASE_ADDR (unsigned) 0x00000000 #define DDR_MEM_HIGH_ADDR (unsigned) 0x08000000 #define DDR_MEM_MAP_SIZE DDR_MEM_HIGH_ADDR - DDR_MEM_BASE_ADDR #define S_AXI_LITE_DMA_BASE_ADDR (unsigned) 0xA0000000 #define S_AXI_LITE_DMA_HIGH_ADDR (unsigned) 0xA0000FFF #define S_AXI_LITE_DMA_MAP_SIZE S_AXI_LITE_DMA_HIGH_ADDR - S_AXI_LITE_DMA_BASE_ADDR #define SG_CTL 0x2C // CACHE CONTROL // S2MM CONTROL #define S2MM_DMACR 0x30 // S2MM_DMACR #define S2MM_DMASR 0x34 // S2MM_DMASR #define S2MM_CURDESC 0x38 // must align 0x40 addresses #define S2MM_CURDESC_MSB 0x3C // unused with 32bit addresses #define S2MM_TAILDESC 0x40 // must align 0x40 addresses #define S2MM_TAILDESC_MSB 0x44 // unused with 32bit addresses unsigned dma_set(unsigned long *addr, unsigned offset, unsigned int value) { addr[offset >> 2] = value; } unsigned dma_get(unsigned long *addr, unsigned offset) { return addr[offset >> 2]; } unsigned dma_is_sgmode(unsigned long *addr) { return dma_get(addr, S2MM_DMASR) & (1 << 3); } unsigned get_ui0_map0_size(void) { unsigned map_size = 0; FILE *file = fopen("/sys/class/uio/uio0/maps/map0/size", "r"); if(file == NULL) { perror("fopen "); return map_size; } fscanf(file, "%x", &map_size); fclose(file); return map_size; } int main(int argc, char *argv[]) { unsigned long *s_axi_lite_addr = NULL; unsigned long *ddr_memory_addr = NULL; unsigned map_size = get_ui0_map0_size(); int uio0_fd = -1; uio0_fd = open("/dev/uio0", O_RDWR); if(uio0_fd <= 0) { perror("open"); return -1; } s_axi_lite_addr = (unsigned long *) mmap(NULL, S_AXI_LITE_DMA_MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, uio0_fd, S_AXI_LITE_DMA_BASE_ADDR); if(s_axi_lite_addr == MAP_FAILED) { perror("s_axi_lite_addr mmap"); return -1; } else printf("s_axi_lite_addr = %p\n", s_axi_lite_addr); printf("Scatter Gather mode %s enabled", *((volatile unsigned long *) (s_axi_lite_addr + S2MM_DMASR)) ? "is" :"is not"); munmap(ddr_memory_addr, DDR_MEM_MAP_SIZE); munmap(s_axi_lite_addr, S_AXI_LITE_DMA_MAP_SIZE); return 0; }
fails with error
mmap: Invalid argument
This is quiet annoying because it's a few days that I am trying to obtain a result without any success.
Could someone drive me to the right direction ?
Thanks.
s.
12-28-2019 07:40 AM
Hello, is it possible to receive a minimal support about this issues, please ?
Thanks.
s.
12-30-2019 02:27 AM
As an additional test, I decompiled the /lib/firmware/base/base.dtbo and I modified it from
/dts-v1/; / { fragment@0 { target = <0xffffffff>; __overlay__ { #address-cells = <0x2>; #size-cells = <0x2>; firmware-name = "design_1_wrapper.bit.bin"; resets = <0xffffffff 0x74 0xffffffff 0x75>; phandle = <0x1>; }; }; fragment@1 { target = <0xffffffff>; __overlay__ { phandle = <0x2>; afi0 { compatible = "xlnx,afi-fpga"; config-afi = <0x0 0x0 0x1 0x0 0x2 0x0 0x3 0x0 0x4 0x0 0x5 0x0 0x6 0x0 0x7 0x0 0x8 0x0 0x9 0x0 0xa 0x0 0xb 0x0 0xc 0x0 0xd 0x0 0xe 0x0 0xf 0x0>; phandle = <0x3>; }; clocking0 { #clock-cells = <0x0>; assigned-clock-rates = <0x8f0cba9>; assigned-clocks = <0xffffffff 0x47>; clock-output-names = "fabric_clk"; clocks = <0xffffffff 0x47>; compatible = "xlnx,fclk"; phandle = <0x4>; }; }; }; fragment@2 { target = <0xffffffff>; __overlay__ { #address-cells = <0x2>; #size-cells = <0x2>; phandle = <0x5>; dma@a0000000 { #dma-cells = <0x1>; clock-names = "s_axi_lite_aclk", "m_axi_sg_aclk", "m_axi_s2mm_aclk"; clocks = <0xffffffff 0x47 0xffffffff 0x47 0xffffffff 0x47>; compatible = "xlnx,axi-dma-7.1", "xlnx,axi-dma-1.00.a"; reg = <0x0 0xa0000000 0x0 0x1000>; xlnx,addrwidth = <0x20>; xlnx,include-sg; xlnx,sg-length-width = <0x16>; phandle = <0x6>; dma-channel@a0000030 { compatible = "xlnx,axi-dma-s2mm-channel; dma-channels = <0x1>; xlnx,datawidth = <0x20>; xlnx,device-id = <0x0>; }; }; }; }; __symbols__ { overlay0 = "/fragment@0/__overlay__"; overlay1 = "/fragment@1/__overlay__"; afi0 = "/fragment@1/__overlay__/afi0"; clocking0 = "/fragment@1/__overlay__/clocking0"; overlay2 = "/fragment@2/__overlay__"; axi_dma_0 = "/fragment@2/__overlay__/dma@a0000000"; }; __fixups__ { fpga_full = "/fragment@0:target:0"; zynqmp_reset = "/fragment@0/__overlay__:resets:0", "/fragment@0/__overlay__:resets:8"; amba = "/fragment@1:target:0", "/fragment@2:target:0"; zynqmp_clk = "/fragment@1/__overlay__/clocking0:assigned-clocks:0", "/fragment@1/__overlay__/clocking0:clocks:0", "/fragment@2/__overlay__/dma@a0000000:clocks:0", "/fragment@2/__overlay__/dma@a0000000:clocks:8", "/fragment@2/__overlay__/dma@a0000000:clocks:16"; }; };
to
/dts-v1/; / { fragment@0 { target = <0xffffffff>; __overlay__ { #address-cells = <0x2>; #size-cells = <0x2>; firmware-name = "design_1_wrapper.bit.bin"; resets = <0xffffffff 0x74 0xffffffff 0x75>; phandle = <0x1>; }; }; fragment@1 { target = <0xffffffff>; __overlay__ { phandle = <0x2>; afi0 { compatible = "xlnx,afi-fpga"; config-afi = <0x0 0x0 0x1 0x0 0x2 0x0 0x3 0x0 0x4 0x0 0x5 0x0 0x6 0x0 0x7 0x0 0x8 0x0 0x9 0x0 0xa 0x0 0xb 0x0 0xc 0x0 0xd 0x0 0xe 0x0 0xf 0x0>; phandle = <0x3>; }; clocking0 { #clock-cells = <0x0>; assigned-clock-rates = <0x8f0cba9>; assigned-clocks = <0xffffffff 0x47>; clock-output-names = "fabric_clk"; clocks = <0xffffffff 0x47>; compatible = "xlnx,fclk"; phandle = <0x4>; }; }; }; fragment@2 { target = <0xffffffff>; __overlay__ { #address-cells = <0x2>; #size-cells = <0x2>; phandle = <0x5>; dma@a0000000 { #dma-cells = <0x1>; clock-names = "s_axi_lite_aclk", "m_axi_sg_aclk", "m_axi_s2mm_aclk"; clocks = <0xffffffff 0x47 0xffffffff 0x47 0xffffffff 0x47>; compatible = "xlnx,axi-dma-7.1", "xlnx,axi-dma-1.00.a", "generic-uio"; reg = <0x0 0xa0000000 0x0 0x1000>; xlnx,addrwidth = <0x20>; xlnx,include-sg; xlnx,sg-length-width = <0x16>; phandle = <0x6>; dma-channel@a0000030 { compatible = "xlnx,axi-dma-s2mm-channel,generic-uio"; dma-channels = <0x1>; xlnx,datawidth = <0x20>; xlnx,device-id = <0x0>; }; }; }; }; __symbols__ { overlay0 = "/fragment@0/__overlay__"; overlay1 = "/fragment@1/__overlay__"; afi0 = "/fragment@1/__overlay__/afi0"; clocking0 = "/fragment@1/__overlay__/clocking0"; overlay2 = "/fragment@2/__overlay__"; axi_dma_0 = "/fragment@2/__overlay__/dma@a0000000"; }; __fixups__ { fpga_full = "/fragment@0:target:0"; zynqmp_reset = "/fragment@0/__overlay__:resets:0", "/fragment@0/__overlay__:resets:8"; amba = "/fragment@1:target:0", "/fragment@2:target:0"; zynqmp_clk = "/fragment@1/__overlay__/clocking0:assigned-clocks:0", "/fragment@1/__overlay__/clocking0:clocks:0", "/fragment@2/__overlay__/dma@a0000000:clocks:0", "/fragment@2/__overlay__/dma@a0000000:clocks:8", "/fragment@2/__overlay__/dma@a0000000:clocks:16"; }; };
but nothing changes in program behaviour.
I also noticed that when I compile the device-tree with dtc the following warnings occurs:
Warning (unit_address_vs_reg): Node /fragment@0 has a unit name, but no reg property Warning (unit_address_vs_reg): Node /fragment@1 has a unit name, but no reg property Warning (unit_address_vs_reg): Node /fragment@2 has a unit name, but no reg property Warning (unit_address_vs_reg): Node /fragment@2/__overlay__/dma@a0000000/dma-channel@a0000030 has a unit name, but no reg property
Any hint ?
s.
12-30-2019 07:24 AM - edited 12-30-2019 07:35 AM
After spending approx. 1k $ on a Xilinx board for pre-production evaluation, how much is worth an help on this forum ?