Lines Matching +full:child +full:- +full:prop +full:- +full:1

3 # Copyright (c) 2019 - 2020 Nordic Semiconductor ASA
6 # SPDX-License-Identifier: BSD-3-Clause
11 # Note: Do not access private (_-prefixed) identifiers from edtlib here (and
25 sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'python-devicetree',
46 with open(args.header_out, "w", encoding="utf-8") as header_file:
58 # Check to see if we have duplicate "zephyr,memory-region" property values.
61 if 'zephyr,memory-region' in node.props:
62 region = node.props['zephyr,memory-region'].val
64 sys.exit(f"ERROR: Duplicate 'zephyr,memory-region' ({region}) properties "
74 out_comment("Node's name with unit-address:")
112 def node_z_path_id(node: edtlib.Node) -> str:
115 # - the root node's path "/" has path identifier "N"
116 # - "/foo" has "N_S_foo"
117 # - "/foo/bar" has "N_S_foo_S_bar"
118 # - "/foo/bar@123" has "N_S_foo_S_bar_123"
126 node.path.split("/")[1:])
131 def parse_args() -> argparse.Namespace:
132 # Returns parsed command-line arguments
135 parser.add_argument("--header-out", required=True,
137 parser.add_argument("--edt-pickle",
143 def write_top_comment(edt: edtlib.EDT) -> None:
160 if len(scc) > 1:
173 def write_utils() -> None:
180 def write_node_comment(node: edtlib.Node) -> None:
209 # themselves couldn't contain C multi-line comments, which is
219 def relativize(path) -> Optional[str]:
235 def write_idents_and_existence(node: edtlib.Node) -> None:
249 out_dt_define(f"{node.z_path_id}_EXISTS", 1)
258 def write_bus(node: edtlib.Node) -> None:
268 out_dt_define(f"{node.z_path_id}_BUS_{str2ident(one_bus)}", 1)
273 def write_special_props(node: edtlib.Node) -> None:
293 def write_ranges(node: edtlib.Node) -> None:
294 # ranges property: edtlib knows the right #address-cells and
295 # #size-cells of parent and child, and can therefore pack the
296 # child & parent addresses and sizes correctly
305 idx_vals.append((f"{path_id}_RANGES_IDX_{i}_EXISTS", 1))
308 idx_vals.append((f"{path_id}_RANGES_IDX_{i}_VAL_CHILD_BUS_FLAGS_EXISTS", 1))
310 idx_value = range.child_bus_addr >> ((range.child_bus_cells - 1) * 32)
316 idx_value = range.child_bus_addr & ((1 << (range.child_bus_cells - 1) * 32) - 1)
337 def write_regs(node: edtlib.Node) -> None:
338 # reg property: edtlib knows the right #address-cells and
339 # #size-cells, and can therefore pack the register base addresses
350 idx_vals.append((f"{path_id}_REG_IDX_{i}_EXISTS", 1))
356 name_vals.append((f"{path_id}_REG_NAME_{reg.name}_EXISTS", 1))
374 def write_interrupts(node: edtlib.Node) -> None:
375 # interrupts property: we have some hard-coded logic for interrupt
385 "interrupt-cells")
390 if irq_type == 1: # GIC_PPI
409 idx_vals.append((f"{path_id}_IRQ_IDX_{i}_EXISTS", 1))
412 idx_vals.append((idx_macro + "_EXISTS", 1))
417 name_vals.append((name_macro + "_EXISTS", 1))
442 def write_compatibles(node: edtlib.Node) -> None:
449 f"{node.z_path_id}_COMPAT_MATCHES_{str2ident(compat)}", 1)
452 out_dt_define(f"{node.z_path_id}_COMPAT_VENDOR_IDX_{i}_EXISTS", 1)
457 out_dt_define(f"{node.z_path_id}_COMPAT_MODEL_IDX_{i}_EXISTS", 1)
461 def write_parent(node: edtlib.Node) -> None:
473 def write_children(node: edtlib.Node) -> None:
476 out_comment("Helper macros for child nodes of this node.")
481 for child in node.children.values():
482 if child.status == "okay":
483 ok_nodes_num = ok_nodes_num + 1
488 " ".join(f"fn(DT_{child.z_path_id})" for child in
492 " DT_DEBRACKET_INTERNAL sep ".join(f"fn(DT_{child.z_path_id})"
493 for child in node.children.values()))
496 " ".join(f"fn(DT_{child.z_path_id}, __VA_ARGS__)"
497 for child in node.children.values()))
500 " DT_DEBRACKET_INTERNAL sep ".join(f"fn(DT_{child.z_path_id}, __VA_ARGS__)"
501 for child in node.children.values()))
504 " ".join(f"fn(DT_{child.z_path_id})"
505 for child in node.children.values() if child.status == "okay"))
508 " DT_DEBRACKET_INTERNAL sep ".join(f"fn(DT_{child.z_path_id})"
509 for child in node.children.values() if child.status == "okay"))
512 " ".join(f"fn(DT_{child.z_path_id}, __VA_ARGS__)"
513 for child in node.children.values() if child.status == "okay"))
516 " DT_DEBRACKET_INTERNAL sep ".join(f"fn(DT_{child.z_path_id}, __VA_ARGS__)"
517 for child in node.children.values() if child.status == "okay"))
520 def write_status(node: edtlib.Node) -> None:
521 out_dt_define(f"{node.z_path_id}_STATUS_{str2ident(node.status)}", 1)
524 def write_pinctrls(node: edtlib.Node) -> None:
525 # Write special macros for pinctrl-<index> and pinctrl-names properties.
527 out_comment("Pin control (pinctrl-<i>, pinctrl-names) properties:")
535 out_dt_define(f"{node.z_path_id}_PINCTRL_IDX_{pc_idx}_EXISTS", 1)
543 # pinctrl-<pc_idx> properties are contiguous, start from 0,
547 out_dt_define(f"{node.z_path_id}_PINCTRL_NAME_{name}_EXISTS", 1)
554 def write_fixed_partitions(node: edtlib.Node) -> None:
555 # Macros for child nodes of each fixed-partitions node.
557 if not (node.parent and "fixed-partitions" in node.parent.compats):
561 out_comment("fixed-partitions identifier:")
563 flash_area_num += 1
566 def write_gpio_hogs(node: edtlib.Node) -> None:
567 # Write special macros for gpio-hog node properties.
576 out_dt_define(f"{macro}_EXISTS", 1)
582 def write_vanilla_props(node: edtlib.Node) -> None:
588 # never-ending amounts of special case code here to skip special
594 for prop_name, prop in node.props.items():
597 val = prop2value(prop)
599 # DT_N_<node-id>_P_<prop-id>
602 if prop.spec.type == 'string':
603 macro2val.update(string_macros(macro, prop.val))
604 # DT_N_<node-id>_P_<prop-id>_IDX_0:
605 # DT_N_<node-id>_P_<prop-id>_IDX_0_EXISTS:
607 # string-array of length 1.
608 macro2val[f"{macro}_IDX_0"] = quote_str(prop.val)
609 macro2val[f"{macro}_IDX_0_EXISTS"] = 1
611 if prop.enum_indices is not None:
612 macro2val.update(enum_macros(prop, macro))
614 if "phandle" in prop.type:
615 macro2val.update(phandle_macros(prop, macro))
616 elif "array" in prop.type:
617 macro2val.update(array_macros(prop, macro))
619 plen = prop_len(prop)
621 # DT_N_<node-id>_P_<prop-id>_FOREACH_PROP_ELEM
626 # DT_N_<node-id>_P_<prop-id>_FOREACH_PROP_ELEM_SEP
632 # DT_N_<node-id>_P_<prop-id>_FOREACH_PROP_ELEM_VARGS
638 # DT_N_<node-id>_P_<prop-id>_FOREACH_PROP_ELEM_SEP_VARGS
644 # DT_N_<node-id>_P_<prop-id>_LEN
647 # DT_N_<node-id>_P_<prop-id>_EXISTS
648 macro2val[f"{macro}_EXISTS"] = 1
660 # The 'macro' argument is the N_<node-id>_P_<prop-id>... part.
664 # DT_N_<node-id>_P_<prop-id>_IDX_<i>_STRING_UNQUOTED
666 # DT_N_<node-id>_P_<prop-id>_IDX_<i>_STRING_TOKEN
668 # DT_N_<node-id>_P_<prop-id>_IDX_<i>_STRING_UPPER_TOKEN
672 def enum_macros(prop: edtlib.Property, macro: str):
673 # Returns a dict of macros for property 'prop' with a defined enum in their dt-binding.
674 # The 'macro' argument is the N_<node-id>_P_<prop-id> part.
676 spec = prop.spec
677 # DT_N_<node-id>_P_<prop-id>_IDX_<i>_ENUM_IDX
678 ret = {f"{macro}_IDX_{i}_ENUM_IDX": index for i, index in enumerate(prop.enum_indices)}
679 …val = prop.val_as_tokens if spec.enum_tokenizable else (prop.val if isinstance(prop.val, list) els…
682 # DT_N_<node-id>_P_<prop-id>_IDX_<i>_EXISTS
683 ret[f"{macro}_IDX_{i}_EXISTS"] = 1
684 # DT_N_<node-id>_P_<prop-id>_IDX_<i>_ENUM_VAL_<val>_EXISTS 1
685 ret[f"{macro}_IDX_{i}_ENUM_VAL_{subval}_EXISTS"] = 1
690 def array_macros(prop: edtlib.Property, macro: str):
691 # Returns a dict of macros for array property 'prop'.
692 # The 'macro' argument is the N_<node-id>_P_<prop-id> part.
695 for i, subval in enumerate(prop.val):
696 # DT_N_<node-id>_P_<prop-id>_IDX_<i>_EXISTS
697 ret[f"{macro}_IDX_{i}_EXISTS"] = 1
699 # DT_N_<node-id>_P_<prop-id>_IDX_<i>
702 # DT_N_<node-id>_P_<prop-id>_IDX_<i>_STRING_...
710 def write_dep_info(node: edtlib.Node) -> None:
711 # Write dependency-related information about the node.
736 def prop2value(prop: edtlib.Property) -> edtlib.PropertyValType:
737 # Gets the macro value for property 'prop', if there is
738 # a single well-defined C rvalue that it can be represented as.
741 if prop.type == "string":
742 return quote_str(prop.val)
744 if prop.type == "int":
745 return prop.val
747 if prop.type == "boolean":
748 return 1 if prop.val else 0
750 if prop.type in ["array", "uint8-array"]:
751 return list2init(f"{val} /* {hex(val)} */" for val in prop.val)
753 if prop.type == "string-array":
754 return list2init(quote_str(val) for val in prop.val)
756 # phandle, phandles, phandle-array, path, compound: nothing
760 def prop_len(prop: edtlib.Property) -> Optional[int]:
769 # This deliberately excludes ranges, dma-ranges, reg and interrupts.
771 # basically nonsense semantically due to #address-cells and
772 # #size-cells for "reg", #interrupt-cells for "interrupts"
773 # and #address-cells, #size-cells and the #address-cells from the
774 # parent node for "ranges" and "dma-ranges".
782 if prop.type in ["phandle", "string"]:
783 # phandle is treated as a phandles of length 1.
784 # string is treated as a string-array of length 1.
785 return 1
787 if (prop.type in ["array", "uint8-array", "string-array",
788 "phandles", "phandle-array"] and
789 prop.name not in ["ranges", "dma-ranges", "reg", "interrupts"]):
790 return len(prop.val)
795 def phandle_macros(prop: edtlib.Property, macro: str) -> dict:
796 # Returns a dict of macros for phandle or phandles property 'prop'.
798 # The 'macro' argument is the N_<node-id>_P_<prop-id> bit.
806 # to use the same macros for phandle, phandles, and phandle-array.
810 if prop.type == "phandle":
811 # A phandle is treated as a phandles with fixed length 1.
812 ret[f"{macro}"] = f"DT_{prop.val.z_path_id}"
813 ret[f"{macro}_IDX_0"] = f"DT_{prop.val.z_path_id}"
814 ret[f"{macro}_IDX_0_PH"] = f"DT_{prop.val.z_path_id}"
815 ret[f"{macro}_IDX_0_EXISTS"] = 1
816 elif prop.type == "phandles":
817 for i, node in enumerate(prop.val):
820 ret[f"{macro}_IDX_{i}_EXISTS"] = 1
821 elif prop.type == "phandle-array":
822 for i, entry in enumerate(prop.val):
824 # Unspecified element. The phandle-array at this index
845 # DT_N_<node-id>_P_<prop-id>_IDX_<i>_EXISTS
846 ret[f"{macro}_IDX_{i}_EXISTS"] = 1
847 # DT_N_<node-id>_P_<prop-id>_IDX_<i>_PH
849 # DT_N_<node-id>_P_<prop-id>_IDX_<i>_VAL_<VAL>
852 ret[f"{macro}_IDX_{i}_VAL_{str2ident(cell)}_EXISTS"] = 1
858 # DT_N_<node-id>_P_<prop-id>_IDX_<i>_EXISTS
859 ret[f"{macro}_IDX_{i}_EXISTS"] = 1
860 # DT_N_<node-id>_P_<prop-id>_IDX_<i>_NAME
862 # DT_N_<node-id>_P_<prop-id>_NAME_<NAME>_PH
864 # DT_N_<node-id>_P_<prop-id>_NAME_<NAME>_EXISTS
865 ret[f"{macro}_NAME_{name}_EXISTS"] = 1
866 # DT_N_<node-id>_P_<prop-id>_NAME_<NAME>_VAL_<VAL>
871 ret[f"{macro}_NAME_{name}_VAL_{cell_ident}_EXISTS"] = 1
877 # Tree-wide information such as chosen nodes is printed here.
883 chosen[f"DT_CHOSEN_{str2ident(name)}_EXISTS"] = 1
890 # Global or tree-wide information, such as number of instances
919 # Helpers for non-INST for-each macros that take node
928 # Helpers for INST versions of for-each macros, which take
930 # avoiding an intermediate node_id --> instance number
942 if compat == "fixed-partitions":
943 for child in node.children.values():
944 if "label" in child.props:
945 label = child.props["label"].val
947 val = f"DT_{child.z_path_id}"
950 out_dt_define(macro + "_EXISTS", 1)
955 out_define(f"DT_COMPAT_HAS_OKAY_{str2ident(compat)}", 1)
967 f"DT_COMPAT_{str2ident(compat)}_BUS_{str2ident(bus)}", 1)
970 def str2ident(s: str) -> str:
973 return re.sub('[-,.@/+]', '_', s.lower())
976 def list2init(l: Iterable[str]) -> str:
987 ) -> str:
990 # The macro will be left-justified to 'width' characters if that
1009 ) -> None:
1024 def out_comment(s: str, blank_before=True) -> None:
1033 # Format multi-line comments like
1049 # Format single-line comments like
1064 def escape(s: str) -> str:
1065 # Backslash-escapes any double quotes, backslashes, and new lines in 's'
1070 def quote_str(s: str) -> str:
1077 def escape_unquoted(s: str) -> str:
1086 def err(s: str) -> NoReturn: