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>
This commit is contained in:
Simon Glass 2018-09-14 04:57:16 -06:00
parent e21c27af47
commit 6434961b2b
2 changed files with 113 additions and 0 deletions

View file

@ -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)

View file

@ -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