From: Antonio Di Bacco <a.dibacco.ks@gmail.com>
To: users@dpdk.org
Subject: PMD for FPGA based network device
Date: Mon, 15 Aug 2022 17:32:21 +0200 [thread overview]
Message-ID: <CAO8pfF=W2aGLSyYP7BmP1fRHkUFX=o0B2EAeVUwOGjEEh_muSw@mail.gmail.com> (raw)
I need to write a PMD for an FPGA based network device based on Xilinx
FPGA (Ultrascale).
Just to start I tried to load a dummy bitstream that has a status
register with a fixed value and a bunch of writable registers.
Then, I bound the vfio-pci to the device (10ee:903f) because I plan
to be able to use "user space DMA" in my PMD.
I was able to mmap the fpga registers and read the status register. I
can write and read back the writable registers but, when I stop my
process and relaunch it, I find that the registers are all cleared
(really bad).
I tried to mmap the fpga using resource0 under sysfs and I'm able to
write and read back the registers correctly and the registers are
persistent (good).
Then it is not a problem related to the bitstream but something wrong
I make on the VFIO mmap or the device is reset when I start my C code
to do the mmap.
I also tried disabling IOMMU when loading the VFIO-PCI driver with no luck.
I don't know if this is the right place to ask this question but I
know there are many knowledgeable people reading this forum and I
cannot find many examples of using VFIO.
This is the script I use to bind vfio:
VID="10ee"
DID="903f"
DBDF="0000:"`lspci -n | grep -E ${VID}:${DID} | cut -d ' ' -f1`
echo ${DBDF}
ROOT_DBDF="0000:3a:00.0"
readlink /sys/bus/pci/devices/${DBDF}/iommu_group
GROUP=`readlink /sys/bus/pci/devices/${DBDF}/iommu_group | rev | cut
-d '/' -f1 | rev`
echo "GROUP " ${GROUP}
# unbind the ROOT device makes the group viable
echo ${ROOT_DBDF} > /sys/bus/pci/devices/${ROOT_DBDF}/driver/unbind; sleep 1
echo ${DBDF} > /sys/bus/pci/devices/${DBDF}/driver/unbind; sleep 1
echo ${VID} ${DID} > /sys/bus/pci/drivers/vfio-pci/remove_id; sleep 1
echo ${VID} ${DID} > /sys/bus/pci/drivers/vfio-pci/new_id; sleep 1
echo 8086 2030 > /sys/bus/pci/drivers/vfio-pci/new_id; sleep 1
ls -l /sys/bus/pci/devices/${DBDF}/iommu_group/devices; sleep 1
chmod 660 /dev/vfio/vfio
WHILE this is the C code I use to do the mmap:
#include <stdio.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <linux/vfio.h>
int main(int argc, char** argv)
{
int container, group, device, i;
struct vfio_group_status group_status =
{ .argsz = sizeof(group_status) };
struct vfio_iommu_type1_info iommu_info = { .argsz =
sizeof(iommu_info) };
struct vfio_iommu_type1_dma_map dma_map = { .argsz = sizeof(dma_map) };
struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
/* Create a new container */
container = open("/dev/vfio/vfio", O_RDWR);
if (ioctl(container, VFIO_GET_API_VERSION) != VFIO_API_VERSION)
printf("Unknown API version\n");
/* Unknown API version */
if (!ioctl(container, VFIO_CHECK_EXTENSION, VFIO_TYPE1_IOMMU))
printf("Doesn't support IOMMU driver we want\n");
/* Open the group */
group = open("/dev/vfio/69", O_RDWR);
/* Test the group is viable and available */
ioctl(group, VFIO_GROUP_GET_STATUS, &group_status);
if (!(group_status.flags & VFIO_GROUP_FLAGS_VIABLE))
printf("Group is not viable\n");
/* Group is not viable (ie, not all devices bound for vfio) */
/* Add the group to the container */
ioctl(group, VFIO_GROUP_SET_CONTAINER, &container);
/* Enable the IOMMU model we want */
ioctl(container, VFIO_SET_IOMMU, VFIO_TYPE1_IOMMU);
/* Get addition IOMMU info */
ioctl(container, VFIO_IOMMU_GET_INFO, &iommu_info);
/* Allocate some space and setup a DMA mapping */
/*
dma_map.vaddr = mmap(0, 1024 * 1024, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
dma_map.size = 1024 * 1024;
dma_map.iova = 0;
dma_map.flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE;
ioctl(container, VFIO_IOMMU_MAP_DMA, &dma_map);
*/
/* Get a file descriptor for the device */
device = ioctl(group, VFIO_GROUP_GET_DEVICE_FD, "0000:3b:00.0");
/* Test and setup the device */
ioctl(device, VFIO_DEVICE_GET_INFO, &device_info);
printf("NUM REGIONS %d\n", device_info.num_regions);
struct vfio_region_info regs[64];
for (i = 0; i < device_info.num_regions; i++) {
regs[i].argsz = sizeof(struct vfio_region_info);
regs[i].index = i;
ioctl(device, VFIO_DEVICE_GET_REGION_INFO, ®s[i]);
printf("region %d flags %08x offset %lld size %lld\n",
i, regs[i].flags, regs[i].offset, regs[i].size);
/* Setup mappings... read/write offsets, mmaps
* For PCI devices, config space is a region */
}
volatile uint8_t* ptr = mmap(0, regs[0].size, PROT_READ |
PROT_WRITE, MAP_SHARED, device, 0);
printf("addr %p\n", ptr);
printf("reg 0x38000 %08x\n", *(uint32_t*)(ptr + 0x38000));
{
uint32_t ival = *(volatile uint32_t*) (ptr + 0x38008);
*(volatile uint32_t*) (ptr + 0x38008) = ival + 0x1000;
printf("%08x\n", *(volatile uint32_t*) (ptr + 0x38008));
}
printf("reg 0x38008 %08x\n", *(volatile uint32_t*)(ptr + 0x38008));
}
reply other threads:[~2022-08-15 15:32 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CAO8pfF=W2aGLSyYP7BmP1fRHkUFX=o0B2EAeVUwOGjEEh_muSw@mail.gmail.com' \
--to=a.dibacco.ks@gmail.com \
--cc=users@dpdk.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).