diff options
author | Stefano Stabellini <stefano.stabellini@eu.citrix.com> | 2012-11-19 12:59:46 +0000 |
---|---|---|
committer | Stefano Stabellini <stefano.stabellini@eu.citrix.com> | 2012-11-19 12:59:46 +0000 |
commit | 2ac19a6b381c9a9cd57afc107af95761bbddb5e0 (patch) | |
tree | 8d77dcf094bf9fee96fe09d6737040fc38ce1a89 /xen/common/device_tree.c | |
parent | a8c81103334f89bf3bfc051201e4b5717a014d4d (diff) | |
download | xen-2ac19a6b381c9a9cd57afc107af95761bbddb5e0.tar.gz xen-2ac19a6b381c9a9cd57afc107af95761bbddb5e0.tar.bz2 xen-2ac19a6b381c9a9cd57afc107af95761bbddb5e0.zip |
xen/arm: get the number of cpus from device tree
The system might have fewer cpus than the GIC supports.
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
Committed-by: Ian Campbell <ian.campbell@citrix.com>
Diffstat (limited to 'xen/common/device_tree.c')
-rw-r--r-- | xen/common/device_tree.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/xen/common/device_tree.c b/xen/common/device_tree.c index 3d1f0f45fc..da0af77d77 100644 --- a/xen/common/device_tree.c +++ b/xen/common/device_tree.c @@ -18,6 +18,7 @@ #include <xen/mm.h> #include <xen/stdarg.h> #include <xen/string.h> +#include <xen/cpumask.h> #include <asm/early_printk.h> struct dt_early_info __initdata early_info; @@ -41,6 +42,18 @@ bool_t device_tree_node_matches(const void *fdt, int node, const char *match) && (name[match_len] == '@' || name[match_len] == '\0'); } +bool_t device_tree_type_matches(const void *fdt, int node, const char *match) +{ + int len; + const void *prop; + + prop = fdt_getprop(fdt, node, "device_type", &len); + if ( prop == NULL ) + return 0; + + return !strncmp(prop, match, len); +} + static void __init get_val(const u32 **cell, u32 cells, u64 *val) { *val = 0; @@ -229,6 +242,34 @@ static void __init process_memory_node(const void *fdt, int node, } } +static void __init process_cpu_node(const void *fdt, int node, + const char *name, + u32 address_cells, u32 size_cells) +{ + const struct fdt_property *prop; + const u32 *cell; + paddr_t start, size; + + if ( address_cells != 1 || size_cells != 0 ) + { + early_printk("fdt: node `%s': invalid #address-cells or #size-cells", + name); + return; + } + + prop = fdt_get_property(fdt, node, "reg", NULL); + if ( !prop ) + { + early_printk("fdt: node `%s': missing `reg' property\n", name); + return; + } + + cell = (const u32 *)prop->data; + device_tree_get_reg(&cell, address_cells, size_cells, &start, &size); + + cpumask_set_cpu(start, &cpu_possible_map); +} + static int __init early_scan_node(const void *fdt, int node, const char *name, int depth, u32 address_cells, u32 size_cells, @@ -236,6 +277,8 @@ static int __init early_scan_node(const void *fdt, { if ( device_tree_node_matches(fdt, node, "memory") ) process_memory_node(fdt, node, name, address_cells, size_cells); + else if ( device_tree_type_matches(fdt, node, "cpu") ) + process_cpu_node(fdt, node, name, address_cells, size_cells); return 0; } |