How is the device determined in PCI enumeration? (bus/device/function)
I am confused about PCI Bus/Device/Function enumeration. Looking at the Wikipedia page for PCI configuration, I see that for a given bus, the master will request vendor ID and device ID for all devices using function 0. If all 0xFFs are returned, then no device is there, and enumeration moves on. If a valid device ID and vendor ID are found, then there is a PCI unit there and it will be enumerated. I am unsure how the device in the bus.device.function is determined.
For example, let's say I have a CPU with one PCI bus and one PCI peripheral attached to it. I understand that the CPU will look on bus 0 (by default) and will check for all device numbers looking at function 0. How does the peripheral's device number get determined?
The device is determined by a hardware line IDSEL that is an input to every PCI endpoint. During configuration transactions, the IDSEL is used to indicate to a PCI endpoint (or bridge) that it is currently selected. In terms of determining the actual device number, this is done by the host hardware. If for example a motherboard has two PCI endpoint slots, there will be two discrete IDSEL lines from the CPU to the endpoints. This is seen in the picture below:
Additionally, it seems that in practice, it is common to tie these IDSEL lines to a one hot mapping from the 32 bit address/data bus. When a configuration is taking place, the address line will assert a one hot address such as 0x00000010. The one bit of the address/data bus will be brought in as the IDSEL for a particular endpoint. Since there are 32 possible devices per bus, this works out nicely. As an example of this, assume that there is a motherboard with 5 possible devices. The following could be an example mapping.
[bus/device/function/offset] have total of 32 bits.
Offset {bits 7:2} interpret directly to PCI device AD7:2 signals - this allow up to 64 DW of configuration registers.
Function {bits 10:9} interpret directly to PCI device AD10:9 signals - this allow up to 8 functions in one PCI device.
Device {bits 15:11} interpret to AD31:11 signals and each connected to device IDSEL pin. Although theoretically max of 32 (2^5) devices, with this method only 21 (AD11 to AD31) can actually be connected on a local bus. IDSEL is Initialization Device Select and used as a chip select during configuration transactions.
B.T.W
There are two types of configuration register transactions:
TYPE0 (AD1:0 are 2'b00): AD7:2 signals used for up to 64 DW of configuration registers. AD10:9 signals used for up to 8 functions in one PCI device. AD31:11 signals are don't care thefroe can be use to distinguish IDSEL on each device. Only devices on a local bus responce to this type.
TYPE1 (AD1:0 are 2'b01): bits AD 31:2 value are much like the [bus/device/function/offset]. Only PCI-to-PCI bridge responce to this type and if it match its local bus number, the bridge convert it to TYPE0, otherwise pass it throw.