File:  [NetBSD Developer Wiki] / wikisrc / projects / project / userland_pci.mdwn
Revision 1.3: download - view: text, annotated - select for diffs
Tue Mar 1 10:38:50 2022 UTC (9 months ago) by martin
Branches: MAIN
CVS tags: HEAD
Adapt open gsoc project suggestion to new gsoc rules, mark as 175/350h

[[!template id=project

title="Userland PCI drivers (350h)"


[Taylor R Campbell](


When developing device drivers inside the kernel, mistakes will usually
 cause the whole kernel to crash unrecoverably and require a reboot.
But device drivers need not run inside the kernel: with
 [rump](, device driver code can be run as a
 process inside userland.

However, userland code has only limited access to the hardware
 registers needed to control devices: currently, NetBSD supports only
 USB device drivers in userland, via
 [[!template id=man name="ugen" section="4"]].
NetBSD should additionally support developing PCI drivers in userland
 with rump -- at least one driver,
 [[!template id=man name="iwm" section="4"]], was
 developed using rump, but on a Linux host!

There are several milestones to this project:

1. Implement enough of the
 [[!template id=man name="bus_space" section="9"]]
 `pci_mapreg()` ([[!template id=man name="pci" section="9"]])
 APIs to map device registers from PCI BARs, using a
 [[!template id=man name="pci" section="4"]] device (/dev/pciN).
A first approximation can be done using
 [[!template id=man name="pci" section="3"]]
 and simply mmapping from
 [[!template id=man name="mem" section="4"]] (/dev/mem),
 but it would be better to cooperate with the kernel so that the
 kernel can limit the user to mapping ranges listed in PCI BARs without
 granting privileges to read all physical pages in the system.
Cooperation with the kernel will also be necessary to implement port
 I/O instead of memory-mapped I/O, without raising the I/O privilege
 level of the userland process, on x86 systems.

2. Expose PCI interrupts as events that can be read from a
 [[!template id=man name="pci" section="4"]] (/dev/pciN)
 device instance, and use that to implement the
 [[!template id=man name="pci_intr" section="9"]]
 API in userland.
For many devices, this may require a small device-specific shim in the
 kernel to acknowledge interrupts while they are masked -- but that is
 a small price to pay for rapidly iterating driver development in

3. Devise a scheme for userland allocate and map memory for DMA in
 order to implement
 [[!template id=man name="bus_dma" section="9"]].
Again, a first approximation can be done by simply wiring pages with
 [[!template id=man name="mlock" section="3"]]
 and then asking the kernel for a virtual-to-physical translation to
 program hardware DMA registers.
However, this will not work on any machines with an IOMMU, which would
 help to prevent certain classes of catastrophic memory corruption in
 the case of a buggy driver.
Cooperation with the kernel, and maintaining a kernel-side mirror of
 each `bus_dmamem` allocation and each `bus_dmamap`.

Inspiration may be found in the Linux
This project is not necessarily PCI-specific -- ideally, most of the
 code to manage
 [[!template id=man name="bus_space" section="9"]],
 [[!template id=man name="bus_dma" section="9"]],
 and interrupt event delivery should be generic.
The focus is PCI because it is widely used and would be applicable to
 many drivers and devices for which someone has yet to write drivers.

[[!tag gsoc]]
[[!tag gsoc350h]]

CVSweb for NetBSD wikisrc <> software: FreeBSD-CVSweb