summaryrefslogtreecommitdiffstats
path: root/arch/sparc/kernel/smp.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc/kernel/smp.c')
-rw-r--r--arch/sparc/kernel/smp.c47
1 files changed, 36 insertions, 11 deletions
diff --git a/arch/sparc/kernel/smp.c b/arch/sparc/kernel/smp.c
index a93f5da..6135d4f 100644
--- a/arch/sparc/kernel/smp.c
+++ b/arch/sparc/kernel/smp.c
@@ -58,7 +58,7 @@ cpumask_t smp_commenced_mask = CPU_MASK_NONE;
/* Used to make bitops atomic */
unsigned char bitops_spinlock = 0;
-void __init smp_store_cpu_info(int id)
+void __cpuinit smp_store_cpu_info(int id)
{
int cpu_node;
@@ -69,6 +69,17 @@ void __init smp_store_cpu_info(int id)
"clock-frequency", 0);
cpu_data(id).prom_node = cpu_node;
cpu_data(id).mid = cpu_get_hwmid(cpu_node);
+
+ /* this is required to tune the scheduler correctly */
+ /* is it possible to have CPUs with different cache sizes? */
+ if (id == boot_cpu_id) {
+ int cache_line,cache_nlines;
+ cache_line = 0x20;
+ cache_line = prom_getintdefault(cpu_node, "ecache-line-size", cache_line);
+ cache_nlines = 0x8000;
+ cache_nlines = prom_getintdefault(cpu_node, "ecache-nlines", cache_nlines);
+ max_cache_size = cache_line * cache_nlines;
+ }
if (cpu_data(id).mid < 0)
panic("No MID found for CPU%d at node 0x%08d", id, cpu_node);
}
@@ -256,22 +267,18 @@ int setup_profiling_timer(unsigned int multiplier)
void __init smp_prepare_cpus(unsigned int max_cpus)
{
extern void smp4m_boot_cpus(void);
- int i, cpuid, ncpus, extra;
+ int i, cpuid, extra;
BUG_ON(sparc_cpu_model != sun4m);
printk("Entering SMP Mode...\n");
- ncpus = 1;
extra = 0;
for (i = 0; !cpu_find_by_instance(i, NULL, &cpuid); i++) {
- if (cpuid == boot_cpu_id)
- continue;
- if (cpuid < NR_CPUS && ncpus++ < max_cpus)
- cpu_set(cpuid, phys_cpu_present_map);
- else
+ if (cpuid >= NR_CPUS)
extra++;
}
- if (max_cpus >= NR_CPUS && extra)
+ /* i = number of cpus */
+ if (extra && max_cpus > i - extra)
printk("Warning: NR_CPUS is too low to start all cpus\n");
smp_store_cpu_info(boot_cpu_id);
@@ -279,7 +286,25 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
smp4m_boot_cpus();
}
-void __devinit smp_prepare_boot_cpu(void)
+/* Set this up early so that things like the scheduler can init
+ * properly. We use the same cpu mask for both the present and
+ * possible cpu map.
+ */
+void __init smp_setup_cpu_possible_map(void)
+{
+ int instance, mid;
+
+ instance = 0;
+ while (!cpu_find_by_instance(instance, NULL, &mid)) {
+ if (mid < NR_CPUS) {
+ cpu_set(mid, phys_cpu_present_map);
+ cpu_set(mid, cpu_present_map);
+ }
+ instance++;
+ }
+}
+
+void __init smp_prepare_boot_cpu(void)
{
int cpuid = hard_smp_processor_id();
@@ -295,7 +320,7 @@ void __devinit smp_prepare_boot_cpu(void)
cpu_set(cpuid, phys_cpu_present_map);
}
-int __devinit __cpu_up(unsigned int cpu)
+int __cpuinit __cpu_up(unsigned int cpu)
{
extern int smp4m_boot_one_cpu(int);
int ret;
OpenPOWER on IntegriCloud