Thread (30 messages) 30 messages, 3 authors, 2025-03-07

Re: [PATCH v9 3/7] PCI: Add parent_bus_offset to resource_entry

From: Bjorn Helgaas <helgaas@kernel.org>
Date: 2025-02-27 00:08:19
Also in: imx, linux-devicetree, linux-pci, lkml

On Tue, Jan 28, 2025 at 05:07:36PM -0500, Frank Li wrote:
Introduce `parent_bus_offset` in `resource_entry` and a new API,
`pci_add_resource_parent_bus_offset()`, to provide necessary information
for PCI controllers with address translation units.

Typical PCI data flow involves:
  CPU (CPU address) -> Bus Fabric (Intermediate address) ->
  PCI Controller (PCI bus address) -> PCI Bus.

While most bus fabrics preserve address consistency, some modify addresses
to intermediate values. 
s/modify/translate/

Specifically, they *translate* addresses, which means the same offset
is added to every address in the range, as opposed to masking or some
other transformation.

I think we can take advantage of this to simplify the callers of
.cpu_addr_fixup() later.

Ironically, most of the .cpu_addr_fixup() implementations *do* mask
the address, e.g., cdns_plat_cpu_addr_fixup() masks with 0x0fffffff.
But I think this is actually incorrect because masking results in a
many-to-one mapping, e.g.,

  0x42000000 & 0x0fffffff == 0x02000000
  0x52000000 & 0x0fffffff == 0x02000000

But presumably the addresses we pass to cdns_plat_cpu_addr_fixup()
don't cross a 256MB (0x10000000) boundary, so we could accomplish the
same by subtracting 0x40000000:

  0x42000000 - 0x40000000 == 0x02000000
quoted hunk ↗ jump to hunk
+++ b/drivers/pci/of.c
@@ -402,7 +402,17 @@ static int devm_of_pci_get_host_bridge_resources(struct device *dev,
 			res->flags &= ~IORESOURCE_MEM_64;
 		}
 
-		pci_add_resource_offset(resources, res,	res->start - range.pci_addr);
+		/*
+		 * IORESOURCE_IO res->start is io space start address.
+		 * IORESOURCE_MEM res->start is cpu start address, which is the
+		 * same as range.cpu_addr.
+		 *
+		 * Use (range.cpu_addr - range.parent_bus_addr) to align both
+		 * IO and MEM's parent_bus_offset always offset to cpu address.
+		 */
+
+		pci_add_resource_parent_bus_offset(resources, res, res->start - range.pci_addr,
+						   range.cpu_addr - range.parent_bus_addr);
Wrap to fit in 80 columns like the rest of the file.  Will have to
unindent the two lines of arguments to make this work.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help