gen_defines: generate ranges defines for PCIe I/O and memory regions
As described in IEEE Std 1275-1994, the PCIe bindings uses the ranges
property to describe the PCI I/O and memory regions.
Write _RANGES_ defines that will be used to determines the I/O and
memory regions from PCIe Controller drivers.
Also exclude "ranges" & "dma-ranges" property's length generation
alogn "reg" and "interrupt".
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
diff --git a/scripts/dts/gen_defines.py b/scripts/dts/gen_defines.py
index 99cf392..86e6198 100755
--- a/scripts/dts/gen_defines.py
+++ b/scripts/dts/gen_defines.py
@@ -355,6 +355,7 @@
# Macros that are special to the devicetree specification
out_comment("Macros for properties that are special in the specification:")
write_regs(node)
+ write_ranges(node)
write_interrupts(node)
write_compatibles(node)
write_status(node)
@@ -364,6 +365,49 @@
write_pinctrls(node)
write_fixed_partitions(node)
+def write_ranges(node):
+ # ranges property: edtlib knows the right #address-cells and
+ # #size-cells of parent and child, and can therefore pack the
+ # child & parent addresses and sizes correctly
+
+ idx_vals = []
+ path_id = node.z_path_id
+
+ if node.ranges is not None:
+ idx_vals.append((f"{path_id}_RANGES_NUM", len(node.ranges)))
+
+ for i,range in enumerate(node.ranges):
+ idx_vals.append((f"{path_id}_RANGES_IDX_{i}_EXISTS", 1))
+
+ if node.bus == "pcie":
+ idx_vals.append((f"{path_id}_RANGES_IDX_{i}_VAL_CHILD_BUS_FLAGS_EXISTS", 1))
+ idx_macro = f"{path_id}_RANGES_IDX_{i}_VAL_CHILD_BUS_FLAGS"
+ idx_value = range.child_bus_addr >> ((range.child_bus_cells - 1) * 32)
+ idx_vals.append((idx_macro,
+ f"{idx_value} /* {hex(idx_value)} */"))
+ if range.child_bus_addr is not None:
+ idx_macro = f"{path_id}_RANGES_IDX_{i}_VAL_CHILD_BUS_ADDRESS"
+ if node.bus == "pcie":
+ idx_value = range.child_bus_addr & ((1 << (range.child_bus_cells - 1) * 32) - 1)
+ else:
+ idx_value = range.child_bus_addr
+ idx_vals.append((idx_macro,
+ f"{idx_value} /* {hex(idx_value)} */"))
+ if range.parent_bus_addr is not None:
+ idx_macro = f"{path_id}_RANGES_IDX_{i}_VAL_PARENT_BUS_ADDRESS"
+ idx_vals.append((idx_macro,
+ f"{range.parent_bus_addr} /* {hex(range.parent_bus_addr)} */"))
+ if range.length is not None:
+ idx_macro = f"{path_id}_RANGES_IDX_{i}_VAL_LENGTH"
+ idx_vals.append((idx_macro,
+ f"{range.length} /* {hex(range.length)} */"))
+
+ for macro, val in idx_vals:
+ out_dt_define(macro, val)
+
+ out_dt_define(f"{path_id}_FOREACH_RANGE(fn)",
+ " ".join(f"fn(DT_{path_id}, {i})" for i,range in enumerate(node.ranges)))
+
def write_regs(node):
# reg property: edtlib knows the right #address-cells and
# #size-cells, and can therefore pack the register base addresses
@@ -682,10 +726,12 @@
# Returns the property's length if and only if we should generate
# a _LEN macro for the property. Otherwise, returns None.
#
- # This deliberately excludes reg and interrupts.
+ # This deliberately excludes ranges, dma-ranges, reg and interrupts.
# While they have array type, their lengths as arrays are
# basically nonsense semantically due to #address-cells and
- # #size-cells for "reg" and #interrupt-cells for "interrupts".
+ # #size-cells for "reg", #interrupt-cells for "interrupts"
+ # and #address-cells, #size-cells and the #address-cells from the
+ # parent node for "ranges" and "dma-ranges".
#
# We have special purpose macros for the number of register blocks
# / interrupt specifiers. Excluding them from this list means
@@ -698,7 +744,7 @@
if (prop.type in ["array", "uint8-array", "string-array",
"phandles", "phandle-array"] and
- prop.name not in ["reg", "interrupts"]):
+ prop.name not in ["ranges", "dma-ranges", "reg", "interrupts"]):
return len(prop.val)
return None