diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/dtoc/dtb_platdata.py | 204 | ||||
-rw-r--r-- | tools/dtoc/dtoc_test_addr32.dts | 27 | ||||
-rw-r--r-- | tools/dtoc/dtoc_test_addr32_64.dts | 33 | ||||
-rw-r--r-- | tools/dtoc/dtoc_test_addr64.dts | 33 | ||||
-rw-r--r-- | tools/dtoc/dtoc_test_addr64_32.dts | 33 | ||||
-rw-r--r-- | tools/dtoc/dtoc_test_phandle.dts | 16 | ||||
-rw-r--r-- | tools/dtoc/dtoc_test_simple.dts | 14 | ||||
-rw-r--r-- | tools/dtoc/fdt.py | 19 | ||||
-rw-r--r-- | tools/dtoc/fdt_util.py | 16 | ||||
-rw-r--r-- | tools/dtoc/test_dtoc.py | 270 |
10 files changed, 609 insertions, 56 deletions
diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py index 041a33188f..dc9c0d9f45 100644 --- a/tools/dtoc/dtb_platdata.py +++ b/tools/dtoc/dtb_platdata.py @@ -12,6 +12,7 @@ This supports converting device tree data to C structures definitions and static data. """ +import collections import copy import sys @@ -38,11 +39,20 @@ TYPE_NAMES = { fdt.TYPE_BYTE: 'unsigned char', fdt.TYPE_STRING: 'const char *', fdt.TYPE_BOOL: 'bool', + fdt.TYPE_INT64: 'fdt64_t', } STRUCT_PREFIX = 'dtd_' VAL_PREFIX = 'dtv_' +# This holds information about a property which includes phandles. +# +# max_args: integer: Maximum number or arguments that any phandle uses (int). +# args: Number of args for each phandle in the property. The total number of +# phandles is len(args). This is a list of integers. +PhandleInfo = collections.namedtuple('PhandleInfo', ['max_args', 'args']) + + def conv_name_to_c(name): """Convert a device-tree name to a C identifier @@ -95,6 +105,8 @@ def get_value(ftype, value): return '"%s"' % value elif ftype == fdt.TYPE_BOOL: return 'true' + elif ftype == fdt.TYPE_INT64: + return '%#x' % value def get_compat_name(node): """Get a node's first compatible string as a C identifier @@ -113,21 +125,6 @@ def get_compat_name(node): compat, aliases = compat[0], compat[1:] return conv_name_to_c(compat), [conv_name_to_c(a) for a in aliases] -def is_phandle(prop): - """Check if a node contains phandles - - We have no reliable way of detecting whether a node uses a phandle - or not. As an interim measure, use a list of known property names. - - Args: - prop: Prop object to check - Return: - True if the object value contains phandles, else False - """ - if prop.name in ['clocks']: - return True - return False - class DtbPlatdata(object): """Provide a means to convert device tree binary data to platform data @@ -141,17 +138,14 @@ class DtbPlatdata(object): _dtb_fname: Filename of the input device tree binary file _valid_nodes: A list of Node object with compatible strings _include_disabled: true to include nodes marked status = "disabled" - _phandle_nodes: A dict of nodes indexed by phandle number (1, 2...) _outfile: The current output file (sys.stdout or a real file) _lines: Stashed list of output lines for outputting in the future - _phandle_nodes: A dict of Nodes indexed by phandle (an integer) """ def __init__(self, dtb_fname, include_disabled): self._fdt = None self._dtb_fname = dtb_fname self._valid_nodes = None self._include_disabled = include_disabled - self._phandle_nodes = {} self._outfile = None self._lines = [] self._aliases = {} @@ -196,6 +190,53 @@ class DtbPlatdata(object): self._lines = [] return lines + def out_header(self): + """Output a message indicating that this is an auto-generated file""" + self.out('''/* + * DO NOT MODIFY + * + * This file was generated by dtoc from a .dtb (device tree binary) file. + */ + +''') + + def get_phandle_argc(self, prop, node_name): + """Check if a node contains phandles + + We have no reliable way of detecting whether a node uses a phandle + or not. As an interim measure, use a list of known property names. + + Args: + prop: Prop object to check + Return: + Number of argument cells is this is a phandle, else None + """ + if prop.name in ['clocks']: + val = prop.value + if not isinstance(val, list): + val = [val] + i = 0 + + max_args = 0 + args = [] + while i < len(val): + phandle = fdt_util.fdt32_to_cpu(val[i]) + target = self._fdt.phandle_to_node.get(phandle) + if not target: + raise ValueError("Cannot parse '%s' in node '%s'" % + (prop.name, node_name)) + prop_name = '#clock-cells' + cells = target.props.get(prop_name) + if not cells: + raise ValueError("Node '%s' has no '%s' property" % + (target.name, prop_name)) + num_args = fdt_util.fdt32_to_cpu(cells.value) + max_args = max(max_args, num_args) + args.append(num_args) + i += 1 + num_args + return PhandleInfo(max_args, args) + return None + def scan_dtb(self): """Scan the device tree to obtain a tree of nodes and properties @@ -207,8 +248,7 @@ class DtbPlatdata(object): def scan_node(self, root): """Scan a node and subnodes to build a tree of node and phandle info - This adds each node to self._valid_nodes and each phandle to - self._phandle_nodes. + This adds each node to self._valid_nodes. Args: root: Root node for scan @@ -219,10 +259,6 @@ class DtbPlatdata(object): if (not self._include_disabled and not status or status.value != 'disabled'): self._valid_nodes.append(node) - phandle_prop = node.props.get('phandle') - if phandle_prop: - phandle = phandle_prop.GetPhandle() - self._phandle_nodes[phandle] = node # recurse to handle any subnodes self.scan_node(node) @@ -231,14 +267,72 @@ class DtbPlatdata(object): """Scan the device tree for useful information This fills in the following properties: - _phandle_nodes: A dict of Nodes indexed by phandle (an integer) _valid_nodes: A list of nodes we wish to consider include in the platform data """ - self._phandle_nodes = {} self._valid_nodes = [] return self.scan_node(self._fdt.GetRoot()) + @staticmethod + def get_num_cells(node): + """Get the number of cells in addresses and sizes for this node + + Args: + node: Node to check + + Returns: + Tuple: + Number of address cells for this node + Number of size cells for this node + """ + parent = node.parent + na, ns = 2, 2 + if parent: + na_prop = parent.props.get('#address-cells') + ns_prop = parent.props.get('#size-cells') + if na_prop: + na = fdt_util.fdt32_to_cpu(na_prop.value) + if ns_prop: + ns = fdt_util.fdt32_to_cpu(ns_prop.value) + return na, ns + + def scan_reg_sizes(self): + """Scan for 64-bit 'reg' properties and update the values + + This finds 'reg' properties with 64-bit data and converts the value to + an array of 64-values. This allows it to be output in a way that the + C code can read. + """ + for node in self._valid_nodes: + reg = node.props.get('reg') + if not reg: + continue + na, ns = self.get_num_cells(node) + total = na + ns + + if reg.type != fdt.TYPE_INT: + raise ValueError("Node '%s' reg property is not an int") + if len(reg.value) % total: + raise ValueError("Node '%s' reg property has %d cells " + 'which is not a multiple of na + ns = %d + %d)' % + (node.name, len(reg.value), na, ns)) + reg.na = na + reg.ns = ns + if na != 1 or ns != 1: + reg.type = fdt.TYPE_INT64 + i = 0 + new_value = [] + val = reg.value + if not isinstance(val, list): + val = [val] + while i < len(val): + addr = fdt_util.fdt_cells_to_cpu(val[i:], reg.na) + i += na + size = fdt_util.fdt_cells_to_cpu(val[i:], reg.ns) + i += ns + new_value += [addr, size] + reg.value = new_value + def scan_structs(self): """Scan the device tree building up the C structures we will use. @@ -305,14 +399,18 @@ class DtbPlatdata(object): for pname, prop in node.props.items(): if pname in PROP_IGNORE_LIST or pname[0] == '#': continue - if isinstance(prop.value, list): - if is_phandle(prop): - # Process the list as pairs of (phandle, id) - value_it = iter(prop.value) - for phandle_cell, _ in zip(value_it, value_it): - phandle = fdt_util.fdt32_to_cpu(phandle_cell) - target_node = self._phandle_nodes[phandle] - node.phandles.add(target_node) + info = self.get_phandle_argc(prop, node.name) + if info: + if not isinstance(prop.value, list): + prop.value = [prop.value] + # Process the list as pairs of (phandle, id) + pos = 0 + for args in info.args: + phandle_cell = prop.value[pos] + phandle = fdt_util.fdt32_to_cpu(phandle_cell) + target_node = self._fdt.phandle_to_node[phandle] + node.phandles.add(target_node) + pos += 1 + args def generate_structs(self, structs): @@ -322,6 +420,7 @@ class DtbPlatdata(object): definitions for node in self._valid_nodes. See the documentation in README.of-plat for more information. """ + self.out_header() self.out('#include <stdbool.h>\n') self.out('#include <libfdt.h>\n') @@ -330,11 +429,13 @@ class DtbPlatdata(object): self.out('struct %s%s {\n' % (STRUCT_PREFIX, name)) for pname in sorted(structs[name]): prop = structs[name][pname] - if is_phandle(prop): + info = self.get_phandle_argc(prop, structs[name]) + if info: # For phandles, include a reference to the target - self.out('\t%s%s[%d]' % (tab_to(2, 'struct phandle_2_cell'), + struct_name = 'struct phandle_%d_arg' % info.max_args + self.out('\t%s%s[%d]' % (tab_to(2, struct_name), conv_name_to_c(prop.name), - len(prop.value) / 2)) + len(info.args))) else: ptype = TYPE_NAMES[prop.type] self.out('\t%s%s' % (tab_to(2, ptype), @@ -370,19 +471,32 @@ class DtbPlatdata(object): vals = [] # For phandles, output a reference to the platform data # of the target node. - if is_phandle(prop): + info = self.get_phandle_argc(prop, node.name) + if info: # Process the list as pairs of (phandle, id) - value_it = iter(prop.value) - for phandle_cell, id_cell in zip(value_it, value_it): + pos = 0 + for args in info.args: + phandle_cell = prop.value[pos] phandle = fdt_util.fdt32_to_cpu(phandle_cell) - id_num = fdt_util.fdt32_to_cpu(id_cell) - target_node = self._phandle_nodes[phandle] + target_node = self._fdt.phandle_to_node[phandle] name = conv_name_to_c(target_node.name) - vals.append('{&%s%s, %d}' % (VAL_PREFIX, name, id_num)) + arg_values = [] + for i in range(args): + arg_values.append(str(fdt_util.fdt32_to_cpu(prop.value[pos + 1 + i]))) + pos += 1 + args + vals.append('\t{&%s%s, {%s}}' % (VAL_PREFIX, name, + ', '.join(arg_values))) + for val in vals: + self.buf('\n\t\t%s,' % val) else: for val in prop.value: vals.append(get_value(prop.type, val)) - self.buf(', '.join(vals)) + + # Put 8 values per line to avoid very long lines. + for i in xrange(0, len(vals), 8): + if i: + self.buf(',\n\t\t') + self.buf(', '.join(vals[i:i + 8])) self.buf('}') else: self.buf(get_value(prop.type, prop.value)) @@ -409,6 +523,7 @@ class DtbPlatdata(object): See the documentation in doc/driver-model/of-plat.txt for more information. """ + self.out_header() self.out('#include <common.h>\n') self.out('#include <dm.h>\n') self.out('#include <dt-structs.h>\n') @@ -442,6 +557,7 @@ def run_steps(args, dtb_file, include_disabled, output): plat = DtbPlatdata(dtb_file, include_disabled) plat.scan_dtb() plat.scan_tree() + plat.scan_reg_sizes() plat.setup_output(output) structs = plat.scan_structs() plat.scan_phandles() diff --git a/tools/dtoc/dtoc_test_addr32.dts b/tools/dtoc/dtoc_test_addr32.dts new file mode 100644 index 0000000000..bcfdcae10b --- /dev/null +++ b/tools/dtoc/dtoc_test_addr32.dts @@ -0,0 +1,27 @@ +/* + * Test device tree file for dtoc + * + * Copyright 2017 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + + /dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + test1 { + u-boot,dm-pre-reloc; + compatible = "test1"; + reg = <0x1234 0x5678>; + }; + + test2 { + u-boot,dm-pre-reloc; + compatible = "test2"; + reg = <0x12345678 0x98765432 2 3>; + }; + +}; diff --git a/tools/dtoc/dtoc_test_addr32_64.dts b/tools/dtoc/dtoc_test_addr32_64.dts new file mode 100644 index 0000000000..1c96243310 --- /dev/null +++ b/tools/dtoc/dtoc_test_addr32_64.dts @@ -0,0 +1,33 @@ +/* + * Test device tree file for dtoc + * + * Copyright 2017 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + + /dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <2>; + + test1 { + u-boot,dm-pre-reloc; + compatible = "test1"; + reg = <0x1234 0x5678 0x0>; + }; + + test2 { + u-boot,dm-pre-reloc; + compatible = "test2"; + reg = <0x12345678 0x98765432 0x10987654>; + }; + + test3 { + u-boot,dm-pre-reloc; + compatible = "test3"; + reg = <0x12345678 0x98765432 0x10987654 2 0 3>; + }; + +}; diff --git a/tools/dtoc/dtoc_test_addr64.dts b/tools/dtoc/dtoc_test_addr64.dts new file mode 100644 index 0000000000..4c0ad0ec36 --- /dev/null +++ b/tools/dtoc/dtoc_test_addr64.dts @@ -0,0 +1,33 @@ +/* + * Test device tree file for dtoc + * + * Copyright 2017 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + + /dts-v1/; + +/ { + #address-cells = <2>; + #size-cells = <2>; + + test1 { + u-boot,dm-pre-reloc; + compatible = "test1"; + reg = /bits/ 64 <0x1234 0x5678>; + }; + + test2 { + u-boot,dm-pre-reloc; + compatible = "test2"; + reg = /bits/ 64 <0x1234567890123456 0x9876543210987654>; + }; + + test3 { + u-boot,dm-pre-reloc; + compatible = "test3"; + reg = /bits/ 64 <0x1234567890123456 0x9876543210987654 2 3>; + }; + +}; diff --git a/tools/dtoc/dtoc_test_addr64_32.dts b/tools/dtoc/dtoc_test_addr64_32.dts new file mode 100644 index 0000000000..c36f6b726e --- /dev/null +++ b/tools/dtoc/dtoc_test_addr64_32.dts @@ -0,0 +1,33 @@ +/* + * Test device tree file for dtoc + * + * Copyright 2017 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + + /dts-v1/; + +/ { + #address-cells = <2>; + #size-cells = <1>; + + test1 { + u-boot,dm-pre-reloc; + compatible = "test1"; + reg = <0x1234 0x0 0x5678>; + }; + + test2 { + u-boot,dm-pre-reloc; + compatible = "test2"; + reg = <0x12345678 0x90123456 0x98765432>; + }; + + test3 { + u-boot,dm-pre-reloc; + compatible = "test3"; + reg = <0x12345678 0x90123456 0x98765432 0 2 3>; + }; + +}; diff --git a/tools/dtoc/dtoc_test_phandle.dts b/tools/dtoc/dtoc_test_phandle.dts index e9828a695b..ba12b0fe65 100644 --- a/tools/dtoc/dtoc_test_phandle.dts +++ b/tools/dtoc/dtoc_test_phandle.dts @@ -12,12 +12,26 @@ phandle: phandle-target { u-boot,dm-pre-reloc; compatible = "target"; + intval = <0>; + #clock-cells = <0>; + }; + + phandle_1: phandle2-target { + u-boot,dm-pre-reloc; + compatible = "target"; intval = <1>; + #clock-cells = <1>; + }; + phandle_2: phandle3-target { + u-boot,dm-pre-reloc; + compatible = "target"; + intval = <2>; + #clock-cells = <2>; }; phandle-source { u-boot,dm-pre-reloc; compatible = "source"; - clocks = <&phandle 1>; + clocks = <&phandle &phandle_1 11 &phandle_2 12 13 &phandle>; }; }; diff --git a/tools/dtoc/dtoc_test_simple.dts b/tools/dtoc/dtoc_test_simple.dts index c736686263..6afe674b1f 100644 --- a/tools/dtoc/dtoc_test_simple.dts +++ b/tools/dtoc/dtoc_test_simple.dts @@ -9,6 +9,8 @@ /dts-v1/; / { + #address-cells = <1>; + #size-cells = <1>; spl-test { u-boot,dm-pre-reloc; compatible = "sandbox,spl-test"; @@ -45,4 +47,16 @@ compatible = "sandbox,spl-test.2"; }; + i2c@0 { + compatible = "sandbox,i2c-test"; + u-boot,dm-pre-reloc; + #address-cells = <1>; + #size-cells = <0>; + pmic@9 { + compatible = "sandbox,pmic-test"; + u-boot,dm-pre-reloc; + reg = <9>; + low-power; + }; + }; }; diff --git a/tools/dtoc/fdt.py b/tools/dtoc/fdt.py index 63a32ea2d7..dbc338653b 100644 --- a/tools/dtoc/fdt.py +++ b/tools/dtoc/fdt.py @@ -21,7 +21,7 @@ import libfdt # so it is fairly efficient. # A list of types we support -(TYPE_BYTE, TYPE_INT, TYPE_STRING, TYPE_BOOL) = range(4) +(TYPE_BYTE, TYPE_INT, TYPE_STRING, TYPE_BOOL, TYPE_INT64) = range(5) def CheckErr(errnum, msg): if errnum: @@ -174,8 +174,9 @@ class Node: props: A dict of properties for this node, each a Prop object. Keyed by property name """ - def __init__(self, fdt, offset, name, path): + def __init__(self, fdt, parent, offset, name, path): self._fdt = fdt + self.parent = parent self._offset = offset self.name = name self.path = path @@ -211,13 +212,17 @@ class Node: searching into subnodes so that the entire tree is built. """ self.props = self._fdt.GetProps(self) + phandle = self.props.get('phandle') + if phandle: + val = fdt_util.fdt32_to_cpu(phandle.value) + self._fdt.phandle_to_node[val] = self offset = libfdt.fdt_first_subnode(self._fdt.GetFdt(), self.Offset()) while offset >= 0: sep = '' if self.path[-1] == '/' else '/' name = self._fdt._fdt_obj.get_name(offset) path = self.path + sep + name - node = Node(self._fdt, offset, name, path) + node = Node(self._fdt, self, offset, name, path) self.subnodes.append(node) node.Scan() @@ -262,6 +267,7 @@ class Fdt: def __init__(self, fname): self._fname = fname self._cached_offsets = False + self.phandle_to_node = {} if self._fname: self._fname = fdt_util.EnsureCompiled(self._fname) @@ -279,7 +285,7 @@ class Fdt: TODO(sjg@chromium.org): Implement the 'root' parameter """ - self._root = self.Node(self, 0, '/', '/') + self._root = self.Node(self, None, 0, '/', '/') self._root.Scan() def GetRoot(self): @@ -386,7 +392,7 @@ class Fdt: return libfdt.fdt_off_dt_struct(self._fdt) + offset @classmethod - def Node(self, fdt, offset, name, path): + def Node(self, fdt, parent, offset, name, path): """Create a new node This is used by Fdt.Scan() to create a new node using the correct @@ -394,11 +400,12 @@ class Fdt: Args: fdt: Fdt object + parent: Parent node, or None if this is the root node offset: Offset of node name: Node name path: Full path to node """ - node = Node(fdt, offset, name, path) + node = Node(fdt, parent, offset, name, path) return node def FdtScan(fname): diff --git a/tools/dtoc/fdt_util.py b/tools/dtoc/fdt_util.py index b9dfae8d0e..338d47a5e1 100644 --- a/tools/dtoc/fdt_util.py +++ b/tools/dtoc/fdt_util.py @@ -29,6 +29,22 @@ def fdt32_to_cpu(val): val = val.encode('raw_unicode_escape') return struct.unpack('>I', val)[0] +def fdt_cells_to_cpu(val, cells): + """Convert one or two cells to a long integer + + Args: + Value to convert (array of one or more 4-character strings) + + Return: + A native-endian long value + """ + if not cells: + return 0 + out = long(fdt32_to_cpu(val[0])) + if cells == 2: + out = out << 32 | fdt32_to_cpu(val[1]) + return out + def EnsureCompiled(fname): """Compile an fdt .dts source file into a .dtb binary blob if needed. diff --git a/tools/dtoc/test_dtoc.py b/tools/dtoc/test_dtoc.py index 8b95c4124f..cc009b2a25 100644 --- a/tools/dtoc/test_dtoc.py +++ b/tools/dtoc/test_dtoc.py @@ -121,6 +121,12 @@ class TestDtoc(unittest.TestCase): data = infile.read() self.assertEqual('''#include <stdbool.h> #include <libfdt.h> +struct dtd_sandbox_i2c_test { +}; +struct dtd_sandbox_pmic_test { +\tbool\t\tlow_power; +\tfdt64_t\t\treg[2]; +}; struct dtd_sandbox_spl_test { \tbool\t\tboolval; \tunsigned char\tbytearray[3]; @@ -146,7 +152,8 @@ static struct dtd_sandbox_spl_test dtv_spl_test = { \t.bytearray\t\t= {0x6, 0x0, 0x0}, \t.byteval\t\t= 0x5, \t.intval\t\t\t= 0x1, -\t.longbytearray\t\t= {0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11}, +\t.longbytearray\t\t= {0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, +\t\t0x11}, \t.stringval\t\t= "message", \t.boolval\t\t= true, \t.intarray\t\t= {0x2, 0x3, 0x4, 0x0}, @@ -162,7 +169,8 @@ static struct dtd_sandbox_spl_test dtv_spl_test2 = { \t.bytearray\t\t= {0x1, 0x23, 0x34}, \t.byteval\t\t= 0x8, \t.intval\t\t\t= 0x3, -\t.longbytearray\t\t= {0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, +\t.longbytearray\t\t= {0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +\t\t0x0}, \t.stringval\t\t= "message2", \t.intarray\t\t= {0x5, 0x0, 0x0, 0x0}, \t.stringarray\t\t= {"another", "multi-word", "message"}, @@ -190,6 +198,24 @@ U_BOOT_DEVICE(spl_test4) = { \t.platdata_size\t= sizeof(dtv_spl_test4), }; +static struct dtd_sandbox_i2c_test dtv_i2c_at_0 = { +}; +U_BOOT_DEVICE(i2c_at_0) = { +\t.name\t\t= "sandbox_i2c_test", +\t.platdata\t= &dtv_i2c_at_0, +\t.platdata_size\t= sizeof(dtv_i2c_at_0), +}; + +static struct dtd_sandbox_pmic_test dtv_pmic_at_9 = { +\t.low_power\t\t= true, +\t.reg\t\t\t= {0x9, 0x0}, +}; +U_BOOT_DEVICE(pmic_at_9) = { +\t.name\t\t= "sandbox_pmic_test", +\t.platdata\t= &dtv_pmic_at_9, +\t.platdata_size\t= sizeof(dtv_pmic_at_9), +}; + ''', data) def test_phandle(self): @@ -202,7 +228,7 @@ U_BOOT_DEVICE(spl_test4) = { self.assertEqual('''#include <stdbool.h> #include <libfdt.h> struct dtd_source { -\tstruct phandle_2_cell clocks[1]; +\tstruct phandle_2_arg clocks[4]; }; struct dtd_target { \tfdt32_t\t\tintval; @@ -217,7 +243,7 @@ struct dtd_target { #include <dt-structs.h> static struct dtd_target dtv_phandle_target = { -\t.intval\t\t\t= 0x1, +\t.intval\t\t\t= 0x0, }; U_BOOT_DEVICE(phandle_target) = { \t.name\t\t= "target", @@ -225,8 +251,30 @@ U_BOOT_DEVICE(phandle_target) = { \t.platdata_size\t= sizeof(dtv_phandle_target), }; +static struct dtd_target dtv_phandle2_target = { +\t.intval\t\t\t= 0x1, +}; +U_BOOT_DEVICE(phandle2_target) = { +\t.name\t\t= "target", +\t.platdata\t= &dtv_phandle2_target, +\t.platdata_size\t= sizeof(dtv_phandle2_target), +}; + +static struct dtd_target dtv_phandle3_target = { +\t.intval\t\t\t= 0x2, +}; +U_BOOT_DEVICE(phandle3_target) = { +\t.name\t\t= "target", +\t.platdata\t= &dtv_phandle3_target, +\t.platdata_size\t= sizeof(dtv_phandle3_target), +}; + static struct dtd_source dtv_phandle_source = { -\t.clocks\t\t\t= {{&dtv_phandle_target, 1}}, +\t.clocks\t\t\t= { +\t\t\t{&dtv_phandle_target, {}}, +\t\t\t{&dtv_phandle2_target, {11}}, +\t\t\t{&dtv_phandle3_target, {12, 13}}, +\t\t\t{&dtv_phandle_target, {}},}, }; U_BOOT_DEVICE(phandle_source) = { \t.name\t\t= "source", @@ -269,3 +317,215 @@ U_BOOT_DEVICE(spl_test) = { }; ''', data) + + def test_addresses64(self): + """Test output from a node with a 'reg' property with na=2, ns=2""" + dtb_file = get_dtb_file('dtoc_test_addr64.dts') + output = tools.GetOutputFilename('output') + dtb_platdata.run_steps(['struct'], dtb_file, False, output) + with open(output) as infile: + data = infile.read() + self.assertEqual('''#include <stdbool.h> +#include <libfdt.h> +struct dtd_test1 { +\tfdt64_t\t\treg[2]; +}; +struct dtd_test2 { +\tfdt64_t\t\treg[2]; +}; +struct dtd_test3 { +\tfdt64_t\t\treg[4]; +}; +''', data) + + dtb_platdata.run_steps(['platdata'], dtb_file, False, output) + with open(output) as infile: + data = infile.read() + self.assertEqual('''#include <common.h> +#include <dm.h> +#include <dt-structs.h> + +static struct dtd_test1 dtv_test1 = { +\t.reg\t\t\t= {0x1234, 0x5678}, +}; +U_BOOT_DEVICE(test1) = { +\t.name\t\t= "test1", +\t.platdata\t= &dtv_test1, +\t.platdata_size\t= sizeof(dtv_test1), +}; + +static struct dtd_test2 dtv_test2 = { +\t.reg\t\t\t= {0x1234567890123456, 0x9876543210987654}, +}; +U_BOOT_DEVICE(test2) = { +\t.name\t\t= "test2", +\t.platdata\t= &dtv_test2, +\t.platdata_size\t= sizeof(dtv_test2), +}; + +static struct dtd_test3 dtv_test3 = { +\t.reg\t\t\t= {0x1234567890123456, 0x9876543210987654, 0x2, 0x3}, +}; +U_BOOT_DEVICE(test3) = { +\t.name\t\t= "test3", +\t.platdata\t= &dtv_test3, +\t.platdata_size\t= sizeof(dtv_test3), +}; + +''', data) + + def test_addresses32(self): + """Test output from a node with a 'reg' property with na=1, ns=1""" + dtb_file = get_dtb_file('dtoc_test_addr32.dts') + output = tools.GetOutputFilename('output') + dtb_platdata.run_steps(['struct'], dtb_file, False, output) + with open(output) as infile: + data = infile.read() + self.assertEqual('''#include <stdbool.h> +#include <libfdt.h> +struct dtd_test1 { +\tfdt32_t\t\treg[2]; +}; +struct dtd_test2 { +\tfdt32_t\t\treg[4]; +}; +''', data) + + dtb_platdata.run_steps(['platdata'], dtb_file, False, output) + with open(output) as infile: + data = infile.read() + self.assertEqual('''#include <common.h> +#include <dm.h> +#include <dt-structs.h> + +static struct dtd_test1 dtv_test1 = { +\t.reg\t\t\t= {0x1234, 0x5678}, +}; +U_BOOT_DEVICE(test1) = { +\t.name\t\t= "test1", +\t.platdata\t= &dtv_test1, +\t.platdata_size\t= sizeof(dtv_test1), +}; + +static struct dtd_test2 dtv_test2 = { +\t.reg\t\t\t= {0x12345678, 0x98765432, 0x2, 0x3}, +}; +U_BOOT_DEVICE(test2) = { +\t.name\t\t= "test2", +\t.platdata\t= &dtv_test2, +\t.platdata_size\t= sizeof(dtv_test2), +}; + +''', data) + + def test_addresses64_32(self): + """Test output from a node with a 'reg' property with na=2, ns=1""" + dtb_file = get_dtb_file('dtoc_test_addr64_32.dts') + output = tools.GetOutputFilename('output') + dtb_platdata.run_steps(['struct'], dtb_file, False, output) + with open(output) as infile: + data = infile.read() + self.assertEqual('''#include <stdbool.h> +#include <libfdt.h> +struct dtd_test1 { +\tfdt64_t\t\treg[2]; +}; +struct dtd_test2 { +\tfdt64_t\t\treg[2]; +}; +struct dtd_test3 { +\tfdt64_t\t\treg[4]; +}; +''', data) + + dtb_platdata.run_steps(['platdata'], dtb_file, False, output) + with open(output) as infile: + data = infile.read() + self.assertEqual('''#include <common.h> +#include <dm.h> +#include <dt-structs.h> + +static struct dtd_test1 dtv_test1 = { +\t.reg\t\t\t= {0x123400000000, 0x5678}, +}; +U_BOOT_DEVICE(test1) = { +\t.name\t\t= "test1", +\t.platdata\t= &dtv_test1, +\t.platdata_size\t= sizeof(dtv_test1), +}; + +static struct dtd_test2 dtv_test2 = { +\t.reg\t\t\t= {0x1234567890123456, 0x98765432}, +}; +U_BOOT_DEVICE(test2) = { +\t.name\t\t= "test2", +\t.platdata\t= &dtv_test2, +\t.platdata_size\t= sizeof(dtv_test2), +}; + +static struct dtd_test3 dtv_test3 = { +\t.reg\t\t\t= {0x1234567890123456, 0x98765432, 0x2, 0x3}, +}; +U_BOOT_DEVICE(test3) = { +\t.name\t\t= "test3", +\t.platdata\t= &dtv_test3, +\t.platdata_size\t= sizeof(dtv_test3), +}; + +''', data) + + def test_addresses32_64(self): + """Test output from a node with a 'reg' property with na=1, ns=2""" + dtb_file = get_dtb_file('dtoc_test_addr32_64.dts') + output = tools.GetOutputFilename('output') + dtb_platdata.run_steps(['struct'], dtb_file, False, output) + with open(output) as infile: + data = infile.read() + self.assertEqual('''#include <stdbool.h> +#include <libfdt.h> +struct dtd_test1 { +\tfdt64_t\t\treg[2]; +}; +struct dtd_test2 { +\tfdt64_t\t\treg[2]; +}; +struct dtd_test3 { +\tfdt64_t\t\treg[4]; +}; +''', data) + + dtb_platdata.run_steps(['platdata'], dtb_file, False, output) + with open(output) as infile: + data = infile.read() + self.assertEqual('''#include <common.h> +#include <dm.h> +#include <dt-structs.h> + +static struct dtd_test1 dtv_test1 = { +\t.reg\t\t\t= {0x1234, 0x567800000000}, +}; +U_BOOT_DEVICE(test1) = { +\t.name\t\t= "test1", +\t.platdata\t= &dtv_test1, +\t.platdata_size\t= sizeof(dtv_test1), +}; + +static struct dtd_test2 dtv_test2 = { +\t.reg\t\t\t= {0x12345678, 0x9876543210987654}, +}; +U_BOOT_DEVICE(test2) = { +\t.name\t\t= "test2", +\t.platdata\t= &dtv_test2, +\t.platdata_size\t= sizeof(dtv_test2), +}; + +static struct dtd_test3 dtv_test3 = { +\t.reg\t\t\t= {0x12345678, 0x9876543210987654, 0x2, 0x3}, +}; +U_BOOT_DEVICE(test3) = { +\t.name\t\t= "test3", +\t.platdata\t= &dtv_test3, +\t.platdata_size\t= sizeof(dtv_test3), +}; + +''', data) |