xref: /OK3568_Linux_fs/u-boot/tools/dtoc/fdt_util.py (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun#!/usr/bin/python
2*4882a593Smuzhiyun#
3*4882a593Smuzhiyun# Copyright (C) 2016 Google, Inc
4*4882a593Smuzhiyun# Written by Simon Glass <sjg@chromium.org>
5*4882a593Smuzhiyun#
6*4882a593Smuzhiyun# SPDX-License-Identifier:      GPL-2.0+
7*4882a593Smuzhiyun#
8*4882a593Smuzhiyun
9*4882a593Smuzhiyunimport os
10*4882a593Smuzhiyunimport struct
11*4882a593Smuzhiyunimport sys
12*4882a593Smuzhiyunimport tempfile
13*4882a593Smuzhiyun
14*4882a593Smuzhiyunimport command
15*4882a593Smuzhiyunimport tools
16*4882a593Smuzhiyun
17*4882a593Smuzhiyundef fdt32_to_cpu(val):
18*4882a593Smuzhiyun    """Convert a device tree cell to an integer
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun    Args:
21*4882a593Smuzhiyun        Value to convert (4-character string representing the cell value)
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun    Return:
24*4882a593Smuzhiyun        A native-endian integer value
25*4882a593Smuzhiyun    """
26*4882a593Smuzhiyun    if sys.version_info > (3, 0):
27*4882a593Smuzhiyun        if isinstance(val, bytes):
28*4882a593Smuzhiyun            val = val.decode('utf-8')
29*4882a593Smuzhiyun        val = val.encode('raw_unicode_escape')
30*4882a593Smuzhiyun    return struct.unpack('>I', val)[0]
31*4882a593Smuzhiyun
32*4882a593Smuzhiyundef fdt_cells_to_cpu(val, cells):
33*4882a593Smuzhiyun    """Convert one or two cells to a long integer
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun    Args:
36*4882a593Smuzhiyun        Value to convert (array of one or more 4-character strings)
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun    Return:
39*4882a593Smuzhiyun        A native-endian long value
40*4882a593Smuzhiyun    """
41*4882a593Smuzhiyun    if not cells:
42*4882a593Smuzhiyun        return 0
43*4882a593Smuzhiyun    out = long(fdt32_to_cpu(val[0]))
44*4882a593Smuzhiyun    if cells == 2:
45*4882a593Smuzhiyun        out = out << 32 | fdt32_to_cpu(val[1])
46*4882a593Smuzhiyun    return out
47*4882a593Smuzhiyun
48*4882a593Smuzhiyundef EnsureCompiled(fname):
49*4882a593Smuzhiyun    """Compile an fdt .dts source file into a .dtb binary blob if needed.
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun    Args:
52*4882a593Smuzhiyun        fname: Filename (if .dts it will be compiled). It not it will be
53*4882a593Smuzhiyun            left alone
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun    Returns:
56*4882a593Smuzhiyun        Filename of resulting .dtb file
57*4882a593Smuzhiyun    """
58*4882a593Smuzhiyun    _, ext = os.path.splitext(fname)
59*4882a593Smuzhiyun    if ext != '.dts':
60*4882a593Smuzhiyun        return fname
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun    dts_input = tools.GetOutputFilename('source.dts')
63*4882a593Smuzhiyun    dtb_output = tools.GetOutputFilename('source.dtb')
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun    search_paths = [os.path.join(os.getcwd(), 'include')]
66*4882a593Smuzhiyun    root, _ = os.path.splitext(fname)
67*4882a593Smuzhiyun    args = ['-E', '-P', '-x', 'assembler-with-cpp', '-D__ASSEMBLY__']
68*4882a593Smuzhiyun    args += ['-Ulinux']
69*4882a593Smuzhiyun    for path in search_paths:
70*4882a593Smuzhiyun        args.extend(['-I', path])
71*4882a593Smuzhiyun    args += ['-o', dts_input, fname]
72*4882a593Smuzhiyun    command.Run('cc', *args)
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun    # If we don't have a directory, put it in the tools tempdir
75*4882a593Smuzhiyun    search_list = []
76*4882a593Smuzhiyun    for path in search_paths:
77*4882a593Smuzhiyun        search_list.extend(['-i', path])
78*4882a593Smuzhiyun    args = ['-I', 'dts', '-o', dtb_output, '-O', 'dtb']
79*4882a593Smuzhiyun    args.extend(search_list)
80*4882a593Smuzhiyun    args.append(dts_input)
81*4882a593Smuzhiyun    command.Run('dtc', *args)
82*4882a593Smuzhiyun    return dtb_output
83*4882a593Smuzhiyun
84*4882a593Smuzhiyundef GetInt(node, propname, default=None):
85*4882a593Smuzhiyun    prop = node.props.get(propname)
86*4882a593Smuzhiyun    if not prop:
87*4882a593Smuzhiyun        return default
88*4882a593Smuzhiyun    value = fdt32_to_cpu(prop.value)
89*4882a593Smuzhiyun    if type(value) == type(list):
90*4882a593Smuzhiyun        raise ValueError("Node '%s' property '%' has list value: expecting"
91*4882a593Smuzhiyun                         "a single integer" % (node.name, propname))
92*4882a593Smuzhiyun    return value
93*4882a593Smuzhiyun
94*4882a593Smuzhiyundef GetString(node, propname, default=None):
95*4882a593Smuzhiyun    prop = node.props.get(propname)
96*4882a593Smuzhiyun    if not prop:
97*4882a593Smuzhiyun        return default
98*4882a593Smuzhiyun    value = prop.value
99*4882a593Smuzhiyun    if type(value) == type(list):
100*4882a593Smuzhiyun        raise ValueError("Node '%s' property '%' has list value: expecting"
101*4882a593Smuzhiyun                         "a single string" % (node.name, propname))
102*4882a593Smuzhiyun    return value
103*4882a593Smuzhiyun
104*4882a593Smuzhiyundef GetBool(node, propname, default=False):
105*4882a593Smuzhiyun    if propname in node.props:
106*4882a593Smuzhiyun        return True
107*4882a593Smuzhiyun    return default
108