I've tried both reading userspace pci entry under /proc/bus/pci directory and calling kernel space API pci_read_config_word() in the driver. but it seems both can only read pci basic configuration space, offset less than 0x100.
The offset I want to read is beyond 0x100, could anyon开发者_运维百科e tell me how to do it in Linux? if done in kernel space, telling which API to call would be very appreciated. Thank you very much!
pci_read_config_word()
is the correct API, but to access extended configuration space you need to use MMCONFIG. This is not something you set up; the kernel should choose to use MMCONFIG by itself if available. Do you see anything like
e0000000-efffffff : PCI MMCONFIG 0000 [bus 00-ff]
in /proc/iomem
? Also in your kernel log, you should see some lines about the ACPI MCFG table and MMCONFIG:
ACPI: MCFG 00000000bb7fec63 0003C (v01 LENOVO TP-6U 00001410 LNVO 00000001)
...
PCI: MMCONFIG for domain 0000 [bus 00-ff] at [mem 0xe0000000-0xefffffff] (base 0xe0000000)
and of course your kernel needs to be built with CONFIG_PCI_MMCONFIG=y
.
I believe that the extended configuration space is restricted for non-root users, at least that's the behaviour I face when executing lspci
when not root. You can use sudo lspci -Qkxxxxnnv
to view all 0xff0
(4080) configuration space data, and some other useful stuff.
$ sudo lspci -Qkxxxxnnv
00:1d.0 PCI bridge [0604]: Intel Corporation Comet Lake PCI Express ...
Flags: bus master, fast devsel, latency 0, IRQ 124
...
Kernel driver in use: pcieport
00: 86 80 98 a3 07 04 10 00 f0 00 04 06 10 00 81 00
...
ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
See: PCI Configuration Space
精彩评论