[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] xen/arm: get the number of cpus from device tree


  • To: xen-changelog@xxxxxxxxxxxxxxxxxxx
  • From: Xen patchbot-unstable <patchbot@xxxxxxx>
  • Date: Wed, 21 Nov 2012 03:11:09 +0000
  • Delivery-date: Wed, 21 Nov 2012 03:11:18 +0000
  • List-id: "Change log for Mercurial \(receive only\)" <xen-changelog.lists.xen.org>

# HG changeset patch
# User Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
# Date 1353329986 0
# Node ID 17539cec2b9d0f1500d76f43178f57ab0a4160a8
# Parent  ddb109120dbd67a166dc0fa512cb0ef54dc799ca
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@xxxxxxxxxxxxx>
Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
Committed-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
---


diff -r ddb109120dbd -r 17539cec2b9d xen/arch/arm/gic.c
--- a/xen/arch/arm/gic.c        Mon Nov 19 12:59:46 2012 +0000
+++ b/xen/arch/arm/gic.c        Mon Nov 19 12:59:46 2012 +0000
@@ -304,7 +304,7 @@ static void __cpuinit gic_hyp_disable(vo
 }
 
 /* Set up the GIC */
-int __init gic_init(void)
+void __init gic_init(void)
 {
     /* XXX FIXME get this from devicetree */
     gic.dbase = GIC_BASE_ADDRESS + GIC_DR_OFFSET;
@@ -328,8 +328,6 @@ int __init gic_init(void)
     gic.lr_mask = 0ULL;
 
     spin_unlock(&gic.lock);
-
-    return gic.cpus;
 }
 
 /* Set up the per-CPU parts of the GIC for a secondary CPU */
diff -r ddb109120dbd -r 17539cec2b9d xen/arch/arm/gic.h
--- a/xen/arch/arm/gic.h        Mon Nov 19 12:59:46 2012 +0000
+++ b/xen/arch/arm/gic.h        Mon Nov 19 12:59:46 2012 +0000
@@ -147,7 +147,7 @@ extern int gic_route_irq_to_guest(struct
 /* Accept an interrupt from the GIC and dispatch its handler */
 extern void gic_interrupt(struct cpu_user_regs *regs, int is_fiq);
 /* Bring up the interrupt controller, and report # cpus attached */
-extern int gic_init(void);
+extern void gic_init(void);
 /* Bring up a secondary CPU's per-CPU GIC interface */
 extern void gic_init_secondary_cpu(void);
 /* Take down a CPU's per-CPU GIC interface */
diff -r ddb109120dbd -r 17539cec2b9d xen/arch/arm/setup.c
--- a/xen/arch/arm/setup.c      Mon Nov 19 12:59:46 2012 +0000
+++ b/xen/arch/arm/setup.c      Mon Nov 19 12:59:46 2012 +0000
@@ -185,10 +185,13 @@ void __init start_xen(unsigned long boot
     size_t fdt_size;
     int cpus, i;
 
+    smp_clear_cpu_maps();
+
     fdt = (void *)BOOT_MISC_VIRT_START
         + (atag_paddr & ((1 << SECOND_SHIFT) - 1));
     fdt_size = device_tree_early_init(fdt);
 
+    cpus = smp_get_max_cpus();
     cmdline_parse(device_tree_bootargs(fdt));
 
     setup_pagetables(boot_phys_offset, get_xen_paddr());
@@ -199,7 +202,7 @@ void __init start_xen(unsigned long boot
     console_init_preirq();
 #endif
 
-    cpus = gic_init();
+    gic_init();
     make_cpus_ready(cpus, boot_phys_offset);
 
     percpu_init_areas();
diff -r ddb109120dbd -r 17539cec2b9d xen/arch/arm/smpboot.c
--- a/xen/arch/arm/smpboot.c    Mon Nov 19 12:59:46 2012 +0000
+++ b/xen/arch/arm/smpboot.c    Mon Nov 19 12:59:46 2012 +0000
@@ -71,18 +71,31 @@ static void setup_cpu_sibling_map(int cp
     cpumask_set_cpu(cpu, per_cpu(cpu_core_mask, cpu));
 }
 
+void __init
+smp_clear_cpu_maps (void)
+{
+    cpumask_clear(&cpu_possible_map);
+    cpumask_clear(&cpu_online_map);
+    cpumask_set_cpu(0, &cpu_online_map);
+    cpumask_set_cpu(0, &cpu_possible_map);
+}
+
+int __init
+smp_get_max_cpus (void)
+{
+    int i, max_cpus = 0;
+
+    for ( i = 0; i < nr_cpu_ids; i++ )
+        if ( cpu_possible(i) )
+            max_cpus++;
+
+    return max_cpus;
+}
+
 
 void __init
 smp_prepare_cpus (unsigned int max_cpus)
 {
-    int i;
-
-    cpumask_clear(&cpu_online_map);
-    cpumask_set_cpu(0, &cpu_online_map);
-
-    cpumask_clear(&cpu_possible_map);
-    for ( i = 0; i < max_cpus; i++ )
-        cpumask_set_cpu(i, &cpu_possible_map);
     cpumask_copy(&cpu_present_map, &cpu_possible_map);
 
     setup_cpu_sibling_map(0);
diff -r ddb109120dbd -r 17539cec2b9d xen/common/device_tree.c
--- a/xen/common/device_tree.c  Mon Nov 19 12:59:46 2012 +0000
+++ b/xen/common/device_tree.c  Mon Nov 19 12:59:46 2012 +0000
@@ -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 vo
         && (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(c
     }
 }
 
+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 
 {
     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;
 }
diff -r ddb109120dbd -r 17539cec2b9d xen/include/asm-arm/smp.h
--- a/xen/include/asm-arm/smp.h Mon Nov 19 12:59:46 2012 +0000
+++ b/xen/include/asm-arm/smp.h Mon Nov 19 12:59:46 2012 +0000
@@ -22,6 +22,8 @@ extern void stop_cpu(void);
 extern void
 make_cpus_ready(unsigned int max_cpus, unsigned long boot_phys_offset);
 
+extern void smp_clear_cpu_maps (void);
+extern int smp_get_max_cpus (void);
 #endif
 /*
  * Local variables:

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.