forked from Mirrors/opensbi
lib: utils: fdt: fix "ranges" translation
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>
This commit is contained in:
@@ -84,23 +84,27 @@ static int fdt_translate_address(const void *fdt, uint64_t reg, int parent,
|
|||||||
uint64_t *addr)
|
uint64_t *addr)
|
||||||
{
|
{
|
||||||
int i, rlen;
|
int i, rlen;
|
||||||
int cell_addr, cell_size;
|
int cell_parent_addr, cell_child_addr, cell_size;
|
||||||
const fdt32_t *ranges;
|
const fdt32_t *ranges;
|
||||||
uint64_t offset, caddr = 0, paddr = 0, rsize = 0;
|
uint64_t offset, caddr = 0, paddr = 0, rsize = 0;
|
||||||
|
|
||||||
cell_addr = fdt_address_cells(fdt, parent);
|
ranges = fdt_getprop(fdt, parent, "ranges", &rlen);
|
||||||
if (cell_addr < 1)
|
if (ranges && rlen > 0) {
|
||||||
|
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;
|
return SBI_ENODEV;
|
||||||
|
|
||||||
cell_size = fdt_size_cells(fdt, parent);
|
cell_size = fdt_size_cells(fdt, parent);
|
||||||
if (cell_size < 0)
|
if (cell_size < 0)
|
||||||
return SBI_ENODEV;
|
return SBI_ENODEV;
|
||||||
|
|
||||||
ranges = fdt_getprop(fdt, parent, "ranges", &rlen);
|
for (i = 0; i < cell_child_addr; i++)
|
||||||
if (ranges && rlen > 0) {
|
|
||||||
for (i = 0; i < cell_addr; i++)
|
|
||||||
caddr = (caddr << 32) | fdt32_to_cpu(*ranges++);
|
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++);
|
paddr = (paddr << 32) | fdt32_to_cpu(*ranges++);
|
||||||
for (i = 0; i < cell_size; i++)
|
for (i = 0; i < cell_size; i++)
|
||||||
rsize = (rsize << 32) | fdt32_to_cpu(*ranges++);
|
rsize = (rsize << 32) | fdt32_to_cpu(*ranges++);
|
||||||
|
Reference in New Issue
Block a user