fdt_util.py 2.9 KB

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