Jump to content

    

Recommended Posts

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

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.

Share this post


Link to post
Share on other sites
19 minutes ago, RobFPGA said:

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

Удачи! Rob.

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

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

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

 

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

 

Share this post


Link to post
Share on other sites
4 hours ago, Lixlex said:

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

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

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

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

Share this post


Link to post
Share on other sites

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

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.

 

Share this post


Link to post
Share on other sites

Приветствую всех, хорошо тема 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 - не заострял на этом моменте внимание. Возможно как раз такого сигнала и не хватает для указания, что пришла посылка? Как его формировать в коде, что за ножка? Возможно ли, что в новой материнке это требуется?

 

Share this post


Link to post
Share on other sites
1 hour ago, exigo said:

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

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

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

Share this post


Link to post
Share on other sites
15 hours ago, exigo said:

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

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

Quote

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

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

Share this post


Link to post
Share on other sites

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

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

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

									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;

 

Share this post


Link to post
Share on other sites
12 hours ago, exigo said:

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

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

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

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

 

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

Share this post


Link to post
Share on other sites

Код сверху как раз по полям 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)
Edited by exigo

Share this post


Link to post
Share on other sites
6 hours ago, exigo said:

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

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

 

Share this post


Link to post
Share on other sites
On 3/12/2019 at 1:04 PM, xvr said:

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

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
8 hours ago, exigo said:

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

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

Share this post


Link to post
Share on other sites

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

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.

Sign in to follow this