PCIe Enumeration
PCIe enumeration is the process by which the system discovers, identifies, and configures all PCIe devices. Understanding enumeration is essential for validating that devices are correctly recognized and configured.
What is Enumeration?
Enumeration is the firmware/software process that:
- Discovers all PCIe devices in the hierarchy
- Identifies each device (Vendor ID, Device ID, Class)
- Allocates resources (memory, I/O, interrupts)
- Configures Base Address Registers (BARs)
- Enables devices for operation
PCIe Topology
graph TB
subgraph "Root Complex"
RC[Root Complex]
RP1[Root Port 0]
RP2[Root Port 1]
end
subgraph "Bus 1"
SW[PCIe Switch]
UP[Upstream Port]
DP1[Downstream Port 0]
DP2[Downstream Port 1]
end
subgraph "Endpoints"
EP1[GPU]
EP2[NIC]
EP3[SSD Controller]
end
RC --> RP1
RC --> RP2
RP1 --> UP
UP --> SW
SW --> DP1
SW --> DP2
DP1 --> EP1
DP2 --> EP2
RP2 --> EP3
Bus/Device/Function (BDF)
Each PCIe function is identified by a unique address:
| Component |
Bits |
Range |
Description |
| Bus |
8 |
0-255 |
Bus number |
| Device |
5 |
0-31 |
Device on bus |
| Function |
3 |
0-7 |
Function in device |
Example: BDF 02:00.0
- Bus 2
- Device 0
- Function 0
Configuration Space
Offset Field
00h Vendor ID | Device ID
04h Command | Status
08h Revision | Class Code
0Ch Cache Line | Latency | Header Type | BIST
10h BAR0
14h BAR1
18h BAR2
1Ch BAR3
20h BAR4
24h BAR5
28h CardBus CIS Pointer
2Ch Subsystem Vendor ID | Subsystem ID
30h Expansion ROM Base
34h Capabilities Pointer
3Ch Interrupt Line | Interrupt Pin | Min_Gnt | Max_Lat
Offset Field
00h Vendor ID | Device ID
04h Command | Status
08h Revision | Class Code
0Ch Cache Line | Latency | Header Type | BIST
10h BAR0
14h BAR1
18h Primary Bus | Secondary Bus | Subordinate Bus
1Ch Secondary Latency | I/O Limit | I/O Base
20h Memory Limit | Memory Base
24h Prefetch Memory Limit | Prefetch Memory Base
28h Prefetch Base Upper 32
2Ch Prefetch Limit Upper 32
30h I/O Limit Upper | I/O Base Upper
34h Capabilities Pointer
38h Expansion ROM Base
3Ch Interrupt Line | Interrupt Pin | Bridge Control
Enumeration Process
Step 1: Bus Enumeration
sequenceDiagram
participant BIOS as BIOS/Firmware
participant RC as Root Complex
participant Dev as Device
BIOS->>RC: Read Config (Bus 0, Dev 0)
RC-->>BIOS: Root Complex Info
loop For each Root Port
BIOS->>RC: Read Config (Bus 0, Dev N)
RC-->>BIOS: Root Port Info
BIOS->>RC: Assign Secondary Bus Number
BIOS->>Dev: Read Config (Secondary Bus, Dev 0)
Dev-->>BIOS: Device Info or No Response
end
Step 2: Device Discovery
For each bus, enumerate devices 0-31:
# Pseudocode for enumeration
def enumerate_bus(bus_number):
for device in range(32):
for function in range(8):
vendor_id = read_config(bus, device, function, 0x00)
if vendor_id == 0xFFFF:
if function == 0:
break # No device, skip remaining functions
continue # Try next function
# Device found - read identification
device_id = read_config(bus, device, function, 0x02)
class_code = read_config(bus, device, function, 0x08)
# Check if multi-function
header_type = read_config(bus, device, function, 0x0E)
if function == 0 and not (header_type & 0x80):
break # Single function device
# If bridge, enumerate secondary bus
if is_bridge(header_type):
assign_secondary_bus()
enumerate_bus(secondary_bus)
Step 3: Resource Allocation
BAR Sizing:
1. Write all 1s to BAR
2. Read back to determine size (zeros indicate size)
3. Allocate memory/IO space
4. Write allocated base address
BAR Sizing Example:
Write: 0xFFFFFFFF
Read: 0xFFF00000
Size: 1MB (inverted low bits + 1)
Memory Types:
| BAR Bit 0 |
Type |
| 0 |
Memory |
| 1 |
I/O |
| BAR Bits 2:1 |
Memory Type |
| 00 |
32-bit |
| 10 |
64-bit |
Key Configuration Registers
Command Register (Offset 04h)
| Bit |
Name |
Description |
| 0 |
I/O Space |
Enable I/O access |
| 1 |
Memory Space |
Enable memory access |
| 2 |
Bus Master |
Enable DMA |
| 6 |
Parity Error |
Enable parity error response |
| 8 |
SERR# Enable |
Enable system error |
| 10 |
Interrupt Disable |
Disable legacy interrupts |
Status Register (Offset 06h)
| Bit |
Name |
Description |
| 3 |
Interrupt Status |
Interrupt pending |
| 4 |
Capabilities List |
Extended caps present |
| 5 |
66MHz Capable |
Legacy (PCIe always 0) |
| 8 |
Master Data Parity Error |
DMA parity error |
| 11 |
Signaled Target Abort |
Transaction aborted |
| 12 |
Received Target Abort |
Target aborted |
| 13 |
Received Master Abort |
No response |
| 14 |
Signaled System Error |
SERR# asserted |
| 15 |
Detected Parity Error |
Parity error |
Extended Configuration Space
PCIe extends configuration space to 4KB (vs 256B legacy):
000h - 0FFh Standard PCI Config (256 bytes)
100h - FFFh PCIe Extended Config (3840 bytes)
Extended Capabilities
| Capability ID |
Name |
| 0001h |
AER (Advanced Error Reporting) |
| 0002h |
VC (Virtual Channel) |
| 0003h |
Serial Number |
| 0004h |
Power Budgeting |
| 0010h |
SRIOV |
| 0019h |
Secondary PCIe |
| 001Eh |
L1 PM Substates |
Enumeration Validation
Device Discovery Checks
| Test |
Expected Result |
| Read Vendor ID |
Valid ID (not 0xFFFF) |
| Read Device ID |
Correct device |
| Read Class Code |
Correct device class |
| BAR sizing |
Correct size reported |
| Capability pointer |
Valid capability list |
Common Enumeration Issues
| Symptom |
Possible Cause |
Debug Steps |
| Device not seen |
Link not trained |
Check LTSSM state |
| Wrong BDF |
Bus number assignment |
Check bridge config |
| BAR not allocated |
Size conflict |
Check memory map |
| Capabilities missing |
Capability pointer |
Dump config space |
| Resource conflict |
Overlapping BARs |
Check all BAR assignments |
Validation Checklist
Linux
# List all PCIe devices
lspci -vvv
# Show tree structure
lspci -tv
# Dump configuration space
lspci -xxx -s 02:00.0
# Read specific register
setpci -s 02:00.0 0x04.w
Windows
- Device Manager
- PCIe diagnostic tools
- Vendor-specific utilities
Common Class Codes
| Class |
Subclass |
Description |
| 01h |
08h |
Mass Storage - NVM |
| 02h |
00h |
Network - Ethernet |
| 03h |
00h |
Display - VGA |
| 04h |
03h |
Multimedia - Audio |
| 06h |
04h |
Bridge - PCI-to-PCI |
| 0Ch |
03h |
Serial Bus - USB |
References
- PCI Express Base Specification
- PCI Local Bus Specification (for legacy compatibility)
- PCI Code and ID Assignment Specification