PCI configuration space
|This article does not cite any references or sources. (January 2010)|
Introduction: PCI devices have a set of registers referred to as ‘Configuration Space’and PCI Express introduces Extended Configuration Space for devices. Configuration space registers are mapped to memory locations.Device drivers and diagnostic software must access the configuration spaces and operating systems have APIs to allow access to device configuration space. When the operating system does not have access methods defined or APIs for memory mapped configuration space requests, the driver or diagnostic software has the burden to access the configuration space in a manner that is compatible with the operating system underlying access rules. In all systems, device drives are encouraged to use APIs provided by the operating system to access the configuration space of the device.
One of the major improvements the PCI Local Bus had over other I/O architectures was its configuration mechanism. In addition to the normal memory-mapped and I/O port spaces, each device function on the bus has a configuration space. This is 256 bytes that are addressable by knowing the 8-bit PCI bus, 5-bit device, and 3-bit function numbers for the device (commonly referred to as the BDF bus/device/function). This allows up to 256 buses, each with up to 32 devices, each supporting 8 functions. A single PCI expansion card can respond as a device and must implement at least function number zero. The first 64 bytes of configuration space are standardized; the remainder are available for vendor-defined purposes.
In order to allow more parts of configuration space to be standardized without conflicting with existing uses, there can be a list of capabilities defined within the first 192 bytes of PCI configuration space. Each capability has one byte that describes which capability it is, and one byte to point to the next capability. The number of additional bytes depends on the capability ID. If capabilities are being used, a bit in the Status register is set, and a pointer to the first in a linked list of capabilities is provided in the Cap. pointer register defined in the Standardized Registers.
PCI-X 2.0 introduced an extended configuration space, up to 4096 bytes. The only standardized part of extended configuration space is the first 4 bytes at 0x100 which are the start of an extended capability list. Extended capabilities are very much like normal capabilities except that they can refer to any byte in the extended configuration space (by using 12 bits instead of 8), have a 4-bit version number and a 16-bit capability ID. Extended capability IDs overlap with normal capability IDs, but there is no chance of confusion as they are in separate lists.
The Vendor ID and Device ID registers identify the device model, and are commonly called the PCI ID. The 16-bit vendor ID is allocated by the PCI-SIG. The 16-bit device ID is then assigned by the vendor. There is an ongoing project to collect all known Vendor and Device IDs. (See external links (below).)
The Subsystem Vendor ID and the Subsystem Device ID further identify the device model. The Vendor ID is that of the chip manufacturer, and the Subsystem Vendor ID is that of the card manufacturer. The Subsystem Device ID is assigned by the subsystem vendor, but is assigned from the same number space as the Device ID.
The Status register is used to report which features are supported and whether certain kinds of error have occurred.
The Command register contains a bitmask of features that can be individually enabled and disabled.
The Header Type register values determine the different layouts of remaining 48 bytes (64-16) of the header, depending on the function of the device. That is, Type 1 headers for Root Complex, switches, and bridges. Then Type 0 for endpoints.
The Cache Line Size register must be programmed before the device is told it can use the memory-write-and-invalidate transaction. This should normally match the CPU's cache line size, but the correct setting is system dependent. This register does not apply to PCI Express.
In order to address a PCI device it must be mapped into the I/O port address space or the memory-mapped address space of the system. The system's firmware/device drivers or the operating system will program the Base Address Registers (commonly called BARs) to inform the device of its address mapping by writing configuration commands to the PCI controller. Because all PCI devices are in an inactive state upon system reset, they will not have any addresses assigned to them by which the operating system or device drivers can communicate with them. Either the BIOS or the operating system geographically addresses the PCI slots (e.g. the first PCI slot, the second PCI slot, or the third PCI slot, etc., on the motherboard) through the PCI controller using the per slot IDSEL (Initialization Device Select) signals.
Since there is no direct method for the BIOS or OS to determine which PCI slots have devices installed (nor the functions the device implements) the PCI bus(es) must be enumerated. Bus enumeration is performed by attempting to read the Vendor- and Device ID register for each combination of bus number and device number, at the device's function #0.
If there is no device that implements the function zero (i.e., vendor and device ID registers), the bus master performs an abort and returns all 1s in binary (hexadecimal FFFFFFFF). All ones is an invalid VID/DID value, thus a device driver can tell that the specified combination bus/device/function (B/D/F) does not exist. So, when a read to a function ID of zero for a given bus/device causes the master (initiator) to abort, it must then be presumed that no working device exists on that bus because devices are required to implement function number zero. In this case, reads to the remaining functions numbers (1–7) are not necessary as they also will not exist.
When a read to a specified BDF combination vendor ID register succeeds, the BIOS or OS knows it exists. It writes all 1s to the BARs, and reads back the device's requested memory size in the form of 0s where the don't care address is. The design implies that all address spaces used are a power of two and are naturally aligned. At this point, the BIOS or OS will program the memory-mapped and I/O port addresses the function will respond to into the devices' BAR configuration register. These addresses stay valid as long as the system remains turned on. On power off, all these settings are lost and on the next system boot, the configuration procedure is repeated. Since this entire process is fully automated, the user is spared the task of configuring any newly added hardware manually by modifying settings of DIP switches on the cards themselves. This is how plug and play is implemented.
If a PCI-to-PCI bridge is found, the system must assign the secondary PCI bus beyond the bridge a bus number other than 0, and then enumerate the devices on that secondary bus.
|For all PCI BARs|
|0||Region Type||0 = Memory
1 = I/O (deprecated)
|For Memory BARs|
|2-1||Locatable||0 = any 32-bit
1 = < 1MiB
2 = any 64-bit
|3||Prefetchable||0 = no
1 = yes
|31-4||Base Address||16-byte aligned|
|For I/O BARs (Deprecated)|
|31-2||Base Address||4-byte aligned|
A device can have a ROM which can contain driver code or configuration information.
When performing a configuration space access, a PCI device does not decode the address to determine if it should respond, but instead looks at the signal IDSEL. There is a system-wide unique activation method for each IDSEL signal. The IDSEL is different for each PCI device/adapter slot. Further, the device is required to decode only the lowest order 11 bits of the address space (AD to AD) address/data signals, and can ignore the high order 21 A/D signals ([AD – AD) completely.
Thus typically, an implementation has each slot's IDSEL pin connected to a different address/data line AD through AD. To configure the card in slot n, the PCI bus bridge performs a configuration-space access cycle with the PCI device's register to be addressed on lines AD[7:2] (AD[1:0] are always zero since registers are double words (32-bits)), and the PCI function number specified on bits AD[10:8], with all higher-order bits zeros except for AD[n+11] being used as the IDSEL signal on a given slot.
To reduce electrical loading on the timing critical (and thus loading sensitive) AD bus, usually the IDSEL signal on the slot connector is connected to an AD[n+11] through a resistor. This causes the IDSEL signal to get to its active condition more slowly than other PCI bus signals (due to the RC time constant of the resistor and the IDSEL pin's input capacitance), so configuration space accesses are performed more slowly to allow time for the IDSEL signal to reach a valid level.
The scanning on the bus is performed on the Intel platform by accessing two defined standardized ports. These ports are the Configuration Space Address (0xCF8) I/O port and Configuration Space Data (0xCFC) I/O port. The value written to the Configuration Space Address I/O port is created by combining D/B/F values and the registers address value into a 32-bit word.
Configuration reads and writes can be initiated from the CPU in two ways: one legacy method via I/O addresses 0xCF8 and 0xCFC, and another called memory-mapped configuration.
The legacy method was present in the original PCI, and it is called Configuration Access Mechanism (CAM). It allows for 256 bytes of a device's address space to be reached indirectly via two registers called PCI CONFIG_ADDRESS and PCI CONFIG_DATA. These registers live at addresses 0xCF8 and 0xCFC in the x86 I/O address space. For example, a software driver (firmware, OS kernel or kernel driver) can use these registers to configure a PCI device by writing the address of the device's register into CONFIG_ADDRESS, and by putting the data that is supposed to be written to the device into CONFIG_DATA. Since this process requires a write to a register in order to write the device’s register, it is referred to as "indirection."
The format of CONFIG_ADDRESS is the following:
bus << 16 | device << 11 | function << 8 | offset
As explained previously, addressing a device via Bus, Device, and Function (BDF) is also referred to as "addressing a device geographically." See arch/i386/pci/early.c  in the Linux kernel code for an example of code that uses geographical addressing.
The second method was created for PCI Express. It is called Enhanced Configuration Access Mechanism (ECAM). It extends device's configuration space to 4k, with the bottom 256 bytes overlapping the original (legacy) configuration space in PCI. The section of the addressable space is "stolen" so that the accesses from the CPU don't go to memory but rather reach a given device in the PCI Express fabric. During system initialization, firmware determines the base address for this “stolen” address region and communicates it to the root complex and to the operating system. This communication method is implementation-specific, and not defined in the PCI express specification.