浏览代码

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 <sjg@chromium.org>
Simon Glass 6 年之前
父节点
当前提交
6434961b2b
共有 2 个文件被更改,包括 113 次插入0 次删除
  1. 70 0
      tools/dtoc/fdt.py
  2. 43 0
      tools/dtoc/test_fdt.py

+ 70 - 0
tools/dtoc/fdt.py

@@ -175,6 +175,16 @@ class Prop:
         self.type = TYPE_INT
         self.type = TYPE_INT
         self.dirty = True
         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):
     def Sync(self, auto_resize=False):
         """Sync property changes back to the device tree
         """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)
         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):
     def SetInt(self, prop_name, val):
         """Update an integer property int the device tree.
         """Update an integer property int the device tree.
 
 
         This is not allowed to change the size of the FDT.
         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:
         Args:
             prop_name: Name of property
             prop_name: Name of property
             val: Value to set
             val: Value to set
         """
         """
         self.props[prop_name].SetInt(val)
         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):
     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
         path = self.path + '/' + name
         subnode = Node(self._fdt, self, None, name, path)
         subnode = Node(self._fdt, self, None, name, path)
         self.subnodes.append(subnode)
         self.subnodes.append(subnode)

+ 43 - 0
tools/dtoc/test_fdt.py

@@ -352,6 +352,7 @@ class TestProp(unittest.TestCase):
         with self.assertRaises(libfdt.FdtException) as e:
         with self.assertRaises(libfdt.FdtException) as e:
             self.dtb.Sync(auto_resize=False)
             self.dtb.Sync(auto_resize=False)
         self.assertIn('FDT_ERR_NOSPACE', str(e.exception))
         self.assertIn('FDT_ERR_NOSPACE', str(e.exception))
+        self.dtb.Sync(auto_resize=True)
 
 
     def testAddNode(self):
     def testAddNode(self):
         self.fdt.pack()
         self.fdt.pack()
@@ -364,6 +365,48 @@ class TestProp(unittest.TestCase):
         offset = self.fdt.path_offset('/spl-test/subnode')
         offset = self.fdt.path_offset('/spl-test/subnode')
         self.assertTrue(offset > 0)
         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):
 class TestFdtUtil(unittest.TestCase):
     """Tests for the fdt_util module
     """Tests for the fdt_util module