summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimur Tabi <timur@freescale.com>2011-05-03 13:24:07 -0500
committerGerald Van Baren <gvb@unssw.com>2011-07-14 21:43:36 -0400
commitbb682001f16504c2885a4ce5f82bff79df7a83c9 (patch)
tree20138fc22710710eb3762a550be1873db689b498
parentd1c6314887c4d6712f7bd9ba7428b6517e7732e0 (diff)
fdt: introduce fdt_verify_alias_address() and fdt_get_base_address()
Introduce two functions, fdt_verify_alias_address() and fdt_get_base_address(), which can be used to verify the physical address of a device in a device tree. fdt_get_base_address() returns the base address of an SOC or PCI node. fdt_verify_alias_address() prints a message if the address of a node specified by an alias does not match the given physical address. Signed-off-by: Timur Tabi <timur@freescale.com>
-rw-r--r--common/fdt_support.c67
-rw-r--r--include/fdt_support.h4
2 files changed, 71 insertions, 0 deletions
diff --git a/common/fdt_support.c b/common/fdt_support.c
index 496040b54c..150a3c5a59 100644
--- a/common/fdt_support.c
+++ b/common/fdt_support.c
@@ -1223,3 +1223,70 @@ err_size:
return ret;
}
#endif
+
+/*
+ * Verify the physical address of device tree node for a given alias
+ *
+ * This function locates the device tree node of a given alias, and then
+ * verifies that the physical address of that device matches the given
+ * parameter. It displays a message if there is a mismatch.
+ *
+ * Returns 1 on success, 0 on failure
+ */
+int fdt_verify_alias_address(void *fdt, int anode, const char *alias, u64 addr)
+{
+ const char *path;
+ const u32 *reg;
+ int node, len;
+ u64 dt_addr;
+
+ path = fdt_getprop(fdt, anode, alias, NULL);
+ if (!path) {
+ /* If there's no such alias, then it's not a failure */
+ return 1;
+ }
+
+ node = fdt_path_offset(fdt, path);
+ if (node < 0) {
+ printf("Warning: device tree alias '%s' points to invalid "
+ "node %s.\n", alias, path);
+ return 0;
+ }
+
+ reg = fdt_getprop(fdt, node, "reg", &len);
+ if (!reg) {
+ printf("Warning: device tree node '%s' has no address.\n",
+ path);
+ return 0;
+ }
+
+ dt_addr = fdt_translate_address(fdt, node, reg);
+ if (addr != dt_addr) {
+ printf("Warning: U-Boot configured device %s at address %llx,\n"
+ " but the device tree has it address %llx.\n",
+ alias, addr, dt_addr);
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ * Returns the base address of an SOC or PCI node
+ */
+u64 fdt_get_base_address(void *fdt, int node)
+{
+ int size;
+ u32 naddr;
+ const u32 *prop;
+
+ prop = fdt_getprop(fdt, node, "#address-cells", &size);
+ if (prop && size == 4)
+ naddr = *prop;
+ else
+ naddr = 2;
+
+ prop = fdt_getprop(fdt, node, "ranges", &size);
+
+ return prop ? fdt_translate_address(fdt, node, prop + naddr) : 0;
+}
diff --git a/include/fdt_support.h b/include/fdt_support.h
index ce6817b6d3..cefc990690 100644
--- a/include/fdt_support.h
+++ b/include/fdt_support.h
@@ -90,5 +90,9 @@ int fdt_node_offset_by_compat_reg(void *blob, const char *compat,
int fdt_alloc_phandle(void *blob);
int fdt_add_edid(void *blob, const char *compat, unsigned char *buf);
+int fdt_verify_alias_address(void *fdt, int anode, const char *alias,
+ u64 addr);
+u64 fdt_get_base_address(void *fdt, int node);
+
#endif /* ifdef CONFIG_OF_LIBFDT */
#endif /* ifndef __FDT_SUPPORT_H */