[U-Boot] [PATCH 16/29] dtoc: Keep track of property offsets
Simon Glass
sjg at chromium.org
Wed Jun 6 00:46:52 UTC 2018
At present the Fdt class does not keep track of property offsets if they
change due to removal of properties. Update the code to handle this, and
add a test.
Signed-off-by: Simon Glass <sjg at chromium.org>
---
tools/dtoc/fdt.py | 19 +++++++++++++++++++
tools/dtoc/test_fdt.py | 39 ++++++++++++++++++++++++++++++++-------
2 files changed, 51 insertions(+), 7 deletions(-)
diff --git a/tools/dtoc/fdt.py b/tools/dtoc/fdt.py
index e24acf12804..2d7b6328f11 100644
--- a/tools/dtoc/fdt.py
+++ b/tools/dtoc/fdt.py
@@ -49,6 +49,9 @@ class Prop:
return
self.type, self.value = self.BytesToValue(bytes)
+ def RefreshOffset(self, poffset):
+ self._offset = poffset
+
def GetPhandle(self):
"""Get a (single) phandle value from a property
@@ -161,6 +164,7 @@ class Prop:
Returns:
The offset of the property (struct fdt_property) within the file
"""
+ self._node._fdt.CheckCache()
return self._node._fdt.GetStructOffset(self._offset)
class Node:
@@ -240,8 +244,22 @@ class Node:
self._offset = my_offset
offset = fdt_obj.first_subnode(self._offset, QUIET_NOTFOUND)
for subnode in self.subnodes:
+ if subnode.name != fdt_obj.get_name(offset):
+ raise ValueError('Node name mismatch %s != %s' %
+ (subnode.name != fdt_obj.get_name(offset)))
subnode.Refresh(offset)
offset = fdt_obj.next_subnode(offset, QUIET_NOTFOUND)
+ if offset != -libfdt.FDT_ERR_NOTFOUND:
+ raise ValueError('Internal error, offset == %d' % offset)
+
+ poffset = fdt_obj.first_property_offset(self._offset, QUIET_NOTFOUND)
+ while poffset >= 0:
+ p = fdt_obj.get_property_by_offset(poffset)
+ prop = self.props[p.name]
+ prop.RefreshOffset(poffset)
+ poffset = fdt_obj.next_property_offset(poffset, QUIET_NOTFOUND)
+ if poffset != -libfdt.FDT_ERR_NOTFOUND:
+ raise ValueError('Internal error, poffset == %d' % poffset)
def DeleteProp(self, prop_name):
"""Delete a property of a node
@@ -285,6 +303,7 @@ class Fdt:
TODO(sjg at chromium.org): Implement the 'root' parameter
"""
+ self._cached_offsets = True
self._root = self.Node(self, None, 0, '/', '/')
self._root.Scan()
diff --git a/tools/dtoc/test_fdt.py b/tools/dtoc/test_fdt.py
index ba95a4b77de..cd86144896f 100755
--- a/tools/dtoc/test_fdt.py
+++ b/tools/dtoc/test_fdt.py
@@ -23,6 +23,30 @@ import libfdt
import test_util
import tools
+def _GetPropertyValue(dtb, node, prop_name):
+ """Low-level function to get the property value based on its offset
+
+ This looks directly in the device tree at the property's offset to find
+ its value. It is useful as a check that the property is in the correct
+ place.
+
+ Args:
+ node: Node to look in
+ prop_name: Property name to find
+
+ Returns:
+ Tuple:
+ Prop object found
+ Value of property as a string (found using property offset)
+ """
+ prop = node.props[prop_name]
+
+ # Add 12, which is sizeof(struct fdt_property), to get to start of data
+ offset = prop.GetOffset() + 12
+ data = dtb.GetContents()[offset:offset + len(prop.value)]
+ return prop, [chr(x) for x in data]
+
+
class TestFdt(unittest.TestCase):
"""Tests for the Fdt module
@@ -122,6 +146,12 @@ class TestNode(unittest.TestCase):
with self.assertRaises(libfdt.FdtException):
self.node.DeleteProp('missing')
+ def testDeleteGetOffset(self):
+ """Test that property offset update when properties are deleted"""
+ self.node.DeleteProp('intval')
+ prop, value = _GetPropertyValue(self.dtb, self.node, 'longbytearray')
+ self.assertEqual(prop.value, value)
+
def testFindNode(self):
"""Tests that we can find a node using the _FindNode() functoin"""
node = self.dtb.GetRoot()._FindNode('i2c at 0')
@@ -203,13 +233,8 @@ class TestProp(unittest.TestCase):
def testGetOffset(self):
"""Test we can get the offset of a property"""
- prop = self.node.props['longbytearray']
-
- # Add 12, which is sizeof(struct fdt_property), to get to start of data
- offset = prop.GetOffset() + 12
- data = self.dtb.GetContents()[offset:offset + len(prop.value)]
- bytes = [chr(x) for x in data]
- self.assertEqual(bytes, prop.value)
+ prop, value = _GetPropertyValue(self.dtb, self.node, 'longbytearray')
+ self.assertEqual(prop.value, value)
def testWiden(self):
"""Test widening of values"""
--
2.17.1.1185.g55be947832-goog
More information about the U-Boot
mailing list