Reputation: 4508
I'm need to communicate with a memory PCI device through /dev/mem
. Why? There are many reasons, one of which is because my boss told me so.
I think I have my answer here. What I can't figure out however is the MMIO_ADDR
in the answer. If I want to communicate with a specific memory region, would I use a value stored in a BAR
register as my MMIO_ADDR
? If no then how do I communicate with my PCI device?
Upvotes: 1
Views: 4076
Reputation: 12337
Your BAR will have been assigned an address by the BIOS/kernel. That address should have been written into the BAR address registers in the PCI configuration header by the time the system is up.
For example, on a VM I have here, the e1000 device is as follows (from lspci -v
):
02:03.0 Ethernet controller: Intel Corporation 82545EM Gigabit Ethernet Controller (Copper) (rev 01)
Subsystem: VMware PRO/1000 MT Single Port Adapter
Physical Slot: 35
Flags: bus master, 66MHz, medium devsel, latency 0, IRQ 17
=> Memory at fd560000 (64-bit, non-prefetchable) [size=128K]
Memory at fdfd0000 (64-bit, non-prefetchable) [size=64K]
I/O ports at 2080 [size=64]
[virtual] Expansion ROM at fd520000 [disabled] [size=64K]
Capabilities: <access denied>
Kernel driver in use: e1000
You'll need to read that info (you can reach it in binary form via /proc/bus/pci/<Bus>/<DevFn>
or via /sys/bus/pci/devices/
) to find the MMIO address.
For example, dumping the binary of the PCI configuration space for the device above shows:
od -tx1z -Ax /proc/bus/pci/02/03.0
000000 86 80 0f 10 17 01 30 02 01 00 00 02 10 00 00 00 >......0.........<
000010 04 00 56 fd 00 00 00 00 04 00 fd fd 00 00 00 00 >..V.............<
000020 81 20 00 00 00 00 00 00 00 00 00 00 ad 15 50 07 >. ............P.<
000030 00 00 00 00 dc 00 00 00 00 00 00 00 0b 01 ff 00 >................<
000040
The first BAR (bar region #0) is at offset 0x10, the second (bar region #2) is at offset 0x18.
See https://en.wikipedia.org/wiki/PCI_configuration_space for description of the layout and interpretation.
Upvotes: 2