Link Basics
Reading PCIe capability registers
A capability register holds the encoded answer a PCI Express function gives when it is asked what it can do.
A capability register holds the encoded answer a PCI Express function gives when it is asked what it can do. It is a fixed layout of bits and fields, defined by the specification, that states supported link speeds, widths, power states, and optional features. The register does not hold the device's behaviour, only the device's declaration of it, and the two are not always identical.
The same discipline applies outside silicon. A vending operator reading a machine's specification sheet faces the same problem as an engineer reading a capability register: the document states what the equipment is permitted to claim, and the operator has to verify it on site. A Dutch-language guide to vending machine selection and operation, vending machine guide, treats that verification as part of the purchase decision rather than an afterthought. The parallel is useful because both cases involve a declared capability, a real installation, and a gap that only inspection closes.
What does a capability register hold?
A capability register is a structured record, not a free-text description. In PCI Express, each function exposes a configuration space, and inside it a linked list of capability structures. Each structure begins with a capability ID and a pointer to the next one, so software can walk the list without knowing the device in advance. The content of each structure is defined field by field: a link capabilities register, for example, carries the maximum link speed, the maximum link width, the supported active state power management levels, and flags for behaviours such as clock power management or link bandwidth notification.
The register holds values, and each value has a permitted range. A link width field is five bits wide, so it can express widths up to thirty-two lanes. A speed field is four bits, which is why the encoding table in the specification stops where it does. Nothing in the register is prose. Every claim is a number or a flag, and every number or flag has a defined meaning that the reader is expected to look up.
What the register does not hold is equally important. It does not hold the negotiated result. After link training, the current speed and width live in a separate link status register, and the two can differ. A device may declare support for a speed it never reaches on a given slot, because the slot, the retimer, or the partner device constrains the outcome. The capability register describes the ceiling, not the floor and not the present.
Why does a device report more than it uses?
A device reports more than it uses because the register describes what the silicon can do, not what the board or the system enables. Three mechanisms produce the gap.
First, a controller may be designed for a family of products. The same die ships in variants with different lane counts, and the capability register is often written from the die's full configuration unless the vendor straps or programs it down. A four-lane part may therefore declare eight lanes if the field is not masked.
Second, firmware and platform policy can disable features after reset. A function may advertise a power management state that the platform never enters because the operating system or the board's power delivery does not support it. The bit remains set because the capability is real; the usage is simply absent.
Third, some fields are advisory. They tell software what the device would like, or what it can tolerate, rather than what it will do. A maximum payload size field is a limit, not a commitment. Software reads it to choose a safe value, and the device accepts whatever is negotiated within that limit.
The practical consequence is that a capability register is a claim to be checked, not a specification to be trusted on its own. The datasheet, the board schematic, and the observed link status are the three places where the claim is tested.
How are the registers read without a driver?
Configuration space is accessible before any driver binds, which is what makes early enumeration possible. On a running system, the usual route is through the operating system's configuration space access mechanism: on Linux, the sysfs tree under `/sys/bus/pci/devices/` exposes a `config` file that can be read with ordinary tools, and `lspci` with verbose flags decodes the capability list into readable fields. On Windows, vendor utilities and the platform's own diagnostic tools perform the same decode.
Before an operating system exists, the firmware reads the same space. During enumeration, firmware walks the bus, assigns addresses, and records the capability list for each function. A reader with a hardware debugger or a bus analyzer can observe those cycles directly and see the raw values, which is the only way to confirm that a decoded field matches the bytes on the wire.
Reading without a driver has limits. Some registers are write-once or read-only after configuration, and some fields return different values depending on the state of the link. A register read during training may not match a read after training completes. The reader should record the state at the moment of the read, not just the value.
| Register | What it holds | What it does not say |
|---|---|---|
| Link Capabilities | Maximum speed, maximum width, supported power management, port number | The negotiated speed and width in use |
| Link Status | Current speed, current width, training state | Whether the current state is the best the device can do |
| Device Capabilities | Maximum payload size, extended tag support, function level reset | Whether the platform enables those features |
| Device Control | Software-selected payload size, error reporting enables | What the device will do if the setting is ignored |
| Power Management Capabilities | Supported power states, wake support | Which states the platform will actually enter |
| Slot Capabilities | Physical slot properties, attention and power controller presence | Whether the slot is populated as described |
Auditing one function
- A single-function audit is a short sequence, and it is worth performing in order.
- Identify the function by vendor and device ID, and record the revision. The same device ID can appear with different capability sets across revisions.
- Walk the capability list and list every structure present. A missing structure is a finding, not a neutral fact.
- For each structure, decode the fields and write down the declared values. Do not interpret yet.
- Compare each declared value against the datasheet. Where the datasheet is silent, mark the field as unverified rather than assumed.
- Compare the declared values against the observed link status and the platform configuration. Record every difference.
- For each difference, decide whether it is a design choice, a platform limit, or a reporting error. Only the third is a defect.
Common mistakes
- Treating the capability register as a performance specification. It states limits, and a limit is not a measurement.
- Assuming a declared feature is enabled. Declaration and enablement are separate, and the gap is where most audit findings live.
- Reading the register once. Link state changes, and a value captured during training may not survive the next read.
- Ignoring the revision. Capability layouts are revised, and a field that exists in one revision may be reserved in another.
- Skipping the datasheet because the decode looks plausible. A plausible decode of the wrong field is still wrong, and the datasheet is the only authority on which field is which.
The page behind these facts
The figures on this page are read from the source the text names, pcisig.com, consulted on September 6, 2026. How this desk reads a document, and what it does with a figure it cannot source, is set out in sources and method.