[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
# 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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |