As in PCI Express a capability register called “pci express capability register” specifies the device/port type field which tells whether its root port, upstream switch port, switch downstream port, end point etc. What mechanism does BIOS use to determine the port/device type during PCI Bus enumeration ?
2 Answers
I am not sure answering your question but while getting bridge operation in coreboot (get_pci_bridge_ops) https://github.com/coreboot/coreboot/blob/master/src/device/pci_device.c it is done that way :
unsigned int pciexpos;
pciexpos = pci_find_capability(dev, PCI_CAP_ID_PCIE);
if (pciexpos) {
u16 flags;
flags = pci_read_config16(dev, pciexpos + PCI_EXP_FLAGS);
switch ((flags & PCI_EXP_FLAGS_TYPE) >> 4) {
case PCI_EXP_TYPE_ROOT_PORT:
case PCI_EXP_TYPE_UPSTREAM:
case PCI_EXP_TYPE_DOWNSTREAM:
printk(BIOS_DEBUG, "%s subordinate bus PCI Express\n",
dev_path(dev));
return &default_pciexp_ops_bus;
case PCI_EXP_TYPE_PCI_BRIDGE:
printk(BIOS_DEBUG, "%s subordinate PCI\n",
dev_path(dev));
return &default_pci_ops_bus;
default:
break;
}
}
It's fixed - the vendor programs that field based on the design of its product.
The manufacturer always knows if a port is upstream or downstream or if it has just designed a root complex instead of a switch or if it is using PCI instread PCIe.
Simply put this is where the vendor knowledge is essential and why it is its duty to write a firmware.
Specifically, the field value can come from an EEPROM/FlashROM or be programmed by the BIOS/UEFI at early boot using hardwired values. It doesn't really matter how it is done, what matters is that the field gets initialized as intended in the factory before any dependent software read it.