patch-2.3.34 linux/arch/ppc/kernel/smp.c
Next file: linux/arch/ppc/lib/Makefile
Previous file: linux/arch/ppc/kernel/process.c
Back to the patch index
Back to the overall index
- Lines: 246
- Date:
Mon Dec 20 14:27:34 1999
- Orig file:
v2.3.33/linux/arch/ppc/kernel/smp.c
- Orig date:
Tue Dec 7 09:32:42 1999
diff -u --recursive --new-file v2.3.33/linux/arch/ppc/kernel/smp.c linux/arch/ppc/kernel/smp.c
@@ -108,34 +108,8 @@
}
}
-/*
- * Dirty hack to get smp message passing working.
- *
- * As it is now, if we're sending two message at the same time
- * we have race conditions. The PowerSurge doesn't easily
- * allow us to send IPI messages so we put the messages in
- * smp_message[].
- *
- * This is because don't have several IPI's on the PowerSurge even though
- * we do on the chrp. It would be nice to use the actual IPI's on the chrp
- * rather than this but having two methods of doing IPI isn't a good idea
- * right now.
- * -- Cort
- */
-int smp_message[NR_CPUS];
-void smp_message_recv(void)
+void smp_message_recv(int msg)
{
- int msg = smp_message[smp_processor_id()];
-
- if ( _machine == _MACH_Pmac )
- {
- /* clear interrupt */
- out_be32(PSURGE_INTR, ~0);
- }
-
- /* make sure msg is for us */
- if ( msg == -1 ) return;
-
ipi_count++;
switch( msg )
@@ -147,15 +121,54 @@
case MSG_RESCHEDULE:
current->need_resched = 1;
break;
- case 0xf0f0: /* syncing time bases - just return */
+ case MSG_INVALIDATE_TLB:
+ _tlbia();
+ case 0xf0f0: /* pmac syncing time bases - just return */
break;
default:
printk("SMP %d: smp_message_recv(): unknown msg %d\n",
smp_processor_id(), msg);
break;
}
- /* reset message */
- smp_message[smp_processor_id()] = -1;
+}
+
+/*
+ * As it is now, if we're sending two message at the same time
+ * we have race conditions on Pmac. The PowerSurge doesn't easily
+ * allow us to send IPI messages so we put the messages in
+ * smp_message[].
+ *
+ * This is because don't have several IPI's on the PowerSurge even though
+ * we do on the chrp. It would be nice to use actual IPI's such as with openpic
+ * rather than this.
+ * -- Cort
+ */
+int pmac_smp_message[NR_CPUS];
+void pmac_smp_message_recv(void)
+{
+ int msg = pmac_smp_message[smp_processor_id()];
+
+ /* clear interrupt */
+ out_be32(PSURGE_INTR, ~0);
+
+ /* make sure msg is for us */
+ if ( msg == -1 ) return;
+
+ smp_message_recv(msg);
+
+ /* reset message */
+ pmac_smp_message[smp_processor_id()] = -1;
+}
+
+/*
+ * 750's don't broadcast tlb invalidates so
+ * we have to emulate that behavior.
+ * -- Cort
+ */
+void smp_send_tlb_invalidate(int cpu)
+{
+ if ( (_get_PVR()>>16) == 8 )
+ smp_message_pass(MSG_ALL_BUT_SELF, MSG_INVALIDATE_TLB, 0, 0);
}
void smp_send_reschedule(int cpu)
@@ -169,6 +182,8 @@
* as the timer).
* -- Cort
*/
+ /* This is only used if `cpu' is running an idle task,
+ so it will reschedule itself anyway... */
smp_message_pass(cpu, MSG_RESCHEDULE, 0, 0);
}
@@ -177,38 +192,39 @@
smp_message_pass(MSG_ALL_BUT_SELF, MSG_STOP_CPU, 0, 0);
}
-spinlock_t mesg_pass_lock = SPIN_LOCK_UNLOCKED;
void smp_message_pass(int target, int msg, unsigned long data, int wait)
{
int i;
- if ( !(_machine & (_MACH_Pmac|_MACH_chrp|_MACH_gemini)) )
+
+ if ( !(_machine & (_MACH_Pmac|_MACH_chrp|_MACH_prep|_MACH_gemini)) )
return;
- spin_lock(&mesg_pass_lock);
-
- /*
- * We assume here that the msg is not -1. If it is,
- * the recipient won't know the message was destined
- * for it. -- Cort
- */
-
- switch( target )
- {
- case MSG_ALL:
- smp_message[smp_processor_id()] = msg;
- /* fall through */
- case MSG_ALL_BUT_SELF:
- for ( i = 0 ; i < smp_num_cpus ; i++ )
- if ( i != smp_processor_id () )
- smp_message[i] = msg;
- break;
- default:
- smp_message[target] = msg;
- break;
- }
-
- if ( _machine == _MACH_Pmac )
- {
+ switch (_machine) {
+ case _MACH_Pmac:
+ /*
+ * IPI's on the Pmac are a hack but without reasonable
+ * IPI hardware SMP on Pmac is a hack.
+ *
+ * We assume here that the msg is not -1. If it is,
+ * the recipient won't know the message was destined
+ * for it. -- Cort
+ */
+ for ( i = 0; i <= smp_num_cpus ; i++ )
+ pmac_smp_message[i] = -1;
+ switch( target )
+ {
+ case MSG_ALL:
+ pmac_smp_message[smp_processor_id()] = msg;
+ /* fall through */
+ case MSG_ALL_BUT_SELF:
+ for ( i = 0 ; i < smp_num_cpus ; i++ )
+ if ( i != smp_processor_id () )
+ pmac_smp_message[i] = msg;
+ break;
+ default:
+ pmac_smp_message[target] = msg;
+ break;
+ }
/* interrupt secondary processor */
out_be32(PSURGE_INTR, ~0);
out_be32(PSURGE_INTR, 0);
@@ -218,40 +234,28 @@
*/
/* interrupt primary */
/**(volatile unsigned long *)(0xf3019000);*/
- }
-
- if ( _machine == _MACH_chrp )
- {
- /*
- * There has to be some way of doing this better -
- * perhaps a send-to-all or send-to-all-but-self
- * in the openpic. This gets us going for now, though.
- * -- Cort
- */
+ break;
+ case _MACH_chrp:
+ case _MACH_prep:
+ case _MACH_gemini:
+ /* make sure we're sending something that translates to an IPI */
+ if ( msg > 0x3 )
+ break;
switch ( target )
{
case MSG_ALL:
- openpic_cause_IPI(smp_processor_id(), 0, 0x0 );
- openpic_cause_IPI(smp_processor_id(), 0, 0xffffffff );
+ openpic_cause_IPI(smp_processor_id(), msg, 0xffffffff);
break;
case MSG_ALL_BUT_SELF:
- for ( i = 0 ; i < smp_num_cpus ; i++ )
- if ( i != smp_processor_id () )
- {
- openpic_cause_IPI(smp_processor_id(), 0,
- 0x0 );
- openpic_cause_IPI(smp_processor_id(), 0,
+ openpic_cause_IPI(smp_processor_id(), msg,
0xffffffff & ~(1 << smp_processor_id()));
- }
break;
default:
- openpic_cause_IPI(smp_processor_id(), 0, 0x0 );
- openpic_cause_IPI(target, 0, 1U << target );
+ openpic_cause_IPI(smp_processor_id(), msg, 1<<target);
break;
}
+ break;
}
-
- spin_unlock(&mesg_pass_lock);
}
void __init smp_boot_cpus(void)
@@ -387,6 +391,9 @@
}
}
+ if ( _machine & (_MACH_gemini|_MACH_chrp|_MACH_prep) )
+ do_openpic_setup_cpu();
+
if ( _machine == _MACH_Pmac )
{
/* reset the entry point so if we get another intr we won't
@@ -432,6 +439,13 @@
current->mm->mmap->vm_end = init_mm.mmap->vm_end;
#endif
cpu_callin_map[current->processor] = 1;
+ /*
+ * Each processor has to do this and this is the best
+ * place to stick it for now.
+ * -- Cort
+ */
+ if ( _machine & (_MACH_gemini|_MACH_chrp|_MACH_prep) )
+ do_openpic_setup_cpu();
while(!smp_commenced)
barrier();
__sti();
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)