blob: 628de4fcafd9c12d48384575b52fca7a0dfc3ffe [file] [log] [blame]
Kumar Gala87915cd2018-11-15 11:51:50 -06001#
2# Copyright (c) 2018-2019 Linaro
Carles Cufifa26ef02019-01-30 17:54:21 +01003# Copyright (c) 2019 Nordic Semiconductor ASA
Kumar Gala87915cd2018-11-15 11:51:50 -06004#
5# SPDX-License-Identifier: Apache-2.0
6
7import os
Kumar Gala57353972019-08-28 09:30:23 -05008import sys
9
10ZEPHYR_BASE = os.environ.get("ZEPHYR_BASE")
11sys.path.insert(0, os.path.join(ZEPHYR_BASE, "scripts/dts"))
12
13import edtlib
Kumar Gala87915cd2018-11-15 11:51:50 -060014
15# Types we support
16# 'string', 'int', 'hex', 'bool'
17
Carles Cufifa26ef02019-01-30 17:54:21 +010018doc_mode = os.environ.get('KCONFIG_DOC_MODE') == "1"
Sebastian Bøecd435432019-02-11 15:57:34 +010019
Kumar Gala87915cd2018-11-15 11:51:50 -060020dt_defines = {}
Ulf Magnussonba312fe2019-03-20 19:30:29 +010021if not doc_mode:
Kumar Gala57353972019-08-28 09:30:23 -050022 DTS_POST_CPP = os.environ["DTS_POST_CPP"]
Peter A. Bigot372a4fe2019-09-14 11:21:14 -050023 BINDINGS_DIRS = os.environ.get("DTS_ROOT_BINDINGS")
Kumar Gala57353972019-08-28 09:30:23 -050024
25 # if a board port doesn't use DTS than these might not be set
Peter A. Bigot372a4fe2019-09-14 11:21:14 -050026 if os.path.isfile(DTS_POST_CPP) and BINDINGS_DIRS is not None:
Sebastian Bøeba287d22019-09-26 17:45:47 +020027 edt = edtlib.EDT(DTS_POST_CPP, BINDINGS_DIRS.split("?"))
Kumar Gala57353972019-08-28 09:30:23 -050028 else:
29 edt = None
30
Carles Cufic2d5e7b2019-02-19 19:48:35 +010031 # The env var 'GENERATED_DTS_BOARD_CONF' must be set unless we are in
32 # doc mode
33 GENERATED_DTS_BOARD_CONF = os.environ['GENERATED_DTS_BOARD_CONF']
34 if os.path.isfile(GENERATED_DTS_BOARD_CONF):
35 with open(GENERATED_DTS_BOARD_CONF, 'r', encoding='utf-8') as fd:
36 for line in fd:
37 if '=' in line:
Ulf Magnusson86b0c222019-04-08 14:13:39 +020038 define, val = line.split('=', 1)
Carles Cufic2d5e7b2019-02-19 19:48:35 +010039 dt_defines[define] = val.strip()
Kumar Gala87915cd2018-11-15 11:51:50 -060040
Kumar Gala1baf2f32019-09-04 14:14:26 -050041
42def _warn(kconf, msg):
43 print("{}:{}: WARNING: {}".format(kconf.filename, kconf.linenr, msg))
44
45
Kumar Gala87915cd2018-11-15 11:51:50 -060046def _dt_units_to_scale(unit):
47 if not unit:
48 return 0
49 if unit in {'k', 'K'}:
50 return 10
51 if unit in {'m', 'M'}:
52 return 20
53 if unit in {'g', 'G'}:
54 return 30
55
56def dt_int_val(kconf, _, name, unit=None):
57 """
58 This function looks up 'name' in the DTS generated "conf" style database
Erwan Gouriou7fce83f2019-02-12 09:44:14 +010059 (generated_dts_board.conf in <build_dir>/zephyr/include/generated/)
David B. Kinder1cc8bbb2019-02-08 13:20:21 -080060 and if it's found it will return the value as an decimal integer. The
Kumar Gala87915cd2018-11-15 11:51:50 -060061 function will divide the value based on 'unit':
62 None No division
63 'k' or 'K' divide by 1024 (1 << 10)
64 'm' or 'M' divide by 1,048,576 (1 << 20)
65 'g' or 'G' divide by 1,073,741,824 (1 << 30)
66 """
Carles Cufifa26ef02019-01-30 17:54:21 +010067 if doc_mode or name not in dt_defines:
Kumar Gala87915cd2018-11-15 11:51:50 -060068 return "0"
69
Kumar Gala1baf2f32019-09-04 14:14:26 -050070 _warn(kconf, "dt_int_val is deprecated.")
71
Kumar Gala87915cd2018-11-15 11:51:50 -060072 d = dt_defines[name]
73 if d.startswith(('0x', '0X')):
74 d = int(d, 16)
75 else:
76 d = int(d)
77 d >>= _dt_units_to_scale(unit)
78
79 return str(d)
80
81def dt_hex_val(kconf, _, name, unit=None):
82 """
83 This function looks up 'name' in the DTS generated "conf" style database
Erwan Gouriou7fce83f2019-02-12 09:44:14 +010084 (generated_dts_board.conf in <build_dir>/zephyr/include/generated/)
David B. Kinder1cc8bbb2019-02-08 13:20:21 -080085 and if it's found it will return the value as an hex integer. The
Kumar Gala87915cd2018-11-15 11:51:50 -060086 function will divide the value based on 'unit':
87 None No division
88 'k' or 'K' divide by 1024 (1 << 10)
89 'm' or 'M' divide by 1,048,576 (1 << 20)
90 'g' or 'G' divide by 1,073,741,824 (1 << 30)
91 """
Carles Cufifa26ef02019-01-30 17:54:21 +010092 if doc_mode or name not in dt_defines:
Kumar Gala87915cd2018-11-15 11:51:50 -060093 return "0x0"
94
Kumar Gala1baf2f32019-09-04 14:14:26 -050095 _warn(kconf, "dt_hex_val is deprecated.")
96
Kumar Gala87915cd2018-11-15 11:51:50 -060097 d = dt_defines[name]
98 if d.startswith(('0x', '0X')):
99 d = int(d, 16)
100 else:
101 d = int(d)
102 d >>= _dt_units_to_scale(unit)
103
104 return hex(d)
105
Kumar Gala2579ade2019-02-08 08:25:21 -0600106def dt_str_val(kconf, _, name):
107 """
108 This function looks up 'name' in the DTS generated "conf" style database
Erwan Gouriou7fce83f2019-02-12 09:44:14 +0100109 (generated_dts_board.conf in <build_dir>/zephyr/include/generated/)
David B. Kinder1cc8bbb2019-02-08 13:20:21 -0800110 and if it's found it will return the value as string. If it's not found we
Kumar Galaf2ef52f2019-02-08 10:59:49 -0600111 return an empty string.
Kumar Gala2579ade2019-02-08 08:25:21 -0600112 """
113 if doc_mode or name not in dt_defines:
114 return ""
115
Kumar Gala1baf2f32019-09-04 14:14:26 -0500116 _warn(kconf, "dt_str_val is deprecated.")
117
Kumar Galaf2ef52f2019-02-08 10:59:49 -0600118 return dt_defines[name].strip('"')
Kumar Gala87915cd2018-11-15 11:51:50 -0600119
Kumar Gala57353972019-08-28 09:30:23 -0500120
121def dt_chosen_label(kconf, _, chosen):
122 """
123 This function takes a 'chosen' property and treats that property as a path
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200124 to an EDT node. If it finds an EDT node, it will look to see if that node
125 has a "label" property and return the value of that "label", if not we
126 return an empty string.
Kumar Gala57353972019-08-28 09:30:23 -0500127 """
128 if doc_mode or edt is None:
129 return ""
130
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200131 node = edt.chosen_node(chosen)
132 if not node:
Kumar Gala57353972019-08-28 09:30:23 -0500133 return ""
134
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200135 if "label" not in node.props:
Kumar Gala57353972019-08-28 09:30:23 -0500136 return ""
137
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200138 return node.props["label"].val
Kumar Gala57353972019-08-28 09:30:23 -0500139
140
Kumar Gala07e5d892019-11-04 10:20:59 -0600141def dt_chosen_enabled(kconf, _, chosen):
142 """
143 This function returns "y" if /chosen contains a property named 'chosen'
144 that points to an enabled node, and "n" otherwise
145 """
146 if doc_mode or edt is None:
147 return "n"
148
149 node = edt.chosen_node(chosen)
150 return "y" if node and node.enabled else "n"
151
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200152def _node_reg_addr(node, index, unit):
153 if not node:
Kumar Gala22e74492019-10-23 15:15:59 -0500154 return 0
Kumar Gala57353972019-08-28 09:30:23 -0500155
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200156 if not node.regs:
Kumar Gala22e74492019-10-23 15:15:59 -0500157 return 0
Kumar Gala57353972019-08-28 09:30:23 -0500158
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200159 if int(index) >= len(node.regs):
Kumar Gala22e74492019-10-23 15:15:59 -0500160 return 0
Kumar Gala57353972019-08-28 09:30:23 -0500161
Kumar Gala22e74492019-10-23 15:15:59 -0500162 return node.regs[int(index)].addr >> _dt_units_to_scale(unit)
Kumar Gala57353972019-08-28 09:30:23 -0500163
164
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200165def _node_reg_size(node, index, unit):
166 if not node:
Kumar Gala22e74492019-10-23 15:15:59 -0500167 return 0
Kumar Gala57353972019-08-28 09:30:23 -0500168
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200169 if not node.regs:
Kumar Gala22e74492019-10-23 15:15:59 -0500170 return 0
Kumar Gala57353972019-08-28 09:30:23 -0500171
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200172 if int(index) >= len(node.regs):
Kumar Gala22e74492019-10-23 15:15:59 -0500173 return 0
Kumar Gala57353972019-08-28 09:30:23 -0500174
Kumar Gala22e74492019-10-23 15:15:59 -0500175 return node.regs[int(index)].size >> _dt_units_to_scale(unit)
Kumar Gala57353972019-08-28 09:30:23 -0500176
177
Kumar Gala22e74492019-10-23 15:15:59 -0500178def _dt_chosen_reg_addr(kconf, chosen, index=0, unit=None):
Kumar Gala57353972019-08-28 09:30:23 -0500179 """
180 This function takes a 'chosen' property and treats that property as a path
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200181 to an EDT node. If it finds an EDT node, it will look to see if that
182 nodnode has a register at the given 'index' and return the address value of
Kumar Gala57353972019-08-28 09:30:23 -0500183 that reg, if not we return 0.
184
185 The function will divide the value based on 'unit':
186 None No division
187 'k' or 'K' divide by 1024 (1 << 10)
188 'm' or 'M' divide by 1,048,576 (1 << 20)
189 'g' or 'G' divide by 1,073,741,824 (1 << 30)
190 """
191 if doc_mode or edt is None:
Kumar Gala22e74492019-10-23 15:15:59 -0500192 return 0
Kumar Gala57353972019-08-28 09:30:23 -0500193
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200194 node = edt.chosen_node(chosen)
Kumar Gala57353972019-08-28 09:30:23 -0500195
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200196 return _node_reg_addr(node, index, unit)
Kumar Gala57353972019-08-28 09:30:23 -0500197
198
Kumar Gala22e74492019-10-23 15:15:59 -0500199def _dt_chosen_reg_size(kconf, chosen, index=0, unit=None):
Kumar Gala57353972019-08-28 09:30:23 -0500200 """
201 This function takes a 'chosen' property and treats that property as a path
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200202 to an EDT node. If it finds an EDT node, it will look to see if that node
203 has a register at the given 'index' and return the size value of that reg,
204 if not we return 0.
Kumar Gala57353972019-08-28 09:30:23 -0500205
206 The function will divide the value based on 'unit':
207 None No division
208 'k' or 'K' divide by 1024 (1 << 10)
209 'm' or 'M' divide by 1,048,576 (1 << 20)
210 'g' or 'G' divide by 1,073,741,824 (1 << 30)
211 """
212 if doc_mode or edt is None:
Kumar Gala22e74492019-10-23 15:15:59 -0500213 return 0
Kumar Gala57353972019-08-28 09:30:23 -0500214
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200215 node = edt.chosen_node(chosen)
Kumar Gala57353972019-08-28 09:30:23 -0500216
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200217 return _node_reg_size(node, index, unit)
Kumar Gala57353972019-08-28 09:30:23 -0500218
219
Kumar Gala22e74492019-10-23 15:15:59 -0500220def dt_chosen_reg(kconf, name, chosen, index=0, unit=None):
221 """
222 This function just routes to the proper function and converts
223 the result to either a string int or string hex value.
224 """
225 if name == "dt_chosen_reg_size_int":
226 return str(_dt_chosen_reg_size(kconf, chosen, index, unit))
227 if name == "dt_chosen_reg_size_hex":
228 return hex(_dt_chosen_reg_size(kconf, chosen, index, unit))
229 if name == "dt_chosen_reg_addr_int":
230 return str(_dt_chosen_reg_addr(kconf, chosen, index, unit))
231 if name == "dt_chosen_reg_addr_hex":
232 return hex(_dt_chosen_reg_addr(kconf, chosen, index, unit))
233
234
235def _dt_node_reg_addr(kconf, path, index=0, unit=None):
Kumar Gala57353972019-08-28 09:30:23 -0500236 """
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200237 This function takes a 'path' and looks for an EDT node at that path. If it
238 finds an EDT node, it will look to see if that node has a register at the
239 given 'index' and return the address value of that reg, if not we return 0.
Kumar Gala57353972019-08-28 09:30:23 -0500240
241 The function will divide the value based on 'unit':
242 None No division
243 'k' or 'K' divide by 1024 (1 << 10)
244 'm' or 'M' divide by 1,048,576 (1 << 20)
245 'g' or 'G' divide by 1,073,741,824 (1 << 30)
246 """
247 if doc_mode or edt is None:
Kumar Gala22e74492019-10-23 15:15:59 -0500248 return 0
Kumar Gala57353972019-08-28 09:30:23 -0500249
250 try:
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200251 node = edt.get_node(path)
Kumar Gala57353972019-08-28 09:30:23 -0500252 except edtlib.EDTError:
Kumar Gala22e74492019-10-23 15:15:59 -0500253 return 0
Kumar Gala57353972019-08-28 09:30:23 -0500254
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200255 return _node_reg_addr(node, index, unit)
Kumar Gala57353972019-08-28 09:30:23 -0500256
257
Kumar Gala22e74492019-10-23 15:15:59 -0500258def _dt_node_reg_size(kconf, path, index=0, unit=None):
Kumar Gala57353972019-08-28 09:30:23 -0500259 """
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200260 This function takes a 'path' and looks for an EDT node at that path. If it
261 finds an EDT node, it will look to see if that node has a register at the
262 given 'index' and return the size value of that reg, if not we return 0.
Kumar Gala57353972019-08-28 09:30:23 -0500263
264 The function will divide the value based on 'unit':
265 None No division
266 'k' or 'K' divide by 1024 (1 << 10)
267 'm' or 'M' divide by 1,048,576 (1 << 20)
268 'g' or 'G' divide by 1,073,741,824 (1 << 30)
269 """
270 if doc_mode or edt is None:
Kumar Gala22e74492019-10-23 15:15:59 -0500271 return 0
Kumar Gala57353972019-08-28 09:30:23 -0500272
273 try:
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200274 node = edt.get_node(path)
Kumar Gala57353972019-08-28 09:30:23 -0500275 except edtlib.EDTError:
Kumar Gala22e74492019-10-23 15:15:59 -0500276 return 0
Kumar Gala57353972019-08-28 09:30:23 -0500277
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200278 return _node_reg_size(node, index, unit)
Kumar Gala57353972019-08-28 09:30:23 -0500279
280
Kumar Gala22e74492019-10-23 15:15:59 -0500281def dt_node_reg(kconf, name, path, index=0, unit=None):
282 """
283 This function just routes to the proper function and converts
284 the result to either a string int or string hex value.
285 """
286 if name == "dt_node_reg_size_int":
287 return str(_dt_node_reg_size(kconf, path, index, unit))
288 if name == "dt_node_reg_size_hex":
289 return hex(_dt_node_reg_size(kconf, path, index, unit))
290 if name == "dt_node_reg_addr_int":
291 return str(_dt_node_reg_addr(kconf, path, index, unit))
292 if name == "dt_node_reg_addr_hex":
293 return hex(_dt_node_reg_addr(kconf, path, index, unit))
294
295
Kumar Gala57353972019-08-28 09:30:23 -0500296def dt_node_has_bool_prop(kconf, _, path, prop):
297 """
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200298 This function takes a 'path' and looks for an EDT node at that path. If it
299 finds an EDT node, it will look to see if that node has a boolean property
300 by the name of 'prop'. If the 'prop' exists it will return "y" otherwise
301 we return "n".
Kumar Gala57353972019-08-28 09:30:23 -0500302 """
303 if doc_mode or edt is None:
304 return "n"
305
306 try:
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200307 node = edt.get_node(path)
Kumar Gala57353972019-08-28 09:30:23 -0500308 except edtlib.EDTError:
309 return "n"
310
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200311 if prop not in node.props:
Kumar Gala57353972019-08-28 09:30:23 -0500312 return "n"
313
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200314 if node.props[prop].type != "boolean":
Kumar Gala57353972019-08-28 09:30:23 -0500315 return "n"
316
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200317 if node.props[prop].val:
Kumar Gala57353972019-08-28 09:30:23 -0500318 return "y"
319
320 return "n"
321
322
323def dt_compat_enabled(kconf, _, compat):
324 """
325 This function takes a 'compat' and returns "y" if we find an "enabled"
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200326 compatible node in the EDT otherwise we return "n"
Kumar Gala57353972019-08-28 09:30:23 -0500327 """
328 if doc_mode or edt is None:
329 return "n"
330
Ulf Magnusson73ac1462019-09-23 05:14:18 +0200331 for node in edt.nodes:
332 if compat in node.compats and node.enabled:
Kumar Gala57353972019-08-28 09:30:23 -0500333 return "y"
334
335 return "n"
336
337
Kumar Gala87915cd2018-11-15 11:51:50 -0600338functions = {
339 "dt_int_val": (dt_int_val, 1, 2),
340 "dt_hex_val": (dt_hex_val, 1, 2),
Kumar Gala2579ade2019-02-08 08:25:21 -0600341 "dt_str_val": (dt_str_val, 1, 1),
Kumar Gala57353972019-08-28 09:30:23 -0500342 "dt_compat_enabled": (dt_compat_enabled, 1, 1),
343 "dt_chosen_label": (dt_chosen_label, 1, 1),
Kumar Gala07e5d892019-11-04 10:20:59 -0600344 "dt_chosen_enabled": (dt_chosen_enabled, 1, 1),
Kumar Gala22e74492019-10-23 15:15:59 -0500345 "dt_chosen_reg_addr_int": (dt_chosen_reg, 1, 4),
346 "dt_chosen_reg_addr_hex": (dt_chosen_reg, 1, 4),
347 "dt_chosen_reg_size_int": (dt_chosen_reg, 1, 4),
348 "dt_chosen_reg_size_hex": (dt_chosen_reg, 1, 4),
349 "dt_node_reg_addr_int": (dt_node_reg, 1, 4),
350 "dt_node_reg_addr_hex": (dt_node_reg, 1, 4),
351 "dt_node_reg_size_int": (dt_node_reg, 1, 4),
352 "dt_node_reg_size_hex": (dt_node_reg, 1, 4),
Kumar Gala57353972019-08-28 09:30:23 -0500353 "dt_node_has_bool_prop": (dt_node_has_bool_prop, 2, 2),
Kumar Gala87915cd2018-11-15 11:51:50 -0600354}