[SPARC]: Try to start getting SMP back into shape.
authorBob Breuer <breuerr@mc.net>
Fri, 24 Mar 2006 06:36:19 +0000 (22:36 -0800)
committerDavid S. Miller <davem@davemloft.net>
Fri, 24 Mar 2006 06:36:19 +0000 (22:36 -0800)
Todo items:
 - IRQ_INPROGRESS flag - use sparc64 irq buckets, or generic irq_desc?
 - sun4d
 - re-indent large chunks of sun4m_smp.c
 - some places assume sequential cpu numbering (i.e. 0,1 instead of 0,2)

Last I checked (with 2.6.14), random programs segfault with dual
HyperSPARC.  And with SuperSPARC II's, it seems stable but will
eventually die from a write lock error (wrong lock owner or something).

I haven't tried the HyperSPARC + highmem combination recently, so that
may still be a problem.

Signed-off-by: David S. Miller <davem@davemloft.net>
arch/sparc/Kconfig
arch/sparc/kernel/irq.c
arch/sparc/kernel/smp.c
arch/sparc/kernel/sparc_ksyms.c
arch/sparc/kernel/sun4d_irq.c
arch/sparc/kernel/sun4d_smp.c
arch/sparc/kernel/sun4m_smp.c
arch/sparc/mm/srmmu.c
include/asm-sparc/cpudata.h
include/asm-sparc/smp.h
include/asm-sparc/spinlock.h

index f944b58..7c58fc1 100644 (file)
@@ -23,7 +23,6 @@ menu "General machine setup"
 
 config SMP
        bool "Symmetric multi-processing support (does not work on sun4/sun4c)"
-       depends on BROKEN
        ---help---
          This enables support for systems with more than one CPU. If you have
          a system with only one CPU, say N. If you have a system with more
index 4c60a6e..aac8af5 100644 (file)
@@ -154,9 +154,11 @@ void (*sparc_init_timers)(irqreturn_t (*)(int, void *,struct pt_regs *)) =
 struct irqaction static_irqaction[MAX_STATIC_ALLOC];
 int static_irq_count;
 
-struct irqaction *irq_action[NR_IRQS] = {
-       [0 ... (NR_IRQS-1)] = NULL
-};
+struct {
+       struct irqaction *action;
+       int flags;
+} sparc_irq[NR_IRQS];
+#define SPARC_IRQ_INPROGRESS 1
 
 /* Used to protect the IRQ action lists */
 DEFINE_SPINLOCK(irq_action_lock);
@@ -177,7 +179,7 @@ int show_interrupts(struct seq_file *p, void *v)
        }
        spin_lock_irqsave(&irq_action_lock, flags);
        if (i < NR_IRQS) {
-               action = *(i + irq_action);
+               action = sparc_irq[i].action;
                if (!action) 
                        goto out_unlock;
                seq_printf(p, "%3d: ", i);
@@ -186,7 +188,7 @@ int show_interrupts(struct seq_file *p, void *v)
 #else
                for_each_online_cpu(j) {
                        seq_printf(p, "%10u ",
-                                   kstat_cpu(cpu_logical_map(j)).irqs[i]);
+                                   kstat_cpu(j).irqs[i]);
                }
 #endif
                seq_printf(p, " %c %s",
@@ -207,7 +209,7 @@ out_unlock:
 void free_irq(unsigned int irq, void *dev_id)
 {
        struct irqaction * action;
-       struct irqaction * tmp = NULL;
+       struct irqaction **actionp;
         unsigned long flags;
        unsigned int cpu_irq;
        
@@ -225,7 +227,8 @@ void free_irq(unsigned int irq, void *dev_id)
 
        spin_lock_irqsave(&irq_action_lock, flags);
 
-       action = *(cpu_irq + irq_action);
+       actionp = &sparc_irq[cpu_irq].action;
+       action = *actionp;
 
        if (!action->handler) {
                printk("Trying to free free IRQ%d\n",irq);
@@ -235,7 +238,7 @@ void free_irq(unsigned int irq, void *dev_id)
                for (; action; action = action->next) {
                        if (action->dev_id == dev_id)
                                break;
-                       tmp = action;
+                       actionp = &action->next;
                }
                if (!action) {
                        printk("Trying to free free shared IRQ%d\n",irq);
@@ -254,11 +257,8 @@ void free_irq(unsigned int irq, void *dev_id)
                       irq, action->name);
                goto out_unlock;
        }
-       
-       if (action && tmp)
-               tmp->next = action->next;
-       else
-               *(cpu_irq + irq_action) = action->next;
+
+       *actionp = action->next;
 
        spin_unlock_irqrestore(&irq_action_lock, flags);
 
@@ -268,7 +268,7 @@ void free_irq(unsigned int irq, void *dev_id)
 
        kfree(action);
 
-       if (!(*(cpu_irq + irq_action)))
+       if (!sparc_irq[cpu_irq].action)
                disable_irq(irq);
 
 out_unlock:
@@ -287,8 +287,11 @@ EXPORT_SYMBOL(free_irq);
 #ifdef CONFIG_SMP
 void synchronize_irq(unsigned int irq)
 {
-       printk("synchronize_irq says: implement me!\n");
-       BUG();
+       unsigned int cpu_irq;
+
+       cpu_irq = irq & (NR_IRQS - 1);
+       while (sparc_irq[cpu_irq].flags & SPARC_IRQ_INPROGRESS)
+               cpu_relax();
 }
 #endif /* SMP */
 
@@ -299,7 +302,7 @@ void unexpected_irq(int irq, void *dev_id, struct pt_regs * regs)
        unsigned int cpu_irq;
        
        cpu_irq = irq & (NR_IRQS - 1);
-       action = *(cpu_irq + irq_action);
+       action = sparc_irq[cpu_irq].action;
 
         printk("IO device interrupt, irq = %d\n", irq);
         printk("PC = %08lx NPC = %08lx FP=%08lx\n", regs->pc, 
@@ -330,7 +333,8 @@ void handler_irq(int irq, struct pt_regs * regs)
        if(irq < 10)
                smp4m_irq_rotate(cpu);
 #endif
-       action = *(irq + irq_action);
+       action = sparc_irq[irq].action;
+       sparc_irq[irq].flags |= SPARC_IRQ_INPROGRESS;
        kstat_cpu(cpu).irqs[irq]++;
        do {
                if (!action || !action->handler)
@@ -338,6 +342,7 @@ void handler_irq(int irq, struct pt_regs * regs)
                action->handler(irq, action->dev_id, regs);
                action = action->next;
        } while (action);
+       sparc_irq[irq].flags &= ~SPARC_IRQ_INPROGRESS;
        enable_pil_irq(irq);
        irq_exit();
 }
@@ -389,7 +394,7 @@ int request_fast_irq(unsigned int irq,
 
        spin_lock_irqsave(&irq_action_lock, flags);
 
-       action = *(cpu_irq + irq_action);
+       action = sparc_irq[cpu_irq].action;
        if(action) {
                if(action->flags & SA_SHIRQ)
                        panic("Trying to register fast irq when already shared.\n");
@@ -452,7 +457,7 @@ int request_fast_irq(unsigned int irq,
        action->dev_id = NULL;
        action->next = NULL;
 
-       *(cpu_irq + irq_action) = action;
+       sparc_irq[cpu_irq].action = action;
 
        enable_irq(irq);
 
@@ -467,7 +472,7 @@ int request_irq(unsigned int irq,
                irqreturn_t (*handler)(int, void *, struct pt_regs *),
                unsigned long irqflags, const char * devname, void *dev_id)
 {
-       struct irqaction * action, *tmp = NULL;
+       struct irqaction * action, **actionp;
        unsigned long flags;
        unsigned int cpu_irq;
        int ret;
@@ -490,20 +495,20 @@ int request_irq(unsigned int irq,
            
        spin_lock_irqsave(&irq_action_lock, flags);
 
-       action = *(cpu_irq + irq_action);
+       actionp = &sparc_irq[cpu_irq].action;
+       action = *actionp;
        if (action) {
-               if ((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ)) {
-                       for (tmp = action; tmp->next; tmp = tmp->next);
-               } else {
+               if (!(action->flags & SA_SHIRQ) || !(irqflags & SA_SHIRQ)) {
                        ret = -EBUSY;
                        goto out_unlock;
                }
-               if ((action->flags & SA_INTERRUPT) ^ (irqflags & SA_INTERRUPT)) {
+               if ((action->flags & SA_INTERRUPT) != (irqflags & SA_INTERRUPT)) {
                        printk("Attempt to mix fast and slow interrupts on IRQ%d denied\n", irq);
                        ret = -EBUSY;
                        goto out_unlock;
-               }   
-               action = NULL;          /* Or else! */
+               }
+               for ( ; action; action = *actionp)
+                       actionp = &action->next;
        }
 
        /* If this is flagged as statically allocated then we use our
@@ -532,10 +537,7 @@ int request_irq(unsigned int irq,
        action->next = NULL;
        action->dev_id = dev_id;
 
-       if (tmp)
-               tmp->next = action;
-       else
-               *(cpu_irq + irq_action) = action;
+       *actionp = action;
 
        enable_irq(irq);
 
index ea5682c..2be8121 100644 (file)
@@ -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 */
@@ -252,20 +253,61 @@ 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)
index 19b2539..2c21d79 100644 (file)
@@ -136,10 +136,6 @@ EXPORT_PER_CPU_SYMBOL(__cpu_data);
 /* IRQ implementation. */
 EXPORT_SYMBOL(synchronize_irq);
 
-/* Misc SMP information */
-EXPORT_SYMBOL(__cpu_number_map);
-EXPORT_SYMBOL(__cpu_logical_map);
-
 /* CPU online map and active count. */
 EXPORT_SYMBOL(cpu_online_map);
 EXPORT_SYMBOL(phys_cpu_present_map);
index cea7fc6..ca656d9 100644 (file)
@@ -54,7 +54,7 @@ unsigned char cpu_leds[32];
 unsigned char sbus_tid[32];
 #endif
 
-extern struct irqaction *irq_action[];
+static struct irqaction *irq_action[NR_IRQS];
 extern spinlock_t irq_action_lock;
 
 struct sbus_action {
index 41bb959..b141b7e 100644 (file)
@@ -46,14 +46,16 @@ extern volatile int smp_processors_ready;
 extern int smp_num_cpus;
 static int smp_highest_cpu;
 extern volatile unsigned long cpu_callin_map[NR_CPUS];
-extern struct cpuinfo_sparc cpu_data[NR_CPUS];
+extern cpuinfo_sparc cpu_data[NR_CPUS];
 extern unsigned char boot_cpu_id;
 extern int smp_activated;
 extern volatile int __cpu_number_map[NR_CPUS];
 extern volatile int __cpu_logical_map[NR_CPUS];
 extern volatile unsigned long ipi_count;
 extern volatile int smp_process_available;
-extern volatile int smp_commenced;
+
+extern cpumask_t smp_commenced_mask;
+
 extern int __smp4d_processor_id(void);
 
 /* #define SMP_DEBUG */
@@ -136,7 +138,7 @@ void __init smp4d_callin(void)
        
        local_irq_enable();     /* We don't allow PIL 14 yet */
        
-       while(!smp_commenced)
+       while (!cpu_isset(cpuid, smp_commenced_mask))
                barrier();
 
        spin_lock_irqsave(&sun4d_imsk_lock, flags);
index 1dde312..70b375a 100644 (file)
@@ -40,15 +40,11 @@ extern ctxd_t *srmmu_ctx_table_phys;
 extern void calibrate_delay(void);
 
 extern volatile int smp_processors_ready;
-extern int smp_num_cpus;
 extern volatile unsigned long cpu_callin_map[NR_CPUS];
 extern unsigned char boot_cpu_id;
-extern int smp_activated;
-extern volatile int __cpu_number_map[NR_CPUS];
-extern volatile int __cpu_logical_map[NR_CPUS];
-extern volatile unsigned long ipi_count;
-extern volatile int smp_process_available;
-extern volatile int smp_commenced;
+
+extern cpumask_t smp_commenced_mask;
+
 extern int __smp4m_processor_id(void);
 
 /*#define SMP_DEBUG*/
@@ -77,8 +73,6 @@ void __init smp4m_callin(void)
        local_flush_cache_all();
        local_flush_tlb_all();
 
-       set_irq_udt(boot_cpu_id);
-
        /* Get our local ticker going. */
        smp_setup_percpu_timer();
 
@@ -95,8 +89,9 @@ void __init smp4m_callin(void)
         * to call the scheduler code.
         */
        /* Allow master to continue. */
-       swap((unsigned long *)&cpu_callin_map[cpuid], 1);
+       swap(&cpu_callin_map[cpuid], 1);
 
+       /* XXX: What's up with all the flushes? */
        local_flush_cache_all();
        local_flush_tlb_all();
        
@@ -111,13 +106,14 @@ void __init smp4m_callin(void)
        atomic_inc(&init_mm.mm_count);
        current->active_mm = &init_mm;
 
-       while(!smp_commenced)
-               barrier();
-
-       local_flush_cache_all();
-       local_flush_tlb_all();
+       while (!cpu_isset(cpuid, smp_commenced_mask))
+               mb();
 
        local_irq_enable();
+
+       cpu_set(cpuid, cpu_online_map);
+       /* last one in gets all the interrupts (for testing) */
+       set_irq_udt(boot_cpu_id);
 }
 
 extern void init_IRQ(void);
@@ -134,102 +130,76 @@ extern unsigned long trapbase_cpu3[];
 
 void __init smp4m_boot_cpus(void)
 {
-       int cpucount = 0;
-       int i, mid;
+       smp_setup_percpu_timer();
+       local_flush_cache_all();
+}
 
-       printk("Entering SMP Mode...\n");
+int smp4m_boot_one_cpu(int i)
+{
+       extern unsigned long sun4m_cpu_startup;
+       unsigned long *entry = &sun4m_cpu_startup;
+       struct task_struct *p;
+       int timeout;
+       int cpu_node;
 
-       local_irq_enable();
-       cpus_clear(cpu_present_map);
+       cpu_find_by_mid(i, &cpu_node);
+
+       /* Cook up an idler for this guy. */
+       p = fork_idle(i);
+       current_set[i] = task_thread_info(p);
+       /* See trampoline.S for details... */
+       entry += ((i-1) * 3);
 
-       for (i = 0; !cpu_find_by_instance(i, NULL, &mid); i++)
-               cpu_set(mid, cpu_present_map);
+       /*
+        * Initialize the contexts table
+        * Since the call to prom_startcpu() trashes the structure,
+        * we need to re-initialize it for each cpu
+        */
+       smp_penguin_ctable.which_io = 0;
+       smp_penguin_ctable.phys_addr = (unsigned int) srmmu_ctx_table_phys;
+       smp_penguin_ctable.reg_size = 0;
 
-       for(i=0; i < NR_CPUS; i++) {
-               __cpu_number_map[i] = -1;
-               __cpu_logical_map[i] = -1;
+       /* whirrr, whirrr, whirrrrrrrrr... */
+       printk("Starting CPU %d at %p\n", i, entry);
+       local_flush_cache_all();
+       prom_startcpu(cpu_node,
+                     &smp_penguin_ctable, 0, (char *)entry);
+
+       /* wheee... it's going... */
+       for(timeout = 0; timeout < 10000; timeout++) {
+               if(cpu_callin_map[i])
+                       break;
+               udelay(200);
        }
 
-       __cpu_number_map[boot_cpu_id] = 0;
-       __cpu_logical_map[0] = boot_cpu_id;
-       current_thread_info()->cpu = boot_cpu_id;
+       if (!(cpu_callin_map[i])) {
+               printk("Processor %d is stuck.\n", i);
+               return -ENODEV;
+       }
 
-       smp_store_cpu_info(boot_cpu_id);
-       set_irq_udt(boot_cpu_id);
-       smp_setup_percpu_timer();
        local_flush_cache_all();
-       if(cpu_find_by_instance(1, NULL, NULL))
-               return;  /* Not an MP box. */
-       for(i = 0; i < NR_CPUS; i++) {
-               if(i == boot_cpu_id)
-                       continue;
-
-               if (cpu_isset(i, cpu_present_map)) {
-                       extern unsigned long sun4m_cpu_startup;
-                       unsigned long *entry = &sun4m_cpu_startup;
-                       struct task_struct *p;
-                       int timeout;
-
-                       /* Cook up an idler for this guy. */
-                       p = fork_idle(i);
-                       cpucount++;
-                       current_set[i] = task_thread_info(p);
-                       /* See trampoline.S for details... */
-                       entry += ((i-1) * 3);
-
-                       /*
-                        * Initialize the contexts table
-                        * Since the call to prom_startcpu() trashes the structure,
-                        * we need to re-initialize it for each cpu
-                        */
-                       smp_penguin_ctable.which_io = 0;
-                       smp_penguin_ctable.phys_addr = (unsigned int) srmmu_ctx_table_phys;
-                       smp_penguin_ctable.reg_size = 0;
-
-                       /* whirrr, whirrr, whirrrrrrrrr... */
-                       printk("Starting CPU %d at %p\n", i, entry);
-                       local_flush_cache_all();
-                       prom_startcpu(cpu_data(i).prom_node,
-                                     &smp_penguin_ctable, 0, (char *)entry);
-
-                       /* wheee... it's going... */
-                       for(timeout = 0; timeout < 10000; timeout++) {
-                               if(cpu_callin_map[i])
-                                       break;
-                               udelay(200);
-                       }
-                       if(cpu_callin_map[i]) {
-                               /* Another "Red Snapper". */
-                               __cpu_number_map[i] = i;
-                               __cpu_logical_map[i] = i;
-                       } else {
-                               cpucount--;
-                               printk("Processor %d is stuck.\n", i);
-                       }
-               }
-               if(!(cpu_callin_map[i])) {
-                       cpu_clear(i, cpu_present_map);
-                       __cpu_number_map[i] = -1;
+       return 0;
+}
+
+void __init smp4m_smp_done(void)
+{
+       int i, first;
+       int *prev;
+
+       /* setup cpu list for irq rotation */
+       first = 0;
+       prev = &first;
+       for (i = 0; i < NR_CPUS; i++) {
+               if (cpu_online(i)) {
+                       *prev = i;
+                       prev = &cpu_data(i).next;
                }
        }
+       *prev = first;
        local_flush_cache_all();
-       if(cpucount == 0) {
-               printk("Error: only one Processor found.\n");
-               cpu_present_map = cpumask_of_cpu(smp_processor_id());
-       } else {
-               unsigned long bogosum = 0;
-               for_each_present_cpu(i)
-                       bogosum += cpu_data(i).udelay_val;
-               printk("Total of %d Processors activated (%lu.%02lu BogoMIPS).\n",
-                      cpucount + 1,
-                      bogosum/(500000/HZ),
-                      (bogosum/(5000/HZ))%100);
-               smp_activated = 1;
-               smp_num_cpus = cpucount + 1;
-       }
 
        /* Free unneeded trap tables */
-       if (!cpu_isset(i, cpu_present_map)) {
+       if (!cpu_isset(1, cpu_present_map)) {
                ClearPageReserved(virt_to_page(trapbase_cpu1));
                init_page_count(virt_to_page(trapbase_cpu1));
                free_page((unsigned long)trapbase_cpu1);
@@ -263,6 +233,9 @@ void __init smp4m_boot_cpus(void)
  */
 void smp4m_irq_rotate(int cpu)
 {
+       int next = cpu_data(cpu).next;
+       if (next != cpu)
+               set_irq_udt(next);
 }
 
 /* Cross calls, in order to work efficiently and atomically do all
@@ -289,7 +262,7 @@ void smp4m_message_pass(int target, int msg, unsigned long data, int wait)
 
        smp_cpu_in_msg[me]++;
        if(target == MSG_ALL_BUT_SELF || target == MSG_ALL) {
-               mask = cpu_present_map;
+               mask = cpu_online_map;
                if(target == MSG_ALL_BUT_SELF)
                        cpu_clear(me, mask);
                for(i = 0; i < 4; i++) {
@@ -314,8 +287,8 @@ static struct smp_funcall {
        unsigned long arg3;
        unsigned long arg4;
        unsigned long arg5;
-       unsigned long processors_in[NR_CPUS];  /* Set when ipi entered. */
-       unsigned long processors_out[NR_CPUS]; /* Set when ipi exited. */
+       unsigned long processors_in[SUN4M_NCPUS];  /* Set when ipi entered. */
+       unsigned long processors_out[SUN4M_NCPUS]; /* Set when ipi exited. */
 } ccall_info;
 
 static DEFINE_SPINLOCK(cross_call_lock);
@@ -324,8 +297,7 @@ static DEFINE_SPINLOCK(cross_call_lock);
 void smp4m_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2,
                    unsigned long arg3, unsigned long arg4, unsigned long arg5)
 {
-       if(smp_processors_ready) {
-               register int ncpus = smp_num_cpus;
+               register int ncpus = SUN4M_NCPUS;
                unsigned long flags;
 
                spin_lock_irqsave(&cross_call_lock, flags);
@@ -340,7 +312,7 @@ void smp4m_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2,
 
                /* Init receive/complete mapping, plus fire the IPI's off. */
                {
-                       cpumask_t mask = cpu_present_map;
+                       cpumask_t mask = cpu_online_map;
                        register int i;
 
                        cpu_clear(smp_processor_id(), mask);
@@ -373,7 +345,6 @@ void smp4m_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2,
                }
 
                spin_unlock_irqrestore(&cross_call_lock, flags);
-       }
 }
 
 /* Running cross calls. */
index 27b0e0b..58c65cc 100644 (file)
@@ -1302,7 +1302,12 @@ void __init srmmu_paging_init(void)
 
        flush_cache_all();
        srmmu_set_ctable_ptr((unsigned long)srmmu_ctx_table_phys);
+#ifdef CONFIG_SMP
+       /* Stop from hanging here... */
+       local_flush_tlb_all();
+#else
        flush_tlb_all();
+#endif
        poke_srmmu();
 
 #ifdef CONFIG_SUN_IO
@@ -1419,6 +1424,7 @@ static void __init init_vac_layout(void)
                                max_size = vac_cache_size;
                        if(vac_line_size < min_line_size)
                                min_line_size = vac_line_size;
+                       //FIXME: cpus not contiguous!!
                        cpu++;
                        if (cpu >= NR_CPUS || !cpu_online(cpu))
                                break;
index ec0d9ef..a2c4d51 100644 (file)
@@ -18,6 +18,7 @@ typedef struct {
        unsigned int counter;
        int prom_node;
        int mid;
+       int next;
 } cpuinfo_sparc;
 
 DECLARE_PER_CPU(cpuinfo_sparc, __cpu_data);
index 580c51d..98c46e3 100644 (file)
@@ -81,16 +81,9 @@ static inline int smp_call_function(void (*func)(void *info), void *info, int no
        return 0;
 }
 
-extern __volatile__ int __cpu_number_map[NR_CPUS];
-extern __volatile__ int __cpu_logical_map[NR_CPUS];
-
 static inline int cpu_logical_map(int cpu)
 {
-       return __cpu_logical_map[cpu];
-}
-static inline int cpu_number_map(int cpu)
-{
-       return __cpu_number_map[cpu];
+       return cpu;
 }
 
 static inline int hard_smp4m_processor_id(void)
index e344c98..3350c90 100644 (file)
@@ -94,7 +94,7 @@ static inline void __read_lock(raw_rwlock_t *rw)
 #define __raw_read_lock(lock) \
 do {   unsigned long flags; \
        local_irq_save(flags); \
-       __raw_read_lock(lock); \
+       __read_lock(lock); \
        local_irq_restore(flags); \
 } while(0)
 
@@ -114,11 +114,11 @@ static inline void __read_unlock(raw_rwlock_t *rw)
 #define __raw_read_unlock(lock) \
 do {   unsigned long flags; \
        local_irq_save(flags); \
-       __raw_read_unlock(lock); \
+       __read_unlock(lock); \
        local_irq_restore(flags); \
 } while(0)
 
-extern __inline__ void __raw_write_lock(raw_rwlock_t *rw)
+static inline void __raw_write_lock(raw_rwlock_t *rw)
 {
        register raw_rwlock_t *lp asm("g1");
        lp = rw;
@@ -131,9 +131,28 @@ extern __inline__ void __raw_write_lock(raw_rwlock_t *rw)
        : "g2", "g4", "memory", "cc");
 }
 
+static inline int __raw_write_trylock(raw_rwlock_t *rw)
+{
+       unsigned int val;
+
+       __asm__ __volatile__("ldstub [%1 + 3], %0"
+                            : "=r" (val)
+                            : "r" (&rw->lock)
+                            : "memory");
+
+       if (val == 0) {
+               val = rw->lock & ~0xff;
+               if (val)
+                       ((volatile u8*)&rw->lock)[3] = 0;
+       }
+
+       return (val == 0);
+}
+
 #define __raw_write_unlock(rw) do { (rw)->lock = 0; } while(0)
 
 #define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
+#define __raw_read_trylock(lock) generic__raw_read_trylock(lock)
 
 #endif /* !(__ASSEMBLY__) */