[PATCH] lib: utils: fdt: fix "ranges" translation

Max Hsu max.hsu at sifive.com
Tue Jul 8 03:48:09 PDT 2025


According to the Device Tree Spec, Chapter 2.3.8 "ranges" [1]:
The parent address size will be determined from the #address-cells
property of the node that defines the parent’s address space.

In fdt_translate_address(), which considered the parent address size
is equal to the child address size; This commit fix to parse two
address sizes and parsing the address independently.

Link: https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#ranges [1]

Signed-off-by: Max Hsu <max.hsu at sifive.com>
---
 lib/utils/fdt/fdt_helper.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/lib/utils/fdt/fdt_helper.c b/lib/utils/fdt/fdt_helper.c
index 0f4859c1a721bc7c2871bacefe27caba7780f752..779149942dd9c7eb5182fee32e9fe7f05c3752cf 100644
--- a/lib/utils/fdt/fdt_helper.c
+++ b/lib/utils/fdt/fdt_helper.c
@@ -84,12 +84,16 @@ static int fdt_translate_address(const void *fdt, uint64_t reg, int parent,
 				 uint64_t *addr)
 {
 	int i, rlen;
-	int cell_addr, cell_size;
+	int cell_parent_addr, cell_child_addr, cell_size;
 	const fdt32_t *ranges;
 	uint64_t offset, caddr = 0, paddr = 0, rsize = 0;
 
-	cell_addr = fdt_address_cells(fdt, parent);
-	if (cell_addr < 1)
+	cell_child_addr = fdt_address_cells(fdt, parent);
+	if (cell_child_addr < 1)
+		return SBI_ENODEV;
+
+	cell_parent_addr = fdt_address_cells(fdt, fdt_parent_offset(fdt, parent));
+	if (cell_parent_addr < 1)
 		return SBI_ENODEV;
 
 	cell_size = fdt_size_cells(fdt, parent);
@@ -98,9 +102,9 @@ static int fdt_translate_address(const void *fdt, uint64_t reg, int parent,
 
 	ranges = fdt_getprop(fdt, parent, "ranges", &rlen);
 	if (ranges && rlen > 0) {
-		for (i = 0; i < cell_addr; i++)
+		for (i = 0; i < cell_child_addr; i++)
 			caddr = (caddr << 32) | fdt32_to_cpu(*ranges++);
-		for (i = 0; i < cell_addr; i++)
+		for (i = 0; i < cell_parent_addr; i++)
 			paddr = (paddr << 32) | fdt32_to_cpu(*ranges++);
 		for (i = 0; i < cell_size; i++)
 			rsize = (rsize << 32) | fdt32_to_cpu(*ranges++);

---
base-commit: a32a91069119e7a5aa31e6bc51d5e00860be3d80
change-id: 20250708-dev-maxh-master_fdt_helper-46d2eeeb07cd

Best regards,
-- 
Max Hsu <max.hsu at sifive.com>




More information about the opensbi mailing list