How is the device determined in PCI enumeration? (bus/device/function)

pci

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?

Best Answer

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: enter image description here

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.

enter image description here

Related Question