2

I'm developing a driver for an FPGA-board connected to my machine via an PCIe expansion slot, and everything works great if the board is powered on prior to the PC. However, if I book up my computer first and then the FPGA board, I get the rather unusual behavior of the device being recognized and loading my module (I see the "init" function called in my syslog), however the "probe" function is never called.

I think this is due to an invalid BAR0. Output from dmesg when I power on the board:

[   71.287587] pci 0000:3b:00.0: [0ae5:0001] type 00 class 0x000000
[   71.287613] pci 0000:3b:00.0: reg 0x10: [mem 0x00000000-0x0000ffff]
[   71.287821] pci 0000:3b:00.0: System wakeup disabled by ACPI
[   71.328537] my_driver:
[   71.328537] ****************************************************************
[   71.328542] my_driver: init debug=2

That first reg should be something like 0xb4000000-0xb400ffff but instead it's coming up as 0. (Like I said, it works perfectly if it's powered on before the computer).

Is there an additional step required to get it to allocate this block? Or somehow to indicate to the kernel that it needs to do this?

Yeraze
  • 3,269
  • 4
  • 28
  • 42
  • Doesn't PCI hotplugging require an actual plug operation? – CL. Aug 21 '14 at 08:05
  • @Yeraze:How did you connect your FPGA to PCIe expansion slot.ie What Interface chip did you use for that purpose? I am sorry this is not related to your question.You can either answer here or I have posted a question "http://stackoverflow.com/questions/25445801/how-to-integrate-a-ntp-on-a-pcie-card" – ddpd Aug 22 '14 at 12:20

3 Answers3

2

The solution wound up being a manual call to pci_assign_resource ( http://lxr.free-electrons.com/source/drivers/pci/setup-res.c#L283 ).

Calling this right before pci_enable_device caused the OS, rather than the BIOS, to allocate the required BAR's and now it all works!

I do still have to manually trigger a PCI bus rescan ( echo 1 > /sys/bus/pci/rescan ).

Yeraze
  • 3,269
  • 4
  • 28
  • 42
1

Your PCI device must be powered up prior to the BIOS PCI enumeration phase. On enumeration phase, the BIOS tries to read the ID of the PCI devices that might be connected. If it reads invalid ID (0xfffff) it skips that PCI device.

I don't have a reference, but AFAIK, you have about a second before you must populate the configuration space of the PCI.

stdcall
  • 27,613
  • 18
  • 81
  • 125
0

Are you sure you register the PCI driver and don't return non-zero from mod_init? Please try to manually bind the device to your driver:

echo -n "0000:3b:00.0" > /sys/bus/pci/drivers/my_driver/bind

Unallocated BAR should not be an issue when loading the driver.

As for the BAR being 0 and HotPlug: find out what is your platform and if and how HotPlug is supported. You need to have the right HotPlug driver in the kernel for this sort of thing to work. BARs are allocated by the kernel (or initially firmware/BIOS) so you can't set them to anything meaningful from the FPGA side - there you can only set the size. Kernel has to do the rescanning and reassignment after device appears. I vaguely recall that there should be some reservation going on during boot, otherwise kernel will not have to space to give to your devices' BAR and it will not reassign the windows on bridges below your device as they can be actively used by other devs. Other option is to just do the BAR programming yourself from the driver. It ain't that hard but you would probably don't want to ship this kind of hacks to customers. Also, even though your device does seem to come up fine, make sure you don't have HP disabled in FW/BIOS.

moorray
  • 222
  • 2
  • 10
  • When I insert or power on the FPGA board, it autodetects the driver to load (it loads my module and calls init), but it never calls probe. – Yeraze Aug 21 '14 at 13:02