aboutsummaryrefslogtreecommitdiffstats
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.c108
1 files changed, 73 insertions, 35 deletions
diff --git a/arch/sparc/kernel/smp.c b/arch/sparc/kernel/smp.c
index c6e721d8f477..2be812115197 100644
--- a/arch/sparc/kernel/smp.c
+++ b/arch/sparc/kernel/smp.c
@@ -45,6 +45,7 @@ volatile int __cpu_logical_map[NR_CPUS];
cpumask_t cpu_online_map = CPU_MASK_NONE;
cpumask_t phys_cpu_present_map = CPU_MASK_NONE;
+cpumask_t smp_commenced_mask = CPU_MASK_NONE;
/* The only guaranteed locking primitive available on all Sparc
* processors is 'ldstub [%reg + immediate], %dest_reg' which atomically
@@ -57,11 +58,6 @@ cpumask_t phys_cpu_present_map = CPU_MASK_NONE;
/* Used to make bitops atomic */
unsigned char bitops_spinlock = 0;
-volatile unsigned long ipi_count;
-
-volatile int smp_process_available=0;
-volatile int smp_commenced = 0;
-
void __init smp_store_cpu_info(int id)
{
int cpu_node;
@@ -79,6 +75,22 @@ void __init smp_store_cpu_info(int id)
void __init smp_cpus_done(unsigned int max_cpus)
{
+ extern void smp4m_smp_done(void);
+ unsigned long bogosum = 0;
+ int cpu, num;
+
+ for (cpu = 0, num = 0; cpu < NR_CPUS; cpu++)
+ if (cpu_online(cpu)) {
+ num++;
+ bogosum += cpu_data(cpu).udelay_val;
+ }
+
+ printk("Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
+ num, bogosum/(500000/HZ),
+ (bogosum/(5000/HZ))%100);
+
+ BUG_ON(sparc_cpu_model != sun4m);
+ smp4m_smp_done();
}
void cpu_panic(void)
@@ -89,17 +101,6 @@ void cpu_panic(void)
struct linux_prom_registers smp_penguin_ctable __initdata = { 0 };
-void __init smp_boot_cpus(void)
-{
- extern void smp4m_boot_cpus(void);
- extern void smp4d_boot_cpus(void);
-
- if (sparc_cpu_model == sun4m)
- smp4m_boot_cpus();
- else
- smp4d_boot_cpus();
-}
-
void smp_send_reschedule(int cpu)
{
/* See sparc64 */
@@ -243,9 +244,8 @@ int setup_profiling_timer(unsigned int multiplier)
return -EINVAL;
spin_lock_irqsave(&prof_setup_lock, flags);
- for(i = 0; i < NR_CPUS; i++) {
- if (cpu_possible(i))
- load_profile_irq(i, lvl14_resolution / multiplier);
+ for_each_cpu(i) {
+ load_profile_irq(i, lvl14_resolution / multiplier);
prof_multiplier(i) = multiplier;
}
spin_unlock_irqrestore(&prof_setup_lock, flags);
@@ -253,33 +253,73 @@ int setup_profiling_timer(unsigned int multiplier)
return 0;
}
-void __init smp_prepare_cpus(unsigned int maxcpus)
+void __init smp_prepare_cpus(unsigned int max_cpus)
{
+ extern void smp4m_boot_cpus(void);
+ int i, cpuid, ncpus, 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
+ extra++;
+ }
+ if (max_cpus >= NR_CPUS && extra)
+ printk("Warning: NR_CPUS is too low to start all cpus\n");
+
+ smp_store_cpu_info(boot_cpu_id);
+
+ smp4m_boot_cpus();
}
void __devinit smp_prepare_boot_cpu(void)
{
- current_thread_info()->cpu = hard_smp_processor_id();
- cpu_set(smp_processor_id(), cpu_online_map);
- cpu_set(smp_processor_id(), phys_cpu_present_map);
+ int cpuid = hard_smp_processor_id();
+
+ if (cpuid >= NR_CPUS) {
+ prom_printf("Serious problem, boot cpu id >= NR_CPUS\n");
+ prom_halt();
+ }
+ if (cpuid != 0)
+ printk("boot cpu id != 0, this could work but is untested\n");
+
+ current_thread_info()->cpu = cpuid;
+ cpu_set(cpuid, cpu_online_map);
+ cpu_set(cpuid, phys_cpu_present_map);
}
int __devinit __cpu_up(unsigned int cpu)
{
- panic("smp doesn't work\n");
+ extern int smp4m_boot_one_cpu(int);
+ int ret;
+
+ ret = smp4m_boot_one_cpu(cpu);
+
+ if (!ret) {
+ cpu_set(cpu, smp_commenced_mask);
+ while (!cpu_online(cpu))
+ mb();
+ }
+ return ret;
}
void smp_bogo(struct seq_file *m)
{
int i;
- for (i = 0; i < NR_CPUS; i++) {
- if (cpu_online(i))
- seq_printf(m,
- "Cpu%dBogo\t: %lu.%02lu\n",
- i,
- cpu_data(i).udelay_val/(500000/HZ),
- (cpu_data(i).udelay_val/(5000/HZ))%100);
+ for_each_online_cpu(i) {
+ seq_printf(m,
+ "Cpu%dBogo\t: %lu.%02lu\n",
+ i,
+ cpu_data(i).udelay_val/(500000/HZ),
+ (cpu_data(i).udelay_val/(5000/HZ))%100);
}
}
@@ -288,8 +328,6 @@ void smp_info(struct seq_file *m)
int i;
seq_printf(m, "State:\n");
- for (i = 0; i < NR_CPUS; i++) {
- if (cpu_online(i))
- seq_printf(m, "CPU%d\t\t: online\n", i);
- }
+ for_each_online_cpu(i)
+ seq_printf(m, "CPU%d\t\t: online\n", i);
}