I am trying to understand how the Base Address Registers (BARs) in a PCI card work, this is how I think they work:

  • Each function in a PCI card have 6 BAR fields, and each BAR field is 32-bit in size.
  • The PCI card manufacturer will write in each BAR field how much memory it wants the Operating System to allocate, and each BAR field will also specify if it wants this allocated memory to use Memory-mapped IO or Port-mapped IO.
  • The Operating System will read each BAR field and will allocate the specified memory, and will write the start address for each allocated memory block in the corresponding BAR field.

Am I correct?

  • 2
    You are probably correct, but such a question is off-topic here. – Basile Starynkevitch Oct 9 '17 at 10:49
  • 1
    This site is about software engineering concepts like design or development processes – please take a look at our help center for details. That means questions about hardware are out of scope. – amon Oct 11 '17 at 14:32

This question should be moved to stackoverflow. Maybe someone will do that.

Am I correct?

Essentially, yes.

Each BAR holds the address of a communication area. This address can be set and read by the operating system as part of the larger device configuration.

For each BAR (independently), the device stores only some of the bits that the processor might write and it ignores others. Of the 28 possible bits (in 32-bit BAR configuration) the device stores only some number of upper bits and ignores the remainder lower bits.

Due to this mechanism, the specification allows only for sizes of the communication area that are powers of 2, and only alignment within the address space of the same power of 2.

If the operating system writes a -1 (i.e. all 1's) to a BAR, and reads it back, it will get back those 1's only for the (upper) bits that this BAR in the device stores/represents, and get back zeros for lower bits this BAR doesn't store/represent.

The number of ones (zeros) it gets back tells the operating system what it needs to know, which is how many bits are (or aren't) represented in the BAR. From that it can easily determine the size of the address space that the device wants, and the alignment it expects. See here for more detail.

After allocating appropriate address space, it writes that real value to the BAR (replacing the prior written -1). The BAR is now properly configured.

NB: The operating system allocates address space, not actual memory: it is as if the memory for the communication area is being supplied by the device, and that the processor can address it starting at this location.

The operating system doesn't really formally ask the hardware for size & alignment of the communication area, but rather uses this trick of writing all 1's and observing the effect.

The hardware doesn't have to know that the operating system is "just kidding" about the -1 (or otherwise that it is actually going about the making of an inquiry); it simply does what it always does with a write to a BAR (i.e. storing the upper N bits), and it honors a (BAR) read request as it normally would (by returning those upper N bits concatenated with zeros for the unstored lower bits).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.