summaryrefslogtreecommitdiff
path: root/tools/dtoc
diff options
context:
space:
mode:
Diffstat (limited to 'tools/dtoc')
-rwxr-xr-xtools/dtoc/dtoc.py7
-rw-r--r--tools/dtoc/fdt.py41
-rw-r--r--tools/dtoc/fdt_util.py12
-rwxr-xr-xtools/dtoc/test_fdt.py48
4 files changed, 99 insertions, 9 deletions
diff --git a/tools/dtoc/dtoc.py b/tools/dtoc/dtoc.py
index c1a1d3534d..514e0dd4a3 100755
--- a/tools/dtoc/dtoc.py
+++ b/tools/dtoc/dtoc.py
@@ -71,6 +71,10 @@ def run_tests(args):
print(err)
for _, err in result.failures:
print(err)
+ if result.errors or result.failures:
+ print('dtoc tests FAILED')
+ return 1
+ return 0
def RunTestCoverage():
"""Run the tests and check that we get 100% coverage"""
@@ -101,7 +105,8 @@ parser.add_option('-T', '--test-coverage', action='store_true',
# Run our meagre tests
if options.test:
- run_tests(args)
+ ret_code = run_tests(args)
+ sys.exit(ret_code)
elif options.test_coverage:
RunTestCoverage()
diff --git a/tools/dtoc/fdt.py b/tools/dtoc/fdt.py
index d9471c4381..6770be79fb 100644
--- a/tools/dtoc/fdt.py
+++ b/tools/dtoc/fdt.py
@@ -362,6 +362,23 @@ class Node:
value = tools.GetBytes(0, len)
self.props[prop_name] = Prop(self, None, prop_name, value)
+ def _CheckProp(self, prop_name):
+ """Check if a property is present
+
+ Args:
+ prop_name: Name of property
+
+ Returns:
+ self
+
+ Raises:
+ ValueError if the property is missing
+ """
+ if prop_name not in self.props:
+ raise ValueError("Fdt '%s', node '%s': Missing property '%s'" %
+ (self._fdt._fname, self.path, prop_name))
+ return self
+
def SetInt(self, prop_name, val):
"""Update an integer property int the device tree.
@@ -374,7 +391,7 @@ class Node:
prop_name: Name of property
val: Value to set
"""
- self.props[prop_name].SetInt(val)
+ self._CheckProp(prop_name).props[prop_name].SetInt(val)
def SetData(self, prop_name, val):
"""Set the data value of a property
@@ -386,7 +403,7 @@ class Node:
prop_name: Name of property to set
val: Data value to set
"""
- self.props[prop_name].SetData(val)
+ self._CheckProp(prop_name).props[prop_name].SetData(val)
def SetString(self, prop_name, val):
"""Set the string value of a property
@@ -400,7 +417,7 @@ class Node:
"""
if sys.version_info[0] >= 3: # pragma: no cover
val = bytes(val, 'utf-8')
- self.props[prop_name].SetData(val + b'\0')
+ self._CheckProp(prop_name).props[prop_name].SetData(val + b'\0')
def AddString(self, prop_name, val):
"""Add a new string property to a node
@@ -481,29 +498,35 @@ class Fdt:
Properties:
fname: Filename of fdt
_root: Root of device tree (a Node object)
+ name: Helpful name for this Fdt for the user (useful when creating the
+ DT from data rather than a file)
"""
def __init__(self, fname):
self._fname = fname
self._cached_offsets = False
self.phandle_to_node = {}
+ self.name = ''
if self._fname:
+ self.name = self._fname
self._fname = fdt_util.EnsureCompiled(self._fname)
with open(self._fname, 'rb') as fd:
self._fdt_obj = libfdt.Fdt(fd.read())
@staticmethod
- def FromData(data):
+ def FromData(data, name=''):
"""Create a new Fdt object from the given data
Args:
data: Device-tree data blob
+ name: Helpful name for this Fdt for the user
Returns:
Fdt object containing the data
"""
fdt = Fdt(None)
fdt._fdt_obj = libfdt.Fdt(bytes(data))
+ fdt.name = name
return fdt
def LookupPhandle(self, phandle):
@@ -551,6 +574,8 @@ class Fdt:
parts = path.split('/')
if len(parts) < 2:
return None
+ if len(parts) == 2 and parts[1] == '':
+ return node
for part in parts[1:]:
node = node.FindNode(part)
if not node:
@@ -670,6 +695,14 @@ class Fdt:
node = Node(fdt, parent, offset, name, path)
return node
+ def GetFilename(self):
+ """Get the filename of the device tree
+
+ Returns:
+ String filename
+ """
+ return self._fname
+
def FdtScan(fname):
"""Returns a new Fdt object"""
dtb = Fdt(fname)
diff --git a/tools/dtoc/fdt_util.py b/tools/dtoc/fdt_util.py
index f47879ac00..b105faec74 100644
--- a/tools/dtoc/fdt_util.py
+++ b/tools/dtoc/fdt_util.py
@@ -43,12 +43,14 @@ def fdt_cells_to_cpu(val, cells):
out = out << 32 | fdt32_to_cpu(val[1])
return out
-def EnsureCompiled(fname, capture_stderr=False):
+def EnsureCompiled(fname, tmpdir=None, capture_stderr=False):
"""Compile an fdt .dts source file into a .dtb binary blob if needed.
Args:
fname: Filename (if .dts it will be compiled). It not it will be
left alone
+ tmpdir: Temporary directory for output files, or None to use the
+ tools-module output directory
Returns:
Filename of resulting .dtb file
@@ -57,8 +59,12 @@ def EnsureCompiled(fname, capture_stderr=False):
if ext != '.dts':
return fname
- dts_input = tools.GetOutputFilename('source.dts')
- dtb_output = tools.GetOutputFilename('source.dtb')
+ if tmpdir:
+ dts_input = os.path.join(tmpdir, 'source.dts')
+ dtb_output = os.path.join(tmpdir, 'source.dtb')
+ else:
+ dts_input = tools.GetOutputFilename('source.dts')
+ dtb_output = tools.GetOutputFilename('source.dtb')
search_paths = [os.path.join(os.getcwd(), 'include')]
root, _ = os.path.splitext(fname)
diff --git a/tools/dtoc/test_fdt.py b/tools/dtoc/test_fdt.py
index bf469dbd54..028c8cbaa8 100755
--- a/tools/dtoc/test_fdt.py
+++ b/tools/dtoc/test_fdt.py
@@ -9,7 +9,9 @@ from __future__ import print_function
from optparse import OptionParser
import glob
import os
+import shutil
import sys
+import tempfile
import unittest
# Bring in the patman libraries
@@ -77,11 +79,16 @@ class TestFdt(unittest.TestCase):
"""Test the GetNode() method"""
node = self.dtb.GetNode('/spl-test')
self.assertTrue(isinstance(node, fdt.Node))
+
node = self.dtb.GetNode('/i2c@0/pmic@9')
self.assertTrue(isinstance(node, fdt.Node))
self.assertEqual('pmic@9', node.name)
self.assertIsNone(self.dtb.GetNode('/i2c@0/pmic@9/missing'))
+ node = self.dtb.GetNode('/')
+ self.assertTrue(isinstance(node, fdt.Node))
+ self.assertEqual(0, node.Offset())
+
def testFlush(self):
"""Check that we can flush the device tree out to its file"""
fname = self.dtb._fname
@@ -421,6 +428,32 @@ class TestProp(unittest.TestCase):
self.dtb.Sync(auto_resize=True)
self.assertTrue(dtb2.GetContents() != self.dtb.GetContents())
+ def testMissingSetInt(self):
+ """Test handling of a missing property with SetInt"""
+ with self.assertRaises(ValueError) as e:
+ self.node.SetInt('one', 1)
+ self.assertIn("node '/spl-test': Missing property 'one'",
+ str(e.exception))
+
+ def testMissingSetData(self):
+ """Test handling of a missing property with SetData"""
+ with self.assertRaises(ValueError) as e:
+ self.node.SetData('one', b'data')
+ self.assertIn("node '/spl-test': Missing property 'one'",
+ str(e.exception))
+
+ def testMissingSetString(self):
+ """Test handling of a missing property with SetString"""
+ with self.assertRaises(ValueError) as e:
+ self.node.SetString('one', 1)
+ self.assertIn("node '/spl-test': Missing property 'one'",
+ str(e.exception))
+
+ def testGetFilename(self):
+ """Test the dtb filename can be provided"""
+ self.assertEqual(tools.GetOutputFilename('source.dtb'),
+ self.dtb.GetFilename())
+
class TestFdtUtil(unittest.TestCase):
"""Tests for the fdt_util module
@@ -514,10 +547,23 @@ class TestFdtUtil(unittest.TestCase):
self.assertEqual(0x12345678, fdt_util.fdt_cells_to_cpu(val, 1))
def testEnsureCompiled(self):
- """Test a degenerate case of this function"""
+ """Test a degenerate case of this function (file already compiled)"""
dtb = fdt_util.EnsureCompiled('tools/dtoc/dtoc_test_simple.dts')
self.assertEqual(dtb, fdt_util.EnsureCompiled(dtb))
+ def testEnsureCompiledTmpdir(self):
+ """Test providing a temporary directory"""
+ try:
+ old_outdir = tools.outdir
+ tools.outdir= None
+ tmpdir = tempfile.mkdtemp(prefix='test_fdt.')
+ dtb = fdt_util.EnsureCompiled('tools/dtoc/dtoc_test_simple.dts',
+ tmpdir)
+ self.assertEqual(tmpdir, os.path.dirname(dtb))
+ shutil.rmtree(tmpdir)
+ finally:
+ tools.outdir= old_outdir
+
def RunTestCoverage():
"""Run the tests and check that we get 100% coverage"""