To illustrate my problem with an example, I have a realtek rt8139 (an Ethernet controller), as an exercise.
I can scan the PCI bus and find it its location on the bus -- vendor ID and device ID matches.
I can read the BAR[0] register in the config space, and during boot time it shows up automatically with the value 0xc201. So, that should be memory mapped (lower bit is 1), and 32-bit (next lowest bit is 0), and addressable at 0xc200.
Code: Select all
(gdb) p/x dev->config
$6 = {vendorId = 0x10ec, deviceId = 0x8139, command = 0x7, status = 0x0,
classCodeRevId = 0x2000020, cacheLineS = 0x0, latTimer = 0x0,
headerType = 0x0, bist = 0x0, bar = {0xc201, 0xf2040000, 0x0, 0x0, 0x0,
0x0}, cardbusCIS = 0x0, subsysVendorID = 0x1af4, subsystemID = 0x1100,
romBaseAddr = 0x0, capPtrRsvd = 0xdc, reserved = 0x0, intrLine = 0xa,
intrPin = 0x1, minGnt = 0x0, maxLat = 0x0}
According to the device's specs, there are a number of registers "Mapped into PCI memory space or I/O space" that presumably I should be able to read. Though the spec never really says addressable from BAR[0], I guess I'm assuming.
So, I'm a little confused - what actually sets up the BAR registers? Should my OS be choosing an address and re-assigning the BAR address (by writing to PCI config space) before trying to dereference those addresses? If I do change the address, do I need to reprogram some PCI root/hub device to tell it too what address I chose -- so it knows that the processor's write should go to the PCI Bus rather than to physical memory?
Any advice here would be much appreciated.
Thanks,
Chris