* [PATCH 01/17] pylibfdt: Cast property length to Py_ssize_t
2026-08-24 13:12 [PATCH 00/17] pylibfdt: Update the U-Boot version with changes from upstream dtc Alexey Charkov
@ 2026-08-24 13:12 ` Alexey Charkov
2026-08-24 13:12 ` [PATCH 02/17] pylibfdt: Restore the upstream bytearray() in getprop() Alexey Charkov
` (17 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Alexey Charkov @ 2026-08-24 13:12 UTC (permalink / raw)
To: u-boot
Cc: Tom Rini, David Gibson, Luca Weiss, Brandon Maier,
Francesco Valla, Simon Glass, Rob Herring, Jaipaul Cheernam,
Alexey Charkov
Commit 7d01bb1c5a1d ("libfdt: Fix build with python 3.10") took only half
of the upstream fix, dtc commit 383e148b70a4 ("pylibfdt: fix with Python
3.10"): it defines PY_SSIZE_T_CLEAN but leaves the length argument passed
to Py_BuildValue() as a plain int. With PY_SSIZE_T_CLEAN in effect the "y#"
and "s#" converters read a Py_ssize_t, so passing an int is undefined
behaviour that happens to work only where the two share a representation.
Take the remaining hunk so the typemap matches upstream and the subsequent
upstream imports apply verbatim.
Signed-off-by: Alexey Charkov <alchark@flipper.net>
---
scripts/dtc/pylibfdt/libfdt.i_shipped | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/scripts/dtc/pylibfdt/libfdt.i_shipped b/scripts/dtc/pylibfdt/libfdt.i_shipped
index 326a15c7941e..eb075c0b92bf 100644
--- a/scripts/dtc/pylibfdt/libfdt.i_shipped
+++ b/scripts/dtc/pylibfdt/libfdt.i_shipped
@@ -1049,9 +1049,9 @@ typedef uint32_t fdt32_t;
$result = Py_None;
else
%#if PY_VERSION_HEX >= 0x03000000
- $result = Py_BuildValue("y#", $1, *arg4);
+ $result = Py_BuildValue("y#", $1, (Py_ssize_t)*arg4);
%#else
- $result = Py_BuildValue("s#", $1, *arg4);
+ $result = Py_BuildValue("s#", $1, (Py_ssize_t)*arg4);
%#endif
}
--
2.54.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 02/17] pylibfdt: Restore the upstream bytearray() in getprop()
2026-08-24 13:12 [PATCH 00/17] pylibfdt: Update the U-Boot version with changes from upstream dtc Alexey Charkov
2026-08-24 13:12 ` [PATCH 01/17] pylibfdt: Cast property length to Py_ssize_t Alexey Charkov
@ 2026-08-24 13:12 ` Alexey Charkov
2026-08-24 13:13 ` [PATCH 03/17] pylibfdt: Fix Python crash on getprop deallocation Alexey Charkov
` (16 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Alexey Charkov @ 2026-08-24 13:12 UTC (permalink / raw)
To: u-boot
Cc: Tom Rini, David Gibson, Luca Weiss, Brandon Maier,
Francesco Valla, Simon Glass, Rob Herring, Jaipaul Cheernam,
Alexey Charkov
Commit 903fe17aa8c8 ("pylibfdt: Sync up with upstream") replaced the
bytearray() that dtc uses here with bytes(), without saying why. The
result is the same either way, since Property derives from bytearray and
copies whatever it is handed, so restore the upstream spelling to keep the
shipped file mechanically comparable with dtc.
Signed-off-by: Alexey Charkov <alchark@flipper.net>
---
scripts/dtc/pylibfdt/libfdt.i_shipped | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/dtc/pylibfdt/libfdt.i_shipped b/scripts/dtc/pylibfdt/libfdt.i_shipped
index eb075c0b92bf..55170431357b 100644
--- a/scripts/dtc/pylibfdt/libfdt.i_shipped
+++ b/scripts/dtc/pylibfdt/libfdt.i_shipped
@@ -421,7 +421,7 @@ class FdtRo(object):
quiet)
if isinstance(pdata, (int)):
return pdata
- return Property(prop_name, bytes(pdata[0]))
+ return Property(prop_name, bytearray(pdata[0]))
def get_phandle(self, nodeoffset):
"""Get the phandle of a node
--
2.54.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 03/17] pylibfdt: Fix Python crash on getprop deallocation
2026-08-24 13:12 [PATCH 00/17] pylibfdt: Update the U-Boot version with changes from upstream dtc Alexey Charkov
2026-08-24 13:12 ` [PATCH 01/17] pylibfdt: Cast property length to Py_ssize_t Alexey Charkov
2026-08-24 13:12 ` [PATCH 02/17] pylibfdt: Restore the upstream bytearray() in getprop() Alexey Charkov
@ 2026-08-24 13:13 ` Alexey Charkov
2026-08-24 13:13 ` [PATCH 04/17] pylibfdt: Add Property.as_stringlist() Alexey Charkov
` (15 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Alexey Charkov @ 2026-08-24 13:13 UTC (permalink / raw)
To: u-boot
Cc: Tom Rini, David Gibson, Luca Weiss, Brandon Maier,
Francesco Valla, Simon Glass, Rob Herring, Jaipaul Cheernam,
Alexey Charkov
From: Luca Weiss <luca@z3ntu.xyz>
Fatal Python error: none_dealloc: deallocating None
Python runtime state: finalizing (tstate=0x000055c9bac70920)
Current thread 0x00007fbe34e47740 (most recent call first):
<no Python frame>
Aborted (core dumped)
This is caused by a missing Py_INCREF on the returned Py_None, as
demonstrated e.g. in https://github.com/mythosil/swig-python-incref or
described at https://edcjones.tripod.com/refcount.html ("Remember to
INCREF Py_None!")
A PoC for triggering this crash is uploaded to
https://github.com/z3ntu/pylibfdt-crash .
With this patch applied to pylibfdt the crash does not happen.
This is a backport of dtc commit d152126bb029 ("Fix Python crash on
getprop deallocation").
Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
[adapted to U-Boot]
Signed-off-by: Alexey Charkov <alchark@flipper.net>
---
scripts/dtc/pylibfdt/libfdt.i_shipped | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/scripts/dtc/pylibfdt/libfdt.i_shipped b/scripts/dtc/pylibfdt/libfdt.i_shipped
index 55170431357b..5025893b1e95 100644
--- a/scripts/dtc/pylibfdt/libfdt.i_shipped
+++ b/scripts/dtc/pylibfdt/libfdt.i_shipped
@@ -1045,14 +1045,16 @@ typedef uint32_t fdt32_t;
/* typemap used for fdt_getprop() */
%typemap(out) (const void *) {
- if (!$1)
+ if (!$1) {
$result = Py_None;
- else
+ Py_INCREF($result);
+ } else {
%#if PY_VERSION_HEX >= 0x03000000
$result = Py_BuildValue("y#", $1, (Py_ssize_t)*arg4);
%#else
$result = Py_BuildValue("s#", $1, (Py_ssize_t)*arg4);
%#endif
+ }
}
/* typemap used for fdt_setprop() */
--
2.54.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 04/17] pylibfdt: Add Property.as_stringlist()
2026-08-24 13:12 [PATCH 00/17] pylibfdt: Update the U-Boot version with changes from upstream dtc Alexey Charkov
` (2 preceding siblings ...)
2026-08-24 13:13 ` [PATCH 03/17] pylibfdt: Fix Python crash on getprop deallocation Alexey Charkov
@ 2026-08-24 13:13 ` Alexey Charkov
2026-08-24 13:13 ` [PATCH 05/17] pylibfdt: Add Property.as_*int*_array() Alexey Charkov
` (14 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Alexey Charkov @ 2026-08-24 13:13 UTC (permalink / raw)
To: u-boot
Cc: Tom Rini, David Gibson, Luca Weiss, Brandon Maier,
Francesco Valla, Simon Glass, Rob Herring, Jaipaul Cheernam,
Alexey Charkov
From: Luca Weiss <luca@z3ntu.xyz>
Add a new method for decoding a string list property, useful for e.g.
the "reg-names" property.
This is a backport of dtc commit 83102717d7c4 ("pylibfdt: add
Property.as_stringlist()"), without the dtc-side test, which has no
counterpart in U-Boot's test suite.
Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
[adapted to U-Boot]
Signed-off-by: Alexey Charkov <alchark@flipper.net>
---
scripts/dtc/pylibfdt/libfdt.i_shipped | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/scripts/dtc/pylibfdt/libfdt.i_shipped b/scripts/dtc/pylibfdt/libfdt.i_shipped
index 5025893b1e95..c8ac578b367b 100644
--- a/scripts/dtc/pylibfdt/libfdt.i_shipped
+++ b/scripts/dtc/pylibfdt/libfdt.i_shipped
@@ -728,6 +728,13 @@ class Property(bytearray):
raise ValueError('Property contains embedded nul characters')
return self[:-1].decode('utf-8')
+ def as_stringlist(self):
+ """Unicode is supported by decoding from UTF-8"""
+ if self[-1] != 0:
+ raise ValueError('Property lacks nul termination')
+ parts = self[:-1].split(b'\x00')
+ return list(map(lambda x: x.decode('utf-8'), parts))
+
class FdtSw(FdtRo):
"""Software interface to create a device tree from scratch
--
2.54.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 05/17] pylibfdt: Add Property.as_*int*_array()
2026-08-24 13:12 [PATCH 00/17] pylibfdt: Update the U-Boot version with changes from upstream dtc Alexey Charkov
` (3 preceding siblings ...)
2026-08-24 13:13 ` [PATCH 04/17] pylibfdt: Add Property.as_stringlist() Alexey Charkov
@ 2026-08-24 13:13 ` Alexey Charkov
2026-08-24 13:13 ` [PATCH 06/17] pylibfdt: Add FdtRo.get_path() Alexey Charkov
` (13 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Alexey Charkov @ 2026-08-24 13:13 UTC (permalink / raw)
To: u-boot
Cc: Tom Rini, David Gibson, Luca Weiss, Brandon Maier,
Francesco Valla, Simon Glass, Rob Herring, Jaipaul Cheernam,
Alexey Charkov
From: Luca Weiss <luca@z3ntu.xyz>
Add new methods to handle decoding of int32, uint32, int64 and uint64
arrays.
This is a backport of dtc commit a04f69025003 ("pylibfdt: add
Property.as_*int*_array()"), without the dtc-side tests, which have no
counterpart in U-Boot's test suite.
Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
[adapted to U-Boot]
Signed-off-by: Alexey Charkov <alchark@flipper.net>
---
scripts/dtc/pylibfdt/libfdt.i_shipped | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/scripts/dtc/pylibfdt/libfdt.i_shipped b/scripts/dtc/pylibfdt/libfdt.i_shipped
index c8ac578b367b..735a3bab6d9f 100644
--- a/scripts/dtc/pylibfdt/libfdt.i_shipped
+++ b/scripts/dtc/pylibfdt/libfdt.i_shipped
@@ -720,6 +720,21 @@ class Property(bytearray):
def as_int64(self):
return self.as_cell('q')
+ def as_list(self, fmt):
+ return list(map(lambda x: x[0], struct.iter_unpack('>' + fmt, self)))
+
+ def as_uint32_list(self):
+ return self.as_list('L')
+
+ def as_int32_list(self):
+ return self.as_list('l')
+
+ def as_uint64_list(self):
+ return self.as_list('Q')
+
+ def as_int64_list(self):
+ return self.as_list('q')
+
def as_str(self):
"""Unicode is supported by decoding from UTF-8"""
if self[-1] != 0:
--
2.54.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 06/17] pylibfdt: Add FdtRo.get_path()
2026-08-24 13:12 [PATCH 00/17] pylibfdt: Update the U-Boot version with changes from upstream dtc Alexey Charkov
` (4 preceding siblings ...)
2026-08-24 13:13 ` [PATCH 05/17] pylibfdt: Add Property.as_*int*_array() Alexey Charkov
@ 2026-08-24 13:13 ` Alexey Charkov
2026-08-24 13:13 ` [PATCH 07/17] pylibfdt: Work-around SWIG limitations with flexible arrays Alexey Charkov
` (12 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Alexey Charkov @ 2026-08-24 13:13 UTC (permalink / raw)
To: u-boot
Cc: Tom Rini, David Gibson, Luca Weiss, Brandon Maier,
Francesco Valla, Simon Glass, Rob Herring, Jaipaul Cheernam,
Alexey Charkov
From: Luca Weiss <luca@z3ntu.xyz>
Add a new Python method wrapping fdt_get_path() from the C API.
This is a backport of dtc commit ed310803ea89 ("pylibfdt: add
FdtRo.get_path()"), without the dtc-side test, which has no counterpart
in U-Boot's test suite.
Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
[adapted to U-Boot]
Signed-off-by: Alexey Charkov <alchark@flipper.net>
---
scripts/dtc/pylibfdt/libfdt.i_shipped | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/scripts/dtc/pylibfdt/libfdt.i_shipped b/scripts/dtc/pylibfdt/libfdt.i_shipped
index 735a3bab6d9f..634ccd2a829a 100644
--- a/scripts/dtc/pylibfdt/libfdt.i_shipped
+++ b/scripts/dtc/pylibfdt/libfdt.i_shipped
@@ -447,6 +447,29 @@ class FdtRo(object):
"""
return fdt_get_alias(self._fdt, name)
+ def get_path(self, nodeoffset, quiet=()):
+ """Get the full path of a node
+
+ Args:
+ nodeoffset: Node offset to check
+
+ Returns:
+ Full path to the node
+
+ Raises:
+ FdtException if an error occurs
+ """
+ size = 1024
+ while True:
+ ret, path = fdt_get_path(self._fdt, nodeoffset, size)
+ if ret == -NOSPACE:
+ size = size * 2
+ continue
+ err = check_err(ret, quiet)
+ if err:
+ return err
+ return path
+
def parent_offset(self, nodeoffset, quiet=()):
"""Get the offset of a node's parent
@@ -1120,6 +1143,11 @@ typedef uint32_t fdt32_t;
}
}
+%include "cstring.i"
+
+%cstring_output_maxsize(char *buf, int buflen);
+int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen);
+
/* We have both struct fdt_property and a function fdt_property() */
%warnfilter(302) fdt_property;
--
2.54.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 07/17] pylibfdt: Work-around SWIG limitations with flexible arrays
2026-08-24 13:12 [PATCH 00/17] pylibfdt: Update the U-Boot version with changes from upstream dtc Alexey Charkov
` (5 preceding siblings ...)
2026-08-24 13:13 ` [PATCH 06/17] pylibfdt: Add FdtRo.get_path() Alexey Charkov
@ 2026-08-24 13:13 ` Alexey Charkov
2026-08-24 13:13 ` [PATCH 08/17] pylibfdt: Add size_hint parameter for get_path Alexey Charkov
` (11 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Alexey Charkov @ 2026-08-24 13:13 UTC (permalink / raw)
To: u-boot
Cc: Tom Rini, David Gibson, Luca Weiss, Brandon Maier,
Francesco Valla, Simon Glass, Rob Herring, Jaipaul Cheernam,
Alexey Charkov
From: Rob Herring <robh@kernel.org>
SWIG cannot generate setters for a struct's flexible array member and
emits C that does not compile:
./pylibfdt/libfdt_wrap.c: In function '_wrap_fdt_node_header_name_set':
./pylibfdt/libfdt_wrap.c:4350:18: error: cast specifies array type
./pylibfdt/libfdt_wrap.c:4350:16: error: invalid use of flexible array member
./pylibfdt/libfdt_wrap.c:4613:18: error: cast specifies array type
./pylibfdt/libfdt_wrap.c:4613:16: error: invalid use of flexible array member
Turns out this is a known issue with SWIG:
https://github.com/swig/swig/issues/1699
Implement the work-around to ignore the flexible array member. U-Boot's
copy of fdt.h still declares those members as zero-length arrays, so
nothing breaks today, but carrying the work-around now keeps the shipped
file in step with upstream and avoids the failure when the C libfdt is
next resynced.
This is a backport of dtc commit abbd523bae6e ("pylibfdt: Work-around
SWIG limitations with flexible arrays").
Signed-off-by: Rob Herring <robh@kernel.org>
Reviewed-by: Simon Glass <sjg@chromium.org>
Tested-by: Simon Glass <sjg@chromium.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
[adapted to U-Boot]
Signed-off-by: Alexey Charkov <alchark@flipper.net>
---
scripts/dtc/pylibfdt/libfdt.i_shipped | 3 +++
1 file changed, 3 insertions(+)
diff --git a/scripts/dtc/pylibfdt/libfdt.i_shipped b/scripts/dtc/pylibfdt/libfdt.i_shipped
index 634ccd2a829a..2a7fdfb2af40 100644
--- a/scripts/dtc/pylibfdt/libfdt.i_shipped
+++ b/scripts/dtc/pylibfdt/libfdt.i_shipped
@@ -1041,6 +1041,9 @@ class NodeAdder():
%rename(fdt_property) fdt_property_func;
+%immutable fdt_property::data;
+%immutable fdt_node_header::name;
+
/*
* fdt32_t is a big-endian 32-bit value defined to uint32_t in libfdt_env.h
* so use the same type here.
--
2.54.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 08/17] pylibfdt: Add size_hint parameter for get_path
2026-08-24 13:12 [PATCH 00/17] pylibfdt: Update the U-Boot version with changes from upstream dtc Alexey Charkov
` (6 preceding siblings ...)
2026-08-24 13:13 ` [PATCH 07/17] pylibfdt: Work-around SWIG limitations with flexible arrays Alexey Charkov
@ 2026-08-24 13:13 ` Alexey Charkov
2026-08-24 13:13 ` [PATCH 09/17] pylibfdt: Support boolean properties Alexey Charkov
` (10 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Alexey Charkov @ 2026-08-24 13:13 UTC (permalink / raw)
To: u-boot
Cc: Tom Rini, David Gibson, Luca Weiss, Brandon Maier,
Francesco Valla, Simon Glass, Rob Herring, Jaipaul Cheernam,
Alexey Charkov
From: Luca Weiss <luca@z3ntu.xyz>
Let the caller pick the initial buffer size, which also makes the
-NOSPACE retry path reachable from a test by passing a tiny hint.
This is a backport of dtc commit 3f29d6d85c24 ("pylibfdt: add size_hint
parameter for get_path").
Signed-off-by: Luca Weiss <luca@z3ntu.xyz>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
[adapt to U-Boot]
Signed-off-by: Alexey Charkov <alchark@flipper.net>
---
scripts/dtc/pylibfdt/libfdt.i_shipped | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/scripts/dtc/pylibfdt/libfdt.i_shipped b/scripts/dtc/pylibfdt/libfdt.i_shipped
index 2a7fdfb2af40..6a900265459d 100644
--- a/scripts/dtc/pylibfdt/libfdt.i_shipped
+++ b/scripts/dtc/pylibfdt/libfdt.i_shipped
@@ -447,11 +447,12 @@ class FdtRo(object):
"""
return fdt_get_alias(self._fdt, name)
- def get_path(self, nodeoffset, quiet=()):
+ def get_path(self, nodeoffset, size_hint=1024, quiet=()):
"""Get the full path of a node
Args:
nodeoffset: Node offset to check
+ size_hint: Hint for size of returned string
Returns:
Full path to the node
@@ -459,11 +460,10 @@ class FdtRo(object):
Raises:
FdtException if an error occurs
"""
- size = 1024
while True:
- ret, path = fdt_get_path(self._fdt, nodeoffset, size)
+ ret, path = fdt_get_path(self._fdt, nodeoffset, size_hint)
if ret == -NOSPACE:
- size = size * 2
+ size_hint *= 2
continue
err = check_err(ret, quiet)
if err:
--
2.54.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 09/17] pylibfdt: Support boolean properties
2026-08-24 13:12 [PATCH 00/17] pylibfdt: Update the U-Boot version with changes from upstream dtc Alexey Charkov
` (7 preceding siblings ...)
2026-08-24 13:13 ` [PATCH 08/17] pylibfdt: Add size_hint parameter for get_path Alexey Charkov
@ 2026-08-24 13:13 ` Alexey Charkov
2026-08-24 13:13 ` [PATCH 10/17] pylibfdt: Fix get_mem_rsv for newer Python versions Alexey Charkov
` (9 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Alexey Charkov @ 2026-08-24 13:13 UTC (permalink / raw)
To: u-boot
Cc: Tom Rini, David Gibson, Luca Weiss, Brandon Maier,
Francesco Valla, Simon Glass, Rob Herring, Jaipaul Cheernam,
Alexey Charkov
From: Simon Glass <sjg@chromium.org>
Boolean properties are unusual in that their presense or absence
indicates the value of the property. This makes them a little painful to
support using the existing getprop() support.
Add new methods to deal with booleans specifically.
This is a backport of dtc commit 52157f13ef3d ("pylibfdt: Support boolean
properties"), without the dtc-side tests, which have no counterpart in
U-Boot's test suite.
Signed-off-by: Simon Glass <sjg@chromium.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
[adapt to U-Boot]
Signed-off-by: Alexey Charkov <alchark@flipper.net>
---
scripts/dtc/pylibfdt/libfdt.i_shipped | 55 +++++++++++++++++++++++++++++++++++
1 file changed, 55 insertions(+)
diff --git a/scripts/dtc/pylibfdt/libfdt.i_shipped b/scripts/dtc/pylibfdt/libfdt.i_shipped
index 6a900265459d..dd568fc74935 100644
--- a/scripts/dtc/pylibfdt/libfdt.i_shipped
+++ b/scripts/dtc/pylibfdt/libfdt.i_shipped
@@ -423,6 +423,35 @@ class FdtRo(object):
return pdata
return Property(prop_name, bytearray(pdata[0]))
+ def hasprop(self, nodeoffset, prop_name, quiet=()):
+ """Check if a node has a property
+
+ This can be used to check boolean properties
+
+ Args:
+ nodeoffset: Node offset containing property to check
+ prop_name: Name of property to check
+ quiet: Errors to ignore (empty to raise on all errors). Note that
+ NOTFOUND is added internally by this function so need not be
+ provided
+
+ Returns:
+ True if the property exists in the node, else False. If an error
+ other than -NOTFOUND is returned by fdt_getprop() then the error
+ is return (-ve integer)
+
+ Raises:
+ FdtError if any error occurs other than NOTFOUND (e.g. the
+ nodeoffset is invalid)
+ """
+ pdata = check_err_null(fdt_getprop(self._fdt, nodeoffset, prop_name),
+ quiet + (NOTFOUND,))
+ if isinstance(pdata, (int)):
+ if pdata == -NOTFOUND:
+ return False
+ return pdata
+ return True
+
def get_phandle(self, nodeoffset):
"""Get the phandle of a node
@@ -609,6 +638,32 @@ class Fdt(FdtRo):
return check_err(fdt_setprop(self._fdt, nodeoffset, prop_name, val,
len(val)), quiet)
+ def setprop_bool(self, nodeoffset, prop_name, val, quiet=()):
+ """Set the boolean value of a property
+
+ Either:
+ adds the property if not already present; or
+ deletes the property if present
+
+ Args:
+ nodeoffset: Node offset containing the property to create/delete
+ prop_name: Name of property
+ val: Boolean value to write (i.e. True or False)
+ 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
+ """
+ exists = self.hasprop(nodeoffset, prop_name, quiet)
+ if val != exists:
+ if val:
+ return self.setprop(nodeoffset, prop_name, b'', quiet=quiet)
+ else:
+ return self.delprop(nodeoffset, prop_name, quiet=quiet)
+
def setprop_u32(self, nodeoffset, prop_name, val, quiet=()):
"""Set the value of a property
--
2.54.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 10/17] pylibfdt: Fix get_mem_rsv for newer Python versions
2026-08-24 13:12 [PATCH 00/17] pylibfdt: Update the U-Boot version with changes from upstream dtc Alexey Charkov
` (8 preceding siblings ...)
2026-08-24 13:13 ` [PATCH 09/17] pylibfdt: Support boolean properties Alexey Charkov
@ 2026-08-24 13:13 ` Alexey Charkov
2026-08-24 13:13 ` [PATCH 11/17] pylibfdt: Fix backwards compatibility of return values Alexey Charkov
` (8 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Alexey Charkov @ 2026-08-24 13:13 UTC (permalink / raw)
To: u-boot
Cc: Tom Rini, David Gibson, Luca Weiss, Brandon Maier,
Francesco Valla, Simon Glass, Rob Herring, Jaipaul Cheernam,
Alexey Charkov, Brandon Maier
From: Brandon Maier <brandon.maier@collins.com>
The test for get_mem_rsv fails on newer versions of Python with the
following error.
> AssertionError: Lists differ:
> [16045690981097406464, 1048576] != [0, 16045690981097406464, 1048576]
It appears this is because the PyTuple_GET_SIZE() function that was used
to build the fdt_get_mem_rsv() return value has changed. It now is
returning a non-zero value when it's passed an integer, which causes the
SWIG wrapper to append the returned arguments to the return error rather
then ignore them.
This is valid behaviour per Python's documentation, which says it will
"Return the size of the tuple p, which must be non-NULL and point to a
tuple; no error checking is performed"[1]. As passing an integer is not
a tuple, its return value is undefined.
Fix this issue on older and newer versions by avoiding
PyTuple_GET_SIZE() entirely. Always append the arguments to the list,
and instead use the wrapper python function to check the first argument
and then splice the last two arguments as the return value.
[1] https://docs.python.org/3/c-api/tuple.html#c.PyTuple_GET_SIZE
This is a backport of dtc commit 822123856980 ("pylibfdt: fix get_mem_rsv
for newer Python versions"), keeping the SWIG_AppendOutput() spelling
introduced by commit a63456b9191f ("scripts/dtc/pylibfdt/libfdt.i_shipped:
Use SWIG_AppendOutput").
Signed-off-by: Brandon Maier <brandon.maier@collins.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
[adapt to U-Boot]
Signed-off-by: Alexey Charkov <alchark@flipper.net>
---
scripts/dtc/pylibfdt/libfdt.i_shipped | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/scripts/dtc/pylibfdt/libfdt.i_shipped b/scripts/dtc/pylibfdt/libfdt.i_shipped
index dd568fc74935..0204708aa6f4 100644
--- a/scripts/dtc/pylibfdt/libfdt.i_shipped
+++ b/scripts/dtc/pylibfdt/libfdt.i_shipped
@@ -299,7 +299,9 @@ class FdtRo(object):
Returns:
Number of memory reserve-map records
"""
- return check_err(fdt_get_mem_rsv(self._fdt, index), quiet)
+ val = fdt_get_mem_rsv(self._fdt, index)
+ check_err(val[0], quiet)
+ return val[1:]
def subnode_offset(self, parentoffset, name, quiet=()):
"""Get the offset of a named subnode
@@ -1193,12 +1195,7 @@ typedef uint32_t fdt32_t;
%typemap(argout) uint64_t * {
PyObject *val = PyLong_FromUnsignedLongLong(*arg$argnum);
- if (!result) {
- if (PyTuple_GET_SIZE(resultobj) == 0)
- resultobj = val;
- else
- resultobj = SWIG_AppendOutput(resultobj, val);
- }
+ resultobj = SWIG_AppendOutput(resultobj, val);
}
%include "cstring.i"
--
2.54.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 11/17] pylibfdt: Fix backwards compatibility of return values
2026-08-24 13:12 [PATCH 00/17] pylibfdt: Update the U-Boot version with changes from upstream dtc Alexey Charkov
` (9 preceding siblings ...)
2026-08-24 13:13 ` [PATCH 10/17] pylibfdt: Fix get_mem_rsv for newer Python versions Alexey Charkov
@ 2026-08-24 13:13 ` Alexey Charkov
2026-08-24 13:13 ` [PATCH 12/17] pylibfdt: Fix a typo in the next_node() docstring Alexey Charkov
` (7 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Alexey Charkov @ 2026-08-24 13:13 UTC (permalink / raw)
To: u-boot
Cc: Tom Rini, David Gibson, Luca Weiss, Brandon Maier,
Francesco Valla, Simon Glass, Rob Herring, Jaipaul Cheernam,
Alexey Charkov
From: Brandon Maier <brandon.maier@gmail.com>
When our Python functions wrap `fdt_getprop()` they return a list
containing `[*data, length]`.
In SWIG v4.2 and earlier SWIG would discard `*data` if it is NULL/None.
Causing the return value to just be `length`.
But starting in SWIG v4.3 it no longer discards `*data`. So the return
value is now `[None, length]`.
Handle this compatibility issue in libfdt.i by checking if the return
value looks like the older 4.2 return value, and casting it to the newer
style.
See https://github.com/swig/swig/pull/2907
This is a backport of dtc commit 9a969f3b70b0 ("pylibfdt/libfdt.i: fix
backwards compatibility of return values"). Its prerequisite is already
in tree as commit a63456b9191f ("scripts/dtc/pylibfdt/libfdt.i_shipped:
Use SWIG_AppendOutput").
Signed-off-by: Brandon Maier <brandon.maier@gmail.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
[adapt to U-Boot]
Signed-off-by: Alexey Charkov <alchark@flipper.net>
---
scripts/dtc/pylibfdt/libfdt.i_shipped | 25 ++++++++++++++-----------
1 file changed, 14 insertions(+), 11 deletions(-)
diff --git a/scripts/dtc/pylibfdt/libfdt.i_shipped b/scripts/dtc/pylibfdt/libfdt.i_shipped
index 0204708aa6f4..2c8efd57a607 100644
--- a/scripts/dtc/pylibfdt/libfdt.i_shipped
+++ b/scripts/dtc/pylibfdt/libfdt.i_shipped
@@ -118,11 +118,14 @@ def check_err_null(val, quiet=()):
FdtException if val indicates an error was reported and the error
is not in @quiet.
"""
- # Normally a list is returned which contains the data and its length.
- # If we get just an integer error code, it means the function failed.
+ # Compatibility for SWIG v4.2 and earlier. SWIG 4.2 would drop the first
+ # item from the list if it was None, returning only the second item.
if not isinstance(val, list):
- if -val not in quiet:
- raise FdtException(val)
+ val = [None, val]
+
+ if val[0] is None:
+ if -val[1] not in quiet:
+ raise FdtException(val[1])
return val
class FdtRo(object):
@@ -399,8 +402,8 @@ class FdtRo(object):
"""
pdata = check_err_null(
fdt_get_property_by_offset(self._fdt, prop_offset), quiet)
- if isinstance(pdata, (int)):
- return pdata
+ if pdata[0] is None:
+ return pdata[1]
return Property(pdata[0], pdata[1])
def getprop(self, nodeoffset, prop_name, quiet=()):
@@ -421,8 +424,8 @@ class FdtRo(object):
"""
pdata = check_err_null(fdt_getprop(self._fdt, nodeoffset, prop_name),
quiet)
- if isinstance(pdata, (int)):
- return pdata
+ if pdata[0] is None:
+ return pdata[1]
return Property(prop_name, bytearray(pdata[0]))
def hasprop(self, nodeoffset, prop_name, quiet=()):
@@ -448,10 +451,10 @@ class FdtRo(object):
"""
pdata = check_err_null(fdt_getprop(self._fdt, nodeoffset, prop_name),
quiet + (NOTFOUND,))
- if isinstance(pdata, (int)):
- if pdata == -NOTFOUND:
+ if pdata[0] is None:
+ if pdata[1] == -NOTFOUND:
return False
- return pdata
+ return pdata[1]
return True
def get_phandle(self, nodeoffset):
--
2.54.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 12/17] pylibfdt: Fix a typo in the next_node() docstring
2026-08-24 13:12 [PATCH 00/17] pylibfdt: Update the U-Boot version with changes from upstream dtc Alexey Charkov
` (10 preceding siblings ...)
2026-08-24 13:13 ` [PATCH 11/17] pylibfdt: Fix backwards compatibility of return values Alexey Charkov
@ 2026-08-24 13:13 ` Alexey Charkov
2026-08-24 13:13 ` [PATCH 13/17] pylibfdt: Grow the FdtSw buffer geometrically Alexey Charkov
` (6 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Alexey Charkov @ 2026-08-24 13:13 UTC (permalink / raw)
To: u-boot
Cc: Tom Rini, David Gibson, Luca Weiss, Brandon Maier,
Francesco Valla, Simon Glass, Rob Herring, Jaipaul Cheernam,
Alexey Charkov, Thomas Huth
From: Thomas Huth <thuth@redhat.com>
Spell "Tuple" correctly.
This is the pylibfdt part of dtc commit 205fbef17b7b ("Fix some typos");
the other files that commit touches carry no such typos in tree.
Signed-off-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
[adapt to U-Boot, rewrite commit message accordingly]
Signed-off-by: Alexey Charkov <alchark@flipper.net>
---
scripts/dtc/pylibfdt/libfdt.i_shipped | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/dtc/pylibfdt/libfdt.i_shipped b/scripts/dtc/pylibfdt/libfdt.i_shipped
index 2c8efd57a607..2179515a144b 100644
--- a/scripts/dtc/pylibfdt/libfdt.i_shipped
+++ b/scripts/dtc/pylibfdt/libfdt.i_shipped
@@ -166,7 +166,7 @@ class FdtRo(object):
quiet: Errors to ignore (empty to raise on all errors)
Returns:
- Typle:
+ Tuple:
Offset of the next node, if any, else a -ve error
Depth of the returned node, if any, else undefined
--
2.54.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 13/17] pylibfdt: Grow the FdtSw buffer geometrically
2026-08-24 13:12 [PATCH 00/17] pylibfdt: Update the U-Boot version with changes from upstream dtc Alexey Charkov
` (11 preceding siblings ...)
2026-08-24 13:13 ` [PATCH 12/17] pylibfdt: Fix a typo in the next_node() docstring Alexey Charkov
@ 2026-08-24 13:13 ` Alexey Charkov
2026-08-24 13:13 ` [PATCH 14/17] pylibfdt: Add address_cells() and size_cells() Alexey Charkov
` (5 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Alexey Charkov @ 2026-08-24 13:13 UTC (permalink / raw)
To: u-boot
Cc: Tom Rini, David Gibson, Luca Weiss, Brandon Maier,
Francesco Valla, Simon Glass, Rob Herring, Jaipaul Cheernam,
Alexey Charkov
Every expansion copies the whole tree into a freshly allocated buffer, so
growing by a fixed amount makes building a tree cost time quadratic in
its size. This is especially painful when assembling larger FIT images with
binman, as it assembles the image with the data inline.
Grow by at least as much as the tree already holds, which is what variable
sized arrays usually do specifically to avoid such excessive copying.
With this change, building a Rockchip TF-A+Falcon image whose FIT carries
a 31 MiB kernel takes 33.1 s rather than 44.4 s, with binman itself down
from 25.3 s to 14.0 s, as 7139 reallocations become 187. The images
produced are byte-identical and the binman and dtoc test results are
unaffected.
This is a backport of dtc commit 0748c384fde6 ("pylibfdt: Grow the FdtSw
buffer geometrically").
Link: https://github.com/dgibson/dtc/pull/189
Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Alexey Charkov <alchark@flipper.net>
---
scripts/dtc/pylibfdt/libfdt.i_shipped | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/scripts/dtc/pylibfdt/libfdt.i_shipped b/scripts/dtc/pylibfdt/libfdt.i_shipped
index 2179515a144b..c00e74a46b76 100644
--- a/scripts/dtc/pylibfdt/libfdt.i_shipped
+++ b/scripts/dtc/pylibfdt/libfdt.i_shipped
@@ -861,7 +861,7 @@ class FdtSw(FdtRo):
device tree. This will be increased automatically as needed as new items
are added to the tree.
"""
- INC_SIZE = 1024 # Expand size by this much when out of space
+ INC_SIZE = 1024 # Expand size by at least this much when out of space
def __init__(self, size_hint=None):
"""Create a new FdtSw object
@@ -906,6 +906,10 @@ class FdtSw(FdtRo):
-NOSPACE then the FDT will be expanded to have more space, and True will
be returned, indicating that the operation needs to be tried again.
+ Each expansion copies the whole tree into a new buffer, so the size is
+ at least doubled rather than grown by a fixed amount, to keep the total
+ amount of copying proportional to the size of the tree.
+
Args:
val: Return value from the operation that was attempted
@@ -913,7 +917,7 @@ class FdtSw(FdtRo):
True if the operation must be retried, else False
"""
if check_err(val, QUIET_NOSPACE) < 0:
- self.resize(len(self._fdt) + self.INC_SIZE)
+ self.resize(len(self._fdt) + max(len(self._fdt), self.INC_SIZE))
return True
return False
--
2.54.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 14/17] pylibfdt: Add address_cells() and size_cells()
2026-08-24 13:12 [PATCH 00/17] pylibfdt: Update the U-Boot version with changes from upstream dtc Alexey Charkov
` (12 preceding siblings ...)
2026-08-24 13:13 ` [PATCH 13/17] pylibfdt: Grow the FdtSw buffer geometrically Alexey Charkov
@ 2026-08-24 13:13 ` Alexey Charkov
2026-08-24 13:13 ` [PATCH 15/17] pylibfdt: Add add_mem_rsv() and del_mem_rsv() Alexey Charkov
` (4 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Alexey Charkov @ 2026-08-24 13:13 UTC (permalink / raw)
To: u-boot
Cc: Tom Rini, David Gibson, Luca Weiss, Brandon Maier,
Francesco Valla, Simon Glass, Rob Herring, Jaipaul Cheernam,
Alexey Charkov
Finding out how many cells a node's children use for addresses and sizes
currently requires calling the raw fdt_address_cells()/fdt_size_cells()
wrappers with the private FdtRo._fdt buffer, as the class exposes no
methods for them.
Add them to FdtRo alongside the other node accessors.
This is a backport of dtc commit 3750493c8b0f ("pylibfdt: Add
address_cells() and size_cells()").
Link: https://github.com/dgibson/dtc/pull/190
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexey Charkov <alchark@flipper.net>
---
scripts/dtc/pylibfdt/libfdt.i_shipped | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/scripts/dtc/pylibfdt/libfdt.i_shipped b/scripts/dtc/pylibfdt/libfdt.i_shipped
index c00e74a46b76..1983ebaee335 100644
--- a/scripts/dtc/pylibfdt/libfdt.i_shipped
+++ b/scripts/dtc/pylibfdt/libfdt.i_shipped
@@ -306,6 +306,38 @@ class FdtRo(object):
check_err(val[0], quiet)
return val[1:]
+ def address_cells(self, nodeoffset, quiet=()):
+ """Return the number of address cells used by a node's children
+
+ Args:
+ nodeoffset: Offset of the node to check
+ quiet: Errors to ignore (empty to raise on all errors)
+
+ Returns:
+ Number of address cells used by the children of @nodeoffset
+
+ Raises:
+ FdtException if the node has an invalid #address-cells property,
+ or another error occurs
+ """
+ return check_err(fdt_address_cells(self._fdt, nodeoffset), quiet)
+
+ def size_cells(self, nodeoffset, quiet=()):
+ """Return the number of size cells used by a node's children
+
+ Args:
+ nodeoffset: Offset of the node to check
+ quiet: Errors to ignore (empty to raise on all errors)
+
+ Returns:
+ Number of size cells used by the children of @nodeoffset
+
+ Raises:
+ FdtException if the node has an invalid #size-cells property, or
+ another error occurs
+ """
+ return check_err(fdt_size_cells(self._fdt, nodeoffset), quiet)
+
def subnode_offset(self, parentoffset, name, quiet=()):
"""Get the offset of a named subnode
--
2.54.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 15/17] pylibfdt: Add add_mem_rsv() and del_mem_rsv()
2026-08-24 13:12 [PATCH 00/17] pylibfdt: Update the U-Boot version with changes from upstream dtc Alexey Charkov
` (13 preceding siblings ...)
2026-08-24 13:13 ` [PATCH 14/17] pylibfdt: Add address_cells() and size_cells() Alexey Charkov
@ 2026-08-24 13:13 ` Alexey Charkov
2026-08-24 13:13 ` [PATCH 16/17] pylibfdt: Document that FdtSw.property() takes bytes Alexey Charkov
` (3 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Alexey Charkov @ 2026-08-24 13:13 UTC (permalink / raw)
To: u-boot
Cc: Tom Rini, David Gibson, Luca Weiss, Brandon Maier,
Francesco Valla, Simon Glass, Rob Herring, Jaipaul Cheernam,
Alexey Charkov
The memory reserve map can be read through num_mem_rsv() and
get_mem_rsv(), but changing it requires calling the raw fdt_* wrappers
with the private Fdt._fdt buffer, as the class exposes no methods for
the write side.
Add them next to the existing accessors.
This is a backport of dtc commit 89c99ce78ac8 ("pylibfdt: Add
add_mem_rsv() and del_mem_rsv()").
Link: https://github.com/dgibson/dtc/pull/190
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexey Charkov <alchark@flipper.net>
---
scripts/dtc/pylibfdt/libfdt.i_shipped | 36 +++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/scripts/dtc/pylibfdt/libfdt.i_shipped b/scripts/dtc/pylibfdt/libfdt.i_shipped
index 1983ebaee335..127ec22de3fe 100644
--- a/scripts/dtc/pylibfdt/libfdt.i_shipped
+++ b/scripts/dtc/pylibfdt/libfdt.i_shipped
@@ -640,6 +640,42 @@ class Fdt(FdtRo):
del self._fdt[self.totalsize():]
return err
+ def add_mem_rsv(self, addr, size, quiet=()):
+ """Add a memory reserve-map record
+
+ This asks the client program not to use the given region of memory,
+ e.g. because something was loaded there.
+
+ Args:
+ addr: Start address of the region to reserve
+ size: Size of the region to reserve, in bytes
+ quiet: Errors to ignore (empty to raise on all errors)
+
+ Returns:
+ Error code, or 0 if OK
+
+ Raises:
+ FdtException if there is no space for another record, or another
+ error occurs
+ """
+ return check_err(fdt_add_mem_rsv(self._fdt, addr, size), quiet)
+
+ def del_mem_rsv(self, index, quiet=()):
+ """Remove the indexed memory reserve-map record
+
+ Args:
+ index: Record to remove (0=first)
+ quiet: Errors to ignore (empty to raise on all errors)
+
+ Returns:
+ Error code, or 0 if OK
+
+ Raises:
+ FdtException if there is no record at @index, or another error
+ occurs
+ """
+ return check_err(fdt_del_mem_rsv(self._fdt, index), quiet)
+
def set_name(self, nodeoffset, name, quiet=()):
"""Set the name of a node
--
2.54.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 16/17] pylibfdt: Document that FdtSw.property() takes bytes
2026-08-24 13:12 [PATCH 00/17] pylibfdt: Update the U-Boot version with changes from upstream dtc Alexey Charkov
` (14 preceding siblings ...)
2026-08-24 13:13 ` [PATCH 15/17] pylibfdt: Add add_mem_rsv() and del_mem_rsv() Alexey Charkov
@ 2026-08-24 13:13 ` Alexey Charkov
2026-08-24 13:13 ` [PATCH 17/17] dtoc: Add tests for the pylibfdt bindings dtoc does not use Alexey Charkov
` (2 subsequent siblings)
18 siblings, 0 replies; 20+ messages in thread
From: Alexey Charkov @ 2026-08-24 13:13 UTC (permalink / raw)
To: u-boot
Cc: Tom Rini, David Gibson, Luca Weiss, Brandon Maier,
Francesco Valla, Simon Glass, Rob Herring, Jaipaul Cheernam,
Alexey Charkov
From: Simon Glass <sjg@chromium.org>
Commit 97de532e59be ("pylibfdt: Correct the type for fdt_property_stub()")
took two of the three hunks of the upstream change and left the docstring
saying only "Value of property", which is what prompted the type fix in
the first place.
Take the remaining hunk of dtc commit fdf3f6d897ab ("pylibfdt: Correct
the type for fdt_property_stub()").
Signed-off-by: Simon Glass <sjg@chromium.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
[rewrite commit message for U-Boot]
Signed-off-by: Alexey Charkov <alchark@flipper.net>
---
scripts/dtc/pylibfdt/libfdt.i_shipped | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/dtc/pylibfdt/libfdt.i_shipped b/scripts/dtc/pylibfdt/libfdt.i_shipped
index 127ec22de3fe..3d527dfe2120 100644
--- a/scripts/dtc/pylibfdt/libfdt.i_shipped
+++ b/scripts/dtc/pylibfdt/libfdt.i_shipped
@@ -1112,7 +1112,7 @@ class FdtSw(FdtRo):
Args:
name: Name of property to add
- val: Value of property
+ val: Value of property (bytes)
quiet: Errors to ignore (empty to raise on all errors)
Raises:
--
2.54.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 17/17] dtoc: Add tests for the pylibfdt bindings dtoc does not use
2026-08-24 13:12 [PATCH 00/17] pylibfdt: Update the U-Boot version with changes from upstream dtc Alexey Charkov
` (15 preceding siblings ...)
2026-08-24 13:13 ` [PATCH 16/17] pylibfdt: Document that FdtSw.property() takes bytes Alexey Charkov
@ 2026-08-24 13:13 ` Alexey Charkov
2026-08-24 18:16 ` [PATCH 00/17] pylibfdt: Update the U-Boot version with changes from upstream dtc Tom Rini
2026-09-01 2:13 ` Tom Rini
18 siblings, 0 replies; 20+ messages in thread
From: Alexey Charkov @ 2026-08-24 13:13 UTC (permalink / raw)
To: u-boot
Cc: Tom Rini, David Gibson, Luca Weiss, Brandon Maier,
Francesco Valla, Simon Glass, Rob Herring, Jaipaul Cheernam,
Alexey Charkov
Exercise additional pylibfdt bindings imported from upstream against the
existing dtoc test tree, which already carries a boolean property, a
string list, integer arrays and a bus node that overrides #address-cells
and #size-cells.
The FdtSw cases cover both halves of the geometric growth change: that an
out-of-space result at least doubles the buffer, and that a tree needing
several expansions still comes out intact.
Signed-off-by: Alexey Charkov <alchark@flipper.net>
---
tools/dtoc/test_fdt.py | 175 ++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 174 insertions(+), 1 deletion(-)
diff --git a/tools/dtoc/test_fdt.py b/tools/dtoc/test_fdt.py
index f141f931a949..4ab1365d5318 100755
--- a/tools/dtoc/test_fdt.py
+++ b/tools/dtoc/test_fdt.py
@@ -10,6 +10,7 @@ Written by Simon Glass <sjg@chromium.org>
from argparse import ArgumentParser
import os
import shutil
+import struct
import sys
import tempfile
import unittest
@@ -754,6 +755,178 @@ class TestProp(unittest.TestCase):
self.dtb.GetFilename())
+class TestPylibfdt(unittest.TestCase):
+ """Tests for the parts of pylibfdt that dtoc does not itself use
+
+ These bindings come from upstream dtc and have no coverage elsewhere in
+ U-Boot, so exercise them directly rather than through the Fdt wrapper.
+ """
+
+ @classmethod
+ def setUpClass(cls):
+ tools.prepare_output_dir(None)
+
+ @classmethod
+ def tearDownClass(cls):
+ tools.finalise_output_dir()
+
+ def setUp(self):
+ self.dtb = fdt.FdtScan(find_dtb_file('dtoc_test_simple.dts'))
+ self.fdt = self.dtb.GetFdtObj()
+ self.node = self.fdt.path_offset('/spl-test')
+
+ def test_hasprop(self):
+ """Test checking for the presence of a property"""
+ self.assertTrue(self.fdt.hasprop(self.node, 'boolval'))
+ self.assertTrue(self.fdt.hasprop(self.node, 'intval'))
+ self.assertFalse(self.fdt.hasprop(self.node, 'missing'))
+
+ def test_hasprop_bad_node(self):
+ """Test that hasprop() still reports errors other than NOTFOUND"""
+ with self.assertRaises(libfdt.FdtException) as exc:
+ self.fdt.hasprop(-1, 'boolval')
+ self.assertEqual(-libfdt.BADOFFSET, exc.exception.err)
+
+ def test_setprop_bool(self):
+ """Test creating and deleting a boolean property"""
+ # Leave room for the new property
+ self.fdt.resize(self.fdt.totalsize() + 1024)
+ node = self.fdt.path_offset('/spl-test')
+
+ self.fdt.setprop_bool(node, 'newbool', True)
+ self.assertTrue(self.fdt.hasprop(node, 'newbool'))
+ self.assertEqual(b'', self.fdt.getprop(node, 'newbool'))
+
+ # Setting it again should be a no-op
+ self.fdt.setprop_bool(node, 'newbool', True)
+ self.assertTrue(self.fdt.hasprop(node, 'newbool'))
+
+ self.fdt.setprop_bool(node, 'newbool', False)
+ self.assertFalse(self.fdt.hasprop(node, 'newbool'))
+
+ # Deleting it again should also be a no-op
+ self.fdt.setprop_bool(node, 'newbool', False)
+ self.assertFalse(self.fdt.hasprop(node, 'newbool'))
+
+ def test_get_path(self):
+ """Test reading back the full path of a node"""
+ node = self.fdt.path_offset('/i2c@0/pmic@9')
+ self.assertEqual('/i2c@0/pmic@9', self.fdt.get_path(node))
+ self.assertEqual('/', self.fdt.get_path(0))
+
+ def test_get_path_no_space(self):
+ """Test that get_path() retries with a larger buffer as needed"""
+ node = self.fdt.path_offset('/i2c@0/pmic@9')
+ self.assertEqual('/i2c@0/pmic@9', self.fdt.get_path(node, size_hint=1))
+
+ def test_get_path_bad_node(self):
+ """Test get_path() on an invalid node offset"""
+ with self.assertRaises(libfdt.FdtException) as exc:
+ self.fdt.get_path(-1)
+ self.assertEqual(-libfdt.BADOFFSET, exc.exception.err)
+
+ def test_as_stringlist(self):
+ """Test decoding a string-list property"""
+ prop = self.fdt.getprop(self.node, 'stringarray')
+ self.assertEqual(['multi-word', 'message'], prop.as_stringlist())
+
+ prop = self.fdt.getprop(self.node, 'stringval')
+ self.assertEqual(['message'], prop.as_stringlist())
+
+ def test_as_int_lists(self):
+ """Test decoding integer-array properties"""
+ prop = self.fdt.getprop(self.node, 'intarray')
+ self.assertEqual([2, 3, 4], prop.as_uint32_list())
+ self.assertEqual([2, 3, 4], prop.as_int32_list())
+
+ prop = self.fdt.getprop(self.node, 'int64val')
+ self.assertEqual([0x123456789abcdef0], prop.as_uint64_list())
+ self.assertEqual([0x123456789abcdef0], prop.as_int64_list())
+
+ def test_as_int_lists_negative(self):
+ """Test that the signed accessors differ from the unsigned ones"""
+ self.fdt.resize(self.fdt.totalsize() + 1024)
+ node = self.fdt.path_offset('/spl-test')
+
+ self.fdt.setprop(node, 'negs32', struct.pack('>ll', -1, -2))
+ prop = self.fdt.getprop(node, 'negs32')
+ self.assertEqual([-1, -2], prop.as_int32_list())
+ self.assertEqual([0xffffffff, 0xfffffffe], prop.as_uint32_list())
+
+ self.fdt.setprop(node, 'negs64', struct.pack('>qq', -1, -2))
+ prop = self.fdt.getprop(node, 'negs64')
+ self.assertEqual([-1, -2], prop.as_int64_list())
+ self.assertEqual([0xffffffffffffffff, 0xfffffffffffffffe],
+ prop.as_uint64_list())
+
+ def test_address_and_size_cells(self):
+ """Test reading the cell counts a node uses for its children"""
+ self.assertEqual(1, self.fdt.address_cells(0))
+ self.assertEqual(1, self.fdt.size_cells(0))
+
+ # i2c@0 overrides both
+ i2c = self.fdt.path_offset('/i2c@0')
+ self.assertEqual(1, self.fdt.address_cells(i2c))
+ self.assertEqual(0, self.fdt.size_cells(i2c))
+
+ def test_mem_rsv(self):
+ """Test adding, reading back and deleting reserve-map records"""
+ self.assertEqual(0, self.fdt.num_mem_rsv())
+
+ # Leave room for the new records
+ self.fdt.resize(self.fdt.totalsize() + 1024)
+ self.fdt.add_mem_rsv(0xdeadbeef00000000, 0x100000)
+ self.fdt.add_mem_rsv(0x1000, 0x2000)
+ self.assertEqual(2, self.fdt.num_mem_rsv())
+ self.assertEqual([0xdeadbeef00000000, 0x100000],
+ list(self.fdt.get_mem_rsv(0)))
+ self.assertEqual([0x1000, 0x2000], list(self.fdt.get_mem_rsv(1)))
+
+ self.fdt.del_mem_rsv(0)
+ self.assertEqual(1, self.fdt.num_mem_rsv())
+ self.assertEqual([0x1000, 0x2000], list(self.fdt.get_mem_rsv(0)))
+
+ def test_del_mem_rsv_missing(self):
+ """Test deleting a reserve-map record which is not there"""
+ with self.assertRaises(libfdt.FdtException) as exc:
+ self.fdt.del_mem_rsv(0)
+ self.assertEqual(-libfdt.NOTFOUND, exc.exception.err)
+
+ def test_fdtsw_growth(self):
+ """Test that running out of space at least doubles the buffer"""
+ fdtsw = libfdt.FdtSw()
+ size = len(fdtsw._fdt)
+ self.assertEqual(fdtsw.INC_SIZE, size)
+
+ self.assertTrue(fdtsw.check_space(-libfdt.NOSPACE))
+ self.assertEqual(size * 2, len(fdtsw._fdt))
+
+ self.assertTrue(fdtsw.check_space(-libfdt.NOSPACE))
+ self.assertEqual(size * 4, len(fdtsw._fdt))
+
+ # Anything that is not an out-of-space error leaves the buffer alone
+ self.assertFalse(fdtsw.check_space(0))
+ self.assertEqual(size * 4, len(fdtsw._fdt))
+
+ def test_fdtsw_build(self):
+ """Test building a tree large enough to need several expansions"""
+ fdtsw = libfdt.FdtSw()
+ fdtsw.finish_reservemap()
+ fdtsw.begin_node('')
+ for i in range(50):
+ fdtsw.begin_node(f'node{i}')
+ fdtsw.property('data', b'x' * 200)
+ fdtsw.end_node()
+ fdtsw.end_node()
+
+ out = fdtsw.as_fdt()
+ self.assertGreater(out.totalsize(), fdtsw.INC_SIZE * 4)
+ for i in range(50):
+ node = out.path_offset(f'/node{i}')
+ self.assertEqual(f'/node{i}', out.get_path(node))
+ self.assertEqual(b'x' * 200, out.getprop(node, 'data'))
+
+
class TestFdtUtil(unittest.TestCase):
"""Tests for the fdt_util module
@@ -970,7 +1143,7 @@ def run_tests(names, processes):
test_name = names[0] if names else None
result = test_util.run_test_suites(
'test_fdt', False, False, False, False, processes, test_name, None,
- [TestFdt, TestNode, TestProp, TestFdtUtil])
+ [TestFdt, TestNode, TestProp, TestPylibfdt, TestFdtUtil])
return (0 if result.wasSuccessful() else 1)
--
2.54.0
^ permalink raw reply related [flat|nested] 20+ messages in thread* Re: [PATCH 00/17] pylibfdt: Update the U-Boot version with changes from upstream dtc
2026-08-24 13:12 [PATCH 00/17] pylibfdt: Update the U-Boot version with changes from upstream dtc Alexey Charkov
` (16 preceding siblings ...)
2026-08-24 13:13 ` [PATCH 17/17] dtoc: Add tests for the pylibfdt bindings dtoc does not use Alexey Charkov
@ 2026-08-24 18:16 ` Tom Rini
2026-09-01 2:13 ` Tom Rini
18 siblings, 0 replies; 20+ messages in thread
From: Tom Rini @ 2026-08-24 18:16 UTC (permalink / raw)
To: Alexey Charkov
Cc: u-boot, David Gibson, Luca Weiss, Brandon Maier, Francesco Valla,
Simon Glass, Rob Herring, Jaipaul Cheernam, Brandon Maier,
Thomas Huth
[-- Attachment #1: Type: text/plain, Size: 1679 bytes --]
On Mon, Aug 24, 2026 at 05:12:57PM +0400, Alexey Charkov wrote:
> U-Boot's copy of the libfdt Python bindings in
> scripts/dtc/pylibfdt/libfdt.i_shipped was last synced wholesale in 2019,
> by commit 903fe17aa8c8 ("pylibfdt: Sync up with upstream"), against dtc
> commit 430419c28100. Since then it has only picked up individual fixes,
> so it has drifted a long way behind dtc, which is now at v1.8.1-19.
>
> Tom asked for an audit of the divergence when reviewing the FdtSw growth
> patch [1]; this is the result. Bring in every missing change from upstream
> as an individual commit, referencing its upstream sibling.
>
> This adds: hasprop() and setprop_bool(), get_path(),
> Property.as_stringlist() and the as_*int*_list() accessors,
> address_cells()/size_cells(), add_mem_rsv()/del_mem_rsv(), geometric FdtSw
> buffer growth, a missing Py_INCREF on the Py_None returned by the
> fdt_getprop() typemap, correct get_mem_rsv() results on current Python,
> and the SWIG 4.3+ return-value compatibility shim.
>
> Not included is dtc commit 5008d1d6a356 ("pylibfdt: Replace removed SWIG
> Python 2 compatibility macros"), which already landed independently as
> commit 527115ef6783 ("pylibfdt: Replace removed SWIG Python 2
> compatibility macros").
>
> The first two patches are preparatory: they take the parts of two upstream
> commits that earlier partial imports left behind, so the rest apply
> verbatim. The last patch adds test coverage, since none of these bindings
> have an in-tree caller yet and dtc's own tests for them live in
> tests/pylibfdt_tests.py, which U-Boot does not carry.
Thanks for doing this update.
--
Tom
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 20+ messages in thread* Re: [PATCH 00/17] pylibfdt: Update the U-Boot version with changes from upstream dtc
2026-08-24 13:12 [PATCH 00/17] pylibfdt: Update the U-Boot version with changes from upstream dtc Alexey Charkov
` (17 preceding siblings ...)
2026-08-24 18:16 ` [PATCH 00/17] pylibfdt: Update the U-Boot version with changes from upstream dtc Tom Rini
@ 2026-09-01 2:13 ` Tom Rini
18 siblings, 0 replies; 20+ messages in thread
From: Tom Rini @ 2026-09-01 2:13 UTC (permalink / raw)
To: u-boot, Alexey Charkov
Cc: David Gibson, Luca Weiss, Brandon Maier, Francesco Valla,
Simon Glass, Rob Herring, Jaipaul Cheernam, Brandon Maier,
Thomas Huth
On Mon, 24 Aug 2026 17:12:57 +0400, Alexey Charkov wrote:
> U-Boot's copy of the libfdt Python bindings in
> scripts/dtc/pylibfdt/libfdt.i_shipped was last synced wholesale in 2019,
> by commit 903fe17aa8c8 ("pylibfdt: Sync up with upstream"), against dtc
> commit 430419c28100. Since then it has only picked up individual fixes,
> so it has drifted a long way behind dtc, which is now at v1.8.1-19.
>
> Tom asked for an audit of the divergence when reviewing the FdtSw growth
> patch [1]; this is the result. Bring in every missing change from upstream
> as an individual commit, referencing its upstream sibling.
>
> [...]
Applied to u-boot/next, thanks!
[01/17] pylibfdt: Cast property length to Py_ssize_t
commit: 9f6d57eaef77a17fafe0d28e4a103786ae2de55f
[02/17] pylibfdt: Restore the upstream bytearray() in getprop()
commit: b737e5cf2bc8d9bd545451a3a2876465bbafb8fa
[03/17] pylibfdt: Fix Python crash on getprop deallocation
commit: 04e670ea3630efadd654a940d893137a3c6c2c9e
[04/17] pylibfdt: Add Property.as_stringlist()
commit: d0c7b9e65bfd30b93aadbd5d0143b2911f8278c1
[05/17] pylibfdt: Add Property.as_*int*_array()
commit: f41cecc1fe9442939f1a81684db1f467f3bd4aba
[06/17] pylibfdt: Add FdtRo.get_path()
commit: 66ccb13a8180bf7d09d79ca136b18301e020ae5e
[07/17] pylibfdt: Work-around SWIG limitations with flexible arrays
commit: ba6d20256305ecff8c879e2acb169aa5b0fba933
[08/17] pylibfdt: Add size_hint parameter for get_path
commit: 69c95e9e4f576b811e640d1bf0ee95cf070dd542
[09/17] pylibfdt: Support boolean properties
commit: 3bf9e7e72ab545d08d9ae30bcb45027ad24609bb
[10/17] pylibfdt: Fix get_mem_rsv for newer Python versions
commit: 5b7d682e1d28383318c6d649d11aef45ed604ce8
[11/17] pylibfdt: Fix backwards compatibility of return values
commit: 0e9f9fda2e4568aae651147c1e59a0b4c394df55
[12/17] pylibfdt: Fix a typo in the next_node() docstring
commit: dfba3eff563cc0bb779791b10e8f78a124f4182e
[13/17] pylibfdt: Grow the FdtSw buffer geometrically
commit: f3e00d4b7f365929e18395194049d569d2288f31
[14/17] pylibfdt: Add address_cells() and size_cells()
commit: 34fddfa16d47bd97f5b11d6b36dcbda91037e02f
[15/17] pylibfdt: Add add_mem_rsv() and del_mem_rsv()
commit: 388137abfd0442c1bbe3df92277823d9070a2747
[16/17] pylibfdt: Document that FdtSw.property() takes bytes
commit: 44a2a718fbe62d703a8ce2ff576d2252c7444087
[17/17] dtoc: Add tests for the pylibfdt bindings dtoc does not use
commit: 01fb2b4d7368483f95b6018b2c069de0b8ebadeb
--
Tom
^ permalink raw reply [flat|nested] 20+ messages in thread