U-Boot PCI BAR Mapping: The Helper Checks Host Windows, Not the BAR’s Own Size
A PCI register mapping returns a pointer, yet the requested register displacement is outside the endpoint’s BAR. Those observations need not contradict each other. In U-Boot v2025.01’s ordinary BAR mapping path, the range check is against the root controller’s PCI region, not a freshly discovered bound for that individual BAR.
This source review is pinned to commit 6d41f0a39d6423c8e57e92ebbe9f8c0333a63f72. It covers ordinary memory BAR mapping without Enhanced Allocation or SR-IOV virtual-function handling. It is not a procedure for probing unknown registers. No configuration-space write, endpoint access, or hardware mapping test was performed.
Name the two nested ranges
A host controller exposes a PCI address window through which the CPU can reach bus resources. An endpoint BAR occupies its own aperture within that larger address space. The first establishes a translation route; the second bounds the endpoint resource that a driver intends to use.
The PCI uclass implementation makes this distinction visible in dm_pci_map_bar. After reading the BAR and adding a requested offset, it forwards the requested length to the bus-to-virtual mapping helper. The source explicitly identifies the check as one against declared PCI ranges rather than the BAR’s own size.
Consequently, a large host window can contain an address that is already beyond the smaller intended BAR. A mapping result is not a certificate that an arbitrary endpoint-relative offset is valid. The driver must know which resource and documented register block it is accessing.

Follow the ordinary BAR path exactly
The function’s bar argument is passed to a configuration-space read as an offset. Do not confuse it with an ordinal BAR number unless the caller converts that number to the correct configuration offset. The nearby dm_pci_read_bar32 helper accepts a barnum and performs such a conversion, but it is a different interface.
For the scoped ordinary memory path, dm_pci_map_bar masks the low attribute bits from the read value to form a bus address. In builds with CONFIG_SYS_PCI_64BIT, it also reads and combines the upper word for a 64-bit memory BAR. Preserve that build condition when investigating an address above the lower 32-bit range.
Before adding the requested offset, the function checks whether that addition would overflow pci_addr_t. That protects one arithmetic operation. It does not determine the aperture size, validate the endpoint’s register layout, or authorize a particular access width.
Keep these observations separate in a review: correct configuration offset, full BAR address reconstruction, overflow-safe displacement, host-window admission, and endpoint-local validity. Passing one does not imply the others.
See what the host-window check actually compares
The dm_pci_bus_to_phys function retrieves the root controller’s region list. If that list is empty, the implementation returns the supplied bus address unchanged. That identity fallback is not independent evidence that the platform has no translation requirement; it is the behavior of this helper when there are no regions to examine.
With regions present, it filters each entry using the supplied mask and flags, rejects an address below the region’s bus start, and computes the address’s offset into the region. It rejects an offset at or beyond the region size, then rejects a length larger than the remaining space.
For the first qualifying region, it returns the region’s CPU physical start plus that offset. The subtraction-based remaining-space check avoids treating a valid start as sufficient when the requested interval crosses the end. But the interval is still measured against that host region, not the endpoint BAR aperture.
Flags are therefore part of the mapping contract, not decoration. Record the caller’s mask and expected region type together with the actual root-controller regions. Looking only at numeric start addresses can hide selection of a different kind of window.
Work through a non-hardware example
Consider a hypothetical memory window beginning at PCI bus address 0x80000000 with size 0x100000. Suppose the intended endpoint BAR starts at that same bus address and has a separately established size of 0x1000. These values are arithmetic examples, not recommended platform assignments.
A request at BAR-relative offset 0x1800 with length 0x100 lies inside the host window but outside that endpoint BAR. The host-region test has enough remaining space to admit it. The endpoint-local test should reject it before an MMIO operation is considered.
For a legitimate endpoint-relative range, use the established BAR size and overflow-safe subtraction: require the offset to lie within the permitted resource and the length not to exceed its remaining space. Then apply any narrower register-block boundary, alignment, access-width, and side-effect rules from the actual device contract.
Do not discover these limits by issuing writes outside the documented aperture. Obtain resource-size evidence through the platform’s reviewed enumeration path or device specification, and preserve its provenance with the driver review.
Do not reduce translation errors to a pointer test
When no matching host region is found, dm_pci_bus_to_phys prints a diagnostic and returns zero. The mapping macro in the pinned PCI header passes that physical result to map_physmem without adding a separate error check.
Whether a particular mapping yields a null pointer therefore depends on additional platform mapping behavior. A generic “pointer is non-null” assertion is not a portable proof that the intended PCI window matched. Preserve translation diagnostics and inspect the platform implementation instead of assuming an errno-style pointer contract that this helper does not provide.
Qualify the nested-boundary contract
A proposed software fixture should cover a valid BAR-local range, a range outside the BAR but inside the host window, a range crossing the host-window end, mismatched region flags, offset-addition overflow, and an empty region list. Record which boundary rejects each case.
The release deliverable should include the endpoint identity, BAR configuration offset and reconstructed address, independently established aperture size, requested displacement and length, root-controller regions, and final mapping path. That evidence explains why a host-reachable address can still be an invalid endpoint register access, without confusing translation coverage with resource ownership.