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