How is PCI / PCIe BAR size determined?

I know that the base address register (BAR) in the PCI configuration space determines the initial location of the PCI address, but how is the size of this region set?

Of course, this is a property of the hardware, since only he knows how far he can get into his address space. However, I cannot see the BAR size field in the PCI configuration structure.

+9
source share
3 answers

First of all, the size of the BAR must be a power of two (for example, 1 KiB, 2 MiB), and each area must be aligned in memory so that the lower bits of log2(size) base address are always zero. For example, suppose the endpoint has a 4 KiB memory area that gives an address range of 0-0xfff . The host can reassign the beginning of this area to fx 0x1000 or 0xabcd000 by writing to the BAR register, but not to 0x1080 or 0xabcd100 .

When the BAR register is written, the endpoint will ignore the LSB and always return zeros when reading. So writing 0xffffffff to a register, and then reading the value indicates the size of the area. For example 4 KiB, this returns 0xfffff00X (the lower four bits are reserved, see Specification). To determine the size:

  • Clear the bottom four bits to zeros ( 0xfffff000 )
  • Invert all 32 bits ( 0xfff )
  • Add to the result ( 0x1000 = 4096 bytes )

This also works for 64-bit areas. The value of the next base address register forms the base address MSB. This is described in section 6.2.5.1 of the PCI 3.0 specification.

+8
source

Found the answer on the OSDev Wiki :

"To determine the amount of address space required for a PCI device, you must keep the original BAR value, write a value of just 1 in the register, and then read it back."

+6
source

A PCIe device can have a configuration space of type 0 (endpoints) or type 1 (RC or switches or bridges).

- A device of type 0 can have a total of 6 measures, and type 1 can only have 2 measures.

--BAR provides information about the address space required for the device.

--Each BAR - 32 bits, of which the first 4 bits 3: 0 are always read-only.

- 2 ^ (position of the last R / W bits of the least significant bit) = address window required by a particular BAR.

How to find the address window or the size of the region represented by any BAR:

1) Initially, having read any BAR (suppose BAR0 in our case), we got the value 32'h0000_000F. (Remember: the last 4 bits are read only !!).

2) Write all 1 to BAR0.

3) Read BAR0 again and suppose we get the value 32'hFFFF_000F. Thus, bit position 16 is the least significant bit of R / W. Thus, the address space required for BAR0 will be 2 ^ 16.

0
source

Source: https://habr.com/ru/post/987041/


All Articles