From 6434961b2b2099b458e7dc9dcced5d450b45cbb4 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 14 Sep 2018 04:57:16 -0600 Subject: [PATCH] dtoc: Add methods for adding and updating properties Add a few more functions which allow creating and modifying property values. If only we could do this so easily in the real world. Signed-off-by: Simon Glass --- tools/dtoc/fdt.py | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++ tools/dtoc/test_fdt.py | 43 +++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+) diff --git a/tools/dtoc/fdt.py b/tools/dtoc/fdt.py index 26f4a4e..c5054e8 100644 --- a/tools/dtoc/fdt.py +++ b/tools/dtoc/fdt.py @@ -175,6 +175,16 @@ class Prop: self.type = TYPE_INT self.dirty = True + def SetData(self, bytes): + """Set the value of a property as bytes + + Args: + bytes: New property value to set + """ + self.bytes = str(bytes) + self.type, self.value = self.BytesToValue(bytes) + self.dirty = True + def Sync(self, auto_resize=False): """Sync property changes back to the device tree @@ -326,18 +336,78 @@ class Node: """ self.props[prop_name] = Prop(self, None, prop_name, '\0' * 4) + def AddEmptyProp(self, prop_name, len): + """Add a property with a fixed data size, for filling in later + + The device tree is marked dirty so that the value will be written to + the blob on the next sync. + + Args: + prop_name: Name of property + len: Length of data in property + """ + value = chr(0) * len + self.props[prop_name] = Prop(self, None, prop_name, value) + def SetInt(self, prop_name, val): """Update an integer property int the device tree. This is not allowed to change the size of the FDT. + The device tree is marked dirty so that the value will be written to + the blob on the next sync. + Args: prop_name: Name of property val: Value to set """ self.props[prop_name].SetInt(val) + def SetData(self, prop_name, val): + """Set the data value of a property + + The device tree is marked dirty so that the value will be written to + the blob on the next sync. + + Args: + prop_name: Name of property to set + val: Data value to set + """ + self.props[prop_name].SetData(val) + + def SetString(self, prop_name, val): + """Set the string value of a property + + The device tree is marked dirty so that the value will be written to + the blob on the next sync. + + Args: + prop_name: Name of property to set + val: String value to set (will be \0-terminated in DT) + """ + self.props[prop_name].SetData(val + chr(0)) + + def AddString(self, prop_name, val): + """Add a new string property to a node + + The device tree is marked dirty so that the value will be written to + the blob on the next sync. + + Args: + prop_name: Name of property to add + val: String value of property + """ + self.props[prop_name] = Prop(self, None, prop_name, val + chr(0)) + def AddSubnode(self, name): + """Add a new subnode to the node + + Args: + name: name of node to add + + Returns: + New subnode that was created + """ path = self.path + '/' + name subnode = Node(self._fdt, self, None, name, path) self.subnodes.append(subnode) diff --git a/tools/dtoc/test_fdt.py b/tools/dtoc/test_fdt.py index c94e455..22a075d 100755 --- a/tools/dtoc/test_fdt.py +++ b/tools/dtoc/test_fdt.py @@ -352,6 +352,7 @@ class TestProp(unittest.TestCase): with self.assertRaises(libfdt.FdtException) as e: self.dtb.Sync(auto_resize=False) self.assertIn('FDT_ERR_NOSPACE', str(e.exception)) + self.dtb.Sync(auto_resize=True) def testAddNode(self): self.fdt.pack() @@ -364,6 +365,48 @@ class TestProp(unittest.TestCase): offset = self.fdt.path_offset('/spl-test/subnode') self.assertTrue(offset > 0) + def testAddMore(self): + """Test various other methods for adding and setting properties""" + self.node.AddZeroProp('one') + self.dtb.Sync(auto_resize=True) + data = self.fdt.getprop(self.node.Offset(), 'one') + self.assertEqual(0, fdt32_to_cpu(data)) + + self.node.SetInt('one', 1) + self.dtb.Sync(auto_resize=False) + data = self.fdt.getprop(self.node.Offset(), 'one') + self.assertEqual(1, fdt32_to_cpu(data)) + + val = '123' + chr(0) + '456' + self.node.AddString('string', val) + self.dtb.Sync(auto_resize=True) + data = self.fdt.getprop(self.node.Offset(), 'string') + self.assertEqual(val + '\0', data) + + self.fdt.pack() + self.node.SetString('string', val + 'x') + with self.assertRaises(libfdt.FdtException) as e: + self.dtb.Sync(auto_resize=False) + self.assertIn('FDT_ERR_NOSPACE', str(e.exception)) + self.node.SetString('string', val[:-1]) + + prop = self.node.props['string'] + prop.SetData(val) + self.dtb.Sync(auto_resize=False) + data = self.fdt.getprop(self.node.Offset(), 'string') + self.assertEqual(val, data) + + self.node.AddEmptyProp('empty', 5) + self.dtb.Sync(auto_resize=True) + prop = self.node.props['empty'] + prop.SetData(val) + self.dtb.Sync(auto_resize=False) + data = self.fdt.getprop(self.node.Offset(), 'empty') + self.assertEqual(val, data) + + self.node.SetData('empty', '123') + self.assertEqual('123', prop.bytes) + class TestFdtUtil(unittest.TestCase): """Tests for the fdt_util module