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

Xilinx UltraScale PCI-E, назначение двух интерфейсов

2 hours ago, dxp said:

Вам какой режим в итоге нужен? PIO или BMD?

И то и другое, значит, нужно работать через 2 порта (cq+cc и rq+rc). Понятно, сделаю тогда через два. Благодарю за прояснение этого момента, так как доступна пока лишь очень медленная ограниченная модель, платы живой пока нет, придется полагаться на фантазию.

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


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

Да, если оба, то все порты нужны. Если скорость выжимать не нужно, почему тогда не хотите использовать корку AXI Bridge? Вот там, как раз, унификации достичь куда проще. Да и вообще она скрывает много нюансов и сложностей - AXI транзакции мечете и всё.

 

Что касается модели, то она вполне рабочая, я на ней все режимы отладил на симе, нареканий нет. Для хоста, конечно, тоже пришлось BFM написать, которая имитирует поведение проца (пишет через PIO) и контроллера системной памяти (запись и чтение), ну, и "драйвер", который обеспечивает соответствующую функциональность - нужно было алгоритм обработки данных в PCIe ускорителе отладить. Пока на симе не заработало, в железо я даже не лез. В железе тоже были свои вопросы, которые на симуляции не поймались. 

 

Или вы не про модель PCIe, а про какую-то свою?

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


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

On 11/22/2021 at 6:55 PM, dxp said:

Что касается модели, то она вполне рабочая, я на ней все режимы отладил на симе, нареканий нет. Для хоста, конечно, тоже пришлось BFM написать, которая имитирует поведение проца (пишет через PIO) и контроллера системной памяти (запись и чтение), ну, и "драйвер", который обеспечивает соответствующую функциональность - нужно было алгоритм обработки данных в PCIe ускорителе отладить. Пока на симе не заработало, в железо я даже не лез. В железе тоже были свои вопросы, которые на симуляции не поймались

Мне удалось разобраться как делать MWr и MRd и на стороне endpoint, запросы видны из CQ/CC.

 

Пробовал работать через RQ/RC на стороне endpoint: в модели на стороне RootPort сообщение не видно. Сначала я брал пакеты как в примере, который успешно читается, но потом увидел что везде нужно именно 4 DW для заголовков. Выставил 4 DW, правильные значения tkeep и прочее, но пакет так и не отправляется. Что я имею ввиду - не появляется в CQ порту со стороны root port. Надо проверить, а уходит ли хоть что то в txp/txn, это и подскажет где застряло.

 

Может я пишу по неверному адресу? Тот адрес что справедлив для MRd в CC, то при MWr через RQ порт я должен всё таки брать иной адрес? Но вот какой? А может ядро должно сообщать ошибку хоть на стороне endpoint или root port? Беда в том что я не нашел пример работы с RQ в тексте тестов, которые поставляются с демо примером. Как же отладить запись в RQ на стороне endpoint, или увидеть суть причины почему от отбрасывает такие пакеты?

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


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

42 минуты назад, AVR сказал:

Мне удалось разобраться как делать MWr и MRd и на стороне endpoint, запросы видны из CQ/CC.

из CQ/CC видны на какой стороне? Хоста? Или эндпоинта?

 

42 минуты назад, AVR сказал:

Может я пишу по неверному адресу? Тот адрес что справедлив для MRd в CC, то при MWr через RQ порт я должен всё таки брать иной адрес? Но вот какой? А может ядро должно сообщать ошибку хоть на стороне endpoint или root port? Беда в том что я не нашел пример работы с RQ в тексте тестов, которые поставляются с демо примером. Как же отладить запись в RQ на стороне endpoint, или увидеть суть причины почему от отбрасывает такие пакеты?

Я запутался. Про какую сторону идёт речь? Про RC или Endpoint? Или про обе стороны?

 

Причин, почему запрос не проходит, может быть много. Смотрите тщательно и внимательно формат дескриптора и корректность всего пакета (длина, все сигналы). Вот пример из рабочего проекта:

 

BvtiBS3.png

 

Показан MWr. Слева выделены значения последних полей дескриптора. Вся транзакция розовой рамке. 4 младших слова - дескриптор: адрес и остальные поля. Далее идут данные (инкремент). С адресами никаких ограничений со стороны корки не помню. У меня на BFM хоста адреса вообще с нуля начинаются.

 

И всё же, если нет жёстких требований по скорости, почему не использовать AXI-PCIe Bridge? Там таких заморочек быть не должно.

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


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

On 11/29/2021 at 1:29 PM, dxp said:

Причин, почему запрос не проходит, может быть много. Смотрите тщательно и внимательно формат дескриптора и корректность всего пакета (длина, все сигналы). Вот пример из рабочего проекта:

Благодарю! Попробовал этот пакет с Вашим содержимым, правда исправил объем пакета на 1 DW, и у меня успешно передалось! Записал в RQ на стороне Endpoint и увидел эти данные на стороне CQ в RootPort. Действительно, если проследить куда идут линии rq/rc/cq/cc то можно заметить что они поступают напрямую в PCI-E hard IP block, значит причина была исключительно в моей какой то ошибке в полях пакета. Но мне сейчас было важно просто проверить сам факт прохождения пакета.


Далее буду проверять больше чем 1 DW, и обязательно MSI. Это позволит проверить кроссплатформенный wrapper для PCI-E Kintex 7/US.

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


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

Извините что еще терзаю вопросами, пытаюсь включить cfg_interrupt_msi_enable. Для этого я пытаюсь сначала включить bus_master, затем записать msi enable в регистре 0x90. Однако, ни bus master и msi_enable не включается, статусные линии висят в нулях. Хотя вот например при read-back в слове status, command= 0x00100406 бит 2 содержит 1, как я и записывал, однако линии всё же висят в нуле (шина cfg_function_status и как раз бит 2). Может для применения параметров нужно осуществить запись в еще какой-то регистр?

task enable_msi;
begin
	$display("enable msi...");

	TSK_TX_TYPE0_CONFIGURATION_WRITE(DEFAULT_TAG, 12'h04, 32'h0000_0406, 4'h3);
	DEFAULT_TAG = DEFAULT_TAG + 1;
	TSK_TX_CLK_EAT(1000);
	TSK_TX_TYPE0_CONFIGURATION_WRITE(DEFAULT_TAG, 12'h94, 32'h0123_0ABC, 4'hF);
	DEFAULT_TAG = DEFAULT_TAG + 1;
	TSK_TX_CLK_EAT(1000);
	TSK_TX_TYPE0_CONFIGURATION_WRITE(DEFAULT_TAG, 12'h98, 32'h0000_0000, 4'hF);
	DEFAULT_TAG = DEFAULT_TAG + 1;
	TSK_TX_CLK_EAT(1000);
	TSK_TX_TYPE0_CONFIGURATION_WRITE(DEFAULT_TAG, 12'h90, 32'h0000_0001, 4'hF);
	DEFAULT_TAG = DEFAULT_TAG + 1;
	TSK_TX_CLK_EAT(1000);

	TSK_TX_TYPE0_CONFIGURATION_READ(DEFAULT_TAG, 12'h90, 4'hF);
	DEFAULT_TAG = DEFAULT_TAG + 1;
	TSK_WAIT_FOR_READ_DATA;
	$display("MSI= 0x%08X", P_READ_DATA);
	TSK_TX_CLK_EAT(100);
	TSK_TX_TYPE0_CONFIGURATION_READ(DEFAULT_TAG, 12'h94, 4'hF);
	DEFAULT_TAG = DEFAULT_TAG + 1;
	TSK_WAIT_FOR_READ_DATA;
	$display("MSI ALOW= 0x%08X", P_READ_DATA);
	TSK_TX_CLK_EAT(100);
	TSK_TX_TYPE0_CONFIGURATION_READ(DEFAULT_TAG, 12'h98, 4'hF);
	DEFAULT_TAG = DEFAULT_TAG + 1;
	TSK_WAIT_FOR_READ_DATA;
	$display("MSI AHIGH= 0x%08X", P_READ_DATA);
	TSK_TX_CLK_EAT(100);

	$display("enable msi OK");

	TSK_TX_TYPE0_CONFIGURATION_READ(DEFAULT_TAG, 12'h00, 4'hF);
	DEFAULT_TAG = DEFAULT_TAG + 1;
	TSK_WAIT_FOR_READ_DATA;
	$display("device, vendor= 0x%08X", P_READ_DATA);
	TSK_TX_CLK_EAT(100);
	TSK_TX_TYPE0_CONFIGURATION_READ(DEFAULT_TAG, 12'h04, 4'hF);
	DEFAULT_TAG = DEFAULT_TAG + 1;
	TSK_WAIT_FOR_READ_DATA;
	$display("status, command= 0x%08X", P_READ_DATA);
	TSK_TX_CLK_EAT(100);
end
endtask

 

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


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

У нас MSI реализован собственными средствами, без участия возможностей IP ядра. MSI - это же по сути просто MWr по определённому адресу определённого значения. Адрес определяется на хосте при регистрации обработчика прерываний (подробнее не знаю, этим программист драйвера занимался), значение этого адреса драйвер через PIO записывает во внутренний мой специально отведённый для этого MMR. Ну, и прерывание генерируется просто записью значения (которое определяет номер вектора прерываний, если вектор один, то пишется 0) по указанному адресу. Подозреваю, что сам адрес этот фиктивный, и технически система прерываний содержит там цифровой компаратор, который сравнивает адреса поступающих MWr, если адрес совпал, то это MSI - далее на хосте генерируется прерывание.

 

Почему был выбран такой способ. Причины две:

  1. При наличие готового механизма генерирования MWr/MRd это оказалось проще, чем городить специальную логику работы с CFG регистрами PCIe (больше она ни для чего была бы не нужна).
  2. У нас логика работы такова, что прерывания нужно посылать строго in order с обработанными пакетами, чтобы не было возможности прерыванию опередить данные. Поэтому MSI генерируются в той же очереди, что и остальные транзакции. При доступе через CFG пространство PCIe возникает параллельный путь передачи и возможны "гонки".

Что касается BFM хоста, и там я просто реализовал вышеописанную логику - сравнение адреса транзакции с определённым адресом. Это реализуется очень просто в процессе обработки входящих TLP. Поэтому эту индусскую "кухню"  с TSK_* я не использовал и не лез в неё совсем, только смотрел кое-что: как реализовано то или иное (в основном состав и порядок действий интересовал), и почти ничего не реализовывал так, как у них, ибо тошнотворно. :)

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


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

11 hours ago, dxp said:

У нас MSI реализован собственными средствами, без участия возможностей IP ядра. MSI - это же по сути просто MWr по определённому адресу определённого значения

Понял, спасибо за ответ! Кстати, на Kintex 7 у меня так и сделано! Вместо MSI механизма, я просто шлю пакет MWr, который идет на адрес, ранее присланный в некоторый регистр. В драйвере Linux bus master и msi включаются без проблем, значит буду считать что это проблема модели и когда будет железо, я просто буду MWr слать как обычно.

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


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

Сегодня наконец получил первые успехи на железе с PCI-E на Ultra Scale, конечно оно работает - заголовки там аццкая жесть, но я применил некрасивый костыль на время - я задаю bus device function как константу, bus номер я подсмотрел в lspci. Ранее в ядре Kintex 7 у меня это всё было видно и так чуть ли не в одноименной линии

 

Где в Ultra Scale брать BDF? Конечно я могу это взять в драйвере через  pci_read_config_dword, прочитать из нее это BDF и заслать в устройство

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


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

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

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

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

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

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

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

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

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

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