0

[编辑]

我有一个带有 fpga (SoC) 的 arm64 板。

任务很简单:

  • 可以将数据从/到“用户空间”区域(应用程序)传输到/从“内核空间”物理内存(设备内存 = fpga regs),有和没有 dma 支持使用(流式传输类型)。那个 dma 在板上(ZynqMP / GDMA)。

我将有几个设备 - 在 fpga 和外部,应该使用这种通信,但现在我只使用 fpga-ddr4 内存区域。

现在我看到了下一个逻辑流程:

  • 一些初始化(dma 参数等);
  • ioremap() 一个 fpga 设备区域;
  • 制作一个缓冲区(通过 kzalloc() 或其他) - 这个缓冲区我应该通过 mmap fops 给美国;
  • 从缓冲区制作一个分散列表(下面的伪代码);
  • 使用 scatterlist 和 dmaengine 来传输数据;
// scatterlist init pseudo-code

struct scatterlist sgl[2];
struct scatterlist *sge;
int i, buf_n, err_code;
__u8 *buffer; // allocated earlier

sg_init_table(sgl, ARRAY_SIZE(sgl));

for_each_sg(sgl, sge, ARRAY_SIZE(sgl), i) {
  struct page *pg = virt_to_page(buffer + i * PAGE_SIZE);
  dma_addr_t dma_handle = dma_map_page(&pdev->dev, pg, 0, PAGE_SIZE, direction /* DMA_TO_DEVICE */);
  if ((err_code = dma_mapping_error(&pdev->dev, dma_handle))) {
    dev_err(&pdev->dev, "dma page mapping failed! (code: %i)\n", err_code);
    break;
  }
  sg_set_page(sge, pg, PAGE_SIZE, 0);
}

dma_map_sg(&pdev->dev, sgl, ARRAY_SIZE(sgl), direction) // with appropriate check

现在我误解了下一个 - 目的地如何或在哪里控制?我的意思是,我已经在 RAM 中分配了缓冲区,从中创建了 scatterlist,并通过 dmaengine 函数的参数给出了这个列表以进行传输。但我没有设置/使用 ioremapped 设备内存区域来保存这个缓冲区数据!这个 dma 是否仅适用于适当的 RAM 内存区域,我应该将缓冲区复制到设备区域?或者,我应该使用 ioremap 区域作为缓冲区吗?是正确的流量吗?请解释一下我的错误?

4

0 回答 0