PCI/PCIe Architecture Overview

Explains PCI/PCIe architecture for firmware work: BDF, config space, BAR, bridges, enumeration, and missing-device debug.

Updated 3 min read
Đọc bằng English Tiếng Việt 日本語
PCI cover

PCI/PCIe architecture is the model firmware uses to discover, identify, resource, and expose PCIe devices to drivers. For a firmware engineer, PCIe is not just a slot on the board. It is a chain of root bridges, bus scans, configuration space reads, BAR sizing, bridge windows, protocol installation, and driver binding.

When the OS does not see an NVMe drive, NIC, or expansion card, the OS driver is not always the first suspect. The device may already have failed during firmware enumeration, BAR assignment, bridge-window setup, or slot-dependent Device Path matching.

Short mental model

A PCIe system often looks like this:

CPU / SoC
└─ Root Complex
   ├─ PCI Root Bridge
   │  ├─ Root Port
   │  │  └─ Endpoint: NVMe, NIC, GPU
   │  └─ PCIe Switch
   │     ├─ Endpoint A
   │     └─ Endpoint B
   └─ Firmware PCI bus driver

Firmware scans this topology, reads configuration space, and creates handles and protocols that DXE drivers can consume.

What enumeration does

PCI enumeration answers four practical questions:

1. Which bus/device/function owns this function?
2. What kind of device is it?
3. How much MMIO or I/O resource does it need?
4. Which driver can bind to it?

A typical flow scans BDFs, reads Vendor ID, Device ID, and Class Code, probes BAR sizes, assigns bridge bus numbers, allocates MMIO windows, and installs EFI_PCI_IO_PROTOCOL.

Core terms

TermWhy it matters during debug
BDFLogical address of a PCI function
Configuration SpacePlace where firmware reads IDs, BARs, and capabilities
Vendor ID / Device IDIdentifies the vendor and concrete device
Class CodeIdentifies the device type for generic driver matching
BARDescribes the device MMIO or I/O aperture request
Bridge WindowResource range assigned to devices behind a bridge
Root BridgeFirmware access point for a PCI segment

When a device disappears, start from BDF and configuration space before blaming a higher-level driver.

How this appears in UEFI

In EDK II, PCI usually touches PciHostBridge, PciBusDxe, EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL, and EFI_PCI_IO_PROTOCOL. A device driver usually does not scan the whole bus by itself. It receives a controller handle with PciIo, then Driver Binding calls Supported() and Start().

If PciIo is never installed, the device driver may never get a valid controller to bind.

Practical failure example

An NVMe card disappears after moving it to another PCIe slot. The old boot option is still in NVRAM, but its Device Path contains the old PCI path. Firmware now enumerates the card at a different path, while Boot#### still points to the stale one. BDS selects the right-looking boot option by name, but ConnectController() or LoadImage() fails.

Useful logs include:

- full Boot#### Device Path
- current PCI topology
- Vendor ID / Device ID at the new BDF
- BAR and bridge-window assignment
- whether the handle has EFI_PCI_IO_PROTOCOL

Source-reading checklist

[ ] Was the root bridge enumerated?
[ ] Are bridge bus numbers valid?
[ ] Does Vendor ID read correctly, or is it 0xFFFF?
[ ] Do BAR sizes look reasonable?
[ ] Is the bridge window large enough for downstream BARs?
[ ] Was EFI_PCI_IO_PROTOCOL installed on the handle?
[ ] Does Driver Binding Supported() match the expected Class Code or ID?
[ ] Does the boot Device Path still match the current topology?

Quick takeaway

PCI/PCIe architecture is the base layer for debugging missing devices in firmware. Before changing a device driver, confirm that the device was enumerated, resourced, and exposed through the expected handle and protocol.

Found this article useful?

Share it with someone learning firmware, BIOS/UEFI, or embedded systems, or support the author.

Feedback

Nội dung liên quan

Một số bài viết, ghi chú hoặc project có liên quan đến nội dung bạn vừa đọc.

Biến note thành bài viết hoàn chỉnh

Notes là nơi ghi nhanh khái niệm.