Aleksei_Rostov 0 24 июня, 2020 Опубликовано 24 июня, 2020 · Жалоба Добрый день! Уважаемые специалисты подскажите пожалуйста, что делаю не так. Написал свой kernel module для SG AXI DMA (канал S2MM). Для тестирования задал в дескрипторах два пакета по 32 слова (32 бита на слово). На мастер SG M AXI отмапировал DDR и BRAM, чтобы по-тестировать модуль при дескрипторах сохраненных в одну или вторую память. Отображаю BRAM в виртуальное пространство ядра. start = desc_physicalAddress; // 0x400000000 -- BRAM address len = 8*1024; desc_virtualAddress = memremap(desc_physicalAddress, len, MEMREMAP_WB); if ( ! desc_virtualAddress ) { printk(KERN_ERR "%s: ERROR: desc_virtualAddress remapping FAILED\n", __FUNCTION__); } printk ( KERN_DEFAULT "%s:%i Descriptors memory phys addr is 0x%x and virt is 0x%x\n", __FUNCTION__, __LINE__, desc_physicalAddress, desc_virtualAddress ); Записываю дескрипторы, запускаю DMA. На шине axi memory для SG наблюдаю как DMA вычитывает все дескрипторы. SG DMA отрабатывает как и задумано. Теперь пробую сохранить дескрипторы в DDR. В DT резервирую память. / { reserved-memory { #address-cells = <1>; #size-cells = <1>; ranges; reserved: buffer@0x38000000 { no-map; reg = <0x38000000 0x00080000>; }; }; reserved-driver@0 { compatible = "xlnx,reserved-memory"; memory-region = <&reserved>; }; }; После старта ядра проверяю, что память успешно зарезервировалась (под дескрипторы 0x38000000-0x380800000 ). root@test:~# cat /proc/iomem 00000000-37ffffff : System RAM 00008000-008fffff : Kernel code 00a00000-00a517bf : Kernel data 38080000-3fffffff : System RAM Получаю указатель на память в виртуальном пространстве start = desc_physicalAddress; // 0x380000000 -- in DDR address len = 512*1024; desc_virtualAddress = memremap(desc_physicalAddress, len, MEMREMAP_WB); if ( ! desc_virtualAddress ) { printk(KERN_ERR "%s: ERROR: desc_virtualAddress remapping FAILED\n", __FUNCTION__); } printk ( KERN_DEFAULT "%s:%i Descriptors memory phys addr is 0x%x and virt is 0x%x\n", __FUNCTION__, __LINE__, desc_physicalAddress, desc_virtualAddress ); Запускаю AXI DMA и получаю ошибку SGIntErr (internal error). Проверяю данные на axi шине SG. действительно, дескрипторы вычитаны неправильно. По сравнению с BRAM все одинаково. Не могу понять, что не так. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gosha-z 1 24 июня, 2020 Опубликовано 24 июня, 2020 · Жалоба Я же вам давал ссылки как правильно работать с DMA в ядре... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Aleksei_Rostov 0 24 июня, 2020 Опубликовано 24 июня, 2020 · Жалоба 23 minutes ago, gosha-z said: Я же вам давал ссылки как правильно работать с DMA в ядре... за ссылки спасибо, но я быстрей запустился используя platform_get_resource для работы с регистрами DMA, прерываниями и dma_alloc_coherent для буфера ДМА. Если выложите простой пример запуска DMA_FROM_DEVICE канала DMA на основе документации по вашей ссылке, буду очень признателен. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gosha-z 1 24 июня, 2020 Опубликовано 24 июня, 2020 · Жалоба Вот Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Aleksei_Rostov 0 24 июня, 2020 Опубликовано 24 июня, 2020 · Жалоба 9 minutes ago, gosha-z said: Вот Георгий, спасибо большое, эта ссылка у меня сохранена. Но я написал свой модуль и он работает. Остался вопрос только с ioremap для памяти в DDR. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gosha-z 1 24 июня, 2020 Опубликовано 24 июня, 2020 · Жалоба В смысле как делать remap памяти ядра в userspace? Почитайте исходники и DMA-HOW-TO, там все написано. У меня, по крайней мере, сделано ровно так и оно работает... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Aleksei_Rostov 0 24 июня, 2020 Опубликовано 24 июня, 2020 · Жалоба remap делаю без проблем. Не понятно вот что. Записываю дескрипторы iowrite32 ( desc_physicalAddress + 0x40, desc_virtualAddress + 0x0000); iowrite32 ( lp->dma_buffer_physical_address, desc_virtualAddress + 0x0008); iowrite32 ( 0x8000080, desc_virtualAddress + 0x0018); iowrite32 ( desc_physicalAddress + 0x40, desc_virtualAddress + 0x0040); iowrite32 ( lp->dma_buffer_physical_address + 0x80, desc_virtualAddress + 0x0048); iowrite32 ( 0x4000080, desc_virtualAddress + 0x0058); Виртуальный адрес получаю с помощью memremap start = desc_physicalAddress; // 0x380000000 -- in DDR address len = 512*1024; desc_virtualAddress = memremap(desc_physicalAddress, len, MEMREMAP_WB); Так вот, если desc_physicalAddress подставляю адрес BRAM, то SG DMA работает, а если desc_physicalAddress подставляю адрес зарезервированной в DDR памяти, то SG DMA вычитывает правильно только несколько первых дескрипторов и виснет. Пока вам отвечал, разобрался)) Ошибка на невнимательность - не проинициализировал desc_physicalAddress (когда использую BRAM там все нули сразу), когда DDR - там мусор. Вообщем SG вычитывал правильные дескрипторы и мусор, поэтому и вис. Проинициализировал зарезервированную область DDR и все заработало Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться