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

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 годы). То есть, какие то биосы и чипсеты прощают эту некую ошибку (или недосказанность в полях). А вот эта система не прощает некое расхождение со стандартом

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


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

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

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

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

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

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

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

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


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

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 бит нулями и НЕ затирая, попробую отпишусь!

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


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

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

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

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

RWcw1AA.png

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

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

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

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

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


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

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 равны нулям для абслютно всех устройств. Наверное это и есть решене проблемы, уже исправляю

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


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

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

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

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

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

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

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

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


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

2 hours ago, dxp said:

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

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

 

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

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


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

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

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

 

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

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

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


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

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 меньше чем уровень для достижения счастья

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


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

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

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

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

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


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

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

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

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

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


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

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. Значит не причина проблем

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


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

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

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

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

 

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


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

2 hours ago, makc said:

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

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

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


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

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

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

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

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


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

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

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

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

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

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

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

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

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

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