PCI in a system consists of a PCI controller that is mapped into the Processor's memory. The PCI bus is connected to the other side of the PCI controller. The PCI Controller will have its own control registers that configure things like access windows (between CPU and PCI address space), there will also probably be access to the configuration space of its connected PCI devices via 'address' and 'data' registers.
PCI has three different address spaces:
Is often used by ethernet adapters, and other peripheral devices.
Is often used by Graphics cards.
Is used to configure all devices. After initialization this address space is rarely used.
Each PCI device can be configured purely by software, the Configuration Space allows this. All devices (except host bus bridges) are required to provide 256 bytes of configuration registers for this purpose. The configuration space can be accessed through a set of registers in the PCI controller. This is system specific.
|bit 31||bit 16||bit 15||bit 0||offset|
|Device ID||Vendor ID||0x00|
|Class Code||Revision ID||0x08|
|BIST||Header Type||Latency Timer||Cache Line Size||0x0C|
|Base Address Register #0||0x10|
|Base Address Register #1||0x14|
|Base Address Register #2||0x18|
|Base Address Register #3||0x1C|
|Base Address Register #4||0x20|
|Base Address Register #5||0x24|
|Cardbus CIS Pointer||0x28|
|Subsystem ID||Subsystem Vendor ID||0x2C|
|Expansion ROM Base Address||0x30|
|Undefined - each device may use this space differently||Capabilities ptr.||0x34|
|Undefined - each device may use this space differently||0x38|
|Max Latency||Min Grant||Interrupt Pin||Interrupt Lane||0x3C|
See wiki.osdev.org for more information (and different header types)
Each PCI slot in a system has an IDSEL pin. This acts similarly to a CS# pin, and is usually the output of a one-hot decode from some high-bits of the PCI-side address bus. This allows the software to attempt to access the system-specific 'PCI Bus Configuration Space' memory and determine which slots have devices present.
A slot that does not have a device present will read logic high (0xFFFFFFFF). There are also pins labelled PRSNT1# and PRSNT2# (see PCI pinout) which may be read by the motherboard to determine device presence.
Before configuration is complete, and access to the PCI device's address space has been 'turned on' by the Command field in the Configuration Space, nothing can access the device's memory.
The PCI bus must be enumerated. This consists of trying to read offset 0x00 (the Device ID & Vendor ID) of each bus and device number (function #0). If there is no device present, the bus master will perform an abort and return 0xFFFFFFFF (which resolves to an invalid Vendor ID).
During configuration two addresses are important: