patch-1.3.4 linux/arch/sparc/kernel/process.c
Next file: linux/arch/sparc/kernel/setup.c
Previous file: linux/arch/sparc/kernel/probe.c
Back to the patch index
Back to the overall index
- Lines: 157
- Date:
Sat Jun 10 09:07:20 1995
- Orig file:
v1.3.3/linux/arch/sparc/kernel/process.c
- Orig date:
Sun Feb 26 20:46:20 1995
diff -u --recursive --new-file v1.3.3/linux/arch/sparc/kernel/process.c linux/arch/sparc/kernel/process.c
@@ -1,7 +1,7 @@
/*
- * linux/arch/i386/kernel/process.c
+ * linux/arch/sparc/kernel/process.c
*
- * Copyright (C) 1995 Linus Torvalds
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
*/
/*
@@ -20,47 +20,43 @@
#include <linux/user.h>
#include <linux/a.out.h>
+#include <asm/oplib.h>
#include <asm/segment.h>
#include <asm/system.h>
-
-void ret_from_sys_call(void) { __asm__("nop"); }
+#include <asm/processor.h>
/*
- * The idle loop on a i386..
+ * The idle loop on a sparc... ;)
*/
asmlinkage int sys_idle(void)
{
+
if (current->pid != 0)
return -EPERM;
+ printk("in sys_idle...\n");
/* Map out the low memory: it's no longer needed */
/* Sparc version RSN */
/* endless idle loop with no priority at all */
current->counter = -100;
for (;;) {
- schedule();
+ printk("calling schedule() aieee!\n");
+ schedule();
+ printk("schedule() returned, halting...\n");
+ halt();
}
}
void hard_reset_now(void)
{
- halt();
+ prom_reboot("boot vmlinux");
}
void show_regs(struct pt_regs * regs)
{
- printk("\nSP: %08lx PC: %08lx NPC: %08lx\n", regs->sp, regs->pc,
- regs->npc);
-}
-
-/*
- * Do necessary setup to start up a newly executed thread.
- */
-void start_thread(struct pt_regs * regs, unsigned long sp, unsigned long fp)
-{
- regs->sp = sp;
- regs->fp = fp;
+ printk("\nFP: %08lx PC: %08lx NPC: %08lx\n", regs->u_regs[14],
+ regs->pc, regs->npc);
}
/*
@@ -76,15 +72,60 @@
halt();
}
-void copy_thread(int nr, unsigned long clone_flags, unsigned long sp, struct task_struct * p, struct pt_regs * regs)
+extern void ret_sys_call(void);
+
+/*
+ * Copy a Sparc thread. The context of a process on the Sparc is
+ * composed of the following:
+ * 1) status registers %psr (for condition codes + CWP) and %wim
+ * 2) current register window (in's and global registers)
+ * 3) the current live stack frame, it contains the register
+ * windows the child may 'restore' into, this is important
+ * 4) kernel stack pointer, user stack pointer (which is %i6)
+ * 5) The pc and npc the child returns to during a switch
+ */
+
+void copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
+ struct task_struct * p, struct pt_regs * regs)
{
- struct pt_regs * childregs;
+ struct pt_regs *childregs;
+ unsigned char *old_stack;
+ unsigned char *new_stack;
+ int i;
+
+ /* This process has no context yet. */
+ p->tss.context = -1;
+
+ /* Grrr, Sparc stack alignment restrictions make things difficult. */
+ childregs = ((struct pt_regs *)
+ ((p->kernel_stack_page + PAGE_SIZE - 80)&(~7)));
- childregs = ((struct pt_regs *) (p->kernel_stack_page + PAGE_SIZE)) - 1;
- p->tss.usp = (unsigned long) childregs;
*childregs = *regs;
- childregs->sp = sp;
- p->tss.psr = regs->psr; /* for condition codes */
+
+ p->tss.usp = sp; /* both processes have the same user stack */
+ /* See entry.S */
+
+ /* Allocate new processes kernel stack right under pt_regs.
+ * Hopefully this should align things the right way.
+ */
+ p->tss.ksp = (unsigned long) ((p->kernel_stack_page + PAGE_SIZE - 80 - 96)&(~7));
+ new_stack = (unsigned char *) (p->tss.ksp);
+ old_stack = (unsigned char *) (((unsigned long) regs) - 96);
+
+ /* Copy c-stack. */
+ for(i=0; i<96; i++) *new_stack++ = *old_stack++;
+
+ /* These pc values are only used when we switch to the child for
+ * the first time, it jumps the child to ret_sys_call in entry.S
+ * so that the child returns from the sys_call just like parent.
+ */
+ p->tss.pc = (((unsigned long) ret_sys_call) - 8);
+ p->tss.npc = p->tss.pc+4;
+
+ /* Set the return values for both the parent and the child */
+ regs->u_regs[8] = p->pid;
+ childregs->u_regs[8] = 0;
+
return;
}
@@ -96,9 +137,9 @@
return; /* solaris does this enough */
}
-asmlinkage int sys_fork(struct pt_regs regs)
+asmlinkage int sys_fork(struct pt_regs *regs)
{
- return do_fork(COPYVM | SIGCHLD, regs.sp, ®s);
+ return do_fork(COPYVM | SIGCHLD, regs->u_regs[14], regs);
}
/*
@@ -106,6 +147,7 @@
*/
asmlinkage int sys_execve(struct pt_regs regs)
{
+ printk("sys_execve()... halting\n");
halt();
return 0;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this