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