FDT wrappers: add functions for read/write bytes

This patch adds 'fdtw_read_bytes' and 'fdtw_write_inplace_bytes'
functions for read/write array of bytes from/to a given property.
It also adds 'fdt_setprop_inplace_namelen_partial' to jmptbl.i
files for builds with USE_ROMLIB=1 option.

Change-Id: Ied7b5c8b38a0e21d508aa7bcf5893e656028b14d
Signed-off-by: Alexei Fedorov <Alexei.Fedorov@arm.com>
diff --git a/common/fdt_wrappers.c b/common/fdt_wrappers.c
index e67fdb0..ca5b455 100644
--- a/common/fdt_wrappers.c
+++ b/common/fdt_wrappers.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -103,6 +103,41 @@
 }
 
 /*
+ * Read bytes from a given property of the given node. Any number of
+ * bytes of the property can be read. The fdt pointer is updated.
+ * Returns 0 on success, and -1 on error.
+ */
+int fdtw_read_bytes(const void *dtb, int node, const char *prop,
+		    unsigned int length, void *value)
+{
+	const void *ptr;
+	int value_len;
+
+	assert(dtb != NULL);
+	assert(prop != NULL);
+	assert(value != NULL);
+	assert(node >= 0);
+
+	/* Access property and obtain its length (in bytes) */
+	ptr = fdt_getprop_namelen(dtb, node, prop, (int)strlen(prop),
+					&value_len);
+	if (ptr == NULL) {
+		WARN("Couldn't find property %s in dtb\n", prop);
+		return -1;
+	}
+
+	/* Verify that property length is not less than number of bytes */
+	if ((unsigned int)value_len < length) {
+		WARN("Property length mismatch\n");
+		return -1;
+	}
+
+	(void)memcpy(value, ptr, length);
+
+	return 0;
+}
+
+/*
  * Read string from a given property of the given node. Up to 'size - 1'
  * characters are read, and a NUL terminator is added. Returns 0 on success,
  * and -1 upon error.
@@ -167,3 +202,45 @@
 
 	return 0;
 }
+
+/*
+ * Write bytes in place to a given property of the given node.
+ * Any number of bytes of the property can be written.
+ * Returns 0 on success, and < 0 on error.
+ */
+int fdtw_write_inplace_bytes(void *dtb, int node, const char *prop,
+			     unsigned int length, const void *data)
+{
+	const void *ptr;
+	int namelen, value_len, err;
+
+	assert(dtb != NULL);
+	assert(prop != NULL);
+	assert(data != NULL);
+	assert(node >= 0);
+
+	namelen = (int)strlen(prop);
+
+	/* Access property and obtain its length in bytes */
+	ptr = fdt_getprop_namelen(dtb, node, prop, namelen, &value_len);
+	if (ptr == NULL) {
+		WARN("Couldn't find property %s in dtb\n", prop);
+		return -1;
+	}
+
+	/* Verify that property length is not less than number of bytes */
+	if ((unsigned int)value_len < length) {
+		WARN("Property length mismatch\n");
+		return -1;
+	}
+
+	/* Set property value in place */
+	err = fdt_setprop_inplace_namelen_partial(dtb, node, prop,
+						  namelen, 0,
+						  data, (int)length);
+	if (err != 0) {
+		WARN("Set property %s failed with error %d\n", prop, err);
+	}
+
+	return err;
+}