diff options
author | Max Hsu <max.hsu@sifive.com> | 2025-07-11 00:12:53 +0800 |
---|---|---|
committer | Anup Patel <anup@brainfault.org> | 2025-07-23 10:32:14 +0530 |
commit | 84044ee83c051fd2f39e34b29854993ecc95d7f0 (patch) | |
tree | 6d0dbe11ea0aa855994eef0c61e6c5947dcf257f | |
parent | cc546e1a06930c5ebaf6e90a9a28dca4218f1954 (diff) | |
download | opensbi-master.zip opensbi-master.tar.gz opensbi-master.tar.bz2 |
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 the child address size, this commit fix the two address sizes
and parsing the address independently.
Signed-off-by: Max Hsu <max.hsu@sifive.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250711-dev-maxh-master_fdt_helper-v2-1-9579e1f02ee1@sifive.com
Signed-off-by: Anup Patel <anup@brainfault.org>
-rw-r--r-- | lib/utils/fdt/fdt_helper.c | 26 |
1 files changed, 15 insertions, 11 deletions
diff --git a/lib/utils/fdt/fdt_helper.c b/lib/utils/fdt/fdt_helper.c index 0f4859c..799fd48 100644 --- a/lib/utils/fdt/fdt_helper.c +++ b/lib/utils/fdt/fdt_helper.c @@ -84,23 +84,27 @@ 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) - return SBI_ENODEV; - - cell_size = fdt_size_cells(fdt, parent); - if (cell_size < 0) - return SBI_ENODEV; - ranges = fdt_getprop(fdt, parent, "ranges", &rlen); if (ranges && rlen > 0) { - for (i = 0; i < cell_addr; i++) + 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); + if (cell_size < 0) + return SBI_ENODEV; + + 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++); |