patch-2.1.101 linux/arch/ppc/kernel/smp.c
Next file: linux/arch/ppc/kernel/softemu8xx.c
Previous file: linux/arch/ppc/kernel/signal.c
Back to the patch index
Back to the overall index
- Lines: 329
- Date:
Fri May 8 00:18:23 1998
- Orig file:
v2.1.100/linux/arch/ppc/kernel/smp.c
- Orig date:
Thu Apr 23 20:21:29 1998
diff -u --recursive --new-file v2.1.100/linux/arch/ppc/kernel/smp.c linux/arch/ppc/kernel/smp.c
@@ -1,5 +1,5 @@
/*
- * $Id: smp.c,v 1.22 1998/04/10 01:53:34 cort Exp $
+ * $Id: smp.c,v 1.24 1998/04/27 09:02:37 cort Exp $
*
* Smp support for ppc.
*
@@ -7,7 +7,6 @@
* deal of code from the sparc and intel versions.
*/
-
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/tasks.h>
@@ -18,6 +17,7 @@
#include <linux/delay.h>
#define __KERNEL_SYSCALLS__
#include <linux/unistd.h>
+#include <linux/init.h>
#include <asm/ptrace.h>
#include <asm/atomic.h>
@@ -53,7 +53,123 @@
extern int cpu_idle(void *unused);
-void smp_boot_cpus(void)
+void smp_local_timer_interrupt(struct pt_regs * regs)
+{
+ int cpu = smp_processor_id();
+ extern void update_one_process(struct task_struct *,unsigned long,
+ unsigned long,unsigned long,int);
+
+ if (!--prof_counter[cpu]) {
+ int user=0,system=0;
+ struct task_struct * p = current;
+
+ /*
+ * After doing the above, we need to make like
+ * a normal interrupt - otherwise timer interrupts
+ * ignore the global interrupt lock, which is the
+ * WrongThing (tm) to do.
+ */
+
+ if (user_mode(regs))
+ user=1;
+ else
+ system=1;
+
+ if (p->pid) {
+ update_one_process(p, 1, user, system, cpu);
+
+ p->counter -= 1;
+ if (p->counter < 0) {
+ p->counter = 0;
+ need_resched = 1;
+ }
+ if (p->priority < DEF_PRIORITY) {
+ kstat.cpu_nice += user;
+ kstat.per_cpu_nice[cpu] += user;
+ } else {
+ kstat.cpu_user += user;
+ kstat.per_cpu_user[cpu] += user;
+ }
+
+ kstat.cpu_system += system;
+ kstat.per_cpu_system[cpu] += system;
+
+ }
+ prof_counter[cpu]=prof_multiplier[cpu];
+ }
+}
+
+/*
+ * Dirty hack to get smp message passing working.
+ * Right now it only works for stop cpu's but will be setup
+ * later for more general message passing.
+ *
+ * As it is now, if we're sending two message as the same time
+ * we have race conditions. I avoided doing locks here since
+ * all that works right now is the stop cpu message.
+ *
+ * -- Cort
+ */
+int smp_message[NR_CPUS];
+void smp_message_recv(void)
+{
+ int msg = smp_message[smp_processor_id()];
+
+ printk("SMP %d: smp_message_recv() msg %x\n", smp_processor_id(),msg);
+
+ /* make sure msg is for us */
+ if ( msg == -1 ) return;
+printk("recv after msg check\n");
+ switch( msg )
+ {
+ case MSG_STOP_CPU:
+ __cli();
+ while (1) ;
+ break;
+ case 0xf0f0: /* 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;
+}
+
+spinlock_t mesg_pass_lock = SPIN_LOCK_UNLOCKED;
+void smp_message_pass(int target, int msg, unsigned long data, int wait)
+{
+ printk("SMP %d: sending smp message\n", current->processor);
+
+ spin_lock(&mesg_pass_lock);
+ if ( _machine != _MACH_Pmac )
+ return;
+
+#define OTHER (~smp_processor_id() & 1)
+
+ switch( target )
+ {
+ case MSG_ALL:
+ smp_message[smp_processor_id()] = msg;
+ /* fall through */
+ case MSG_ALL_BUT_SELF:
+ smp_message[OTHER] = msg;
+ break;
+ default:
+ smp_message[target] = msg;
+ break;
+ }
+ /* interrupt secondary processor */
+ /**(volatile unsigned long *)(0xf80000c0) = 0xffffffff;
+ eieio();*/
+ *(volatile unsigned long *)(0xf80000c0) = 0;
+ /* interrupt primary */
+ /**(volatile unsigned long *)(0xf3019000);*/
+ spin_unlock(&mesg_pass_lock);
+}
+
+__initfunc(void smp_boot_cpus(void))
{
extern unsigned long secondary_entry[];
extern struct task_struct *current_set[NR_CPUS];
@@ -118,10 +234,10 @@
__cpu_logical_map[i] = 1;
printk("Processor 1 found.\n");
-#if 0 /* this sync's the decr's */
+#if 0 /* this sync's the decr's, but we don't want this now -- Cort */
set_dec(decrementer_count);
#endif
- /* interrupt secondary to sync the time bases */
+ /* interrupt secondary to start decr's again */
smp_message_pass(1,0xf0f0, 0, 0);
/* interrupt secondary to begin executing code */
/**(volatile unsigned long *)(0xf80000c0) = 0L;
@@ -132,7 +248,7 @@
}
}
-void smp_commence(void)
+__initfunc(void smp_commence(void))
{
printk("SMP %d: smp_commence()\n",current->processor);
/*
@@ -144,19 +260,19 @@
}
/* intel needs this */
-void initialize_secondary(void)
+__initfunc(void initialize_secondary(void))
{
}
/* Activate a secondary processor. */
-int start_secondary(void *unused)
+__initfunc(int start_secondary(void *unused))
{
printk("SMP %d: start_secondary()\n",current->processor);
smp_callin();
return cpu_idle(NULL);
}
-void smp_callin(void)
+__initfunc(void smp_callin(void))
{
printk("SMP %d: smp_callin()\n",current->processor);
smp_store_cpu_info(1);
@@ -174,128 +290,12 @@
__sti();
}
-void smp_setup(char *str, int *ints)
+__initfunc(void smp_setup(char *str, int *ints))
{
printk("SMP %d: smp_setup()\n",current->processor);
}
-void smp_local_timer_interrupt(struct pt_regs * regs)
-{
- int cpu = smp_processor_id();
- extern void update_one_process(struct task_struct *,unsigned long,
- unsigned long,unsigned long,int);
-
- if (!--prof_counter[cpu]) {
- int user=0,system=0;
- struct task_struct * p = current;
-
- /*
- * After doing the above, we need to make like
- * a normal interrupt - otherwise timer interrupts
- * ignore the global interrupt lock, which is the
- * WrongThing (tm) to do.
- */
-
- if (user_mode(regs))
- user=1;
- else
- system=1;
-
- if (p->pid) {
- update_one_process(p, 1, user, system, cpu);
-
- p->counter -= 1;
- if (p->counter < 0) {
- p->counter = 0;
- need_resched = 1;
- }
- if (p->priority < DEF_PRIORITY) {
- kstat.cpu_nice += user;
- kstat.per_cpu_nice[cpu] += user;
- } else {
- kstat.cpu_user += user;
- kstat.per_cpu_user[cpu] += user;
- }
-
- kstat.cpu_system += system;
- kstat.per_cpu_system[cpu] += system;
-
- }
- prof_counter[cpu]=prof_multiplier[cpu];
- }
-}
-
-/*
- * Dirty hack to get smp message passing working.
- * Right now it only works for stop cpu's but will be setup
- * later for more general message passing.
- *
- * As it is now, if we're sending two message as the same time
- * we have race conditions. I avoided doing locks here since
- * all that works right now is the stop cpu message.
- *
- * -- Cort
- */
-int smp_message[NR_CPUS];
-void smp_message_recv(void)
-{
- int msg = smp_message[smp_processor_id()];
-
- printk("SMP %d: smp_message_recv() msg %x\n", smp_processor_id(),msg);
-
- /* make sure msg is for us */
- if ( msg == -1 ) return;
-printk("recv after msg check\n");
- switch( msg )
- {
- case MSG_STOP_CPU:
- __cli();
- while (1) ;
- break;
- case 0xf0f0: /* 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;
-}
-
-spinlock_t mesg_pass_lock = SPIN_LOCK_UNLOCKED;
-void smp_message_pass(int target, int msg, unsigned long data, int wait)
-{
- printk("SMP %d: sending smp message\n", current->processor);
-
- spin_lock(&mesg_pass_lock);
- if ( _machine != _MACH_Pmac )
- return;
-
-#define OTHER (~smp_processor_id() & 1)
-
- switch( target )
- {
- case MSG_ALL:
- smp_message[smp_processor_id()] = msg;
- /* fall through */
- case MSG_ALL_BUT_SELF:
- smp_message[OTHER] = msg;
- break;
- default:
- smp_message[target] = msg;
- break;
- }
- /* interrupt secondary processor */
- /**(volatile unsigned long *)(0xf80000c0) = 0xffffffff;
- eieio();*/
- *(volatile unsigned long *)(0xf80000c0) = 0;
- /* interrupt primary */
- /**(volatile unsigned long *)(0xf3019000);*/
- spin_unlock(&mesg_pass_lock);
-}
-
-int setup_profiling_timer(unsigned int multiplier)
+__initfunc(int setup_profiling_timer(unsigned int multiplier))
{
return 0;
}
@@ -307,4 +307,3 @@
c->loops_per_sec = loops_per_sec;
c->pvr = _get_PVR();
}
-
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov