aboutsummaryrefslogtreecommitdiffstats
path: root/xen/common/device_tree.c
diff options
context:
space:
mode:
authorStefano Stabellini <stefano.stabellini@eu.citrix.com>2012-11-19 12:59:46 +0000
committerStefano Stabellini <stefano.stabellini@eu.citrix.com>2012-11-19 12:59:46 +0000
commit2ac19a6b381c9a9cd57afc107af95761bbddb5e0 (patch)
tree8d77dcf094bf9fee96fe09d6737040fc38ce1a89 /xen/common/device_tree.c
parenta8c81103334f89bf3bfc051201e4b5717a014d4d (diff)
downloadxen-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.c43
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;
}