diff --git a/lopper/assists/xlnx_overlay_pl_dt.py b/lopper/assists/xlnx_overlay_pl_dt.py index a190d34a..3c674c53 100644 --- a/lopper/assists/xlnx_overlay_pl_dt.py +++ b/lopper/assists/xlnx_overlay_pl_dt.py @@ -166,6 +166,8 @@ def usage(): print(' --exclude-nodes=[,,...] - Comma-separated list of node paths/labels to exclude') print(' These nodes will be removed from the generated overlay output.') print(' Example: --exclude-nodes=/amba_pl/some_node') + print(' --exclude-overlays=[,,...] - Exclude specific *.dtso files from auto-discovery') + print(' Supports glob patterns (e.g., --exclude-overlays=*.dtso to skip all)') print('\nExamples:') print(' With machine argument:') print(' lopper -O / -f --enhanced /system-top.dts /lopper-gen.dts -- xlnx_overlay_pl_dt /pl.dtsi') @@ -272,6 +274,7 @@ def validate_and_parse_options(options, sdt): node_specs = None exclude_props = None exclude_nodes = None + exclude_overlays = None for arg in optional_args: if arg.startswith("--firmware-name="): firmware_override = arg.split("=", 1)[1] @@ -281,6 +284,11 @@ def validate_and_parse_options(options, sdt): exclude_props = [p.strip() for p in arg.split("=", 1)[1].split(",") if p.strip()] elif arg.startswith("--exclude-nodes="): exclude_nodes = [n.strip() for n in arg.split("=", 1)[1].split(",") if n.strip()] + elif arg.startswith("--exclude-overlays="): + exclude_overlays = [f.strip() for f in arg.split("=", 1)[1].split(",") if f.strip()] + elif arg == "--exclude-overlays": + _error("--exclude-overlays requires a value (e.g., --exclude-overlays=a.dtso,b.dtso)") + sys.exit(1) # Parse arguments based on count try: @@ -350,7 +358,7 @@ def validate_and_parse_options(options, sdt): usage() sys.exit(1) - return platform, config, zynq_platforms, versal_platforms, firmware_override, node_specs, exclude_props, exclude_nodes + return platform, config, zynq_platforms, versal_platforms, firmware_override, node_specs, exclude_props, exclude_nodes, exclude_overlays def validate_amba_pl_node(amba_node): """ @@ -769,10 +777,55 @@ def write_output_files(overlay_tree, sdt, pl_file, dtso_file): - pl.dtso: Copy of pl.dtsi with .dtso extension Note: Modified system device tree (with /amba_pl node removed) is written by lopper itself """ + +def discover_overlay_files(sdt, exclude_overlays=None): + """Auto-discover *.dtso overlay files co-located with system-top.dts. + + Scans the directory containing the input SDT file for files matching + the *.dtso extension and registers them via the same compilation path + used by the -i flag, so fragment_add_for_refs() emits them as overlay + fragments in pl.dtsi automatically. + + Args: + sdt: LopperSDT object with .dts pointing to the input file + exclude_overlays: list of filename patterns to exclude (supports glob) + """ + if not sdt.dts: + return + + sdt_dir = Path(sdt.dts).resolve().parent + overlay_files = sorted(sdt_dir.glob('*.dtso')) + + if not overlay_files: + return + + if exclude_overlays: + overlay_files = [f for f in overlay_files + if not any(f.match(pat) for pat in exclude_overlays)] + + if not overlay_files: + return + + existing = set(sdt.tree._metadata.get('overlay_subtrees', {}).keys()) + new_files = [] + for f in overlay_files: + if f.stem not in existing: + new_files.append(str(f)) + else: + _info(f"Overlay '{f.stem}' already registered (via -i?), skipping") + + if not new_files: + return + + for f in new_files: + print(f"Auto-discovered overlay: {Path(f).name}") + + sdt._compile_overlay_subtrees(new_files, str(sdt_dir)) + def xlnx_generate_overlay_dt(tgt_node, sdt, options): _level(utils.log_setup(options), __name__) # Parse and validate options - platform, config, zynq_platforms, versal_platforms, firmware_override, node_specs, exclude_props, exclude_nodes = validate_and_parse_options(options, sdt) + platform, config, zynq_platforms, versal_platforms, firmware_override, node_specs, exclude_props, exclude_nodes, exclude_overlays = validate_and_parse_options(options, sdt) # Remove SDT-specific properties from overlay automatically if exclude_props is None: @@ -780,6 +833,8 @@ def xlnx_generate_overlay_dt(tgt_node, sdt, options): elif 'address-map' not in exclude_props: exclude_props.append('address-map') + discover_overlay_files(sdt, exclude_overlays) + overlay_tree = LopperTree() print("Starting overlay generation...")