1

I would like to write a driver and software that:

the software asks for data every twenty seconds ,and the hardware writes data to the DMA buffer and raises an interrupt when it’s done.

Unfortunately I have no experience writing drivers,and I can't use the Xilinx IP core which already has Driver.

The PCIe IP Core I use is UltraScale+ Device Integrated Block for PCI Express (PCIe).


I have implemented a simple driver that can read the status register on FPGA. And I follow these steps to implement DMA:

//Driver_Probe
pci_set_master(pdev);
drv_priv->virt_addr = kmalloc(2048, GFP_DMA);
if (!drv_priv->virt_addr)
{
    dev_err(dev, "Failed to kmalloc");
    err = -ENOMEM;
    return err;
}
drv_priv->bus_addr = pci_map_single(pdev, drv_priv->virt_addr, 2048, PCI_DMA_FROMDEVICE);
if (!drv_priv->bus_addr)
{
    dev_err(dev, "Failed to allocate DMA buffer");
    err = -ENOMEM;
    return err;
}

What else do I need to add to achieve this driver?

It is said that the data in the buffer cannot be read until the action is unmapped in the documentation. How can I successfully read the data after unmapping?

Are there any complete examples? The references I found were too brief for newbies.

I will be grateful for any help.

dys
  • 13
  • 3

1 Answers1

0

I wrote a tutorial to transfert data from FPGA to CPU RAM with PCIe some years ago but it's with a CycloneV.

In short:

  • First you have to allocate a coherent buffer with :
/* Allocate and initialize shared control data */
dmas->dmabuff = dmam_alloc_coherent(&pdev->dev, BUFF_SIZE, &dmas->dma_handle, GFP_KERNEL);
if (!dmas->dmabuff){
  printk("Error, can't alloc coherent\n");
  goto err_return;
}
  • then write the buffer address in your DMA controller under the FPGA.
writel((unsigned long)(dmas->dma_handle), &dmas->bar0[CRA_REG_A2P_ADDR_MAP_LO0/4]);

In this example, the dma address configuration register is located under BAR0 in CRA_REG_A2P_ADDR_MAP_LO0.

Once, PCIe core in FPGA have the buffer address, it will be able to read/write to CPU RAM.

It's an old tutorial, maybe Linux API changed a little bit now. But the spirit remain the same I think.

FabienM
  • 3,421
  • 23
  • 45
  • I’m a little confused about a few points. If I put the address into the TLP according to the format and pass it into the PCIe RQ/RC channel, it will be automatically judged as a dma action. Is that correct? I appreciate your help very much. – dys Mar 02 '22 at 05:30
  • It depend of your dma controller coded under the FPGA. In my example, I had to write in a BAR register to trigger dma transfert. – FabienM Mar 02 '22 at 07:50
  • 1
    I appreciate your help very much. – dys Mar 04 '22 at 12:40