Allow updating and creating properties, including special methods for integers. Signed-off-by: Simon Glass <sjg@xxxxxxxxxxxx> Reviewed-by: David Gibson <david@xxxxxxxxxxxxxxxxxxxxx> --- Changes in v2: - Use resize() instead of open_into() since that method was renamed libfdt/libfdt.h | 3 +++ pylibfdt/libfdt.i | 59 +++++++++++++++++++++++++++++++++++++++++ tests/pylibfdt_tests.py | 48 +++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+) diff --git a/libfdt/libfdt.h b/libfdt/libfdt.h index f044298..b4be2d6 100644 --- a/libfdt/libfdt.h +++ b/libfdt/libfdt.h @@ -1342,10 +1342,13 @@ static inline int fdt_property_u64(void *fdt, const char *name, uint64_t val) fdt64_t tmp = cpu_to_fdt64(val); return fdt_property(fdt, name, &tmp, sizeof(tmp)); } + +#ifndef SWIG /* Not available in Python */ static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val) { return fdt_property_u32(fdt, name, val); } +#endif /** * fdt_property_placeholder - add a new property and return a ptr to its value diff --git a/pylibfdt/libfdt.i b/pylibfdt/libfdt.i index 4d87da9..0eefc5a 100644 --- a/pylibfdt/libfdt.i +++ b/pylibfdt/libfdt.i @@ -547,6 +547,60 @@ class Fdt: """ return check_err(fdt_parent_offset(self._fdt, nodeoffset), quiet) + def setprop(self, nodeoffset, prop_name, val, quiet=()): + """Set the value of a property + + Args: + nodeoffset: Node offset containing the property to create/update + prop_name: Name of property + val: Value to write (string or bytearray) + quiet: Errors to ignore (empty to raise on all errors) + + Returns: + Error code, or 0 if OK + + Raises: + FdtException if no parent found or other error occurs + """ + return check_err(fdt_setprop(self._fdt, nodeoffset, prop_name, val, + len(val)), quiet) + + def setprop_u32(self, nodeoffset, prop_name, val, quiet=()): + """Set the value of a property + + Args: + nodeoffset: Node offset containing the property to create/update + prop_name: Name of property + val: Value to write (integer) + quiet: Errors to ignore (empty to raise on all errors) + + Returns: + Error code, or 0 if OK + + Raises: + FdtException if no parent found or other error occurs + """ + return check_err(fdt_setprop_u32(self._fdt, nodeoffset, prop_name, val), + quiet) + + def setprop_u64(self, nodeoffset, prop_name, val, quiet=()): + """Set the value of a property + + Args: + nodeoffset: Node offset containing the property to create/update + prop_name: Name of property + val: Value to write (integer) + quiet: Errors to ignore (empty to raise on all errors) + + Returns: + Error code, or 0 if OK + + Raises: + FdtException if no parent found or other error occurs + """ + return check_err(fdt_setprop_u64(self._fdt, nodeoffset, prop_name, val), + quiet) + def delprop(self, nodeoffset, prop_name): """Delete a property from a node @@ -644,6 +698,11 @@ typedef int fdt32_t; $result = Py_BuildValue("s#", $1, *arg4); } +/* typemap used for fdt_setprop() */ +%typemap(in) (const void *val) { + $1 = PyString_AsString($input); /* char *str */ +} + /* typemaps used for fdt_next_node() */ %typemap(in, numinputs=1) int *depth (int depth) { depth = (int) PyInt_AsLong($input); diff --git a/tests/pylibfdt_tests.py b/tests/pylibfdt_tests.py index 96a46f3..2badef2 100644 --- a/tests/pylibfdt_tests.py +++ b/tests/pylibfdt_tests.py @@ -49,6 +49,7 @@ # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # +import struct import sys import types import unittest @@ -57,6 +58,18 @@ sys.path.insert(0, '../pylibfdt') import libfdt from libfdt import Fdt, FdtException, QUIET_NOTFOUND, QUIET_ALL +small_size = 160 +full_size = 1024 + +TEST_VALUE_1 = 0xdeadbeef + +TEST_VALUE64_1H = 0xdeadbeef +TEST_VALUE64_1L = 0x01abcdef +TEST_VALUE64_1 = (TEST_VALUE64_1H << 32) | TEST_VALUE64_1L + +TEST_STRING_1 = 'hello world' + + def get_err(err_code): """Convert an error code into an error message @@ -393,6 +406,41 @@ class PyLibfdtTests(unittest.TestCase): fdt.pack() self.assertTrue(fdt.totalsize() < 128) + def testSetProp(self): + """Test that we can update and create properties""" + node = self.fdt.path_offset('/subnode@1') + self.fdt.setprop(node, 'compatible', TEST_STRING_1) + self.assertEquals(TEST_STRING_1, self.fdt.getprop(node, 'compatible')) + + # Check that this property is missing, and that we don't have space to + # add it + self.assertEquals(-libfdt.NOTFOUND, + self.fdt.getprop(node, 'missing', QUIET_NOTFOUND)) + self.assertEquals(-libfdt.NOSPACE, + self.fdt.setprop(node, 'missing', TEST_STRING_1, + quiet=(libfdt.NOSPACE,))) + + # Expand the device tree so we now have room + self.fdt.resize(self.fdt.totalsize() + 50) + self.fdt.setprop(node, 'missing', TEST_STRING_1) + self.assertEquals(TEST_STRING_1, self.fdt.getprop(node, 'missing')) + + def testSetPropU32(self): + """Test that we can update and create integer properties""" + node = 0 + prop = 'prop-int' + self.fdt.setprop_u32(node, prop, TEST_VALUE_1) + self.assertEquals(struct.pack('>I', TEST_VALUE_1), + self.fdt.getprop(node, prop)) + + def testSetPropU64(self): + """Test that we can update and create integer properties""" + node = 0 + prop = 'prop-int64' + self.fdt.setprop_u64(node, prop, TEST_VALUE64_1) + self.assertEquals(struct.pack('>Q', TEST_VALUE64_1), + self.fdt.getprop(node, prop)) + if __name__ == "__main__": unittest.main() -- 2.17.1.1185.g55be947832-goog -- To unsubscribe from this list: send the line "unsubscribe devicetree-compiler" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html