pltnmvenus
pltnmvenus

Reputation: 11

Passing data to/from a PCIe device

We have a prototype PCIe endpoint that we control via out-of-band, external connections (ie a USB cable to the board itself, letting us load the FPGA, perform register access, load and debug firmware, etc). We are looking into transitioning to performing at least some of these actions in-band, over the PCIe connection itself.

However, my knowledge in this area (PCIe) is rather limited. So before diving headlong down one path or another, I want to make sure we're not taking a deliberately difficult route or missing something obvious.

In the most basic sense, it should be sufficient to be able to pass 32-bit values back and forth at will with the endpoint's firmware. In other words, if we wanted to execute a "read", we could send an "address" value down to the device, and retrieve a "data" value. No DMA, no fancy stuff - just peek and poke transactions to the firmware. That's it.

I haven't found any generic method to accomplish this for PCIe - by contrast, if I wanted to (say) do something similar to a SCSI device, I could do things in the form of a CDB. The only vaguely similar method I can find would be to access the PCIe endpoint's configuration space; write a "value" to a certain known location, and poll for completion/data. But that capability seems to be restricted to drivers. This significantly complicating things, especially with the more restrictive hoops required in 64-bit versions (to say nothing of the inherent complexity that writing your very first driver entails).

So, two real questions.

  1. What is the simplest way (from an implementation point of view) to go about doing basic peek-poke transactions over a PCIe connection? Speed and efficiency are lesser concerns than ease of implementation and reliability - this is primarily a development environment. (It does, however, have to be code-based - I can't just use WinDbg to dump stuff.)
  2. If a driver is required to accomplish #1, is it possible to accomplish via a filter driver, rather than creating a full-blown driver? Things like power management and such are going to be handled by other people, or perhaps even by the default drivers; implementing the entire feature set of the device's functionality is way outside the scope of what I need to do. In this case, I just want a foot in the proverbial door to send data down to a target device.

This is intended for a Windows-based environment. It's probably safe to restrict to Vista/7 and higher (most of the test machines are W7 anyway), though if possible it should be doable on both 32-bit and 64-bit. Linux compatibility is a non-issue.

Thank you in advance.

Upvotes: 1

Views: 3523

Answers (1)

Baruch Even
Baruch Even

Reputation: 2636

You can use uio_pci_generic driver in the kernel to expose the device to user-space and then you can use the device directly from user-space. It requires minimal configuration in the kernel to make the device attach to the uio_pci_generic driver and then not too hard interface to map the PCIe BAR to the user-space memory and from there on it will be a simple memory read/write.

I am using NVMe and network devices through SPDK and DPDK and you can find in these examples for how to utilize uio_pci_generic. There may also be other examples for simpler devices that you can find.

Upvotes: 1

Related Questions