PCI BAR Registers
Posted: Wed Apr 28, 2010 11:15 pm
I'm a little confused on the responsibility of the OS in handling PCI base address registers.
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.
But, if I just deference addresses in the range 0xc200 - 0xc300, I get all 0's.
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
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