PCI: Difference between revisions

314 bytes added ,  11 months ago
→‎Base Address Registers: mention disabling IO and memory decode for BAR info reading
[unchecked revision][unchecked revision]
No edit summary
(→‎Base Address Registers: mention disabling IO and memory decode for BAR info reading)
Line 628:
 
When you want to retrieve the actual base address of a BAR, be sure to mask the lower bits. For 16-bit Memory Space BARs, you calculate <code>(BAR[x] & 0xFFF0)</code>. For 32-bit Memory Space BARs, you calculate <code>(BAR[x] & 0xFFFFFFF0)</code>. For 64-bit Memory Space BARs, you calculate <code>((BAR[x] & 0xFFFFFFF0) + ((BAR[x + 1] & 0xFFFFFFFF) << 32))</code> For I/O Space BARs, you calculate <code>(BAR[x] & 0xFFFFFFFC)</code>.
 
Before attempting to read the information about the BAR, make sure to disable both I/O and memory decode in the command byte. You can restore the original value after completing the BAR info read. This is needed as some devices are known to decode the write of all ones to the register as an (unintended) access.
 
To determine the amount of address space needed by a PCI device, you must save the original value of the BAR, write a value of all 1's to the register, then read it back. The amount of memory can then be determined by masking the information bits, performing a bitwise NOT ('~' in C), and incrementing the value by 1. The original value of the BAR should then be restored. The BAR register is naturally aligned and as such you can only modify the bits that are set. For example, if a device utilizes 16 MB it will have BAR0 filled with 0xFF000000 (0x1000000 after decoding) and you can only modify the upper 8-bits. [https://web.archive.org/web/20150101180929/https://www.pcisig.com/reflector/msg05233.html]
Anonymous user