enjoy-digital / litepcie

Small footprint and configurable PCIe core
Other
478 stars 117 forks source link

Create /dev/ttyX device on Host to access crossover UART when kernel driver is loaded #35

Open enjoy-digital opened 4 years ago

enjoy-digital commented 4 years ago

When the SoC is configured with a crossover UART, it could be useful to create a /dev/ttyX device on the Host to access the UART of the SoC directly.

ozbenh commented 4 years ago

Not terribly hard. I assume the UART has the same interface as the LiteX UART ? So we'd need to instanciate the same driver more/less.

The main issue is going to be discovery. Do you have a PCI vendor ID ? We'll need some way for the PCIe device to describe itself which ties into a whole pile of conversations already floating around. One way would be to carry some kind of device-tree blob I suppose, but in the meantime, if you have a VID, we could define some kind of simple header for the common case that indicates if there's a UART, where, and a few other things. We can then have a PCIe driver that binds to that and create platform devices which will allow things like the litex uart driver to bind.

mithro commented 4 years ago

@kgugala -- This was a feature that I was requesting for interfacing with the NeTV2 board when used as a PCIe card.

enjoy-digital commented 4 years ago

@ozbenh: in fact for the moment the kernel is compiled with the generated csr.h/soc.h, so the information is already present in these files.

ozbenh commented 4 years ago

@enjoy-digital This is suitable for tightly coupled embedded devices, but will not scale. Since it's unrealistic to have new PCI IDs for every possible FPGA device configuration, I think there's value in putting together some simple discoverability mechanism for LiteX based devices.

One reasonably simple way to do it would be to define BAR0 to start with some kind of small ROM and build a reasonably simple and extensible mechanism on top of that. IE. First word would be the mechanism "version" so we can change it for example.

We could then define two simple variants to begin with. One with purely a list of "ID" + offset which in effect says that device ID "ID" is at offset N of the BAR where the IDs are assigned by LiteX and represent LiteX IP blocks with a fixed interface (we may need the ID to be bigg enough to represent versions/variants).

The more flexible approach is to have the BAR "ROM" contain a flat device-tree fragment. This would also allow to describe things like virtio devices, thus opening the door for things like virtio-net etc... over PCIe (we would have to sort out how to implement the device-side of course).

I prefer the latter, but it uses a bit more resources (ROM/BRAM) and we probably need some upstream work in Linux to support live DT fragment injection, including on archs/platforms like x86 that don't normally do DT at all.

In either case, provided we get somebody to donate LiteX a PCI vendor/device ID pair, we can then have a stub driver in Linux that matches and creates platform devices based on that description.

Note: We would be better off having a UART that looks more like a real 16550...

enjoy-digital commented 4 years ago

@ozbenh: i agree the solution i was suggesting would not scale, that was a first step. Regarding embedding information about the gateware in a ROM, i would rather reuse something already existing if possible (so device-tree fragment). For the UART, i agree it would have been nice to have a gateware similar to a real 16550, but we are already using ours for some years with different software and already agreed to try to keep it and already have the driver for it.