[отредактировано]
У меня есть доска на arm64 с fpga (Итак C).
Задача проста:
- позволяет передавать данные из / в область "User Space" (приложение) в / из "Kernel Space" phys mem (device mem = fpga regs), с использованием поддержки dma и без нее (тип потоковой передачи). Этот dma находится на плате (ZynqMP / GDMA).
У меня будет несколько устройств - на fpga и снаружи, которые должны использовать эту связь, но сейчас я работаю только с fpga-ddr4 mem area.
Теперь я вижу следующий логический поток c:
- некоторая инициализация (параметры dma и т. д.);
- ioremap () устройства fpga area;
- сделать буфер (по kzallo c () или другому) - этот буфер я должен дать США с помощью mmap fops;
- сделать список рассеяния из буфера (псевдо- код ниже);
- используйте список рассеяния с 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
Теперь я неправильно понял следующее - как или где управлял пункт назначения? Я имею в виду, что я выделил буфер в ОЗУ, сделал из него scatterlist и передал этот список аргументом функций dmaengine для передачи. Но я не устанавливаю / не использую область памяти устройства ioremapped для сохранения этих данных буфера! Это dma работает только с соответствующей областью памяти RAM, и я должен скопировать буфер в область устройства? Или я должен использовать область ioremapped в качестве буфера? Это правильный поток? Объясните мне мои ошибки, признает?