Skip to content

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:

  1. Discovers all PCIe devices in the hierarchy
  2. Identifies each device (Vendor ID, Device ID, Class)
  3. Allocates resources (memory, I/O, interrupts)
  4. Configures Base Address Registers (BARs)
  5. 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

Type 0 Header (Endpoints)

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

Type 1 Header (Bridges/Switches)

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

  • Device appears at expected BDF
  • Vendor/Device ID correct
  • Class code correct
  • All BARs sized correctly
  • BARs assigned valid addresses
  • No resource conflicts
  • Capabilities list valid
  • Link capabilities reported correctly
  • Device capabilities match datasheet

Tools for Enumeration Debug

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