PCIe · Module 2
Hierarchy Domains — Identifying Positions in the Tree
Why a branching PCIe hierarchy needs structured identification: how positions in the tree are named, why identity is hierarchical rather than a flat list, and how a system can host more than one independent hierarchy namespace.
Module 2 has assembled a structure that can grow. Chapter 2.4 showed how Switches branch it and add depth; Chapter 2.5 showed how Bridges extend it past the edge of the architecture. A real system may contain many devices at varying depths across several branches.
That creates a problem the simple tree of Chapter 2.1 could ignore:
Once the hierarchy grows beyond a few direct connections, how is it organised so that software and hardware can identify where a given function actually sits?
A structure you cannot refer to positions within is not usable. Configuration has to be directed somewhere. A log entry has to name which device. A test has to target a particular path. All of that needs identity, and identity for a tree is not the same thing as identity for a list.
1. Why a Flat List Will Not Do
Begin with why the problem is not trivial, because the naive answer seems adequate until you examine it.
The naive answer is to number every device in the system sequentially — device 0, device 1, device 2 — and treat the result as a list. That is sufficient to name things, and insufficient for everything else.
Consider what the structure actually requires. A configuration access must reach a specific function, and Chapter 2.2 established that it does so by originating at the host side and travelling a path — because no universally visible medium exists any more. That means the identity of a target has to be usable for directing something through a branching structure, not merely for labelling it after the fact.
A flat number carries no information about the path. Knowing something is "device 47" tells you nothing about which branch it is on or what it sits behind. The structure would have to be consulted separately every time, and any change to the topology would invalidate the mapping wholesale.
So identity is made hierarchical — it reflects position in the tree. That single decision is what this chapter is about, and it is why the identifiers you will meet later have the shape they do.
2. Positions in a Branching Tree
The structure that needs describing has a specific shape, worth stating precisely.
Each Root Port of the Root Complex anchors a branch. A branch may lead directly to a device, or to a Switch that divides it further, and each of those subdivisions may itself branch again. Every position in the resulting tree has exactly one path back toward the root — a property that follows from it being a tree rather than an arbitrary graph, and one that makes unambiguous identification possible at all.
Two observations from the figure carry weight.
Depth varies within one system. The Endpoint on branch A sits one level from the root; those below the Switch sit deeper. Both are ordinary. An identification scheme must handle a tree of uneven depth rather than assuming a uniform arrangement.
Components that branch create structure that must be accounted for. A Switch does not merely pass traffic — by subdividing a branch it creates further regions of the hierarchy that need to be distinguishable. This is why Switches and Bridges are relevant to a chapter ostensibly about identification: components that branch the tree also extend what has to be named.
3. Hierarchical Identity
The identification model that emerged from PCI, and that PCIe carried forward as part of the software continuity Chapter 1.8 described, locates a function using a hierarchical identifier with three parts:
- a bus component, identifying a region of the hierarchy
- a device component, identifying a position within that region
- a function component, identifying which function of that device is meant
Written together these are commonly referred to as bus/device/function, and you will see the abbreviation BDF used constantly in documentation, logs, and tooling.
Two things about this are worth understanding now, and both are conceptual rather than numeric.
It mirrors the tree. The identifier is not an arbitrary key assigned from a pool — its parts correspond to the structure, which is exactly what makes it usable for directing configuration accesses through a branching hierarchy rather than merely labelling devices.
The addressable unit is the function, not the physical device. Chapter 2.3 flagged this: a single device may present more than one function, each independently identifiable and separately configured. The identifier's third component exists precisely because "which device" is not always a complete answer.
4. More Than One Hierarchy Namespace
There is a further level of organisation worth introducing, and it is where the word domain needs care.
A system is not obliged to contain exactly one PCIe hierarchy. It can host more than one independently identified hierarchy namespace, each with its own root and its own identifier space — so the same bus/device/function values can occur in two of them while referring to entirely different functions. Distinguishing them requires naming the namespace as well as the position within it.
These namespaces are commonly called segments, and also domains — the terminology varies between specifications, operating systems, and tooling, which is the first reason to be careful with the word.
How many such namespaces a given system has, how they are identified, and how software addresses across them are platform and implementation matters that this chapter deliberately does not attempt to specify. The architectural point is only that one system may contain more than one independently identified hierarchy, so an identifier that is unambiguous within a hierarchy is not automatically unambiguous within a system.
5. Common Misconceptions
6. Real Engineering Relevance
Structural identity is the thing that makes a PCIe system discussable, and that turns out to matter constantly in practice.
Configuration has to be directed. Every access that reaches a specific function does so because that function can be named in a way the structure understands. This is the primary consumer of hierarchical identity, and it is why the identifier exists.
Logs and diagnostics name positions. System messages, driver output, and diagnostic tooling identify devices by their position in the hierarchy. An engineer who cannot read that identification cannot tell which physical device a message refers to — a routine and entirely avoidable source of wasted time.
Testbenches target paths, not just devices. Verification frequently needs to exercise a particular position: a function at depth behind a Switch behaves differently under load than a direct-attached one, for reasons Chapter 2.4 established about convergence. Being able to specify which position is being exercised is what makes such tests meaningful.
Reproduction depends on topology. A failure that occurs for a function on one branch may not occur for an equivalent function elsewhere, because what it shares upstream differs. "It fails on this device" is a much weaker report than "it fails at this position in this topology," and only the second is reliably reproducible.
The habit worth forming: when reasoning about a PCIe problem, fix the position before analysing the behaviour. Where something sits in the hierarchy determines what it shares, what it contends with, and what its path back to the root traverses — and none of that is visible from the device's identity alone unless that identity is structural.
7. Understanding Check
8. Summary
A PCIe hierarchy that can branch through Switches and extend through Bridges needs a way to refer to positions within it, because structure without identity is not usable: configuration must be directed somewhere, logs must name something, tests must target something.
A flat list is insufficient, since identity must support directing an access through a branching structure rather than merely labelling devices after the fact. Identity is therefore hierarchical — it mirrors the shape of the tree. A function is located by a bus component identifying a region, a device component identifying a position within it, and a function component identifying which function is meant, commonly written bus/device/function. The addressable unit is the function, because a device may present more than one.
A system may also contain more than one independently identified hierarchy namespace — commonly called a segment or domain — so an identifier unambiguous within one hierarchy is not automatically unambiguous within a system. The word domain carries at least three unrelated meanings in this material and is worth disambiguating on sight.
Hold the model: a PCIe hierarchy is a rooted tree whose components occupy identifiable positions, and the naming model is structured so that transactions, discovery, and resource assignment can refer to where functions live.
9. What Comes Next
Module 2 has now assembled the complete cast and the structure it forms: the map, the root, the leaves, the branching element, the boundary component, and how positions within the result are identified.
Three chapters remain. Chapter 2.7 — The PCIe Fabric takes the whole-structure view: reasoning about complete paths and traffic across the fabric rather than component by component. Chapter 2.8 develops the Link itself in depth, and Chapter 2.9 returns to the switched-versus-shared comparison with enough architectural detail to make the contrast rigorous rather than motivational.
Beyond Module 2, Modules 7 and 8 take up what this chapter deliberately deferred: how a hierarchy is actually discovered, how identifiers are assigned, and what a function's configuration contains.
Browse the full path on the PCIe tutorials index.