dde29 0 20 сентября, 2022 Опубликовано 20 сентября, 2022 · Жалоба Всем привет! По роду своей деятельности появилась необходимость "поднимать" PCIe. Прочитано немноло даташитов и прочих талмудов. Собираюсь тут задавать вопросы по данной теме и внимательно слушать советы... Вводные данные: Плата на базе Xilinx Kintex UltraScale, PCIe Gen 3.0 x8, Vivado 2018.1 Первое, что я сделал сконфигурировал IP-блок UltraScale FPGA Gen3 Integrated Block for PCI Express. Сразу появилась нужна знать - как выглядит конфигурационное пространство, полученного IP-блока PCIe? (Данная информация нужна будет для тех, кто будет писать драйвер для ПК). Имеется ли возможность прочитать содержимое конфигурационного пространства (хотя бы ту часть, которую не трогает ОС) без непосредственного подлючения платы в слот ПК? Например, может в процессе генерации IP-блока создается некоторый файл или я могу это сделать через какой-либо интерфейс полученного IP-блока? Заранее, спасибо! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 35 20 сентября, 2022 Опубликовано 20 сентября, 2022 · Жалоба 17 minutes ago, dde29 said: Сразу появилась нужна знать - как выглядит конфигурационное пространство, полученного IP-блока PCIe? Как выглядит это пространство показано в UG на эту корку. А возможность читать это пространство есть как со стороны самого PCIe так и изнутри FPGA через cfg_* интерфейс насколько я это помню. Ну а без подключения к ПК проще всего начать работать с коркой это запустить симуляцию оной. Тогда будет доступно делать с коркой все тоже что и в ПК, но естественно это все будет медленно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
new123 0 20 сентября, 2022 Опубликовано 20 сентября, 2022 · Жалоба Чтобы в линуксе просто стартануть драйвер и подцепить железяку, для начала из конфига нужен просто VID и DID, они есть в самой корке. Чтобы просто стартануть PCIE чисто проверить, без драйвера командой lspci, конфиг на этом этапе пока не нужен Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RobFPGA 35 20 сентября, 2022 Опубликовано 20 сентября, 2022 · Жалоба 3 minutes ago, new123 said: Чтобы в линуксе просто стартануть драйвер и подцепить железяку Даже больше - Linux (как и обычно др. ОС) уже имеет в себе стандартный драйвер PCIe который собственно и работает со стандартным конфигурационным пространством каждого PCIe девайса в системе. И lspci как раз через этот драйвер работает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ovn 0 20 сентября, 2022 Опубликовано 20 сентября, 2022 (изменено) · Жалоба По работе поднимал PCIe на Xilinx Kintex 7 и UltraScale, IP блок DMA/Bridge Subsystem for PCI Express https://www.hackster.io/Roy_Messinger/pci-express-with-dma-sub-system-241d15, под Виндой использовал Xilinx Answer 65444 Xilinx PCI Express Windows DMA Drivers and Software Guide, ставил драйвер xdma, на основе исходников их утилиты писал свой драйвер, под Линухом то же самое. Изменено 20 сентября, 2022 пользователем ovn Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dde29 0 21 сентября, 2022 Опубликовано 21 сентября, 2022 · Жалоба On 9/20/2022 at 3:46 PM, RobFPGA said: Как выглядит это пространство показано в UG на эту корку. А возможность читать это пространство есть как со стороны самого PCIe так и изнутри FPGA через cfg_* интерфейс насколько я это помню. Ну а без подключения к ПК проще всего начать работать с коркой это запустить симуляцию оной. Тогда будет доступно делать с коркой все тоже что и в ПК, но естественно это все будет медленно. Да, как выглядит пространство известно. Т.е. имеется возможность прочитать содержимое конфигурационного пространства через (как я понял) интерфейс: cfg_mgmt_addr, cfg_mgmt_write, cfg_mgmt_write_data, cfg_mgmt_byte_enable, cfg_mgmt_read, cfg_mgmt_read_data, cfg_mgmt_read_write_done, cfg_mgmt_type1_cfg_reg_access Только вот, у меня мозг так устроен, что лучше всего обмен данными устроен через изучение временных диаграмм, коих по данной теме почти нет (ну или мне было не по глазам). Буду Разбираться, благодарю! Да, есть вариант запустить симуляцию, но тут меня кидает в холодный пот. Причина - я раньше работал только с продуктами Altera/Intel? поэтому переход на Вивадо происходит у меня болезненно. Но, хныкать не будем, тоже буду копать в этом направлении! On 9/20/2022 at 4:04 PM, new123 said: Чтобы в линуксе просто стартануть драйвер и подцепить железяку, для начала из конфига нужен просто VID и DID, они есть в самой корке. Чтобы просто стартануть PCIE чисто проверить, без драйвера командой lspci, конфиг на этом этапе пока не нужен VID и PID, согласен известны уже в самой корке, и также, да, в Линуксе добился того, что ОС подружилась с платой, а значит корка по минимальным настройкам сконфигурирована верно (через lspci распознается как надо). Для того, чтобы начать писать драйвер, согласен достаточно VID PID, но в дальнейшем нужно чтобы корка как-то отвечала на посылки с хоста на плату. Как я понимаю, для этого нужно изучить интерфейс AXI4-Stream (вроде простой). Только вопрос: Посылку от хоста я (мой user code на ПЛИС) могу получить на интерфейсе Completer Request, в ответ мне нужно будет сформировать пакет на интерфейсе Completer Completion. Подскажите, я правильно понимаю данный процесс "запрос/ответ" в контексте простого взаимодействия хост-девайс ? On 9/20/2022 at 4:12 PM, RobFPGA said: Даже больше - Linux (как и обычно др. ОС) уже имеет в себе стандартный драйвер PCIe который собственно и работает со стандартным конфигурационным пространством каждого PCIe девайса в системе. И lspci как раз через этот драйвер работает. А через этот стандартный драйвер каким образом можно реализовать простейший обмен данными между ОС и платой - через какие рычаги? В каком направлении мне тут покопать? On 9/20/2022 at 6:00 PM, ovn said: По работе поднимал PCIe на Xilinx Kintex 7 и UltraScale, IP блок DMA/Bridge Subsystem for PCI Express https://www.hackster.io/Roy_Messinger/pci-express-with-dma-sub-system-241d15, под Виндой использовал Xilinx Answer 65444 Xilinx PCI Express Windows DMA Drivers and Software Guide, ставил драйвер xdma, на основе исходников их утилиты писал свой драйвер, под Линухом то же самое. Спасибо! Поизучаю инфу по Вашим ссылкам! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dtmf73 5 21 сентября, 2022 Опубликовано 21 сентября, 2022 · Жалоба On 9/20/2022 at 2:00 PM, ovn said: По работе поднимал PCIe на Xilinx Kintex 7 и UltraScale, IP блок DMA/Bridge Subsystem for PCI Express https://www.hackster.io/Roy_Messinger/pci-express-with-dma-sub-system-241d15, под Виндой использовал Xilinx Answer 65444 Xilinx PCI Express Windows DMA Drivers and Software Guide, ставил драйвер xdma, на основе исходников их утилиты писал свой драйвер, под Линухом то же самое. Добрый день. Подскажите почему писали свой драйвер, а не использовали xdma? Как потом устанавливали драйвер без подписи? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dde29 0 21 сентября, 2022 Опубликовано 21 сентября, 2022 · Жалоба On 9/21/2022 at 12:20 PM, dtmf73 said: Добрый день. Подскажите почему писали свой драйвер, а не использовали xdma? Как потом устанавливали драйвер без подписи? Здравствуйте! Драйвер еще не написан, им только занялись, причем не лично я (я плисовод и цифровик-железячник), а другой отдел программистов. По поводу xdma - могу уточнить... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
new123 0 21 сентября, 2022 Опубликовано 21 сентября, 2022 (изменено) · Жалоба 7 hours ago, dde29 said: Для того, чтобы начать писать драйвер, согласен достаточно VID PID, но в дальнейшем нужно чтобы корка как-то отвечала на посылки с хоста на плату. Как я понимаю, для этого нужно изучить интерфейс AXI4-Stream (вроде простой). Только вопрос: надо определиться какой механизм задействовать. Или DMA или BAR. BAR для пробы в разы проще, но подходит для малых пересылок, примерно до 64байт, дальше выигрывает DMA. Из драйвера пишем в BAR (если доступ нужен из user space, то пишем в файл /bus/pci/../resourceX Потом это дело на нужном AXI читаем В обратную сторону так же. Изменено 21 сентября, 2022 пользователем new123 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dde29 0 22 сентября, 2022 Опубликовано 22 сентября, 2022 (изменено) · Жалоба On 9/21/2022 at 6:34 PM, new123 said: надо определиться какой механизм задействовать. Или DMA или BAR. BAR для пробы в разы проще, но подходит для малых пересылок, примерно до 64байт, дальше выигрывает DMA. Из драйвера пишем в BAR (если доступ нужен из user space, то пишем в файл /bus/pci/../resourceX Потом это дело на нужном AXI читаем В обратную сторону так же. Для первого этапа - достаточно BAR, так как необходимо просто обмен медленными посылками между ПЛИС на плате и ПК. Для второго этапа, скорее всего да - придется задействовать механизм DMA... Изменено 22 сентября, 2022 пользователем dde29 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ovn 0 22 сентября, 2022 Опубликовано 22 сентября, 2022 (изменено) · Жалоба В 21.09.2022 в 08:20, dtmf73 сказал: Добрый день. Подскажите почему писали свой драйвер, а не использовали xdma? Как потом устанавливали драйвер без подписи? В Винде устанавливал драйвер xdma от Xilinx, он без цифровой подписи, с драйвером работал из Microsoft Visual Studio, на основе исходников их утилиты писал свой "драйвер", на низшем уровне там, хоть в Линухе, хоть в Винде работа с устройством xdma, как с файлом(пишем в файл, читаем из файла), ну и соответственно уже на более верхнем уровне писал драйвер для своей конкретной железки, обращение к её регистрам и DDR и т.д. Изменено 22 сентября, 2022 пользователем ovn Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dde29 0 22 сентября, 2022 Опубликовано 22 сентября, 2022 · Жалоба Немного запутался в принципах интерфейса AXI4-Stream. Основными интерфейсам взаимодействия хоста и user logic через IP-блок являются: Completer Requester Interface (AXI4-Stream Master) Completer Completion Interface (AXI4-Stream Slave) Requester Requester Interface (AXI4-Stream Slave) Requester Completion Interface (AXI4-Stream Master) Насколько я понял, изучая документ PG156, взаимодействие между хостом и user logic происходит следующим образом: 1.1 Если хост инициирует передачу пакета - данные появятся на линиях интерфейса Completer Requester 1.2 В ответ на принятый пакет user logic отдает ответный пакет (а может и не отдавать) на линии интерфейса Completer Completion Interface 2.1 Если же user logic инициирует передачу пакета на хост, то это необходимо сделать через линии интерфейса Requester Requester Interface 2.2 В ответ хост может ответить посылкой на линии Requester Completion Interface Правильно ли я понял процесс обмена данными? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexadmin 0 22 сентября, 2022 Опубликовано 22 сентября, 2022 · Жалоба Если не хочется ломать голову - возьмите ядро AXI Bridge for PCI Express. В нем можно просто писать по адресам, а не вручную формировать очереди запросов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alxkon 0 22 сентября, 2022 Опубликовано 22 сентября, 2022 (изменено) · Жалоба Подскажите пожалуйста по следующей проблеме: Использую XDMA на Kintex девките. Девкит в свою очередь подключен к Jetson TX2 девкиту. Создал простой AXI4 Lite Slave на 4 регистра. Slave прошел через SV AXI4 BFM тест, использвал готовый который генерит Vivado. Подключен он к 32бит BAR 0, выделен 1МБ. Работаю с Ubuntu, использовал софт по моему автора туториала по XDMA . Получается запись и чтение регистров ведется из user space, а не из ядра линукса. Могут ли быть какие то проблемы с этим? Получается только 1 раз записать и считать определенное значение, далее чтение показывает 0. sudo ./pcie_test /sys/bus/pci/devices/0000\:01\:00.0/resource0 0x00000000 w 0xDEADAB Пока разбираюсь с System ILA, посмотреть что реально просходит на шине. Железо на несколько дней недоступно, хотелось бы понять есть ли риск в том что чтение/запись в регистры из user space на самом деле не работает всегда корректно? #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <unistd.h> #include <string.h> #include <errno.h> #include <signal.h> #include <fcntl.h> #include <ctype.h> #include <termios.h> #include <sys/types.h> #include <sys/mman.h> #include <linux/pci.h> #define PRINT_ERROR \ do { \ fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n", \ __LINE__, __FILE__, errno, strerror(errno)); exit(1); \ } while(0) #define MAP_SIZE 4096UL #define MAP_MASK (MAP_SIZE - 1) int main(int argc, char **argv) { int fd; void *map_base, *virt_addr; uint32_t read_result, writeval; char *filename; off_t target; int access_type = 'w'; if(argc < 3) { // pcimem /sys/bus/pci/devices/0001\:00\:07.0/resource0 0x100 w 0x00 // argv[0] [1] [2] [3] [4] fprintf(stderr, "\nUsage:\t%s { sys file } { offset } [ type [ data ] ]\n" "\tsys file: sysfs file for the pci resource to act on\n" "\toffset : offset into pci memory region to act upon\n" "\ttype : access operation type : [b]yte, [h]alfword, [w]ord\n" "\tdata : data to be written\n\n", argv[0]); exit(1); } filename = argv[1]; target = strtoul(argv[2], 0, 0); if(argc > 3) access_type = tolower(argv[3][0]); if((fd = open(filename, O_RDWR | O_SYNC)) == -1){ PRINT_ERROR; } printf("%s opened.\n", filename); printf("Target offset is 0x%x, page size is %ld map mask is 0x%lX\n", (int) target, sysconf(_SC_PAGE_SIZE), MAP_MASK); fflush(stdout); /* Map one page */ #if 0 //map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, (off_t) (target & ~MAP_MASK)); //map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, target & ~MAP_MASK); #endif printf("mmap(%d, %ld, 0x%x, 0x%x, %d, 0x%x)\n", 0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, (int) (target & ~MAP_MASK)); map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, (target & ~MAP_MASK)); if(map_base == (void *) -1){ printf("PCI Memory mapped ERROR.\n"); PRINT_ERROR; close(fd); return 1; } printf("mmap(%d, %ld, 0x%x, 0x%x, %d, 0x%x)\n", 0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, (int) (target & ~MAP_MASK)); printf("PCI Memory mapped %ld byte region to map_base 0x%08lx.\n", MAP_SIZE, (unsigned long) map_base); fflush(stdout); virt_addr = map_base + (target & MAP_MASK); printf("PCI Memory mapped access 0x %08X.\n", (uint32_t ) virt_addr); switch(access_type) { case 'b': read_result = *((uint8_t *) virt_addr); break; case 'h': read_result = *((uint16_t *) virt_addr); break; case 'w': read_result = *((uint32_t *) virt_addr); printf("READ Value at offset 0x%X (%p): 0x%X\n", (int) target, virt_addr, read_result); break; default: fprintf(stderr, "Illegal data type '%c'.\n", access_type); exit(2); } fflush(stdout); if(argc > 4) { writeval = strtoul(argv[4], 0, 0); switch(access_type) { case 'b': *((uint8_t *) virt_addr) = writeval; read_result = *((uint8_t *) virt_addr); break; case 'h': *((uint16_t *) virt_addr) = writeval; read_result = *((uint16_t *) virt_addr); break; case 'w': *((uint32_t *) virt_addr) = writeval; read_result = *((uint32_t *) virt_addr); break; } printf("Written 0x%X; readback 0x%X\n", writeval, read_result); fflush(stdout); } if(munmap(map_base, MAP_SIZE) == -1) { PRINT_ERROR;} close(fd); return 0; } Изменено 22 сентября, 2022 пользователем alxkon Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dde29 0 23 сентября, 2022 Опубликовано 23 сентября, 2022 · Жалоба Еще один момент, который я обнаружил, непонятный мне: сконфигурировав IP-блок UltraScale FPGA Gen3 Integrated Block for PCI Express, я должен был получить user_clock частотой 250 МГц, согласно настройкам корки... Вывед данный клок наружу ПЛИС - осциллом наблюдаю 25 Мгц (да, я не гоню, ноликом не ошибься ). Как можно это объяснить? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться