return 0;
}
-int fdt_get_node_addr_size(void *fdt, int node, uint64_t *addr, uint64_t *size)
+int fdt_get_node_addr_size(void *fdt, int node, int index,
+ uint64_t *addr, uint64_t *size)
{
int parent, len, i, rc;
int cell_addr, cell_size;
const fdt32_t *prop_addr, *prop_size;
uint64_t temp = 0;
+ if (!fdt || node < 0 || index < 0)
+ return SBI_EINVAL;
+
parent = fdt_parent_offset(fdt, node);
if (parent < 0)
return parent;
prop_addr = fdt_getprop(fdt, node, "reg", &len);
if (!prop_addr)
return SBI_ENODEV;
+
+ if ((len / sizeof(u32)) <= (index * (cell_addr + cell_size)))
+ return SBI_EINVAL;
+
+ prop_addr = prop_addr + (index * (cell_addr + cell_size));
prop_size = prop_addr + cell_addr;
if (addr) {
if (nodeoffset < 0 || !uart || !fdt)
return SBI_ENODEV;
- rc = fdt_get_node_addr_size(fdt, nodeoffset, ®_addr, ®_size);
+ rc = fdt_get_node_addr_size(fdt, nodeoffset, 0,
+ ®_addr, ®_size);
if (rc < 0 || !reg_addr || !reg_size)
return SBI_ENODEV;
uart->addr = reg_addr;
if (nodeoffset < 0 || !uart || !fdt)
return SBI_ENODEV;
- rc = fdt_get_node_addr_size(fdt, nodeoffset, ®_addr, ®_size);
+ rc = fdt_get_node_addr_size(fdt, nodeoffset, 0,
+ ®_addr, ®_size);
if (rc < 0 || !reg_addr || !reg_size)
return SBI_ENODEV;
uart->addr = reg_addr;
if (nodeoffset < 0 || !uart || !fdt)
return SBI_ENODEV;
- rc = fdt_get_node_addr_size(fdt, nodeoffset, ®_addr, ®_size);
+ rc = fdt_get_node_addr_size(fdt, nodeoffset, 0,
+ ®_addr, ®_size);
if (rc < 0 || !reg_addr || !reg_size)
return SBI_ENODEV;
uart->addr = reg_addr;
if (nodeoffset < 0 || !uart || !fdt)
return SBI_ENODEV;
- rc = fdt_get_node_addr_size(fdt, nodeoffset, ®_addr, ®_size);
+ rc = fdt_get_node_addr_size(fdt, nodeoffset, 0,
+ ®_addr, ®_size);
if (rc < 0 || !reg_addr || !reg_size)
return SBI_ENODEV;
uart->addr = reg_addr;
if (nodeoffset < 0 || !plic || !fdt)
return SBI_ENODEV;
- rc = fdt_get_node_addr_size(fdt, nodeoffset, ®_addr, ®_size);
+ rc = fdt_get_node_addr_size(fdt, nodeoffset, 0,
+ ®_addr, ®_size);
if (rc < 0 || !reg_addr || !reg_size)
return SBI_ENODEV;
plic->addr = reg_addr;
!out_first_hartid || !out_hart_count)
return SBI_EINVAL;
- rc = fdt_get_node_addr_size(fdt, nodeoffset, ®_addr, ®_size);
+ rc = fdt_get_node_addr_size(fdt, nodeoffset, 0,
+ ®_addr, ®_size);
if (rc < 0 || !reg_addr || !reg_size)
return SBI_ENODEV;
*out_addr = reg_addr;
if (nodeoffset < 0)
return nodeoffset;
- rc = fdt_get_node_addr_size(fdt, nodeoffset, addr, NULL);
+ rc = fdt_get_node_addr_size(fdt, nodeoffset, 0, addr, NULL);
if (rc < 0 || !addr)
return SBI_ENODEV;