Anas Nashif | ed3d7c1 | 2017-04-10 08:53:23 -0400 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
Tomasz Bursztyka | 6a9ebdc | 2018-03-07 15:17:28 +0100 | [diff] [blame] | 2 | # |
| 3 | # Copyright (c) 2017, Linaro Limited |
Bobby Noelte | ca7fc2a | 2018-06-16 20:11:52 +0200 | [diff] [blame] | 4 | # Copyright (c) 2018, Bobby Noelte |
Tomasz Bursztyka | 6a9ebdc | 2018-03-07 15:17:28 +0100 | [diff] [blame] | 5 | # |
| 6 | # SPDX-License-Identifier: Apache-2.0 |
| 7 | # |
Anas Nashif | 6b08141 | 2017-05-20 19:16:39 -0400 | [diff] [blame] | 8 | |
Ulf Magnusson | 7de2f4d | 2019-07-25 09:43:35 +0200 | [diff] [blame] | 9 | # NOTE: This file is part of the old device tree scripts, which will be removed |
| 10 | # later. They are kept to generate some legacy #defines via the |
| 11 | # --deprecated-only flag. |
| 12 | # |
| 13 | # The new scripts are gen_defines.py, edtlib.py, and dtlib.py. |
| 14 | |
Anas Nashif | 6b08141 | 2017-05-20 19:16:39 -0400 | [diff] [blame] | 15 | # vim: ai:ts=4:sw=4 |
| 16 | |
Kumar Gala | 03fb9ff | 2017-10-23 02:32:15 -0500 | [diff] [blame] | 17 | import os, fnmatch |
Andy Gross | bb06316 | 2017-01-29 23:53:17 -0600 | [diff] [blame] | 18 | import re |
| 19 | import yaml |
Anas Nashif | 6b08141 | 2017-05-20 19:16:39 -0400 | [diff] [blame] | 20 | import argparse |
Ulf Magnusson | 3f8616a | 2019-02-12 05:54:58 +0100 | [diff] [blame] | 21 | from collections import defaultdict |
Andy Gross | bb06316 | 2017-01-29 23:53:17 -0600 | [diff] [blame] | 22 | |
| 23 | from devicetree import parse_file |
Bobby Noelte | b6005bf | 2017-12-30 12:06:27 +0100 | [diff] [blame] | 24 | from extract.globals import * |
Kumar Gala | 112b0f5 | 2018-12-04 13:30:20 -0600 | [diff] [blame] | 25 | import extract.globals |
Andy Gross | 70e54f9 | 2017-06-15 13:15:23 -0400 | [diff] [blame] | 26 | |
Bobby Noelte | 08216f5 | 2018-06-16 19:59:39 +0200 | [diff] [blame] | 27 | from extract.clocks import clocks |
Erwan Gouriou | c5ada39 | 2018-09-14 13:33:38 +0200 | [diff] [blame] | 28 | from extract.compatible import compatible |
Bobby Noelte | 08216f5 | 2018-06-16 19:59:39 +0200 | [diff] [blame] | 29 | from extract.interrupts import interrupts |
| 30 | from extract.reg import reg |
| 31 | from extract.flash import flash |
Bobby Noelte | 08216f5 | 2018-06-16 19:59:39 +0200 | [diff] [blame] | 32 | from extract.default import default |
| 33 | |
Ulf Magnusson | a1f1969 | 2019-02-13 02:13:43 +0100 | [diff] [blame] | 34 | |
Ulf Magnusson | f5b17d4 | 2019-02-20 19:32:15 +0100 | [diff] [blame] | 35 | def extract_bus_name(node_path, def_label): |
Ulf Magnusson | 6127f0a | 2019-02-07 16:31:55 +0100 | [diff] [blame] | 36 | label = def_label + '_BUS_NAME' |
Erwan Gouriou | 074c90c | 2018-03-29 17:25:13 +0200 | [diff] [blame] | 37 | prop_alias = {} |
Andy Gross | bb06316 | 2017-01-29 23:53:17 -0600 | [diff] [blame] | 38 | |
Ulf Magnusson | f5b17d4 | 2019-02-20 19:32:15 +0100 | [diff] [blame] | 39 | add_compat_alias(node_path, 'BUS_NAME', label, prop_alias) |
Andy Gross | bb06316 | 2017-01-29 23:53:17 -0600 | [diff] [blame] | 40 | |
Ulf Magnusson | 6127f0a | 2019-02-07 16:31:55 +0100 | [diff] [blame] | 41 | # Generate defines for node aliases |
Ulf Magnusson | f5b17d4 | 2019-02-20 19:32:15 +0100 | [diff] [blame] | 42 | if node_path in aliases: |
Ulf Magnusson | f5ee8f6 | 2019-02-07 15:09:31 +0100 | [diff] [blame] | 43 | add_prop_aliases( |
Ulf Magnusson | f5b17d4 | 2019-02-20 19:32:15 +0100 | [diff] [blame] | 44 | node_path, |
Ulf Magnusson | c631edd | 2019-02-07 15:30:46 +0100 | [diff] [blame] | 45 | lambda alias: str_to_label(alias) + '_BUS_NAME', |
Ulf Magnusson | f5ee8f6 | 2019-02-07 15:09:31 +0100 | [diff] [blame] | 46 | label, |
| 47 | prop_alias) |
Andy Gross | bb06316 | 2017-01-29 23:53:17 -0600 | [diff] [blame] | 48 | |
Ulf Magnusson | f5b17d4 | 2019-02-20 19:32:15 +0100 | [diff] [blame] | 49 | insert_defs(node_path, |
| 50 | {label: '"' + find_parent_prop(node_path, 'label') + '"'}, |
Ulf Magnusson | 6127f0a | 2019-02-07 16:31:55 +0100 | [diff] [blame] | 51 | prop_alias) |
Andy Gross | bb06316 | 2017-01-29 23:53:17 -0600 | [diff] [blame] | 52 | |
Ulf Magnusson | 9eb0d33 | 2019-02-08 19:57:24 +0100 | [diff] [blame] | 53 | |
Ulf Magnusson | f5b17d4 | 2019-02-20 19:32:15 +0100 | [diff] [blame] | 54 | def extract_string_prop(node_path, key, label): |
| 55 | if node_path not in defs: |
Ulf Magnusson | 00c43d4 | 2019-02-07 19:31:07 +0100 | [diff] [blame] | 56 | # Make all defs have the special 'aliases' key, to remove existence |
| 57 | # checks elsewhere |
Ulf Magnusson | f5b17d4 | 2019-02-20 19:32:15 +0100 | [diff] [blame] | 58 | defs[node_path] = {'aliases': {}} |
Ulf Magnusson | 9eb0d33 | 2019-02-08 19:57:24 +0100 | [diff] [blame] | 59 | |
Ulf Magnusson | f5b17d4 | 2019-02-20 19:32:15 +0100 | [diff] [blame] | 60 | defs[node_path][label] = '"' + reduced[node_path]['props'][key] + '"' |
Kumar Gala | 65e72be | 2017-07-07 11:05:05 -0500 | [diff] [blame] | 61 | |
Kumar Gala | 65e72be | 2017-07-07 11:05:05 -0500 | [diff] [blame] | 62 | |
Ulf Magnusson | e04139f | 2019-02-20 21:21:46 +0100 | [diff] [blame] | 63 | def generate_prop_defines(node_path, prop): |
Ulf Magnusson | 79906fc | 2019-02-20 21:29:48 +0100 | [diff] [blame] | 64 | # Generates #defines (and .conf file values) from the prop |
| 65 | # named 'prop' on the device tree node at 'node_path' |
| 66 | |
Ulf Magnusson | f5b17d4 | 2019-02-20 19:32:15 +0100 | [diff] [blame] | 67 | binding = get_binding(node_path) |
Ulf Magnusson | 5b791d1 | 2019-02-20 17:54:33 +0100 | [diff] [blame] | 68 | if 'parent' in binding and 'bus' in binding['parent']: |
| 69 | # If the binding specifies a parent for the node, then include the |
| 70 | # parent in the #define's generated for the properties |
Ulf Magnusson | f5b17d4 | 2019-02-20 19:32:15 +0100 | [diff] [blame] | 71 | parent_path = get_parent_path(node_path) |
Ulf Magnusson | 0a3f00a | 2019-02-27 19:32:08 +0100 | [diff] [blame] | 72 | def_label = 'DT_' + node_label(parent_path) + '_' \ |
| 73 | + node_label(node_path) |
Ulf Magnusson | 5b791d1 | 2019-02-20 17:54:33 +0100 | [diff] [blame] | 74 | else: |
Ulf Magnusson | 0a3f00a | 2019-02-27 19:32:08 +0100 | [diff] [blame] | 75 | def_label = 'DT_' + node_label(node_path) |
Erwan Gouriou | fa47748 | 2017-11-20 16:43:20 +0100 | [diff] [blame] | 76 | |
Ulf Magnusson | f5b17d4 | 2019-02-20 19:32:15 +0100 | [diff] [blame] | 77 | names = prop_names(reduced[node_path], prop) |
Ulf Magnusson | e539479 | 2019-02-18 21:35:23 +0100 | [diff] [blame] | 78 | |
Erwan Gouriou | e099f38 | 2018-04-27 14:40:13 +0200 | [diff] [blame] | 79 | if prop == 'reg': |
Ulf Magnusson | f5b17d4 | 2019-02-20 19:32:15 +0100 | [diff] [blame] | 80 | reg.extract(node_path, names, def_label, 1) |
Bobby Noelte | 08216f5 | 2018-06-16 19:59:39 +0200 | [diff] [blame] | 81 | elif prop == 'interrupts' or prop == 'interrupts-extended': |
Ulf Magnusson | f5b17d4 | 2019-02-20 19:32:15 +0100 | [diff] [blame] | 82 | interrupts.extract(node_path, prop, names, def_label) |
Erwan Gouriou | c5ada39 | 2018-09-14 13:33:38 +0200 | [diff] [blame] | 83 | elif prop == 'compatible': |
Ulf Magnusson | f5b17d4 | 2019-02-20 19:32:15 +0100 | [diff] [blame] | 84 | compatible.extract(node_path, prop, def_label) |
Erwan Gouriou | 93d3a42 | 2018-05-04 14:37:31 +0200 | [diff] [blame] | 85 | elif 'clocks' in prop: |
Ulf Magnusson | f5b17d4 | 2019-02-20 19:32:15 +0100 | [diff] [blame] | 86 | clocks.extract(node_path, prop, def_label) |
Kumar Gala | 30960e6 | 2018-11-01 11:24:36 -0500 | [diff] [blame] | 87 | elif 'pwms' in prop or 'gpios' in prop: |
Ulf Magnusson | f5b17d4 | 2019-02-20 19:32:15 +0100 | [diff] [blame] | 88 | prop_values = reduced[node_path]['props'][prop] |
Ulf Magnusson | b278500 | 2019-02-06 20:49:29 +0100 | [diff] [blame] | 89 | generic = prop[:-1] # Drop the 's' from the prop |
Erwan Gouriou | 93d3a42 | 2018-05-04 14:37:31 +0200 | [diff] [blame] | 90 | |
Kumar Gala | 5c78b93 | 2019-06-19 18:07:05 -0500 | [diff] [blame] | 91 | # Deprecated the non-'S' form |
Ulf Magnusson | f5b17d4 | 2019-02-20 19:32:15 +0100 | [diff] [blame] | 92 | extract_controller(node_path, prop, prop_values, 0, |
Kumar Gala | 5c78b93 | 2019-06-19 18:07:05 -0500 | [diff] [blame] | 93 | def_label, generic, deprecate=True) |
Kumar Gala | 593d628 | 2019-06-19 16:53:52 -0500 | [diff] [blame] | 94 | extract_controller(node_path, prop, prop_values, 0, |
| 95 | def_label, prop) |
Kumar Gala | 5c78b93 | 2019-06-19 18:07:05 -0500 | [diff] [blame] | 96 | # Deprecated the non-'S' form |
Ulf Magnusson | f5b17d4 | 2019-02-20 19:32:15 +0100 | [diff] [blame] | 97 | extract_cells(node_path, prop, prop_values, |
Kumar Gala | 5c78b93 | 2019-06-19 18:07:05 -0500 | [diff] [blame] | 98 | names, 0, def_label, generic, deprecate=True) |
Kumar Gala | 593d628 | 2019-06-19 16:53:52 -0500 | [diff] [blame] | 99 | extract_cells(node_path, prop, prop_values, |
| 100 | names, 0, def_label, prop) |
Andy Gross | 70e54f9 | 2017-06-15 13:15:23 -0400 | [diff] [blame] | 101 | else: |
Ulf Magnusson | f5b17d4 | 2019-02-20 19:32:15 +0100 | [diff] [blame] | 102 | default.extract(node_path, prop, |
Ulf Magnusson | 5b791d1 | 2019-02-20 17:54:33 +0100 | [diff] [blame] | 103 | binding['properties'][prop]['type'], |
Ulf Magnusson | 797eaa7 | 2019-02-18 21:43:55 +0100 | [diff] [blame] | 104 | def_label) |
Andy Gross | bb06316 | 2017-01-29 23:53:17 -0600 | [diff] [blame] | 105 | |
Andy Gross | bb06316 | 2017-01-29 23:53:17 -0600 | [diff] [blame] | 106 | |
Ulf Magnusson | 44467ef | 2019-02-14 09:29:46 +0100 | [diff] [blame] | 107 | def generate_node_defines(node_path): |
Ulf Magnusson | 79906fc | 2019-02-20 21:29:48 +0100 | [diff] [blame] | 108 | # Generates #defines (and .conf file values) from the device |
| 109 | # tree node at 'node_path' |
| 110 | |
Ulf Magnusson | 75c6d2c | 2019-02-18 22:29:46 +0100 | [diff] [blame] | 111 | if get_compat(node_path) not in get_binding_compats(): |
Ulf Magnusson | 44467ef | 2019-02-14 09:29:46 +0100 | [diff] [blame] | 112 | return |
Andy Gross | bb06316 | 2017-01-29 23:53:17 -0600 | [diff] [blame] | 113 | |
Ulf Magnusson | edc1f6a | 2019-02-20 17:12:42 +0100 | [diff] [blame] | 114 | # We extract a few different #defines for a flash partition, so it's easier |
| 115 | # to handle it in one step |
| 116 | if 'partition@' in node_path: |
| 117 | flash.extract_partition(node_path) |
| 118 | return |
| 119 | |
Kumar Gala | bf0f6d9 | 2019-06-21 01:29:57 -0500 | [diff] [blame] | 120 | if get_binding(node_path) is None: |
| 121 | return |
| 122 | |
Ulf Magnusson | 5b791d1 | 2019-02-20 17:54:33 +0100 | [diff] [blame] | 123 | generate_bus_defines(node_path) |
| 124 | |
| 125 | # Generate per-property ('foo = <1 2 3>', etc.) #defines |
Ulf Magnusson | 75c6d2c | 2019-02-18 22:29:46 +0100 | [diff] [blame] | 126 | for yaml_prop, yaml_val in get_binding(node_path)['properties'].items(): |
Kumar Gala | 3105283 | 2019-07-10 12:28:23 -0500 | [diff] [blame] | 127 | if yaml_prop.startswith("#") or yaml_prop.endswith("-map"): |
Ulf Magnusson | af3580c | 2019-02-18 13:39:03 +0100 | [diff] [blame] | 128 | continue |
Kumar Gala | 6fd3fbb | 2018-10-30 14:53:02 -0500 | [diff] [blame] | 129 | |
Ulf Magnusson | af3580c | 2019-02-18 13:39:03 +0100 | [diff] [blame] | 130 | match = False |
| 131 | |
| 132 | # Handle each property individually, this ends up handling common |
| 133 | # patterns for things like reg, interrupts, etc that we don't need |
| 134 | # any special case handling at a node level |
Ulf Magnusson | 75c6d2c | 2019-02-18 22:29:46 +0100 | [diff] [blame] | 135 | for prop in reduced[node_path]['props']: |
Ulf Magnusson | 75c6d2c | 2019-02-18 22:29:46 +0100 | [diff] [blame] | 136 | if re.fullmatch(yaml_prop, prop): |
Ulf Magnusson | af3580c | 2019-02-18 13:39:03 +0100 | [diff] [blame] | 137 | match = True |
Ulf Magnusson | e04139f | 2019-02-20 21:21:46 +0100 | [diff] [blame] | 138 | generate_prop_defines(node_path, prop) |
Andy Gross | bb06316 | 2017-01-29 23:53:17 -0600 | [diff] [blame] | 139 | |
Ulf Magnusson | af3580c | 2019-02-18 13:39:03 +0100 | [diff] [blame] | 140 | # Handle the case that we have a boolean property, but its not |
| 141 | # in the dts |
Ulf Magnusson | 75c6d2c | 2019-02-18 22:29:46 +0100 | [diff] [blame] | 142 | if not match and yaml_val['type'] == 'boolean': |
Ulf Magnusson | e04139f | 2019-02-20 21:21:46 +0100 | [diff] [blame] | 143 | generate_prop_defines(node_path, yaml_prop) |
Tomasz Bursztyka | 7ef3dde | 2018-03-07 15:03:27 +0100 | [diff] [blame] | 144 | |
Ulf Magnusson | 7bb57fe | 2019-02-18 20:39:51 +0100 | [diff] [blame] | 145 | |
Ulf Magnusson | 5b791d1 | 2019-02-20 17:54:33 +0100 | [diff] [blame] | 146 | def generate_bus_defines(node_path): |
| 147 | # Generates any node-level #defines related to |
| 148 | # |
| 149 | # parent: |
| 150 | # bus: ... |
| 151 | |
| 152 | binding = get_binding(node_path) |
| 153 | if not ('parent' in binding and 'bus' in binding['parent']): |
| 154 | return |
| 155 | |
Ulf Magnusson | f5b17d4 | 2019-02-20 19:32:15 +0100 | [diff] [blame] | 156 | parent_path = get_parent_path(node_path) |
Ulf Magnusson | 5b791d1 | 2019-02-20 17:54:33 +0100 | [diff] [blame] | 157 | |
| 158 | # Check that parent has matching child bus value |
| 159 | try: |
| 160 | parent_binding = get_binding(parent_path) |
| 161 | parent_bus = parent_binding['child']['bus'] |
Ulf Magnusson | 399c04c | 2019-03-19 18:47:39 +0100 | [diff] [blame] | 162 | except (KeyError, TypeError): |
Ulf Magnusson | 5b791d1 | 2019-02-20 17:54:33 +0100 | [diff] [blame] | 163 | raise Exception("{0} defines parent {1} as bus master, but {1} is not " |
| 164 | "configured as bus master in binding" |
| 165 | .format(node_path, parent_path)) |
| 166 | |
| 167 | if parent_bus != binding['parent']['bus']: |
| 168 | raise Exception("{0} defines parent {1} as {2} bus master, but {1} is " |
| 169 | "configured as {3} bus master" |
| 170 | .format(node_path, parent_path, |
| 171 | binding['parent']['bus'], parent_bus)) |
| 172 | |
Ulf Magnusson | 5b791d1 | 2019-02-20 17:54:33 +0100 | [diff] [blame] | 173 | # Generate *_BUS_NAME #define |
| 174 | extract_bus_name( |
| 175 | node_path, |
Ulf Magnusson | 0a3f00a | 2019-02-27 19:32:08 +0100 | [diff] [blame] | 176 | 'DT_' + node_label(parent_path) + '_' + node_label(node_path)) |
Ulf Magnusson | 5b791d1 | 2019-02-20 17:54:33 +0100 | [diff] [blame] | 177 | |
| 178 | |
Ulf Magnusson | 7bb57fe | 2019-02-18 20:39:51 +0100 | [diff] [blame] | 179 | def prop_names(node, prop_name): |
| 180 | # Returns a list with the *-names for the property (reg-names, |
| 181 | # interrupt-names, etc.) The list is copied so that it can be modified |
| 182 | # in-place later without stomping on the device tree data. |
| 183 | |
Kumar Gala | 1c55882 | 2019-06-06 15:36:26 -0500 | [diff] [blame] | 184 | # The first case turns 'interrupts' into 'interrupt-names' |
| 185 | names = node['props'].get(prop_name[:-1] + '-names', []) or \ |
| 186 | node['props'].get(prop_name + '-names', []) |
Ulf Magnusson | 7bb57fe | 2019-02-18 20:39:51 +0100 | [diff] [blame] | 187 | |
| 188 | if isinstance(names, list): |
| 189 | # Allow the list of names to be modified in-place without |
| 190 | # stomping on the property |
| 191 | return names.copy() |
| 192 | |
| 193 | return [names] |
| 194 | |
| 195 | |
Ulf Magnusson | 732fa65 | 2019-02-13 09:13:40 +0100 | [diff] [blame] | 196 | def merge_properties(parent, fname, to_dict, from_dict): |
| 197 | # Recursively merges the 'from_dict' dictionary into 'to_dict', to |
| 198 | # implement !include. 'parent' is the current parent key being looked at. |
| 199 | # 'fname' is the top-level .yaml file. |
Andy Gross | bb06316 | 2017-01-29 23:53:17 -0600 | [diff] [blame] | 200 | |
Ulf Magnusson | 399c04c | 2019-03-19 18:47:39 +0100 | [diff] [blame] | 201 | for k in from_dict: |
Ulf Magnusson | 14de997 | 2019-02-13 08:51:34 +0100 | [diff] [blame] | 202 | if (k in to_dict and isinstance(to_dict[k], dict) |
Ulf Magnusson | 732fa65 | 2019-02-13 09:13:40 +0100 | [diff] [blame] | 203 | and isinstance(from_dict[k], dict)): |
| 204 | merge_properties(k, fname, to_dict[k], from_dict[k]) |
Erwan Gouriou | 104553d | 2017-11-23 08:48:10 +0100 | [diff] [blame] | 205 | else: |
Ulf Magnusson | 14de997 | 2019-02-13 08:51:34 +0100 | [diff] [blame] | 206 | to_dict[k] = from_dict[k] |
Andy Gross | ad70493 | 2017-08-18 00:04:05 -0500 | [diff] [blame] | 207 | |
Ulf Magnusson | 298b443 | 2019-02-13 08:23:34 +0100 | [diff] [blame] | 208 | # Warn when overriding a property and changing its value... |
Ulf Magnusson | 14de997 | 2019-02-13 08:51:34 +0100 | [diff] [blame] | 209 | if (k in to_dict and to_dict[k] != from_dict[k] and |
Ulf Magnusson | 298b443 | 2019-02-13 08:23:34 +0100 | [diff] [blame] | 210 | # ...unless it's the 'title', 'description', or 'version' |
Anas Nashif | f2cb20c | 2019-06-18 14:45:40 -0400 | [diff] [blame] | 211 | # property. These are overridden deliberately. |
Ulf Magnusson | 298b443 | 2019-02-13 08:23:34 +0100 | [diff] [blame] | 212 | not k in {'title', 'version', 'description'} and |
| 213 | # Also allow the category to be changed from 'optional' to |
| 214 | # 'required' without a warning |
Ulf Magnusson | 14de997 | 2019-02-13 08:51:34 +0100 | [diff] [blame] | 215 | not (k == "category" and to_dict[k] == "optional" and |
| 216 | from_dict[k] == "required")): |
Ulf Magnusson | 298b443 | 2019-02-13 08:23:34 +0100 | [diff] [blame] | 217 | |
| 218 | print("extract_dts_includes.py: {}('{}') merge of property " |
| 219 | "'{}': '{}' overwrites '{}'" |
Ulf Magnusson | 14de997 | 2019-02-13 08:51:34 +0100 | [diff] [blame] | 220 | .format(fname, parent, k, from_dict[k], to_dict[k])) |
Ulf Magnusson | 298b443 | 2019-02-13 08:23:34 +0100 | [diff] [blame] | 221 | |
Erwan Gouriou | 1ee8eea | 2017-11-22 13:26:04 +0100 | [diff] [blame] | 222 | |
Ulf Magnusson | 6a15130 | 2019-02-12 05:20:08 +0100 | [diff] [blame] | 223 | def merge_included_bindings(fname, node): |
Ulf Magnusson | 2b8766d | 2019-02-12 06:32:34 +0100 | [diff] [blame] | 224 | # Recursively merges properties from files !include'd from the 'inherits' |
| 225 | # section of the binding. 'fname' is the path to the top-level binding |
| 226 | # file, and 'node' the current top-level YAML node being processed. |
Andy Gross | ad70493 | 2017-08-18 00:04:05 -0500 | [diff] [blame] | 227 | |
Ulf Magnusson | b29a5b0 | 2019-02-12 06:40:30 +0100 | [diff] [blame] | 228 | check_binding_properties(node) |
Bobby Noelte | ca7fc2a | 2018-06-16 20:11:52 +0200 | [diff] [blame] | 229 | |
Bobby Noelte | 58967c7 | 2018-04-15 11:50:21 +0200 | [diff] [blame] | 230 | if 'inherits' in node: |
Ulf Magnusson | 298b443 | 2019-02-13 08:23:34 +0100 | [diff] [blame] | 231 | for inherited in node.pop('inherits'): |
| 232 | inherited = merge_included_bindings(fname, inherited) |
Ulf Magnusson | 732fa65 | 2019-02-13 09:13:40 +0100 | [diff] [blame] | 233 | merge_properties(None, fname, inherited, node) |
Ulf Magnusson | 298b443 | 2019-02-13 08:23:34 +0100 | [diff] [blame] | 234 | node = inherited |
Ulf Magnusson | b29a5b0 | 2019-02-12 06:40:30 +0100 | [diff] [blame] | 235 | |
Erwan Gouriou | 104553d | 2017-11-23 08:48:10 +0100 | [diff] [blame] | 236 | return node |
Andy Gross | ad70493 | 2017-08-18 00:04:05 -0500 | [diff] [blame] | 237 | |
| 238 | |
Ulf Magnusson | b29a5b0 | 2019-02-12 06:40:30 +0100 | [diff] [blame] | 239 | def check_binding_properties(node): |
| 240 | # Checks that the top-level YAML node 'node' has the expected properties. |
| 241 | # Prints warnings and substitutes defaults otherwise. |
| 242 | |
| 243 | if 'title' not in node: |
| 244 | print("extract_dts_includes.py: node without 'title' -", node) |
| 245 | |
Ulf Magnusson | 0ec0c84 | 2019-07-19 23:59:17 +0200 | [diff] [blame] | 246 | for prop in 'title', 'description': |
Ulf Magnusson | b29a5b0 | 2019-02-12 06:40:30 +0100 | [diff] [blame] | 247 | if prop not in node: |
| 248 | node[prop] = "<unknown {}>".format(prop) |
| 249 | print("extract_dts_includes.py: '{}' property missing " |
| 250 | "in '{}' binding. Using '{}'." |
| 251 | .format(prop, node['title'], node[prop])) |
| 252 | |
| 253 | if 'id' in node: |
| 254 | print("extract_dts_includes.py: WARNING: id field set " |
| 255 | "in '{}', should be removed.".format(node['title'])) |
| 256 | |
| 257 | |
Kumar Gala | 561d6dd | 2019-02-08 10:10:57 -0600 | [diff] [blame] | 258 | def define_str(name, value, value_tabs, is_deprecated=False): |
Ulf Magnusson | 298f9e1 | 2019-02-07 23:10:14 +0100 | [diff] [blame] | 259 | line = "#define " + name |
Kumar Gala | 561d6dd | 2019-02-08 10:10:57 -0600 | [diff] [blame] | 260 | if is_deprecated: |
| 261 | line += " __DEPRECATED_MACRO " |
Ulf Magnusson | 298f9e1 | 2019-02-07 23:10:14 +0100 | [diff] [blame] | 262 | return line + (value_tabs - len(line)//8)*'\t' + str(value) + '\n' |
Andy Gross | 70e54f9 | 2017-06-15 13:15:23 -0400 | [diff] [blame] | 263 | |
Andy Gross | bb06316 | 2017-01-29 23:53:17 -0600 | [diff] [blame] | 264 | |
Ulf Magnusson | 72f0125 | 2019-02-07 20:03:56 +0100 | [diff] [blame] | 265 | def write_conf(f): |
Ulf Magnusson | 00c43d4 | 2019-02-07 19:31:07 +0100 | [diff] [blame] | 266 | for node in sorted(defs): |
Ulf Magnusson | 72f0125 | 2019-02-07 20:03:56 +0100 | [diff] [blame] | 267 | f.write('# ' + node.split('/')[-1] + '\n') |
Anas Nashif | b60ff2f | 2017-05-20 19:44:46 -0400 | [diff] [blame] | 268 | |
Ulf Magnusson | 00c43d4 | 2019-02-07 19:31:07 +0100 | [diff] [blame] | 269 | for prop in sorted(defs[node]): |
Kumar Gala | 1f1282a | 2019-02-09 06:30:51 -0600 | [diff] [blame] | 270 | if prop != 'aliases' and prop.startswith("DT_"): |
Ulf Magnusson | 72f0125 | 2019-02-07 20:03:56 +0100 | [diff] [blame] | 271 | f.write('%s=%s\n' % (prop, defs[node][prop])) |
Anas Nashif | b60ff2f | 2017-05-20 19:44:46 -0400 | [diff] [blame] | 272 | |
Ulf Magnusson | 00c43d4 | 2019-02-07 19:31:07 +0100 | [diff] [blame] | 273 | for alias in sorted(defs[node]['aliases']): |
| 274 | alias_target = defs[node]['aliases'][alias] |
Kumar Gala | e3e87f6 | 2019-02-08 16:03:44 -0600 | [diff] [blame] | 275 | if alias_target not in defs[node]: |
| 276 | alias_target = defs[node]['aliases'][alias_target] |
Kumar Gala | 1f1282a | 2019-02-09 06:30:51 -0600 | [diff] [blame] | 277 | if alias.startswith("DT_"): |
| 278 | f.write('%s=%s\n' % (alias, defs[node].get(alias_target))) |
Ulf Magnusson | 00c43d4 | 2019-02-07 19:31:07 +0100 | [diff] [blame] | 279 | |
Ulf Magnusson | 72f0125 | 2019-02-07 20:03:56 +0100 | [diff] [blame] | 280 | f.write('\n') |
Tomasz Bursztyka | 1134393 | 2018-03-07 11:15:00 +0100 | [diff] [blame] | 281 | |
Anas Nashif | b60ff2f | 2017-05-20 19:44:46 -0400 | [diff] [blame] | 282 | |
Ulf Magnusson | a72e451 | 2019-07-25 01:05:54 +0200 | [diff] [blame] | 283 | def write_header(f, deprecated_only): |
Ulf Magnusson | 72f0125 | 2019-02-07 20:03:56 +0100 | [diff] [blame] | 284 | f.write('''\ |
Sebastian Bøe | 361daf8 | 2019-01-24 10:18:05 +0100 | [diff] [blame] | 285 | /********************************************** |
| 286 | * Generated include file |
| 287 | * DO NOT MODIFY |
| 288 | */ |
| 289 | #ifndef GENERATED_DTS_BOARD_UNFIXED_H |
| 290 | #define GENERATED_DTS_BOARD_UNFIXED_H |
Ulf Magnusson | 0e922bf | 2019-02-07 20:11:23 +0100 | [diff] [blame] | 291 | ''') |
Andy Gross | bb06316 | 2017-01-29 23:53:17 -0600 | [diff] [blame] | 292 | |
Ulf Magnusson | 638e89b | 2019-02-07 22:38:24 +0100 | [diff] [blame] | 293 | def max_dict_key(dct): |
| 294 | return max(len(key) for key in dct) |
| 295 | |
Ulf Magnusson | 0e922bf | 2019-02-07 20:11:23 +0100 | [diff] [blame] | 296 | for node in sorted(defs): |
| 297 | f.write('/* ' + node.split('/')[-1] + ' */\n') |
Andy Gross | bb06316 | 2017-01-29 23:53:17 -0600 | [diff] [blame] | 298 | |
Ulf Magnusson | 638e89b | 2019-02-07 22:38:24 +0100 | [diff] [blame] | 299 | maxlen = max_dict_key(defs[node]) |
Ulf Magnusson | 0e922bf | 2019-02-07 20:11:23 +0100 | [diff] [blame] | 300 | if defs[node]['aliases']: |
Ulf Magnusson | 638e89b | 2019-02-07 22:38:24 +0100 | [diff] [blame] | 301 | maxlen = max(maxlen, max_dict_key(defs[node]['aliases'])) |
| 302 | maxlen += len('#define ') |
Aska Wu | 729a7b1 | 2017-09-13 17:53:18 +0800 | [diff] [blame] | 303 | |
Ulf Magnusson | 638e89b | 2019-02-07 22:38:24 +0100 | [diff] [blame] | 304 | value_tabs = (maxlen + 8)//8 # Tabstop index for value |
| 305 | if 8*value_tabs - maxlen <= 2: |
| 306 | # Add some minimum room between the macro name and the value |
| 307 | value_tabs += 1 |
Andy Gross | bb06316 | 2017-01-29 23:53:17 -0600 | [diff] [blame] | 308 | |
Ulf Magnusson | 0e922bf | 2019-02-07 20:11:23 +0100 | [diff] [blame] | 309 | for prop in sorted(defs[node]): |
| 310 | if prop != 'aliases': |
Kumar Gala | 08a5f9f | 2019-06-22 10:38:30 -0500 | [diff] [blame] | 311 | deprecated_warn = False |
| 312 | if prop in deprecated_main: |
| 313 | deprecated_warn = True |
Kumar Gala | 81072b5 | 2019-06-21 13:15:13 -0500 | [diff] [blame] | 314 | if not prop.startswith('DT_'): |
| 315 | deprecated_warn = True |
Ulf Magnusson | a72e451 | 2019-07-25 01:05:54 +0200 | [diff] [blame] | 316 | if deprecated_only and not deprecated_warn: |
Kumar Gala | 4d2625c | 2019-07-10 07:41:50 -0500 | [diff] [blame] | 317 | continue |
Kumar Gala | 08a5f9f | 2019-06-22 10:38:30 -0500 | [diff] [blame] | 318 | f.write(define_str(prop, defs[node][prop], value_tabs, deprecated_warn)) |
Anas Nashif | b60ff2f | 2017-05-20 19:44:46 -0400 | [diff] [blame] | 319 | |
Ulf Magnusson | 0e922bf | 2019-02-07 20:11:23 +0100 | [diff] [blame] | 320 | for alias in sorted(defs[node]['aliases']): |
| 321 | alias_target = defs[node]['aliases'][alias] |
Kumar Gala | 561d6dd | 2019-02-08 10:10:57 -0600 | [diff] [blame] | 322 | deprecated_warn = False |
| 323 | # Mark any non-DT_ prefixed define as deprecated except |
| 324 | # for now we special case LED, SW, and *PWM_LED* |
Kumar Gala | 81072b5 | 2019-06-21 13:15:13 -0500 | [diff] [blame] | 325 | if not alias.startswith('DT_'): |
Kumar Gala | 561d6dd | 2019-02-08 10:10:57 -0600 | [diff] [blame] | 326 | deprecated_warn = True |
Kumar Gala | 01e54a5 | 2019-06-07 15:36:57 -0500 | [diff] [blame] | 327 | if alias in deprecated: |
| 328 | deprecated_warn = True |
Ulf Magnusson | a72e451 | 2019-07-25 01:05:54 +0200 | [diff] [blame] | 329 | if deprecated_only and not deprecated_warn: |
Kumar Gala | 4d2625c | 2019-07-10 07:41:50 -0500 | [diff] [blame] | 330 | continue |
Kumar Gala | 561d6dd | 2019-02-08 10:10:57 -0600 | [diff] [blame] | 331 | f.write(define_str(alias, alias_target, value_tabs, deprecated_warn)) |
Andy Gross | bb06316 | 2017-01-29 23:53:17 -0600 | [diff] [blame] | 332 | |
Ulf Magnusson | 0e922bf | 2019-02-07 20:11:23 +0100 | [diff] [blame] | 333 | f.write('\n') |
| 334 | |
| 335 | f.write('#endif\n') |
Anas Nashif | 6b08141 | 2017-05-20 19:16:39 -0400 | [diff] [blame] | 336 | |
Andy Gross | 70e54f9 | 2017-06-15 13:15:23 -0400 | [diff] [blame] | 337 | |
Ulf Magnusson | a1f1969 | 2019-02-13 02:13:43 +0100 | [diff] [blame] | 338 | def load_bindings(root, binding_dirs): |
| 339 | find_binding_files(binding_dirs) |
Ulf Magnusson | 32e6565 | 2019-02-13 02:44:39 +0100 | [diff] [blame] | 340 | dts_compats = all_compats(root) |
Ulf Magnusson | a1f1969 | 2019-02-13 02:13:43 +0100 | [diff] [blame] | 341 | |
Ulf Magnusson | 32e6565 | 2019-02-13 02:44:39 +0100 | [diff] [blame] | 342 | compat_to_binding = {} |
| 343 | # Maps buses to dictionaries that map compats to YAML nodes |
| 344 | bus_to_binding = defaultdict(dict) |
| 345 | compats = [] |
Andy Gross | 70e54f9 | 2017-06-15 13:15:23 -0400 | [diff] [blame] | 346 | |
Ulf Magnusson | 35b3d44 | 2019-02-13 04:37:59 +0100 | [diff] [blame] | 347 | # Add '!include foo.yaml' handling |
Michael Scott | 4278bf5 | 2019-03-13 15:04:40 -0700 | [diff] [blame] | 348 | yaml.Loader.add_constructor('!include', yaml_include) |
Ulf Magnusson | 35b3d44 | 2019-02-13 04:37:59 +0100 | [diff] [blame] | 349 | |
Ulf Magnusson | 32e6565 | 2019-02-13 02:44:39 +0100 | [diff] [blame] | 350 | loaded_yamls = set() |
| 351 | |
| 352 | for file in binding_files: |
| 353 | # Extract compat from 'constraint:' line |
| 354 | for line in open(file, 'r', encoding='utf-8'): |
| 355 | match = re.match(r'\s+constraint:\s*"([^"]*)"', line) |
| 356 | if match: |
| 357 | break |
| 358 | else: |
| 359 | # No 'constraint:' line found. Move on to next yaml file. |
| 360 | continue |
| 361 | |
| 362 | compat = match.group(1) |
| 363 | if compat not in dts_compats or file in loaded_yamls: |
| 364 | # The compat does not appear in the device tree, or the yaml |
| 365 | # file has already been loaded |
| 366 | continue |
| 367 | |
| 368 | # Found a binding (.yaml file) for a 'compatible' value that |
| 369 | # appears in DTS. Load it. |
| 370 | |
| 371 | loaded_yamls.add(file) |
| 372 | |
| 373 | if compat not in compats: |
| 374 | compats.append(compat) |
| 375 | |
| 376 | with open(file, 'r', encoding='utf-8') as yf: |
Michael Scott | 4278bf5 | 2019-03-13 15:04:40 -0700 | [diff] [blame] | 377 | binding = merge_included_bindings(file, |
| 378 | yaml.load(yf, Loader=yaml.Loader)) |
Ulf Magnusson | 32e6565 | 2019-02-13 02:44:39 +0100 | [diff] [blame] | 379 | |
| 380 | if 'parent' in binding: |
| 381 | bus_to_binding[binding['parent']['bus']][compat] = binding |
Henrik Brix Andersen | f9dd536 | 2019-03-24 20:32:42 +0100 | [diff] [blame] | 382 | |
| 383 | compat_to_binding[compat] = binding |
Ulf Magnusson | 32e6565 | 2019-02-13 02:44:39 +0100 | [diff] [blame] | 384 | |
| 385 | if not compat_to_binding: |
| 386 | raise Exception("No bindings found in '{}'".format(binding_dirs)) |
| 387 | |
| 388 | extract.globals.bindings = compat_to_binding |
| 389 | extract.globals.bus_bindings = bus_to_binding |
Ulf Magnusson | 59a0c43 | 2019-02-21 21:34:45 +0100 | [diff] [blame] | 390 | extract.globals.binding_compats = compats |
Tomasz Bursztyka | 7ef3dde | 2018-03-07 15:03:27 +0100 | [diff] [blame] | 391 | |
| 392 | |
Ulf Magnusson | a1f1969 | 2019-02-13 02:13:43 +0100 | [diff] [blame] | 393 | def find_binding_files(binding_dirs): |
| 394 | # Initializes the global 'binding_files' variable with a list of paths to |
| 395 | # binding (.yaml) files |
| 396 | |
| 397 | global binding_files |
| 398 | |
| 399 | binding_files = [] |
| 400 | |
| 401 | for binding_dir in binding_dirs: |
Ulf Magnusson | 399c04c | 2019-03-19 18:47:39 +0100 | [diff] [blame] | 402 | for root, _, filenames in os.walk(binding_dir): |
Ulf Magnusson | a1f1969 | 2019-02-13 02:13:43 +0100 | [diff] [blame] | 403 | for filename in fnmatch.filter(filenames, '*.yaml'): |
| 404 | binding_files.append(os.path.join(root, filename)) |
| 405 | |
| 406 | |
Ulf Magnusson | 35b3d44 | 2019-02-13 04:37:59 +0100 | [diff] [blame] | 407 | def yaml_include(loader, node): |
| 408 | # Implements !include. Returns a list with the top-level YAML structures |
| 409 | # for the included files (a single-element list if there's just one file). |
| 410 | |
| 411 | if isinstance(node, yaml.ScalarNode): |
| 412 | # !include foo.yaml |
| 413 | return [load_binding_file(loader.construct_scalar(node))] |
| 414 | |
| 415 | if isinstance(node, yaml.SequenceNode): |
| 416 | # !include [foo.yaml, bar.yaml] |
| 417 | return [load_binding_file(fname) |
| 418 | for fname in loader.construct_sequence(node)] |
| 419 | |
Ulf Magnusson | f0eeb11 | 2019-02-13 07:46:03 +0100 | [diff] [blame] | 420 | yaml_inc_error("Error: unrecognised node type in !include statement") |
Ulf Magnusson | 35b3d44 | 2019-02-13 04:37:59 +0100 | [diff] [blame] | 421 | |
| 422 | |
| 423 | def load_binding_file(fname): |
| 424 | # yaml_include() helper for loading an !include'd file. !include takes just |
| 425 | # the basename of the file, so we need to make sure that there aren't |
| 426 | # multiple candidates. |
| 427 | |
| 428 | filepaths = [filepath for filepath in binding_files |
| 429 | if os.path.basename(filepath) == os.path.basename(fname)] |
| 430 | |
| 431 | if not filepaths: |
Ulf Magnusson | f0eeb11 | 2019-02-13 07:46:03 +0100 | [diff] [blame] | 432 | yaml_inc_error("Error: unknown file name '{}' in !include statement" |
| 433 | .format(fname)) |
Ulf Magnusson | 35b3d44 | 2019-02-13 04:37:59 +0100 | [diff] [blame] | 434 | |
| 435 | if len(filepaths) > 1: |
Ulf Magnusson | f0eeb11 | 2019-02-13 07:46:03 +0100 | [diff] [blame] | 436 | yaml_inc_error("Error: multiple candidates for file name '{}' in " |
| 437 | "!include statement: {}".format(fname, filepaths)) |
Ulf Magnusson | 35b3d44 | 2019-02-13 04:37:59 +0100 | [diff] [blame] | 438 | |
| 439 | with open(filepaths[0], 'r', encoding='utf-8') as f: |
Michael Scott | 4278bf5 | 2019-03-13 15:04:40 -0700 | [diff] [blame] | 440 | return yaml.load(f, Loader=yaml.Loader) |
Ulf Magnusson | 35b3d44 | 2019-02-13 04:37:59 +0100 | [diff] [blame] | 441 | |
| 442 | |
Ulf Magnusson | f0eeb11 | 2019-02-13 07:46:03 +0100 | [diff] [blame] | 443 | def yaml_inc_error(msg): |
| 444 | # Helper for reporting errors in the !include implementation |
| 445 | |
| 446 | raise yaml.constructor.ConstructorError(None, None, msg) |
| 447 | |
| 448 | |
Ulf Magnusson | cbf9afc | 2019-02-14 05:53:03 +0100 | [diff] [blame] | 449 | def generate_defines(): |
Ulf Magnusson | 79906fc | 2019-02-20 21:29:48 +0100 | [diff] [blame] | 450 | # Generates #defines (and .conf file values) from DTS |
| 451 | |
Marc Herbert | 73cb0bf | 2019-03-06 11:43:37 -0800 | [diff] [blame] | 452 | # sorted() otherwise Python < 3.6 randomizes the order of the flash |
| 453 | # partition table |
| 454 | for node_path in sorted(reduced.keys()): |
Ulf Magnusson | 858701f | 2019-02-19 09:12:14 +0100 | [diff] [blame] | 455 | generate_node_defines(node_path) |
Andy Gross | 70e54f9 | 2017-06-15 13:15:23 -0400 | [diff] [blame] | 456 | |
Ulf Magnusson | 87193b0 | 2019-02-07 17:50:44 +0100 | [diff] [blame] | 457 | if not defs: |
Andy Gross | 70e54f9 | 2017-06-15 13:15:23 -0400 | [diff] [blame] | 458 | raise Exception("No information parsed from dts file.") |
| 459 | |
Tomasz Bursztyka | 7ef3dde | 2018-03-07 15:03:27 +0100 | [diff] [blame] | 460 | for k, v in regs_config.items(): |
| 461 | if k in chosen: |
Kumar Gala | 35afcc9 | 2018-12-04 13:26:05 -0600 | [diff] [blame] | 462 | reg.extract(chosen[k], None, v, 1024) |
Kumar Gala | 8a6381d | 2018-01-18 13:31:54 -0600 | [diff] [blame] | 463 | |
Tomasz Bursztyka | 7ef3dde | 2018-03-07 15:03:27 +0100 | [diff] [blame] | 464 | for k, v in name_config.items(): |
| 465 | if k in chosen: |
Kumar Gala | 35afcc9 | 2018-12-04 13:26:05 -0600 | [diff] [blame] | 466 | extract_string_prop(chosen[k], "label", v) |
Tomasz Bursztyka | 7ef3dde | 2018-03-07 15:03:27 +0100 | [diff] [blame] | 467 | |
Ulf Magnusson | 958e2d3 | 2019-02-27 23:59:17 +0100 | [diff] [blame] | 468 | flash.extract_flash() |
| 469 | flash.extract_code_partition() |
Andy Gross | bb06316 | 2017-01-29 23:53:17 -0600 | [diff] [blame] | 470 | |
Tomasz Bursztyka | 7ef3dde | 2018-03-07 15:03:27 +0100 | [diff] [blame] | 471 | |
| 472 | def parse_arguments(): |
| 473 | rdh = argparse.RawDescriptionHelpFormatter |
| 474 | parser = argparse.ArgumentParser(description=__doc__, formatter_class=rdh) |
| 475 | |
Ulf Magnusson | 2528b53 | 2019-02-07 17:26:52 +0100 | [diff] [blame] | 476 | parser.add_argument("-d", "--dts", required=True, help="DTS file") |
Bobby Noelte | 5a16b90 | 2018-08-21 11:02:48 +0200 | [diff] [blame] | 477 | parser.add_argument("-y", "--yaml", nargs='+', required=True, |
| 478 | help="YAML file directories, we allow multiple") |
Ulf Magnusson | 2528b53 | 2019-02-07 17:26:52 +0100 | [diff] [blame] | 479 | parser.add_argument("-i", "--include", |
Tomasz Bursztyka | 7ef3dde | 2018-03-07 15:03:27 +0100 | [diff] [blame] | 480 | help="Generate include file for the build system") |
Ulf Magnusson | 2528b53 | 2019-02-07 17:26:52 +0100 | [diff] [blame] | 481 | parser.add_argument("-k", "--keyvalue", |
Tomasz Bursztyka | 7ef3dde | 2018-03-07 15:03:27 +0100 | [diff] [blame] | 482 | help="Generate config file for the build system") |
Andrzej Głąbek | a7c430f | 2018-10-31 19:19:54 +0100 | [diff] [blame] | 483 | parser.add_argument("--old-alias-names", action='store_true', |
| 484 | help="Generate aliases also in the old way, without " |
| 485 | "compatibility information in their labels") |
Ulf Magnusson | a72e451 | 2019-07-25 01:05:54 +0200 | [diff] [blame] | 486 | parser.add_argument("--deprecated-only", action='store_true', |
Kumar Gala | 4d2625c | 2019-07-10 07:41:50 -0500 | [diff] [blame] | 487 | help="Generate only the deprecated defines") |
Tomasz Bursztyka | 7ef3dde | 2018-03-07 15:03:27 +0100 | [diff] [blame] | 488 | return parser.parse_args() |
| 489 | |
| 490 | |
| 491 | def main(): |
| 492 | args = parse_arguments() |
Andrzej Głąbek | a7c430f | 2018-10-31 19:19:54 +0100 | [diff] [blame] | 493 | enable_old_alias_names(args.old_alias_names) |
Tomasz Bursztyka | 7ef3dde | 2018-03-07 15:03:27 +0100 | [diff] [blame] | 494 | |
Ulf Magnusson | cb50788 | 2019-02-08 21:40:33 +0100 | [diff] [blame] | 495 | # Parse DTS and fetch the root node |
Ulf Magnusson | 4217de0 | 2019-02-07 17:40:01 +0100 | [diff] [blame] | 496 | with open(args.dts, 'r', encoding='utf-8') as f: |
Ulf Magnusson | cb50788 | 2019-02-08 21:40:33 +0100 | [diff] [blame] | 497 | root = parse_file(f)['/'] |
Tomasz Bursztyka | 7ef3dde | 2018-03-07 15:03:27 +0100 | [diff] [blame] | 498 | |
Ulf Magnusson | cb50788 | 2019-02-08 21:40:33 +0100 | [diff] [blame] | 499 | # Create some global data structures from the parsed DTS |
| 500 | create_reduced(root, '/') |
Ulf Magnusson | 8c515b2 | 2019-02-08 22:26:51 +0100 | [diff] [blame] | 501 | create_phandles(root, '/') |
Ulf Magnusson | cb50788 | 2019-02-08 21:40:33 +0100 | [diff] [blame] | 502 | create_aliases(root) |
| 503 | create_chosen(root) |
Tomasz Bursztyka | 7ef3dde | 2018-03-07 15:03:27 +0100 | [diff] [blame] | 504 | |
Kumar Gala | 062bd06 | 2019-06-10 11:23:09 -0500 | [diff] [blame] | 505 | # Re-sort instance_id by reg addr |
| 506 | # |
| 507 | # Note: this is a short term fix and should be removed when |
| 508 | # generate defines for instance with a prefix like 'DT_INST' |
| 509 | # |
| 510 | # Build a dict of dicts, first level is index by compat |
| 511 | # second level is index by reg addr |
| 512 | compat_reg_dict = defaultdict(dict) |
| 513 | for node in reduced.values(): |
| 514 | instance = node.get('instance_id') |
| 515 | if instance and node['addr'] is not None: |
| 516 | for compat in instance: |
| 517 | reg = node['addr'] |
| 518 | compat_reg_dict[compat][reg] = node |
| 519 | |
| 520 | # Walk the reg addr in sorted order to re-index 'instance_id' |
| 521 | for compat in compat_reg_dict: |
| 522 | # only update if we have more than one instance |
| 523 | if len(compat_reg_dict[compat]) > 1: |
| 524 | for idx, reg_addr in enumerate(sorted(compat_reg_dict[compat])): |
| 525 | compat_reg_dict[compat][reg_addr]['instance_id'][compat] = idx |
| 526 | |
Ulf Magnusson | 0e40c96 | 2019-02-14 05:57:58 +0100 | [diff] [blame] | 527 | # Load any bindings (.yaml files) that match 'compatible' values from the |
| 528 | # DTS |
Ulf Magnusson | d859f4f | 2019-02-13 02:03:19 +0100 | [diff] [blame] | 529 | load_bindings(root, args.yaml) |
Tomasz Bursztyka | 7ef3dde | 2018-03-07 15:03:27 +0100 | [diff] [blame] | 530 | |
Ulf Magnusson | 0e40c96 | 2019-02-14 05:57:58 +0100 | [diff] [blame] | 531 | # Generate keys and values for the configuration file and the header file |
Ulf Magnusson | cbf9afc | 2019-02-14 05:53:03 +0100 | [diff] [blame] | 532 | generate_defines() |
Tomasz Bursztyka | 7ef3dde | 2018-03-07 15:03:27 +0100 | [diff] [blame] | 533 | |
Ulf Magnusson | 0e40c96 | 2019-02-14 05:57:58 +0100 | [diff] [blame] | 534 | # Write the configuration file and the header file |
Ulf Magnusson | 4217de0 | 2019-02-07 17:40:01 +0100 | [diff] [blame] | 535 | |
Ulf Magnusson | e8a077b | 2019-02-06 21:14:34 +0100 | [diff] [blame] | 536 | if args.keyvalue is not None: |
Ulf Magnusson | 4217de0 | 2019-02-07 17:40:01 +0100 | [diff] [blame] | 537 | with open(args.keyvalue, 'w', encoding='utf-8') as f: |
Ulf Magnusson | 72f0125 | 2019-02-07 20:03:56 +0100 | [diff] [blame] | 538 | write_conf(f) |
Tomasz Bursztyka | 1134393 | 2018-03-07 11:15:00 +0100 | [diff] [blame] | 539 | |
Ulf Magnusson | e8a077b | 2019-02-06 21:14:34 +0100 | [diff] [blame] | 540 | if args.include is not None: |
Ulf Magnusson | 4217de0 | 2019-02-07 17:40:01 +0100 | [diff] [blame] | 541 | with open(args.include, 'w', encoding='utf-8') as f: |
Ulf Magnusson | a72e451 | 2019-07-25 01:05:54 +0200 | [diff] [blame] | 542 | write_header(f, args.deprecated_only) |
Andy Gross | 70e54f9 | 2017-06-15 13:15:23 -0400 | [diff] [blame] | 543 | |
Andy Gross | bb06316 | 2017-01-29 23:53:17 -0600 | [diff] [blame] | 544 | |
| 545 | if __name__ == '__main__': |
Anas Nashif | 6b08141 | 2017-05-20 19:16:39 -0400 | [diff] [blame] | 546 | main() |