fdt: introduce fdt_verify_alias_address() and fdt_get_base_address()
authorTimur Tabi <timur@freescale.com>
Tue, 3 May 2011 18:24:07 +0000 (13:24 -0500)
committerGerald Van Baren <gvb@unssw.com>
Fri, 15 Jul 2011 01:43:36 +0000 (21:43 -0400)
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>
common/fdt_support.c
include/fdt_support.h

index 496040b54c8daf0188eef1f8680d3ac45809d9ad..150a3c5a591dadacf72e8daafc77b199a43c47d7 100644 (file)
@@ -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;
+}
index ce6817b6d34ac06e32fd598b9972ce4c9828c67f..cefc990690bb9333681557cc8171f8b9815dcfd8 100644 (file)
@@ -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 */