|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [UNIKRAFT PATCH RFCv2 15/27] lib/fdt: Fix fdt_address_cell and fdt_size_cell
The address-cell and size_cell should be probed from parent.
Signed-off-by: Jia He <justin.he@xxxxxxx>
---
lib/fdt/fdt_addresses.c | 57 ++++++++++++++++++++++-------------------
plat/drivers/ofw/fdt.c | 7 +++--
2 files changed, 34 insertions(+), 30 deletions(-)
diff --git a/lib/fdt/fdt_addresses.c b/lib/fdt/fdt_addresses.c
index a1860e6..736858a 100644
--- a/lib/fdt/fdt_addresses.c
+++ b/lib/fdt/fdt_addresses.c
@@ -55,42 +55,47 @@
#include "libfdt_internal.h"
+#define OFW_ROOT_NODE_ADDR_CELLS_DEFAULT 2
+#define OFW_ROOT_NODE_SIZE_CELLS_DEFAULT 1
+
int fdt_address_cells(const void *fdt, int nodeoffset)
{
- const fdt32_t *ac;
- int val;
- int len;
-
- ac = fdt_getprop(fdt, nodeoffset, "#address-cells", &len);
- if (!ac)
- return 2;
+ int cells;
+ int parent;
+ int off = nodeoffset;
+ const fdt32_t *prop;
- if (len != sizeof(*ac))
- return -FDT_ERR_BADNCELLS;
+ do {
+ parent = fdt_parent_offset(fdt, off);
+ if (parent >= 0)
+ off = parent;
- val = fdt32_to_cpu(*ac);
- if ((val <= 0) || (val > FDT_MAX_NCELLS))
- return -FDT_ERR_BADNCELLS;
+ prop = fdt_getprop(fdt, off, "#address-cells", &cells);
+ if (prop != NULL)
+ return fdt32_to_cpu(prop[0]);
+ } while (parent >= 0);
- return val;
+ /* No #address-cells property for the root node */
+ return OFW_ROOT_NODE_ADDR_CELLS_DEFAULT;
}
int fdt_size_cells(const void *fdt, int nodeoffset)
{
- const fdt32_t *sc;
- int val;
- int len;
-
- sc = fdt_getprop(fdt, nodeoffset, "#size-cells", &len);
- if (!sc)
- return 1;
+ int cells;
+ int parent;
+ int off = nodeoffset;
+ const fdt32_t *prop;
- if (len != sizeof(*sc))
- return -FDT_ERR_BADNCELLS;
+ do {
+ parent = fdt_parent_offset(fdt, off);
+ if (parent >= 0)
+ off = parent;
- val = fdt32_to_cpu(*sc);
- if ((val < 0) || (val > FDT_MAX_NCELLS))
- return -FDT_ERR_BADNCELLS;
+ prop = fdt_getprop(fdt, off, "#size-cells", &cells);
+ if (prop != NULL)
+ return fdt32_to_cpu(prop[0]);
+ } while (parent >= 0);
- return val;
+ /* No #size-cells property for the root node */
+ return OFW_ROOT_NODE_SIZE_CELLS_DEFAULT;
}
diff --git a/plat/drivers/ofw/fdt.c b/plat/drivers/ofw/fdt.c
index 780b8dd..876637d 100644
--- a/plat/drivers/ofw/fdt.c
+++ b/plat/drivers/ofw/fdt.c
@@ -234,7 +234,7 @@ bail:
int fdt_get_address(const void *fdt, int nodeoffset, uint32_t index,
uint64_t *addr, uint64_t *size)
{
- int parent;
+ int off = nodeoffset;
int len, prop_addr, prop_size;
int naddr, nsize, term_size;
const void *regs;
@@ -242,12 +242,11 @@ int fdt_get_address(const void *fdt, int nodeoffset,
uint32_t index,
UK_ASSERT(addr && size);
/* Get address,size cell from parent */
- parent = fdt_parent_offset(fdt, nodeoffset);
- naddr = fdt_address_cells(fdt, parent);
+ naddr = fdt_address_cells(fdt, off);
if (naddr < 0 || naddr >= FDT_MAX_NCELLS)
return naddr;
- nsize = fdt_size_cells(fdt, parent);
+ nsize = fdt_size_cells(fdt, off);
if (nsize < 0 || nsize >= FDT_MAX_NCELLS)
return nsize;
--
2.17.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |