Jump to content
    

1891ВМ12Я

Свой
  • Posts

    1,661
  • Joined

  • Last visited

Everything posted by 1891ВМ12Я


  1. Вы оказались правы. Действительно, 1 пакет всё же принимается, я зафиксировал на каком такте всё обрывается - на первом же. И на первом же такте tlast. Стал смотреть, там маска 0x07 = 0111, всего три DW пришло. Смотрю содержимое и вижу там 40009000 00000000 00000000, то есть первое слово 40009000 И тут догадка появилась! По схеме там стоит pci-e switch. А что если компьютер умеет 256/512 байт, а свитч нет??? Но там стоит PEX8725 и "In addition to low latency, the device supports a packet payload size of up to 2048 bytes" - не причина 40009000 - что за странный адрес, а может не адрес а спец пакет, заголовок. Пойду читать документацию, что значит в CplD такое содержимое. Буду рад идеям Идея появилась! А что если это тандемный ответ? Что если мне стоит пропустить этот ответ, а дальше уже пойдет корректный??? Просто первый пакет корявый и заслоняет собой второй корректный. Вот так брать и откидывать неполный пакет и считать что начинаем принимать данные с нуля. Хотя, у меня есть счетчик 256 битных слов с шины, и он устанавливает отладочный регистр при tlast, похоже ничего после него не приходит
  2. Есть, могу хоть ILA или по UART, но главное что смотреть. Проект работал на других процессорных модулях. Ответы не приходят. Я могу в прошивку добавить вывод в UART какого либо статуса, но какой статус поможет понять, почему нет ответа на чтение?
  3. В другом городе, захожу по удаленке и затем по ssh. Да, это Gen 2. У меня там UART, так и определил что повесилось, ни единого пакета в ответ. Но я перепроверю, пока кажется что ни одного в ответ
  4. Да, Вы правы, я добавлю всё это когда появится возможность завтра. Адреса выровнены, все инкременты кратны 256 байт (максимальный размер payload). Запрашиваю по 256 байт (64 DW): if(s_axis_rq_tready == 4'b1111) begin s_axis_rq_tdata <= {32'h0, {1'b0, 3'b0, 3'b0, 1'b0, 16'h0, 8'hCC}, {bdf, 1'b0, 4'b0000, 11'd64}, {32'h0, h2ddr_source_addr[31:2], 2'b0}}; s_axis_rq_tuser <= {32'b0, 4'b1010, 8'b0, 1'b0, 2'b0, 1'b0, 1'b0, 3'b0, 4'b0, 4'b1111}; s_axis_rq_tkeep <= 8'h0F; s_axis_rq_tvalid <= 1; s_axis_rq_tlast <= 1; m_axis_rc_tready <= 1; end На других компьютерах работает, даже если тут размер страницы был бы не 4096, это надо бы уточнить, вдруг 8192 или 16384. Вся суть заминки в том, что на другом похожем модуле всё работало с этой же прошивкой. Пока теряюсь в догадках, какие идеи могут быть чтобы проверить s_axis_rq_tdata <= {32'h0, {1'b0, 3'b0, 3'b0, 1'b0, 16'h0, 8'hCC}, {bdf, 1'b0, 4'b0000, 11'd64}, {32'h0, h2ddr_source_addr[31:2], 2'b0}}; Тут, справа на лево 2 бита нулевые (выровнено по 4 байтам), h2ddr_source_addr это адрес буфера выделенного в драйвере, он передается через MMIO (эта часть работает железно). Затем идет 32 бита нулей, так как у меня dma_mask 32 бит, дефолтные. Далее указано что хочу 64 DW. Четыре нуля это Memory Read Request согласно таблице в документации. Далее poison bit должен быть нулем. Затем следует BDF и он 16 битный регистр, его я в драйвере пишу и читаю (readback). Далее идет tag, у меня настройка .AXISTEN_IF_ENABLE_CLIENT_TAG("FALSE"), значит это поле игнорируется hard ip блоком, в общем, не участвует и не влияет. Есть тут подозрения... Это поле 8'hCC Далее 16 бит Completer ID, то есть PCI root port, это bus device function 0, всё нули. Верно ли это? Но для чтений MMIO я задаю это 16 нулями и всё работает. Далее Requester ID Enable Endpoint mode: Must be set to 1’b0 - верно. Transaction Class (TC) ставлю нулями, но как я понял из документации, мне эти 3 бита вернется в пакете CplD Затем три бита - атрибуты. Если опция не включена - ядро забивает это нулями. Ни в конфиге ядра, ни в текстовом списке настроек не вижу чтобы это было включено или выключено. Может влиять? Force ECRC оставил нулем, с этим работает Вроде нигде ошибки нет. И память точно выделяется, ее я вижу в драйвере, ее адрес. Его же пишу как обычно в MMIO для инициации чтения со стороны ПЛИС, как и на рабочих системах. Всё же в системе другие PCI-E устройства, и очевидно в их наборе команд точно есть MRd, без него не обойтись Добавлено: у меня DWORD aligned режим, и 4 DW заголовок. Но в s_axis_rq_tuser задано что first byte enable это 1111, будто передается еще один DW. А может это ошибка для MRd так задавать??? Может у него не должно быть такого слова, и другие компьютеры это принимали, а этот не хочет?
  5. Продолжаются приключения с Ultrascale и PCI-E портом. Плата пробовалась на бытовом компьютере через CPCI-Serial самодельный переходник - отлично, пробовалась в корзине с i7 процессорным модулем - отлично. Но вот, этот i7 модуль умер. И срочно нашли замену, Fastwel CPC-512. И с ним проблемы На этом CPC-512 чтение запись MMIO работает отлично, MSI прерывания ходят. Но по зависанию прошивки ПЛИС, я обнаружил, что зависание прям с первой же попытки, не случайное не периодическое, а просто с ходу, когда я пытаюсь делать MRd запросы по шине s_axis_rq и получать ответы по шине m_axis_rc, тут "s" это имеется ввиду что это у PCI-E ядра это slave, и "m" наоборот, просто не стал инвертировать эти буквы RQ - запрос, RC - тут ответ. На предыдущих системах, которые я описал всё работало, даже на Байкал-Т1 работало ровно это самое. Но вот пришла система на замену, и другой нет, и она не хочет давать ответы! Работало с адресами, выделенными через dma_alloc_coherent, но пробовал также и через dma_map_single - результат всё тот же, оно просто не хочет давать результаты чтения! Как понять, что запрос ушел без ошибки? Ориентируюсь на s_axis_rq_tready. Пробовал выделять не сколько надо, а больше, например по размеру страницы памяти Подозрения: 1) Ориентируюсь на if(s_axis_rq_tready == 4'b1111) begin, а вдруг оно просто один бит ready? 2) Оно дает мне ready, но вдруг оно как то сигнализирует что надо повторить? Я снимаю valid бит на отправку лишь когда есть второй s_axis_rq_tready == 4'b1111 3) А может настройка компьютера какая то неверная? Что предположительно может быть 4) Я проверял, что у меня dma_mask 32 битное, все адреса 32 битные должны быть в запросах MWr и MRd 5) У меня фиксированные tag биты и прочие биты не меняю в запросе, но для одного запроса это не должно быть проблемой. Увы, на первом же и повиснет, то есть повиснет в месте где жду ответ CplD Добавлено: Драйвер для Linux. Может какие то флаги в kmalloc добавить дополнительные? GFP_DMA есть. Может работать через softmmu - не пробовал еще, или это не относится к реальному железу. Может какие диапазоны указать пошире. Явно какая то настройка кроется в ОС, и в БИОС всё облазил
  6. Суть проблемы в том, что так перестает что то работать? А если подать CI_P/CI_N сразу на IDDR_2CLK, и вообще сразу этот буфер объявить как IDDR_2CLK, что будет?
  7. Прошу уточнить, что подразумевается под "Конфликт связан с тем, что там одно имя на 2 устройства в драйвере". Если можно, кусочек кода драйвера. А что значит ошибка -38, ее удалось посмотреть как расшифровывается?
  8. Я так понимаю, устройство используется в качестве root, и подключается внешний накопитель. Есть ли уверенность, что сам порт работает. Есть ли возможность вывести статусы типа LTSSM ядра PCI-E? Или например, загрузиться с другого носителя, но к этому root порту подключить иное устройство, или то же что сейчас, и вывести sudo lspci -vvv ?
  9. Могу я не вызывать unmap тогда каждый раз? Сделал sync, забрал что хотел, далее устройство может в него снова писать?
  10. Хотел бы дополнить мой ответ. Наткнулся на статью 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. Значит не причина проблем
  11. Проверил решение. Оно условно работает. Как бы да, Verilog файлы реально все воспринимают этот define и файлы из подпроектов, всё вроде хорошо. Только вот Vivado выкидывает файлы через своё AutoDisabled в файле xpr вижу. Надо искать способ, чтобы отключить это AutoDisabled, оно же не понимает что файлы всё же будут задействованы, модули будут использоваться, и потом выкидывает их, хотя компилятор воспринимает это verilog_define
  12. Понятно, большое спасибо за ответы. Ясно, значит в more options прописать -verilog_define. Похоже это абсолютно именно то что надо. Мне не хватало этой подсказки с именем опции
  13. Использую Vivado. У меня два XPR файла, один и тот же проект нацеливается на разные ПЛИС и разную распиновку на плате. И только буквально один `ifdef в коде отличают версии реализации во множестве мест. Поэтому очень хочется вот что - есть ли возможность в самом XPR-файле проекта объявить глобальный define для Verilog? Или как то задать опцию, которая попадет при компиляции до каждого Verilog-файла, чтобы сработал ifdef. Если возможно, то где как это задать?
  14. DMA свой, но его можно улучшить существенно. А еще лучше использовать ядро Linux с DMA CMA механизмом с огромными страницами, этак на мегабайт. На самодельной плате и на отладочной покупной - разницы нет
  15. Посоветуйте, пожалуйста, модель Это чистая правда. Хотелось сделать тесты на более узкой полосе, 5-10 МГц там вполне работает, хочется выйти на более высокую мощность
  16. Добрый день! Требуется разработать приемник-передатчик с усилителем на частоту 9-10 ГГц. Полоса 100 МГц, мощность передатчика 10 Вт. На входах и выходах будет АЦП и ЦАП (LVDS или подобное). Требуемая чувствительность приемника пока на стадии определения В теории, как запасной вариант, есть возможность убрать часть сложности и оставить ее на таких устройствах типа HackRf One и остаться на частотах 5900-6000 МГц Подскажите пожалуйста, какие могут быть сроки и самое главное стоимость такой работы, для обоих вариантов?
  17. Если честно, очень низкую, раза в 3-4 меньше ожидаемой пиковой. У меня x8 линии, 8 * 8 = 64, минус оверхед, и все равно получил 15 гигабит всего, а это раза в 3 меньше чем уровень для достижения счастья
  18. Подскажите пожалуйста, сейчас вожусь с GD32F103 и имею лютые проблемы с USB конкретно - внезапные ребуты МК. Так получается, есть некий HAL от GD? Хорошо что выяснилось, для меня...
  19. Да, получилось! Всё заработало как надо, как на других системах. Премного благодарю и спасибирую!!! И да, уточню что действительно MSI Message Data подставил вот как есть, не меняя никакие биты и не сбрасывая их в ноль
  20. pci_bus_read_config_dword(device->pci->bus, 0, 148, &device->msi_address); UPDATE: исправил вместо нуля надо device->pci->devfn Тут же возьму message data. Могу ли я полагаться на эту константу в смещении - наверное нет, наверное там могут быть еще какие то поля, а может и не могут, ввиду того что как разработчик, не добавлю туда других опций, то и доп структуры там не следует ожидать Выше я исправил пост, Вы оказались правы, на целевой системе message data не нули, а на "бытовых" компьютерах через переходник работало потому что везде там message data равны нулям для абслютно всех устройств. Наверное это и есть решене проблемы, уже исправляю
  21. Если по картинке, то передаю MSI Vector 0 (все 6 бит нули). А вот Message Data - эти 10 бит надо откуда то брать? Задать какое-то значение или же вычитать его откуда то в системе? Пока что у меня там нули, буду читать что там требуется передать, и вот на трех системах нули в этом поле устраивали Сам факт прихода сообщений не проверял, но могу сделать, просто выделив небольшое dma и подпихнуть его адрес там где передаю msi_address, так я и отлаживал первоначально UPDATE: dxp, Вы правы, у меня в компьютере Data: 0000 везде для всех устройств. А на целевой системе там везде не нулевые Data относительно MSI! Получается, что я должен передавать message data в пакете MSI! Но должен ли я затирать 6 бит нулями? Сделаю так, чтобы в драйвере можно было писать это, легко попробовать оба варианта: и затирая 6 бит нулями и НЕ затирая, попробую отпишусь!
  22. Проблема такая. Есть устройство на 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 годы). То есть, какие то биосы и чипсеты прощают эту некую ошибку (или недосказанность в полях). А вот эта система не прощает некое расхождение со стандартом
  23. Прошу прощения за небольшой оффтопичек, хотя всё же вопрос очень близок к теме. На платформе Linux есть dma_alloc_coherent и оно дает буфер смежный. Его можно один раз выделить и пользоваться им "вечно". Но я и сам это видел, что нельзя выделить буфер большой, иногда проблемы, предположительно из за фрагментации, не позволяли даже взять буфер 128 килобайт. С тех пор я решал эту проблему выделением N страниц памяти и постоянным обменом этими адресами с устройством, хотя coherent dma очень удобно И тут я узнал про CMA, ни один линуксоид не упоминал про эту штуку на тематических форумах, и оно позволяет выделить слитный кусок coherent dma памяти да хоть 32 гигабайта! Система резевирует отдельную область при старте. Есть ли какие то проблемы с этим механизмом? Накладные расходы, сложности? Падение производительности? Тут подробнее https://stackoverflow.com/questions/56508117/how-to-allocate-large-contiguous-memory-regions-in-linux dma_alloc_coherent(&pdev->dev, dbsize, paddr, GFP_KERNEL); // dbsize may specify up to 32G. Подумать только 32 гигабайта, а мне и 16 мегабайт будет большой помощью
  24. Не подскажете, а без этого CMA какой максимальный объем можно выделять через dma_alloc_coherent? И всегда ли на всех системах можно рассчитывать на 512 килобайт даже? Читал где то, что всё бьется на страницы памяти 4 килобайта например, и по мере работы фрагментация снижает шансы на выделение этих несчастных даже 128 килобайт, опасно И не налагает ли в dma_alloc_coherent вот это coherent дополнительных накладных расходов и оверхедов? Поэтому я всегда работал через выделение N буферов по например 4 килобайт (или получал размер страницы памяти настроенной в ядре). Так меня учили гуру, опытные линуксоиды "А что, так можно было?" (с) Просто врубить CMA на сотню мегабайт и наслаждаться однократно выделенным буфером? Какие недостатки?
×
×
  • Create New...