PCIe Root Complexes still expose PCI-compatible configuration mechanisms. Operating systems use the same driver model for PCI and PCIe devices. 9. Practical Example: Programming a PCI Controller To access a PCI device’s configuration space on x86:
| Function | Description | | :--- | :--- | | | Manages requests from multiple bus masters (devices wanting to initiate transfers). Grants access based on a fairness algorithm (e.g., rotating priority). | | Address Decoding | Determines whether a memory or I/O access from the CPU targets a PCI device or main memory. Routes accordingly. | | Data Transfer Control | Orchestrates burst transfers, target termination, and error handling (parity checking, master abort, target abort). | | Configuration Access | Implements Configuration Space (256 bytes per device) for resource assignment (Base Address Registers – BARs), interrupt routing, and device identification. | | Bridge Logic | Connects primary (CPU side) to secondary (PCI bus side) interfaces. Handles transaction forwarding, buffering, and speed adaptation. | 4. System Topology & PCI Hierarchy A typical PCI system uses a host bridge (the PCI Controller) to connect the CPU/memory to PCI bus 0. Additional PCI-to-PCI bridges allow expansion. pci controller
// Write to CONFIG_ADDRESS (I/O port 0xCF8) uint32_t addr = (1 << 31) // Enable bit | (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xFC); // Dword-aligned outl(0xCF8, addr); // Read from CONFIG_DATA (I/O port 0xCFC) uint32_t data = inl(0xCFC); Practical Example: Programming a PCI Controller To access