01-15-2019 07:06 PM
I'm currently trying to implement a DMA mechanism to stream data to a FIFO. The problem I'm having is that the DMA mechanism is retrieving seemingly random data that has nothing to do with the memory contents of the address specified to the DMA engine (Xilinx AXI DMA v7.1). I instrumented the HP0 interface and I found that even though it is reading the correct address, it is retreiving random data.
In the following capture, you can see it is reading the specified start address (0x110c080). That memory location (all the way to 0x110c280) has been loaded with the same dummy value (0x8192). Nevertheless, when the data comes through that HP0 interface, it looks random like if it was reading another memory location.
Does anybody know if I'm doing anything wrong? I used the programming sequence provided in this guide (https://www.xilinx.com/support/documentation/ip_documentation/axi_dma/v7_1/pg021_axi_dma.pdf) for a simple DMA. All the interfaces are configured for 64bit data and 32bit address and I'm using Vivado and XSDK 2018.2 with all the patches.
01-16-2019 05:27 AM
No answers yet... just questions:
Your PL design makes timing, right?
You're trying to DMA from external DDR memory--starting at 0x11_c080?
What SW--if any--is running on the PS, prior-to or while you're attempting the DMA?
What's the 'red blob', on the line that says OVERFLOW?
How are you initializing the DDR with the dummy values?
01-16-2019 04:35 PM
Yes, the design doesn't have any timing violations. The DMA is trying to access the DDR memory region at that address (the address region is specified in the linker script that was automatically generated from the BSP). I am running a small piece of FW in the Zynq core that initializes that specific memory region using a simple for-loop and the values can be seen in the memory dump of the screenshot. After initializing the values, it simply writes to the DMA control register to enable it along with the interrupts. Then it writes the data address pointer and finally the transfer size (like the guide mentions).
Regarding the OVERFLOW, I'm not very sure. It appeared in the instrumentation waveforms when it decoded the transaction. I'm not very experienced in the AXI protocol.
Could it be that I'm specifying the memory address in the wrong way? Do I need to make some adjustments when attempting to perform DMAs?
01-16-2019 05:14 PM
After looking at this example (https://www.xilinx.com/support/answers/54941.html), it looks like for some reason I need to flush the cache once I initialized the memory segment. After doing that I no longer read garbage.
01-16-2019 05:21 PM
Drat. I was hoping you were running Linux, and I could blame it all on the MMU messing-up addresses for APU accesses--like the Monitor Window data fetches. But your "simple FW" shouldn't be turning on the MMU.
That aside, the data being returned could be un-initialized DDR. Which means your memory-initialization routine could be writing a different part of DDR than your PL-based DMA is reading from. The Monitor Window appears to show the correct address, though. So how do we account for messed-up memory addresses without the MMU?
The DMA IP registers look good for Direct Access operation, and the IP must be initiating the transactions you're capturing, so that's all good.
01-16-2019 05:37 PM
I was just about to say 'cache'...
Ehhh... No, I wasn't.
You shouldn't be using a cacheable area of DDR to exchange information with the PL--unless the PL is accessing DDR through the ACP port. This has been an example of why.
01-17-2019 02:00 PM
Yeah, I'm just realizing that I have got to learn more about this whole cache thing...
You are mentioning that I shouldn't be using a cacheable area of the DDR for these kinds or purposes. Is there a setting for that? (maybe in the linker script?)
01-17-2019 03:02 PM
Sorry; I'm a HW guy. How to control the cache varies, depending on what SW you're using. If I can't do it myself in U-boot with 'dcache off', I usually just get a SW guy to set it up for me.
01-21-2019 09:22 AM
Please take a look at the Xil_SetTlbAttributes function in xil_mmu.c. This allows you to alter the attributes of a memory region in your bare metal code.
In your case, you would want to set the DMA-able memory to NORM_NONCACHE. This is defined in xil_mmu.h. After changing the MMU setting, you would no longer need to do the cache flush since that region of memory is now non-cacheable.