From bb682001f16504c2885a4ce5f82bff79df7a83c9 Mon Sep 17 00:00:00 2001 From: Timur Tabi Date: Tue, 3 May 2011 13:24:07 -0500 Subject: [PATCH] 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 --- common/fdt_support.c | 67 +++++++++++++++++++++++++++++++++++++++++++ include/fdt_support.h | 4 +++ 2 files changed, 71 insertions(+) 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 */ -- 2.30.2