Forum Discussion
How Can I set up DMA operation with my own PC software application?
Hi All:
I want to re-use the pcie_highperformancedesign example provided by the Arria GX Development Kit. Now I am confused with the PC software application altpcie_demo.exe. :confused: I am trying to control FPGA to initiate dma read and write operation just like altpcie_demo does with my own PC software application but failed. Firstly, I used Jungo Windriver to generate a pcie driver. With the API functions provided by the driver I can access(R/W) configure registers ,memory bar 1:0(the syncram) and bar2(dma control registers). Secondly, I creat a Read Descriptor Table--Header+2 Descriptors and set data(Length,Ep mem addr, RC mem addr)for desciptors. The header has four dw(DW0,DW1,DW2,DW3). For DMA Read, I set DW0=0x00040002,DW1=0,DW2=addr of header,DW3=0x1. Then I write DW0 to Bar2+0x10,DW1 to Bar2+0x14,DW2 to Bar2+0x18,DW3 to Bar2+0x1c. My first question: Where(mem addr) can I poll the RCLast value to indicate the completion of DMA read?:confused: Thirdly, I want to transfer the DMA Read data back to PC. I creat a Write Descriptor Table--Header+2 Descriptors.In each descriptor, I set PC mem addr for write back data and addr of EP mem correctly .The header has four dw(DW0-DW3). For DMA Write, I set DW0=0x00050002,DW1=0,DW2=addr of Header,DW3=0x1. Then I write DW0 to Bar2+0x0,DW1 to Bar2+0x4,DW2 to Bar2+0x8,DW3 to Bar2+0xc. At the end, I checked the write back data and found that the write back data are all zeros.It seems like that the FPGA does nothing at all.:confused: What are the detailed steps I should follow to set up the DMA operation correctly? I read the pci express compiler doc but didn't get enough information about software application. Thanks a lot for any help.33 Replies
- Altera_Forum
Honored Contributor
At least in Linux, -1 (or 0xffff...) is the default value when you are reading non-existent I/O or memory mapped locations. Not sure if this goes for PCI as well.
However, we cannot guess what you might be doing wrong without seeing source code. - Altera_Forum
Honored Contributor
TO_BE_DONE
- Altera_Forum
Honored Contributor
Hello Hey Hey,
The Linux command lspci does show my device, and further more the kernel registers this device with my driver so I am confident that the PnP features of PCI are operating correctly on my Arria dev board. It seems like the board is configuring correctly, hopefully member 'likewise' has a clue of what I am doing wrong. Thanks. PS. I bumped your rep points. I appreciate the continued help. - Altera_Forum
Honored Contributor
Hmm....You might not be doing anything wrong, this all might be 'features' of the chaining DMA hardware.
Whether there is actually anything behind the BAR0 is controlled by the USE_RCSLAVE Verilog generic on the altpcierd_example_app_chaining module in the example design. Depending on which version of the PCIe compiler you are using this may be set to either 0 or 1 by default. You can change it to a 1 and recompile your design to enable the memory behind BAR0. When USE_RCSLAVE == 0 reads to BAR0 will not generate a completion on the PCIe link. The Root Complex (motherboard chipset) will timeout and probably return all FF's to the CPU. Now the .sof file that comes with the dev kit should have this set to a 1, so the memory should be there. But... I think the hardware may not respond completely correctly to a single byte read. The completion would probably still be for a Dword (4 bytes). The root complex may not like this and still return all FF"s to the CPU. Even though I'm not a software guy, with a little help from Google it looks like the readb() function you are using is just a single byte read. So if your design has USE_RCSLAVE == 1 (like the development kit .sof), I suggest trying to use writel() and readl() instead of writeb() and readb(), to see if that works for accesses to BAR0. Now as far as accesses to BAR2 go, it turns out those registers are write-only. The PCIe Compiler User Guide is just plain wrong on that. So reads to those will fail. The chaining DMA was designed to provide all of it's status through interrupts and writes to the host memory. Those registers are also never changed by the hardware so they always have the same value that was written by software. So there was no real functional need to have read-back, you just have to trust the hardware. Though I admit read-back would be nice for the "trust but verify" mindset. :) - Altera_Forum
Honored Contributor
Another suggestion, when setting USE_RCSLAVE to 1 and trying to Write and Read from BAR0, use an offset above 32 (and less than 32KB) when accessing it. That should be some just plain old Read/Write memory. Offsets 0-31 from BAR0 have some undocumented internal testing features.
- Altera_Forum
Honored Contributor
Hello,
in first instance I would like to mimick what the testbench does, when starting a device driver. I am reading PCIe Compiler 8.0 UG, May 2008. Page 7-16 describes the Test Module: the Descriptor Header for write DMA is at 0x00-0x10, and for reads is at 0x10-x20. In the Descriptor Header, the base address descriptor fields is set to 0x800. However, the first Descriptor is placed at 0x810, the next at 0x820, etc. Now, my question is, what must be at 0x800?? The only reference to 0x800, is page 7-18 where it is said that at 0x80c the DMA engine is writing its completed DMA number. My suspicion is that at 0x800 a copy of the header must be, which is written by the DMA engine and where EPLAST is written. Any ideas? Regards, Leon. - Altera_Forum
Honored Contributor
Leon,
The chaining DMA hardware does write to the EPLAST field at 0x800c as you suspected. Nothing else needs to be in the 0x800 to 0x80b range. (The testbench BFM Driver may store a copy of the descriptor header there for it's own bookeeping purposes, I can't remember off the top of head for sure, but that is not needed for the actual hardware operation.) See my post# 5 (http://www.alteraforum.com/forum/showpost.php?p=10857&postcount=5) above where I said the same basic thing. - Altera_Forum
Honored Contributor
I have a Linux driver that at least triggers some DMA transfer. I will post it online once I have the last issues worked out. I need some insights though, can someone look along at what I miss?
Table 7-13 on page 7-19 of PCIe UG 8.0: 82 DWORDS (32-bit words) are transferred by the End Point DMA engine from Root Complex (or BFM) memory from (bus) address 0x8EF0 to End Point memory address 0x3. The table also specifies that "Data" is initialized with incrementing values in the address range 0x8900-0x8940. But this address range is not used in the DMA transfer at all??! What did I miss? The same question applies to descriptor [1] and [2]. Second unclearity: In the header, no control bits are set. In the descriptors, no control bits are set. How then can the Root Complex (BFM) poll for EPLAST??! It is only updated if either EPLAST_ENA is set in the descriptor control bits or header control bits. - Altera_Forum
Honored Contributor
I am correct that DMA operates on the End Point memory mapped to BAR[0], or is the memory involved in DMA located elsewhere?
Also, for individual DWORD read/writes to RC_SLAVE memory, must I set USE_RC_DIRECT_MEM to 1? altpcierd_rc_slave.vhd: USE_EP_MWR := 0;-- Allow EP to issue MemWr to RC on command USE_RC_MWR_MRD := 1; -- Allow RC access to EP MEM thru opcode regs USE_INIT_MEM: INTEGER := 0; USE_RC_DIRECT_MEM: INTEGER := 0;-- Allow RC direct access to EP MEM USE_EP_IO_RDWR:= 0; -- Allow EP to issue IO Rd/Wr to RC on command Thanks for any insights. - Altera_Forum
Honored Contributor
--- Quote Start --- I have a Linux driver that at least triggers some DMA transfer. I will post it online once I have the last issues worked out. I need some insights though, can someone look along at what I miss? Table 7-13 on page 7-19 of PCIe UG 8.0: 82 DWORDS (32-bit words) are transferred by the End Point DMA engine from Root Complex (or BFM) memory from (bus) address 0x8EF0 to End Point memory address 0x3. The table also specifies that "Data" is initialized with incrementing values in the address range 0x8900-0x8940. But this address range is not used in the DMA transfer at all??! What did I miss? The same question applies to descriptor [1] and [2]. Second unclearity: In the header, no control bits are set. In the descriptors, no control bits are set. How then can the Root Complex (BFM) poll for EPLAST??! It is only updated if either EPLAST_ENA is set in the descriptor control bits or header control bits. --- Quote End --- Regarding the first issue, unfortunately it appears the User Guide documentation is out of sync with the actual altpcietb_bfm_driver_chaining.v descriptor setup. The Verilog localparam statements that define all of the WR_DESCxxx and RD_DESCxxx values are by definition the correct values. I don't see the problem with the second issue. The first two times the "chained_dma_test" task is called, the input "use_eplast" is set to 1. Through some sub task calls we end up in task "dma_set_header" where "use_eplast" sets dt_dw0[18]. dt_dwo0 is then written to the descriptor header register in the Endpoint. Setting this bit in the EP register is what causes EPLAST to be updated during the DMA operation. The next two calls to the "chained_dma_test" use MSI instead of updating EPLAST to report the status.