diff options
Diffstat (limited to 'arch/sparc/kernel/mdesc.c')
| -rw-r--r-- | arch/sparc/kernel/mdesc.c | 96 | 
1 files changed, 67 insertions, 29 deletions
diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c index 6addb914fcc..a1a4400d402 100644 --- a/arch/sparc/kernel/mdesc.c +++ b/arch/sparc/kernel/mdesc.c @@ -11,11 +11,13 @@  #include <linux/mm.h>  #include <linux/miscdevice.h>  #include <linux/bootmem.h> +#include <linux/export.h>  #include <asm/cpudata.h>  #include <asm/hypervisor.h>  #include <asm/mdesc.h>  #include <asm/prom.h> +#include <asm/uaccess.h>  #include <asm/oplib.h>  #include <asm/smp.h> @@ -107,7 +109,7 @@ static struct mdesc_handle * __init mdesc_memblock_alloc(unsigned int mdesc_size  	return hp;  } -static void mdesc_memblock_free(struct mdesc_handle *hp) +static void __init mdesc_memblock_free(struct mdesc_handle *hp)  {  	unsigned int alloc_size;  	unsigned long start; @@ -508,6 +510,8 @@ const char *mdesc_node_name(struct mdesc_handle *hp, u64 node)  }  EXPORT_SYMBOL(mdesc_node_name); +static u64 max_cpus = 64; +  static void __init report_platform_properties(void)  {  	struct mdesc_handle *hp = mdesc_grab(); @@ -543,8 +547,10 @@ static void __init report_platform_properties(void)  	if (v)  		printk("PLATFORM: watchdog-max-timeout [%llu ms]\n", *v);  	v = mdesc_get_property(hp, pn, "max-cpus", NULL); -	if (v) -		printk("PLATFORM: max-cpus [%llu]\n", *v); +	if (v) { +		max_cpus = *v; +		printk("PLATFORM: max-cpus [%llu]\n", max_cpus); +	}  #ifdef CONFIG_SMP  	{ @@ -565,9 +571,7 @@ static void __init report_platform_properties(void)  	mdesc_release(hp);  } -static void __cpuinit fill_in_one_cache(cpuinfo_sparc *c, -					struct mdesc_handle *hp, -					u64 mp) +static void fill_in_one_cache(cpuinfo_sparc *c, struct mdesc_handle *hp, u64 mp)  {  	const u64 *level = mdesc_get_property(hp, mp, "level", NULL);  	const u64 *size = mdesc_get_property(hp, mp, "size", NULL); @@ -610,7 +614,7 @@ static void __cpuinit fill_in_one_cache(cpuinfo_sparc *c,  	}  } -static void __cpuinit mark_core_ids(struct mdesc_handle *hp, u64 mp, int core_id) +static void mark_core_ids(struct mdesc_handle *hp, u64 mp, int core_id)  {  	u64 a; @@ -643,7 +647,7 @@ static void __cpuinit mark_core_ids(struct mdesc_handle *hp, u64 mp, int core_id  	}  } -static void __cpuinit set_core_ids(struct mdesc_handle *hp) +static void set_core_ids(struct mdesc_handle *hp)  {  	int idx;  	u64 mp; @@ -668,7 +672,7 @@ static void __cpuinit set_core_ids(struct mdesc_handle *hp)  	}  } -static void __cpuinit mark_proc_ids(struct mdesc_handle *hp, u64 mp, int proc_id) +static void mark_proc_ids(struct mdesc_handle *hp, u64 mp, int proc_id)  {  	u64 a; @@ -687,7 +691,7 @@ static void __cpuinit mark_proc_ids(struct mdesc_handle *hp, u64 mp, int proc_id  	}  } -static void __cpuinit __set_proc_ids(struct mdesc_handle *hp, const char *exec_unit_name) +static void __set_proc_ids(struct mdesc_handle *hp, const char *exec_unit_name)  {  	int idx;  	u64 mp; @@ -708,14 +712,14 @@ static void __cpuinit __set_proc_ids(struct mdesc_handle *hp, const char *exec_u  	}  } -static void __cpuinit set_proc_ids(struct mdesc_handle *hp) +static void set_proc_ids(struct mdesc_handle *hp)  {  	__set_proc_ids(hp, "exec_unit");  	__set_proc_ids(hp, "exec-unit");  } -static void __cpuinit get_one_mondo_bits(const u64 *p, unsigned int *mask, -					 unsigned char def) +static void get_one_mondo_bits(const u64 *p, unsigned int *mask, +			       unsigned long def, unsigned long max)  {  	u64 val; @@ -726,6 +730,9 @@ static void __cpuinit get_one_mondo_bits(const u64 *p, unsigned int *mask,  	if (!val || val >= 64)  		goto use_default; +	if (val > max) +		val = max; +  	*mask = ((1U << val) * 64U) - 1U;  	return; @@ -733,25 +740,34 @@ use_default:  	*mask = ((1U << def) * 64U) - 1U;  } -static void __cpuinit get_mondo_data(struct mdesc_handle *hp, u64 mp, -				     struct trap_per_cpu *tb) +static void get_mondo_data(struct mdesc_handle *hp, u64 mp, +			   struct trap_per_cpu *tb)  { +	static int printed;  	const u64 *val;  	val = mdesc_get_property(hp, mp, "q-cpu-mondo-#bits", NULL); -	get_one_mondo_bits(val, &tb->cpu_mondo_qmask, 7); +	get_one_mondo_bits(val, &tb->cpu_mondo_qmask, 7, ilog2(max_cpus * 2));  	val = mdesc_get_property(hp, mp, "q-dev-mondo-#bits", NULL); -	get_one_mondo_bits(val, &tb->dev_mondo_qmask, 7); +	get_one_mondo_bits(val, &tb->dev_mondo_qmask, 7, 8);  	val = mdesc_get_property(hp, mp, "q-resumable-#bits", NULL); -	get_one_mondo_bits(val, &tb->resum_qmask, 6); +	get_one_mondo_bits(val, &tb->resum_qmask, 6, 7);  	val = mdesc_get_property(hp, mp, "q-nonresumable-#bits", NULL); -	get_one_mondo_bits(val, &tb->nonresum_qmask, 2); +	get_one_mondo_bits(val, &tb->nonresum_qmask, 2, 2); +	if (!printed++) { +		pr_info("SUN4V: Mondo queue sizes " +			"[cpu(%u) dev(%u) r(%u) nr(%u)]\n", +			tb->cpu_mondo_qmask + 1, +			tb->dev_mondo_qmask + 1, +			tb->resum_qmask + 1, +			tb->nonresum_qmask + 1); +	}  } -static void * __cpuinit mdesc_iterate_over_cpus(void *(*func)(struct mdesc_handle *, u64, int, void *), void *arg, cpumask_t *mask) +static void *mdesc_iterate_over_cpus(void *(*func)(struct mdesc_handle *, u64, int, void *), void *arg, cpumask_t *mask)  {  	struct mdesc_handle *hp = mdesc_grab();  	void *ret = NULL; @@ -768,7 +784,7 @@ static void * __cpuinit mdesc_iterate_over_cpus(void *(*func)(struct mdesc_handl  			       cpuid, NR_CPUS);  			continue;  		} -		if (!cpu_isset(cpuid, *mask)) +		if (!cpumask_test_cpu(cpuid, mask))  			continue;  #endif @@ -781,7 +797,8 @@ out:  	return ret;  } -static void * __cpuinit record_one_cpu(struct mdesc_handle *hp, u64 mp, int cpuid, void *arg) +static void *record_one_cpu(struct mdesc_handle *hp, u64 mp, int cpuid, +			    void *arg)  {  	ncpus_probed++;  #ifdef CONFIG_SMP @@ -790,7 +807,7 @@ static void * __cpuinit record_one_cpu(struct mdesc_handle *hp, u64 mp, int cpui  	return NULL;  } -void __cpuinit mdesc_populate_present_mask(cpumask_t *mask) +void mdesc_populate_present_mask(cpumask_t *mask)  {  	if (tlb_type != hypervisor)  		return; @@ -799,7 +816,32 @@ void __cpuinit mdesc_populate_present_mask(cpumask_t *mask)  	mdesc_iterate_over_cpus(record_one_cpu, NULL, mask);  } -static void * __cpuinit fill_in_one_cpu(struct mdesc_handle *hp, u64 mp, int cpuid, void *arg) +static void * __init check_one_pgsz(struct mdesc_handle *hp, u64 mp, int cpuid, void *arg) +{ +	const u64 *pgsz_prop = mdesc_get_property(hp, mp, "mmu-page-size-list", NULL); +	unsigned long *pgsz_mask = arg; +	u64 val; + +	val = (HV_PGSZ_MASK_8K | HV_PGSZ_MASK_64K | +	       HV_PGSZ_MASK_512K | HV_PGSZ_MASK_4MB); +	if (pgsz_prop) +		val = *pgsz_prop; + +	if (!*pgsz_mask) +		*pgsz_mask = val; +	else +		*pgsz_mask &= val; +	return NULL; +} + +void __init mdesc_get_page_sizes(cpumask_t *mask, unsigned long *pgsz_mask) +{ +	*pgsz_mask = 0; +	mdesc_iterate_over_cpus(check_one_pgsz, pgsz_mask, mask); +} + +static void *fill_in_one_cpu(struct mdesc_handle *hp, u64 mp, int cpuid, +			     void *arg)  {  	const u64 *cfreq = mdesc_get_property(hp, mp, "clock-frequency", NULL);  	struct trap_per_cpu *tb; @@ -848,16 +890,12 @@ static void * __cpuinit fill_in_one_cpu(struct mdesc_handle *hp, u64 mp, int cpu  	return NULL;  } -void __cpuinit mdesc_fill_in_cpu_data(cpumask_t *mask) +void mdesc_fill_in_cpu_data(cpumask_t *mask)  {  	struct mdesc_handle *hp;  	mdesc_iterate_over_cpus(fill_in_one_cpu, NULL, mask); -#ifdef CONFIG_SMP -	sparc64_multi_core = 1; -#endif -  	hp = mdesc_grab();  	set_core_ids(hp);  | 
