Jump to content
    

Xilinx UltraScale PCI-E - компьютер не видит прерывания от устройства

Проблема такая. Есть устройство на PCI-E Kintex UltraScale. Оно определяется, мой драйвер позволяет читать и писать регистры (MMIO), это работает надежно. Также устройство поддерживает (точнее требует) работу с MSI, их я формирую своими сообщениями MWr по адресу, который получил по MMIO (там пишется и BDF и msi address и прочее). Но вот беда - /proc/interrupts показывает нули, а место где драйвер ждет прерывание - вот там он и вешается в ожидании

 

У меня и раньше была проблема с Kintex 7 со старым интерфейсом где TLP, я пока не добавил кое какое поле в пакете - оно не воспринимало мои пакеты как MSI, ситуация 1 в 1. Думаю и сейчас какое то поле забыл

 

Самое смешное, что устройство работает нормально на трех других совершенно непохожих системах. А тут пришел вот промышленный ПК (одноплатник cPCI-Serial) и в нем то оно и не хочет ловить MSI

 

На какие поля стоит обратить внимание, что они могут быть критичны? Поля в PCI сообщении MWr. Может битность 64 включилась, а я на 32 бита рассчитываю? Система 64 битная, старая относительно (2015-2017 годы). То есть, какие то биосы и чипсеты прощают эту некую ошибку (или недосказанность в полях). А вот эта система не прощает некое расхождение со стандартом

Share this post


Link to post
Share on other sites

15 часов назад, 1891ВМ12Я сказал:

MSI, их я формирую своими сообщениями MWr по адресу, который получил по MMIO

А данные в этом MWr вы какие передаёте? 16-битное поле. Его тоже вместе с адресом хост генерит. Чаще всего там 0, поэтому можно передавать его (как значение по умолчанию), и всё работает. Но есть хосты, где генерится какое-то другое значение. Если у вас этот случай, то вполне объяснимо следующее:

15 часов назад, 1891ВМ12Я сказал:

Самое смешное, что устройство работает нормально на трех других совершенно непохожих системах. А тут пришел вот промышленный ПК (одноплатник cPCI-Serial) и в нем то оно и не хочет ловить MSI

Корректно оба значения (и адрес, и данные) MSI передавать дивайсу через MMIO.

Share this post


Link to post
Share on other sites

2 hours ago, dxp said:

А данные в этом MWr вы какие передаёте? 16-битное поле. Его тоже вместе с адресом хост генерит. Чаще всего там 0, поэтому можно передавать его (как значение по умолчанию), и всё работает. Но есть хосты, где генерится какое-то другое значение. Если у вас этот случай, то вполне объяснимо следующее:

Корректно оба значения (и адрес, и данные) MSI передавать дивайсу через MMIO.

Если по картинке, то передаю MSI Vector 0 (все 6 бит нули). А вот Message Data - эти 10 бит надо откуда то брать? Задать какое-то значение или же вычитать его откуда то в системе? Пока что у меня там нули, буду читать что там требуется передать, и вот на трех системах нули в этом поле устраивали

Сам факт прихода сообщений не проверял, но могу сделать, просто выделив небольшое dma и подпихнуть его адрес там где передаю msi_address, так я и отлаживал первоначально

Снимок экрана от 2023-01-28 10-12-55.png

 

UPDATE: dxp, Вы правы, у меня в компьютере Data: 0000 везде для всех устройств. А на целевой системе там везде не нулевые Data относительно MSI! Получается, что я должен передавать message data в пакете MSI! Но должен ли я затирать 6 бит нулями? Сделаю так, чтобы в драйвере можно было писать это, легко попробовать оба варианта: и затирая 6 бит нулями и НЕ затирая, попробую отпишусь!

Share this post


Link to post
Share on other sites

19 минут назад, 1891ВМ12Я сказал:

Если по картинке, то передаю MSI Vector 0 (все 6 бит нули). А вот Message Data - эти 10 бит надо откуда то брать?

Не эксперт в теме, но насколько знаю, значения адреса и данных хост программирует в пространстве регистров IO PCIe устройства. Это происходит при регистрации прерывания. Т.е. вам нужно посмотреть, какие значения адреса и данных MSI находятся в IO ядра:

RWcw1AA.png

Значение адреса вы откуда берёте?

28 минут назад, 1891ВМ12Я сказал:

Сам факт прихода сообщений не проверял, но могу сделать, просто выделив небольшое dma и подпихнуть его адрес там где передаю msi_address, так я и отлаживал первоначально

Приход этого сообщения так просто не определите: этот адрес для MSI — фиктивный. Т.е. памяти по этому адресу может и не быть. Смысл его в том, что контроллер прерываний в RC настроен на перехват таких сообщений, которые являются сигнализацией о событии прерывания.

Share this post


Link to post
Share on other sites

19 minutes ago, dxp said:

Значение адреса вы откуда берёте?

pci_bus_read_config_dword(device->pci->bus, 0, 148, &device->msi_address);

UPDATE: исправил вместо нуля надо device->pci->devfn

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

 

Выше я исправил пост, Вы оказались правы, на целевой системе message data не нули, а на "бытовых" компьютерах через переходник работало потому что везде там message data равны нулям для абслютно всех устройств. Наверное это и есть решене проблемы, уже исправляю

Share this post


Link to post
Share on other sites

49 минут назад, 1891ВМ12Я сказал:

Но должен ли я затирать 6 бит нулями?

Насколько понимаю, надо брать все 16 бит как есть — хост туда уже кладёт корректное значение, включая вектор для данного прерывания.

7 минут назад, 1891ВМ12Я сказал:

Наверное это и есть решене проблемы, уже исправляю

Сообщите, получилось ли? Интересно.

Share this post


Link to post
Share on other sites

2 hours ago, dxp said:

Сообщите, получилось ли? Интересно.

Да, получилось! Всё заработало как надо, как на других системах. Премного благодарю и спасибирую!!!

 

И да, уточню что действительно MSI Message Data подставил вот как есть, не меняя никакие биты и не сбрасывая их в ноль

Share this post


Link to post
Share on other sites

On 1/28/2023 at 5:28 PM, 1891ВМ12Я said:

Да, получилось! Всё заработало как надо, как на других системах. Премного благодарю и спасибирую!!!

 

И да, уточню что действительно MSI Message Data подставил вот как есть, не меняя никакие биты и не сбрасывая их в ноль

Подскажите, пожалуйста, кто работал с аппаратным блоком pcie artix ultrascale+ pcie4 какую скорость удалось полчить в режиме pcie4 x4 линии?

Share this post


Link to post
Share on other sites

On 2/8/2023 at 12:42 PM, dmitry-tomsk said:

Подскажите, пожалуйста, кто работал с аппаратным блоком pcie artix ultrascale+ pcie4 какую скорость удалось полчить в режиме pcie4 x4 линии?

Если честно, очень низкую, раза в 3-4 меньше ожидаемой пиковой. У меня x8 линии, 8 * 8 = 64, минус оверхед, и все равно получил 15 гигабит всего, а это раза в 3 меньше чем уровень для достижения счастья

Share this post


Link to post
Share on other sites

On 3/1/2023 at 8:22 PM, 1891ВМ12Я said:

Если честно, очень низкую, раза в 3-4 меньше ожидаемой пиковой. У меня x8 линии, 8 * 8 = 64, минус оверхед, и все равно получил 15 гигабит всего, а это раза в 3 меньше чем уровень для достижения счастья

Спасибо. А что за плата? Чей дма контроллер? Мы планировали свою рисовать без теста на макете, скорость нужна хотя бы 40.

Share this post


Link to post
Share on other sites

On 3/3/2023 at 5:01 PM, dmitry-tomsk said:

Спасибо. А что за плата? Чей дма контроллер? Мы планировали свою рисовать без теста на макете, скорость нужна хотя бы 40.

DMA свой, но его можно улучшить существенно. А еще лучше использовать ядро Linux с DMA CMA механизмом с огромными страницами, этак на мегабайт. На самодельной плате и на отладочной покупной - разницы нет

Share this post


Link to post
Share on other sites

On 3/3/2023 at 5:01 PM, dmitry-tomsk said:

Спасибо. А что за плата? Чей дма контроллер? Мы планировали свою рисовать без теста на макете, скорость нужна хотя бы 40

Хотел бы дополнить мой ответ. Наткнулся на статью https://www.oreilly.com/library/view/linux-device-drivers/0596005903/ch15.html

И в ней пишется, если я верно всё понимаю, что после получения данных от устройства надо делать dma_sync_single_for_cpu, это понятно зачем (мне понятно), но затем я делал dma_unmap_single, повторяя как попугай за примерами

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

Еще открытием стало то, что надо делать dma_set_mask(dev, DMA_BIT_MASK(32)), пишут что без этого что то может не работать. На одной из систем, сижу страдаю сейчас, работает dma_map_single, но не срабатывает чтение от dma_alloc_coherent. На 5 разных системах работает, а на одной из - нет. Хотя, пишут Again, if your device supports normal, 32-bit DMA operations, there is no need to call dma_set_mask. Значит не причина проблем

Share this post


Link to post
Share on other sites

25 минут назад, 1891ВМ12Я сказал:

Открытием для меня стало то, что можно вызвать dma_sync_single_for_device, и это как бы вернет владение буфером обратно устройству, позволит ему туда писать снова.

Если посмотреть по исходникам, то суть этой функции в синхронизации кешей и т.п. узлов системы с областью памяти, читаемой устройством посредством DMA. В противном случае процессор может видеть одни данные, а через DMA будут читаться другие. Если этот буфер не читается устройством, а только пишется из устройства и читается процессором (не модифицируется соответствующий блок данных в кеше), то смысла в этой функции по сути нет.

 

Share this post


Link to post
Share on other sites

2 hours ago, makc said:

то смысла в этой функции по сути нет

Могу я не вызывать unmap тогда каждый раз? Сделал sync, забрал что хотел, далее устройство может в него снова писать?

Share this post


Link to post
Share on other sites

1 час назад, 1891ВМ12Я сказал:

Могу я не вызывать unmap тогда каждый раз? Сделал sync, забрал что хотел, далее устройство может в него снова писать?

Да, именно так у меня и работало одно устройство под линуксом. Мэппинг выполнялся один раз при старте драйвера. Минус этого подхода проявляется при работе через SWIOTLB - он не резиновый. 😉

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...