Перейти к содержанию
    

PCI-E + XDMA + пользовательское ПО на х86

Собственно задача - с минимальными потерями времени и усилий работать с хоста через PCI-E с ускорителем в ПЛИС.
Насколько я понял самый простой способ - использование ядра XDMA (обёртка над ядром PCI-E) [1], готовых драйверов xdma.ko [2] и шаблонов приложений которые идут в комплекте [3]

Но после вдумчивого изучения pg195 и запуска на плате тестового примера остались вопросы, хотя они скорее системного плана, но связаны именно со спецификой ядра XDMA.

Что надо от ускорителя (для определенности - пусть будет крипто-ускоритель):
1) "стримить" с хоста данные на обработку, притом чтобы ускоритель мог сообщать, что достаточно, пока больше не надо присылать данные (т.е. некий flow control на отправку)
2) уведомлять хост о том, что данные обработаны и можно забирать, и соответственно отдавать "стрим" в хост.

 

Почему стрим в кавычках: по сути это не непрерывный стрим, а блоки по 4К (притом с заголовками, чтобы на приёмной стороне (хосте) можно было сматчить контекст - какому выходному блоку какой входной соответствовал), но по природе обработки ускоритель это как PIPE: с одной стороны вышло, с другой вышло и есть некая "глубина" внутри - чтобы начал выдавать первые данные надо несколько десятков блоков в него "застримить".

Т.о. в терминах xdma для этой задачи AXI Stream подходит очень хорошо, но вот на тестовом проекте заметил нестабильную работу AXI Stream (пропадание данных) в связи с чем рассматриваю и AXI MM как альтерантиву.


Но что бы написать "правильное" и надёжно работающее хостовое приложение хотелось бы понимать несколько вещей (далее список вопросов):

 


##### BAR #####

pg195, таблица 3, соответствующа вкладка в конфигураторе XDMA

* DMA - это собственно работа с самим движком
* Bypass DMA - думал что это прямой доступ к пространству памяти карточки в обход движка ДМА, но похоже это не так, это ЕЩЕ ОДНО выделенное адресное пространство (доп.канал) никак не связанное ни с движком ДМА ни с памятью в которую пишет движок ДМА.
* AXI Lite Master - видимо от Bypass DMA отличается только тем, что это Lite

photo_2020-07-29_15-27-57.thumb.jpg.863eab48465ac0109ad2957e5f3e1fdd.jpg

1084472326_Screenshotfrom2020-07-2916-30-53.thumb.png.43c1c083b58d67a1a71b92ef5da7e66e.png


1.1 Смущает то, что для BAR DMA в режиме AXI MM в конфиге вивадо никак не задаётся размер BAR - это как?.. где/чем определяется размеры адресного пространства с которым работает карточка?
1.2 Далее в разделе про прерывания вскользь упомянуто, что BAR может быть _address space_ а может быть и _register space_. Надо ли держать это в уме или при использовании готового драйвера просто работать с /dev/xdma0_xxx и не париться?
1.3 Какие реальные кейсы могут быть для использования Bypass DMA ?


##### IRQ & user app #####

У самого IP-ядра есть внешние ножки прерывания, но как их использовать pg195 ответа не даёт, ограничиваясь тестовым примером проекта, в котором прерывания взводятся записью из хостовой программы в регистр в пространстве AXI Lite Master.

Но как это обработать из хостовой программы совершенно неясно:

2.2 Вот мы открыли /dev/xdma0_h2c и льём туда данные, как считать прерывание "BUSY", что дескать лить хорош уже (и дальше ждать прерывания "FREE") - как это на стороне пользователя обрабатывать?
2.2 При приёме мы открываем /dev/xdma0_c2h и ждём прерывания "READY" указывающее на готовность данных  в /dev/xdma0_c2h - как это на стороне пользователя обрабатывать?
2.3 Чем "правильнее" пользоваться на стороне карточки - ножками usr_irq_req и usr_irq_ack, или же механизмом MSI (msi_enable, msi_vector_width)?
2.4 В AR654444 еще описан способ загрузки драйвера в режиме поллинга (работает только в направлении c2h) - стоит ли использовать его вместо прерывания для упощения логики приложения?

photo_2020-07-29_15-27-56.thumb.jpg.60276d8fc50d61108bbea158a1543e00.jpg


##### AXI ST #####

Самое интересное: управление потоками, нарезка на "пакеты"

DMA H2C Stream
--------------
For host-to-card transfers, data is read from the host at the source address, but the destination address in the descriptor is unused. Packets can span multiple descriptors. The termination of a packet is indicated by the EOP control bit. A descriptor with an EOP bit asserts tlast on the AXI4-Stream user interface on the last beat of data.


- т.е. на стороне хоста за формирование для AXI4-Stream сигнала tlast, который фактически нарезает пакеты как мне надо, отвечает отвечает механизм, выставляющий бит EOP (в TLP???)

3.1 достаточно ли для user app указать size=4K, для формирования EOP в xdma.ko?
3.2 см. пп.1.1 если мы не задали размер BAR для DMA, то кто будет заботиться о буферах в движке DMA на карточке и в пользовательском РТЛ коде? Буферы в движке DMA на карточке вообще черный ящик: вот отправим мы пакет с size=1М - куда его сохраняет движок DMA? - не налету же он его в пользовательскую логику передаёт???
3.3 по размерам нашёл такое упоминание в PG195, эти значения как-то завязаны на размер внутренних буферов движка ДМА??:

photo_2020-07-29_15-27-59.thumb.jpg.37eea576b32d63d5ef24e021fbc4afaf.jpg

DMA C2H Stream
--------------
For card-to-host transfers, the data is received from the AXI4-Stream interface and written to the destination address. Packets can span multiple descriptors. The C2H channel accepts data when it is enabled, and has valid descriptors. As data is received, it fills descriptors in order. When a descriptor is filled completely or closed due to an end of packet on the interface, the C2H channel writes back information to the writeback address on the host with pre-defined WB Magic value 16'h52b4 (Table 10: C2H Stream Writeback Fields), and updated EOP and Length as appropriate.

- тут вроде бы тоже всё прозрачно - нарезаем пакаты для отправки сигналом tlast в AXI4-Stream, который по идее должен устанавливать в дескрипторе поле EOP

3.4 Удаляет ли при приёме дескриптор с WB Magic драйвер xdma.ko или же его должно удалять пользовательское приложение?
3.5 не очень понятна строка "For valid data cycles on the C2H AXI4-Stream interface, all data associated with a given packet must be contiguous" - означает ли это, что до взведения tlast надо держать tvalid и лить данные без пропуска клоков (иначе движок ДМА "отрежет" и отправит пакет на хост по таймауту)?

1169503984_Screenshotfrom2020-07-2917-34-37.thumb.png.af5e54e527278e93d6fd31936361d8fa.png


##### AXI MM #####

4.1 опять см. пп.1.1 - как задаётся размер пространства для AXI MM? В интерфейсе конфигурирования нет такой настройки.


##### источники #####

[1] https://www.xilinx.com/support/documentation/ip_documentation/xdma/v4_1/pg195-pcie-dma.pdf
[2] https://github.com/Xilinx/dma_ip_drivers
[3] https://github.com/Xilinx/dma_ip_drivers/tree/master/XDMA/linux-kernel/tools

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

На всякий случай - QDMA:

Quote

The Xilinx® LogiCORE™ QDMA for PCI Express® (PCIe) implements a high performance, configurable Scatter Gather DMA for use with the PCI Express Integrated Block.  The IP provides an optional AXI4-MM or AXI4-Stream user interface.

The QDMA solution provides support for multiple Physical/ Virtual Functions with scalable queues, and is ideal for applications that require small packet performance at low latency.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую!

Много вопросов,  сразу не ответишь на все :unknw:

Вы для какой версии/чипа  хотите DMA?  

1.1 Для  режима DMA AXI MM  вам задавать размер BAR не нужно  так как DMA AXI MM  это выход DMA и адреса на ней задаются  в дескрипторах  DMA

DMA bypass AXI  это  мастер шина  адреса на которой отображаются в соответсвующий BAR.  Но слать туда с CPU быстро не получится - для этого нужен внешний DMA ( в PC или на другой карте в контексте 1.3

 

Странно что у вас проблемы со Stream  у меня  несколько проектов с ним работало, но правда исходный пример драйвера  допиливали. Как раз с "нарезкой" (со стороны железа) там все удобно было  tvalid|tready контролируют поток  а tlast делит на пакеты переключаясь на след дескриптор. Со стороны софта  крутился классический кольцевой буфер дескрипторов. 

 

Удачи! Rob.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 minutes ago, RobFPGA said:

Вы для какой версии/чипа  хотите DMA?  

US/US+

8 minutes ago, blackfin said:

На всякий случай - QDMA:

да, видел, но это прям задание со звёздочкой, уж больно он монстроузный как по утилизации ресурсов не карточке, так и по хостовой части (поддержка DPDK например)

его точно с наскока вот так не взять

11 minutes ago, RobFPGA said:

Странно что у вас проблемы со Stream  у меня  несколько проектов с ним работало, но правда исходный пример драйвера  допиливали. Как раз с "нарезкой" (со стороны железа) там все удобно было  tvalid|tready контролируют поток  а tlast делит на пакеты переключаясь на след дескриптор.

может у меня вообще на хостовой стороне лажа, надо код показать какому-нить знакомому линуксоиду

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1. 64Bit Enable ставить рекомендуется, это рекомендация PCI SIG, если мне память не изменяет. Тогда у вас BARы начинают парами ходить (0+1,2+3,4+5 и т.д.). Соотв. в драйвере соответствующим образом ставьте DMA mask.

2. AXI Lite Master - это если вы хотите с хоста порулить какой-нибудь периферией типа SPI/I2C/MDIO внутри карточки.

3. Прерывания транслируются в хост - LEGACY/MSI/MSI-X, как хотите.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую!

54 minutes ago, Doka said:

2.3 Чем "правильнее" пользоваться на стороне карточки - ножками usr_irq_req и usr_irq_ack, или же механизмом MSI (msi_enable, msi_vector_width)?

Проще usr_irq_req/usr_irq_ack так как внутри DMA они подключаются к модулю формирующему транзакции на MSI

54 minutes ago, Doka said:

- т.е. на стороне хоста за формирование для AXI4-Stream сигнала tlast, который фактически нарезает пакеты как мне надо, отвечает отвечает механизм, выставляющий бит EOP (в TLP???)

Для режима Stream вы в дескрипторе DMA пишете длину данных и в поле EOP пишете 1,  и тогда  по окончании передачи данных этого дескриптора  на выходе stream сформируется tlast.  

Соответственно при приеме  сигнал  tlast на входе stream DMA  "закрывает" текущий  дескриптор (даже если там еще есть место в буфере) и в статусе этого дескриптора в поле EOP появится 1.   

54 minutes ago, Doka said:

3.5 не очень понятна строка "For valid data cycles on the C2H AXI4-Stream interface, all data associated with a given packet must be contiguous" - означает ли это, что до взведения tlast надо держать tvalid и лить данные без пропуска клоков (иначе движок ДМА "отрежет" и отправит пакет на хост по таймауту)?

Скорее всего имелось ввиду что данные одного пакета не должны мешаться с данными других пакетов. tvalid/tready  работают классически  управляя потоком.
Движок DMA шлет данные в PC через PCIe  либо если набралось данных на PCIe транзакцию, либо счетчик байтов в дескрипторе закончился, либо на входе tlast.         

Удачи! Rob.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 minute ago, gosha-z said:

Прерывания транслируются в хост - LEGACY/MSI/MSI-X, как хотите.

пытаюсь это увязать с хостовой стороной (в кишки драйвера не лезем), вот к чему я могу обращаться из user space:

 

ll /dev/xdma*

xdma0_bypass
xdma0_bypass_c2h_0
xdma0_bypass_h2c_0
xdma0_c2h_0
xdma0_h2c_0
xdma0_control
xdma0_events_0
xdma0_events_1
xdma0_events_2
xdma0_events_3
xdma0_events_4
xdma0_events_5
xdma0_events_6
xdma0_events_7
xdma0_events_8
xdma0_events_9
xdma0_events_10
xdma0_events_11
xdma0_events_12
xdma0_events_13
xdma0_events_14
xdma0_events_15
xdma0_user
xdma0_xvc

xdma0_user = AXI Lite Master

xdma0_c2h_0 & xdma0_h2c_0 == DMA

а вот как работать с прерываниями примеров нет

 

 

5 minutes ago, RobFPGA said:

Для режима Stream вы в дескрипторе DMA пишете длину данных и в поле EOP пишете 1,  и тогда  по окончании передачи данных этого дескриптора  на выходе stream сформируется tlast.  

правильно ли понимаю, что этот дескриптор (64бита, но на скрине 64байта - кажется опечатка) на стороне хоста должно формировать user app?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 minute ago, Doka said:

а вот как работать с прерываниями примеров нет

И не будет. В вашем случае приложение, которое работает в user space, живет в стандартном epoll-цикле, соотв. character driver должен в file_operations заявлять кастомный полл, который проверяет, есть ли данные на отдачу в приложение и возвращает соответствующее значение. Приложение изначально делает mmap куска памяти, получая адрес буфера, в который DMA складывает (или откуда берет данные) и работает с этими данными.

18 minutes ago, Doka said:

правильно ли понимаю, что этот дескриптор (64бита, но на скрине 64байта - кажется опечатка) на стороне хоста должно формировать user app?

Нет. DMA работает с физическими адресами, про которые user app, в наиболее общем случае, ничего не знает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую!

28 minutes ago, Doka said:

правильно ли понимаю, что этот дескриптор (64бита, но на скрине 64байта - кажется опечатка) на стороне хоста должно формировать user app?

Мне  сложно точно сказать  так как я в основном с железом работал а не с драйвером.  Обычно сами дескрипторы  формирует и заполняет драйвер, а user-app только рулит этим дергая соответствующие вызовы с указанием буферов данных, размером и режимами.

Размер и формат дескриптора DMA надо в доке смотреть, для XDMA это вроде 32 байта. 

Удачи! Rob.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 hours ago, gosha-z said:

Приложение изначально делает mmap куска памяти, получая адрес буфера, в который DMA складывает (или откуда берет данные) и работает с этими данными.

ага. это как раз есть в примерах комплекта поставки xdma.ko

 

3 hours ago, gosha-z said:

приложение, которое работает в user space, живет в стандартном epoll-цикле, соотв. character driver должен в file_operations заявлять кастомный полл, который проверяет, есть ли данные на отдачу в приложение и возвращает соответствующее значение

а есть может какая книжуля где об этом подробнее почитать, а то чувствую мне матчасти не хватает, что бы что-то стабильно работающее в user space соорудить. Я так понимаю Linux Device Driver не подойдёт?

2 hours ago, RobFPGA said:

Обычно сами дескрипторы  формирует и заполняет драйвер, а user-app только рулит этим дергая соответствующие вызовы с указанием буферов данных, размером и режимами.

да там полная чехарда с дескрипторами ( или не там, а у меня в голове ): есть для AXI MM, есть свой формат для AXI Stream, а помимо этого есть ДМАшные (которые как раз делают SG) - вот последние-то точно драйвер разбирает, а для AXI Stream уже засомневался, да и примера нету в поставке для xdma.ko чтобы посмотреть "как правильно", придётся в исходники xdma.ko лезть, смотреть где там этот magic number пришивается/отрезается.

2 hours ago, RobFPGA said:

Размер и формат дескриптора DMA надо в доке смотреть, для XDMA это вроде 32 байта. 

вот конкретно по AXI Stream в доке написано

The length of a C2H Stream descriptor (the size of the destination buffer) must always be a multiple of 64 bytes.

но в таблице дескриптор занимает 64 бита:

224327207_Screenshotfrom2020-07-2923-28-48.thumb.png.9be1213e1d77d0a4c4045c6c8ea67267.png

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

13 minutes ago, Doka said:

а есть может какая книжуля где об этом подробнее почитать

Первоисточникеще один, grep -R по исходникам и гугл - вот мои университеты.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 minutes ago, gosha-z said:

Первоисточникеще один, grep -R по исходникам и гугл - вот мои университеты.

спасибо. первоисточник вполне удобоварим!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую!

28 minutes ago, Doka said:

вот конкретно по AXI Stream в доке написано

The length of a C2H Stream descriptor (the size of the destination buffer) must always be a multiple of 64 bytes.

но в таблице дескриптор занимает 64 бита:

Stream writeback  это не дескриптор  а  статус который записывается DMA  когда очередной дескриптор  канала C2H выполнен.  В нем  как раз и пишется актуальное число принятых  байт в буфере и был ли tlast.

Формат дескриптора смотрите в Table 5: Descriptor Format
Offset Fields
0x0   Magic[15:0] Rsv[1:0] Nxt_adj[5:0] Control[7:0]
0x04 4’h0, Len[27:0]
0x08 Src_adr[31:0]
0x0C Src_adr[63:32]
0x10 Dst_adr[31:0]
0x14 Dst_adr[63:32]
0x18 Nxt_adr[31:0]  
0x1C Nxt_adr[63:32]

Удачи! Rob.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 7/30/2020 at 12:06 AM, new123 said:

я по ней начинал, многое объясняет. Third edition которая

Не очень многое. Но к счастью, исходники драйверов, наиболее простых, очень помогают. Если у автора темы будут вопросы по драйверам Linux, пишите, может что-то смогу помочь. Правда я делал DMA врукопашную, и API на стороне ядра Linux по части SGDMA мне показались не очень хорошими, запутанными. На стороне ПЛИС и драйвера делал DMA сам, мне это показалось проще чем страдать с корками производителей, хотя возможно я упустил какие-то фантастические преимущества этих IP-ядер (понять бы каких).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...