Virtual PCIe driver

Hi All, I am wondering, Is there a way to emulate a PCIe device in windows. The way we use to do using virtual Storport miniport driver for exposing a disk. Similarly is it possible to write a virtual PCIe driver and expose my own virtual PCIe device. All I am able to find is writing sample PCIe driver for a physical device. https://github.com/microsoft/Windows-driver-samples/tree/master/general/pcidrv Is it even possible in Windows? Thanks in advance, Muthu

Not without unreasonable effort, no. It depends how complicated your device is. If you are religious about using the HAL macros to access your registers (like READ_REGISTER_ULONG), you can replace those macros with calls to an emulation library. It isn’t quite the same thing, but it can help you get the register sequencing right.

It may be possible to implement such a thing using a Hypervisor app, but in my opinion, that’s way more trouble than it’s worth.

1 Like

Hi Tim, Sorry for the late reply. I was going through all the below posts and got some fair understanding.

https://community.osr.com/discussion/140400/pci-device-simulation
https://community.osr.com/discussion/138685/how-to-do-software-simulation-of-pci-device
http://www.osronline.com/article.cfm^article=289.htm

But I don’t see any documentation in MSDN for writing a Virtual PCI driver .
and there are no samples available in Windows-driver-samples apart from below links but again these sample are NOT meant for virtual device.

Windows-driver-samples/tree/master/general/PLX9x5x
Windows-driver-samples/tree/master/general/pcidrv

I am doing some trial and error to figure out on writing a virtual PCI driver, But it feels like dead-end to me without finding a proper documentation.
Could you please provide some links/documents/some hint to kick start this activity. It will be very grateful.

Thanks and Regards,
Muthu

Well, you’re not finding any examples or documentation, because writing what is effectively an emulator for the PCI bus, without virtualizing the entire system, isn’t something that many people need/want to do. It’s a pretty complex undertaking… and couple be SUPER complex if you want to be thorough about what you’re emulating.

Reading your post again… I’m now not 100% sure what you’re asking. Do you want to create a virtual PCI bus instance, that will emulate a PCI bus and that can host a driver? Or do you just want to write a “software only driver that receives reads and writes and sort of looks like a PCI device”?

These are, of course, very different things.

Peter

Yes, I am looking for “a way to create a virtual PCI bus instance, that will emulate a PCI bus and that can host a driver”. Pretty much similar to this link http://htfsoftware.com/wp-content/uploads/2016/01/PciDevSim1.pdf

And have you contacted him to find out about licensing his code? It’d be a heck of a lot cheaper and quicker then reinventing all of that yourself.

No I have not contacted him, But this is more like our internal experiment(Not a commercial product), that is the reason I am trying to understand and explore by myself. If there is any document it would speed up the activity way faster.

I’m sure that it is. The short answer is that there just is no easy path. It’s a heck of a lot of work. The one time I did something like this, what I did was redefine the HAL macros (READ_REGISTER_ULONG, etc) to redirect to a library where I simulated the device responses. Even though that’s an intrusive solution, it allowed us to debug the driver logic before the hardware was ready, and in fact the driver worked the first time we ran it on real hardware. This was a graphics card driver (a long time ago), so we could actually create a bitmap to verify the results. You could even simulate interrupts that way, by passing the address of the interrupt handler to the library.

It’s quite difficult to do an emulation that doesn’t require source changes. You’d have to exploit the paging system, so that reads and writes to your register BARs trigger a page fault that you handle. Really, it’s not worth the trouble.

@OP what kind of device do you need and why it must be PCI?
A “root enumerated” device is a very easy, well known way to create a “real” PnP device object and install a custom driver.
However, it is limited - no h/w resources, interrupts, DMA and so on.
There are also other kinds of “software devices”, including remote.

What about this paper http://htfsoftware.com/wp-content/uploads/2016/01/PciDevSim1.pdf (PFD created in 2015) … his plans to extend the simlation to Linux and FPGAs are known and implemented long ago. We’ve worked with simulated PCI devices on Dini’s in the days of yore, and more recently on Cadence platforms. Of course, Windows does not rhyme with anything of that.

– pa

@Pavel_A could you please explain what is “root enumerated” device.

A root enumerated device is a device that is enumerated by the PnP manager, as a result of data in the registry (as opposed to a device that’s enumerated by a bus driver, as a result of the discovery of a hardware instance being present).

Software-only, or pseudo-device, drivers are root enumerated.

Peter

Is there a way to emulate a PCIe device in windows.

IIRC, we had briefly discussed this option few months ago (IIRC, it was a thread where Peter was asking us to advise him on a custom PCIe device for his class)…

This task is not infeasible, but it would require a MAJOR effort to do something like that. First of all, you will have to develop a kernel-mode framework that is capable of simulating (at least from the driver’s perspective) interrupts, DMA transfers and power-related evens, as well as some virtual IO space that your target driver may treat as its device BARs. Then you will have to develop some virtual bus driver that actually makes use of above mentioned framework, simulates and enumerates its child device(s), and present them to the system. Finally, if you really want your driver a virtual PCIe device to be source-compatible with the one for a real PCIe device, you have to provide a header that encapsulates all the API that your framework/virtual bus driver provide, and controls the compilation process with
#ifdef PCIe__SIMULATION’ definition. If you do it this way, the only thing that you will have to change in order to build a binary for the real device from the same sources is to comment ‘#define PCIe__SIMULATION__’ line.

As it usually happens in this NG, the key question here is “what are you trying to do”. It is understandable that the above mentioned framework may make sense only for someone who actually develops PCIe devices, so that they want to develop the actual device and its driver simultaneously, i.e. to have a more or less workable driver available at the time when the actual device is not yet fully prototyped on FPGA, let alone burnt on silicon. This approach allows you more flexibility in defining and changing device specifications. To make it even more interesting, it allows you to simulate the scenarios that are not that easily reproducible with the real hardware device
(like, for example, hardware errors, power failures, etc)

Anton Bassov

Thank you all for giving thoughtful insights .