patch-2.1.79 linux/arch/ppc/kernel/process.c
Next file: linux/arch/ppc/kernel/prom.c
Previous file: linux/arch/ppc/kernel/prep_time.c
Back to the patch index
Back to the overall index
- Lines: 205
- Date:
Mon Jan 12 15:18:13 1998
- Orig file:
v2.1.78/linux/arch/ppc/kernel/process.c
- Orig date:
Mon Aug 18 18:19:44 1997
diff -u --recursive --new-file v2.1.78/linux/arch/ppc/kernel/process.c linux/arch/ppc/kernel/process.c
@@ -1,15 +1,16 @@
+
/*
* linux/arch/ppc/kernel/process.c
*
- * PowerPC version
- * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
- *
* Derived from "arch/i386/kernel/process.c"
* Copyright (C) 1995 Linus Torvalds
*
* Updated and modified by Cort Dougan (cort@cs.nmt.edu) and
* Paul Mackerras (paulus@cs.anu.edu.au)
*
+ * PowerPC version
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
@@ -38,15 +39,17 @@
#include <asm/io.h>
#include <asm/smp_lock.h>
#include <asm/processor.h>
+#include <asm/mmu.h>
+#include <asm/prom.h>
int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpregs);
void switch_to(struct task_struct *, struct task_struct *);
-extern unsigned long _get_SP(void);
+extern unsigned long _get_SP(void);
+extern spinlock_t scheduler_lock;
#undef SHOW_TASK_SWITCHES 1
#undef CHECK_STACK 1
-#undef IDLE_ZERO 1
unsigned long
kernel_stack_top(struct task_struct *tsk)
@@ -68,6 +71,9 @@
struct mm_struct init_mm = INIT_MM;
union task_union init_task_union = { INIT_TASK };
+/* only used to get secondary processor up */
+struct task_struct *current_set[NR_CPUS] = {&init_task, };
+
int
dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpregs)
{
@@ -145,17 +151,30 @@
{
struct thread_struct *new_tss, *old_tss;
int s = _disable_interrupts();
-
#if CHECK_STACK
check_stack(prev);
check_stack(new);
#endif
#ifdef SHOW_TASK_SWITCHES
- printk("%s/%d (%x) -> %s/%d (%x) ctx %x\n",
- prev->comm,prev->pid,prev->tss.regs->nip,
- new->comm,new->pid,new->tss.regs->nip,new->mm->context);
+ printk("%s/%d -> %s/%d cpu %d\n",
+ prev->comm,prev->pid,
+ new->comm,new->pid,new->processor);
#endif
+#ifdef __SMP__
+ /* bad news if last_task_used_math changes processors right now -- Cort */
+ if ( (last_task_used_math == new) &&
+ (new->processor != new->last_processor) )
+ panic("last_task_used_math switched processors");
+ /* be noisy about processor changes for debugging -- Cort */
+ if ( new->last_processor != new->processor )
+ printk("switch_to(): changing cpu's %d -> %d %s/%d\n",
+ new->last_processor,new->processor,
+ new->comm,new->pid);
+
+ prev->last_processor = prev->processor;
+ current_set[smp_processor_id()] = new;
+#endif /* __SMP__ */
new_tss = &new->tss;
old_tss = ¤t->tss;
_switch(old_tss, new_tss, new->mm->context);
@@ -181,7 +200,13 @@
printk("TASK = %p[%d] '%s' mm->pgd %p ",
current, current->pid, current->comm, current->mm->pgd);
printk("Last syscall: %ld ", current->tss.last_syscall);
- printk("\nlast math %p\n", last_task_used_math);
+ printk("\nlast math %p", last_task_used_math);
+
+#ifdef __SMP__
+ printk(" CPU: %d last CPU: %d", current->processor,current->last_processor);
+#endif /* __SMP__ */
+
+ printk("\n");
for (i = 0; i < 32; i++)
{
long r;
@@ -226,7 +251,7 @@
struct task_struct * p, struct pt_regs * regs)
{
struct pt_regs * childregs;
-
+
/* Copy registers */
childregs = ((struct pt_regs *)
((unsigned long)p + sizeof(union task_union)
@@ -245,7 +270,6 @@
/* Provided stack is in user space */
childregs->gpr[1] = usp;
}
-
p->tss.last_syscall = -1;
/*
@@ -321,6 +345,10 @@
lock_kernel();
ret = do_fork(SIGCHLD, regs->gpr[1], regs);
+#if 0/*def __SMP__*/
+ if ( ret ) /* drop scheduler lock in child */
+ scheduler_lock.lock = 0L;
+#endif /* __SMP__ */
unlock_kernel();
return ret;
}
@@ -332,6 +360,7 @@
int error;
char * filename;
+ lock_kernel();
filename = getname((char *) a0);
error = PTR_ERR(filename);
if (IS_ERR(filename))
@@ -353,6 +382,16 @@
lock_kernel();
res = do_fork(clone_flags, regs->gpr[1], regs);
+#ifdef __SMP__
+ /* When we clone the idle task we keep the same pid but
+ * the return value of 0 for both causes problems.
+ * -- Cort
+ */
+ if ((current->pid == 0) && (current == &init_task))
+ res = 1;
+ if ( 0 /*res*/ ) /* drop scheduler lock in child */
+ scheduler_lock.lock = 0L;
+#endif /* __SMP__ */
unlock_kernel();
return res;
}
@@ -377,7 +416,6 @@
printk("\n");
}
-#if 0
/*
* Low level print for debugging - Cort
*/
@@ -394,15 +432,37 @@
return i;
}
-char *vidmem = (char *)0xC00B8000;
int lines = 24, cols = 80;
int orig_x = 0, orig_y = 0;
void ll_puts(const char *s)
{
int x,y;
+ char *vidmem = (char *)(_ISA_MEM_BASE + 0xB8000) /*0xC00B8000*/;
char c;
+ extern int mem_init_done;
+
+ if ( mem_init_done ) /* assume this means we can printk */
+ {
+ printk(s);
+ return;
+ }
+
+#if 0
+ if ( have_of )
+ {
+ prom_print(s);
+ return;
+ }
+#endif
+ /*
+ * can't ll_puts on chrp without openfirmware yet.
+ * vidmem just needs to be setup for it.
+ * -- Cort
+ */
+ if ( ! is_prep )
+ return;
x = orig_x;
y = orig_y;
@@ -430,4 +490,3 @@
orig_x = x;
orig_y = y;
}
-#endif /* CONFIG_PREP */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov