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

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

1 hour ago, Lixlex said:

...

Правильно ли я понимаю, что на одиночный запрос Memory Read Request может прийти как целый одиночный пакет с данными, так и несколько "дробленных", причем в произвольном порядке?

Какая будет граница данных при дроблении?

Как правильно организовать сбор принятых данных?

Да так и есть - в запросе на чтение вы можете запросить до MRS (Max Read Size) данных (но не более 4К).  И ни кто не гарантирует что они придут одним куском. Граница дробления - слово 4 байта. Так что по любому надо городить буфер для "сборки" пакетов c данными чтения. В общем виде при отправке запроса запоминаете его параметры в CAM памти. По получению Completion TLP ищете в CAM по TAG и Completion ID  активный запрос и по смещению в Lower Address заполняете принятые байты.  И так пока не приняли все что запросили (Byte Count == длинна запроса).

Если не ошибаюсь (давно уже "столь низко падал" :scratch_one-s_head:) то последовательность данных в Completion  для одного запроса стого последовательна,  а вот порядок ответа на несколько последовательных запросов  может быть любой. 

Удачи! Rob.

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


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

19 minutes ago, RobFPGA said:

Если не ошибаюсь (давно уже "столь низко падал" :scratch_one-s_head:) то последовательность данных в Completion  для одного запроса стого последовательна,  а вот порядок ответа на несколько последовательных запросов  может быть любой. 

Удачи! Rob.

Благодарю за ответ! А не подскажите в каком документе можно уточнить этот момент? Если действительно данные с одинаковым тегом приходят в строго определенном порядке это немного упростит жизнь.

А не затруднит ли Вас подробнее рассказать про заполнение памяти?

Из ядра выходит 256-битная axi-stream, соответственно память должна быть аналогичной разрядности. Учитывая, что граница дробления меньше разрядности шины данных, данные подаваемые на вход памяти нужно как-то динамически сдвигать. И всё это дело должно происходить на 250 МГц. Как это сделать не могу представить.

 

Упростит ли мне задачу режим Address Aligned? Правильно ли я понимаю, что в этом режиме, если первый пакет имел валидные данные с 0 по 2й DWORD, то в следующем пакете валидные данные пойдут начиная с 3го DWORDа?

 

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


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

4 hours ago, Lixlex said:

Правильно ли я понимаю, что на одиночный запрос Memory Read Request может прийти как целый одиночный пакет с данными, так и несколько "дробленных", причем в произвольном порядке?

Какая будет граница данных при дроблении?

Как правильно организовать сбор принятых данных?

На счет дробления не скажу, но Вы попробуйте сначала поймать то что приходит, а раскладывать... не поверите, по... адресу! :) Там же адреса у пакетов есть. Берем начальный адрес + величину payload.

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


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

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

14 hours ago, Lixlex said:

А не подскажите в каком документе можно уточнить этот момент? Если действительно данные с одинаковым тегом приходят в строго определенном порядке это немного упростит жизнь.

Основной документ это PCI Express® Base Specification Revision 3.0. Ну и естественно datasheet и BFM той PCIe корки с которой будете работать. Ну и без рабочей BFM root-complex в симуляторе делать что-то для PCIe это кошмар. 

14 hours ago, Lixlex said:

Из ядра выходит 256-битная axi-stream, соответственно память должна быть аналогичной разрядности. Учитывая, что граница дробления меньше разрядности шины данных, данные подаваемые на вход памяти нужно как-то динамически сдвигать. И всё это дело должно происходить на 250 МГц. Как это сделать не могу представить.

Да сдвигать нужно будет (запоминая неполное слово до следующего completion). Но в тех чипах где можно сделать PCIe Gen3 x8  такой сдвиг на 250 MHz проблем не составляет (ясень пень с некоторым pipeline). Про Address Aligned сейчас не скажу (не помню точно) но вполне может помочь так как по описанию этот сдвиг уже сделан внутри корки. 

 

Успехов! Rob.

 

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


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

Приветствую всех, хорошо тема pcie как раз актуальна.

У меня ситуация следующая:

Камень kintex7. Писал проект в ISE на основе ядра 7 Series Integrated Block. Модернизировал EP_TX, добавил формирование tlp запросов по заданным адресам писал в память ПК. Все прекрасно работает. На ПК используется разъем pcie gen2.

Перешел на другой ПК с разъемом pcie gen3 (в биосе везде выставил ген2). И устройство видится, читаю/записываю в БАР, но ПК мои запросы игнорирует - в памяти пусто.

Установил последнюю вивадо, запустил dma stream example - работает, начал думать на изменения в ядре, организовал тот же проект на основе обновленного ядра  7 Series Integrated Block в вивадо, а нет, так же не работает, а на старом ПК все четко.

Проанализировал линии dma stream example "в процессе" - пакеты формируются такие же. Не пойму какие еще надстройки требуются? Перечитав тему смотрю затрагивается  MSI - не заострял на этом моменте внимание. Возможно как раз такого сигнала и не хватает для указания, что пришла посылка? Как его формировать в коде, что за ножка? Возможно ли, что в новой материнке это требуется?

 

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


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

1 hour ago, exigo said:

затрагивается  MSI

Это просто прерывание - сказать процессору, что что-то произошло, чтобы он отвлекся от других задач на обработку этого события.

То, что Вы пишете с помощью своих tlp в память - должно туда заходить и без прерываний.

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


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

15 hours ago, exigo said:

Перешел на другой ПК с разъемом pcie gen3 (в биосе везде выставил ген2). И устройство видится, читаю/записываю в БАР, но ПК мои запросы игнорирует - в памяти пусто

В "бар" ведь пишет ПК, так? И в том же предложении "ПК игнорирует запросы" - а они откуда?

Quote

добавил формирование tlp запросов по заданным адресам писал в память ПК

Кто же задает эти адреса? Захардкодили что ли? Не помню я проблем, когда пробовал на PCI-E 3 разъеме, никаких отличий быть не должно. Скорее отличие в том, что тепличные условия эксперимента сменились на другом ПК и всё сломалось, т.к. было неверно изначально.

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


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

запросы на чтение/запись в БАР обрабатываются, через них задаю адрес и управляющие значения.

но мои тлп записи в память уходят в ПК (кредиты тратяться, потом восстанавливаются), но в памяти пусто.

прилагаю запрос записи, заготовок, а потом идут данные.

									s_axis_tx_tdata <= (
														dma_addr(31 downto 0) &--lo addr
														dma_addr(63 downto 32)& --X"00000000" & --hi addr
														completer_id&--X"0000" & --X"0600" &
														tx_tag&--tx_tag & --"10000000"
														"1111" &
														"1111" &
														"01100000" & --0100
														'0' &
														"000" &
														"0000" &
														'0' &
														'0' &
														"10" &
														"00" &
														"0000100000" --0000100000												
														) after TCQ;
									s_axis_tx_tlast <= '0' after TCQ;
									s_axis_tx_tvalid <= '1' after TCQ;
									s_axis_tx_tkeep <= x"FFFF" after TCQ;
									tx_tag<=tx_tag+1;

 

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


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

12 hours ago, exigo said:

запросы на чтение/запись в БАР обрабатываются, через них задаю адрес и управляющие значения.

но мои тлп записи в память уходят в ПК (кредиты тратяться, потом восстанавливаются), но в памяти пусто.прилагаю запрос записи, заготовок, а потом идут данные.

Не все переваривают VHDL (в плане, могут легко его читать). Если можно, выложить TLP в простом виде: 0F 44 5C 31 ... и так далее.

Второе, с помощью каких функций и каких параметров были получены адреса, в которые ПЛИС пытается закармливать пакеты? Где уверенность, что хост готов их принимать по именно этим адресам? Вы самое интересное/важное от публики прячете :)

 

Вроде с Вами уже обсуждали, что в x86 чуть ли не три "вида адресов", они должны быть корректно отображены, и то что годится в пространстве ядра, не годится для адресов шины и требуется отображение. Вот это я и хочу видеть. Я конечно, судя по моему аватару, Linux-озабоченый, но код драйвера Windows понять смогу.

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


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

Код сверху как раз по полям TLP запроса раскидан последовательно, --  комментарии надо было затереть, чтобы не сбивали)

Драйвер писали другие люди, и раз на других материнках работает, не смотрел туда, но уже начал грешить туда.

Прилагаю функции выделения памяти и получения стартового адреса:

unsigned __int64 PPMapBuf(HANDLE PPDev)
{
	ULONGLONG nBuf2;
	ULONG nBuf;
	ULONG nOutput;

	LPFN_ISWOW64PROCESS fnIsWow64Process;
	BOOL bIsWow64 = FALSE;

	if (sizeof(PULONG)==8)
	{
		DeviceIoControl(PPDev, PP_IOCTL_MAPBUF, 
		NULL,0,
		&nBuf2,8,//sizeof(PULONG),
		&nOutput,NULL);
	}
	else // if (sizeof(PULONG)==4)
	{
		fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(
			GetModuleHandle(TEXT("kernel32")),"IsWow64Process");

		if (NULL != fnIsWow64Process)
		{
			fnIsWow64Process(GetCurrentProcess(),&bIsWow64);
			if (bIsWow64)
			{
				DeviceIoControl(PPDev, PP_IOCTL_MAPBUF, 
					NULL,0,
					&nBuf2,8,//sizeof(PULONG),
					&nOutput,NULL);
			}
			else
			{
				DeviceIoControl(PPDev, PP_IOCTL_MAPBUF, 
					NULL,0,
					&nBuf,4,//sizeof(PULONG),
					&nOutput,NULL);
				nBuf2 = 0 + nBuf;
			}
		}
		else
		{
			DeviceIoControl(PPDev, PP_IOCTL_MAPBUF, 
				NULL,0,
				&nBuf,4,//sizeof(PULONG),
				&nOutput,NULL);
			nBuf2 = 0 + nBuf;
		}
	}
	return nBuf2;
}

unsigned __int64 PPGetAdr(HANDLE PPDev)
{
	ULONGLONG nBuf2;
	ULONG nBuf;
	ULONG nOutput;

	LPFN_ISWOW64PROCESS fnIsWow64Process;
	BOOL bIsWow64 = FALSE;

	if (sizeof(PULONG)==8)
	{
		DeviceIoControl(PPDev, PP_IOCTL_GETADR, 
		NULL,0,
		&nBuf2,8,//sizeof(PULONG),
		&nOutput,NULL);
	}
	else // if (sizeof(PULONG)==4)
	{
		fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(
			GetModuleHandle(TEXT("kernel32")),"IsWow64Process");

		if (NULL != fnIsWow64Process)
		{
			fnIsWow64Process(GetCurrentProcess(),&bIsWow64);
			if (bIsWow64)
			{
				DeviceIoControl(PPDev, PP_IOCTL_GETADR, 
					NULL,0,
					&nBuf2,8,//sizeof(PULONG),
					&nOutput,NULL);
			}
			else
			{
				DeviceIoControl(PPDev, PP_IOCTL_GETADR, 
					NULL,0,
					&nBuf,4,//sizeof(PULONG),
					&nOutput,NULL);
				nBuf2 = 0 + nBuf;
			}
		}
		else
		{
			DeviceIoControl(PPDev, PP_IOCTL_GETADR, 
				NULL,0,
				&nBuf,4,//sizeof(PULONG),
				&nOutput,NULL);
			nBuf2 = 0 + nBuf;
		}
	}
	return nBuf2;

}
#define PP_IOCTL_GETADR		CTL_CODE(FILE_DEVICE_UNKNOWN, 0x806, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define PP_IOCTL_GETSIZE	CTL_CODE(FILE_DEVICE_UNKNOWN, 0x807, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define PP_IOCTL_MAPBUF		CTL_CODE(FILE_DEVICE_UNKNOWN, 0x808, METHOD_BUFFERED, FILE_ANY_ACCESS)
Изменено пользователем exigo

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


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

6 hours ago, exigo said:

Прилагаю функции выделения памяти и получения стартового адреса:

Это не она - это обращение к драйверу, который и выделяет память и пр. Код самого драйвера отсутствует (драйвер то хоть загружен?)

 

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


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

On 3/12/2019 at 1:04 PM, xvr said:

Это не она - это обращение к драйверу, который и выделяет память и пр. Код самого драйвера отсутствует (драйвер то хоть загружен?)

Так и есть - кода драйвера нет, это лишь тестовая программа. Автор темы, плохо читая то что его просят, лишь задерживает решение своей проблемы. У меня есть догадки почему у него не работает, но без кода драйвера я это понять не смогу.

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


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

Просто ПК прогой не я занимаюсь, и пока нет возможности уточнить :( .sys файл только и вот эти функции вызова. Но функции чтения/записи в бар работают, адреса тоже возвращает, этот же драйвер на других ПК с ген2 работает, есть вероятность, что драйвер неправильно работает на этой материнке?

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


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

8 hours ago, exigo said:

есть вероятность, что драйвер неправильно работает на этой материнке?

Есть. Надо смотреть именно код драйвера (того, что в sys лежит)

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


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

провели разные эксперименты с драйверами, и подключили другое устройство работающее на нашем драйвере. Все хорошо, но там не наше устройство, виртекс стоит и прошивка не известно как организована. Поэтому склоняемся в ошибке в прошивке ПЛИС. Как и говорили, видимо на ген2 тепличные условия и все работает, а на двух других материнках с ген3 нет. Врятли может быть проблема в формирование тлп запроса, может другие нюансы есть?

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


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

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

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

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

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

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

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

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

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

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