root/arch/alpha/kernel/process.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sys_sethae
  2. sys_idle
  3. hard_reset_now
  4. show_regs
  5. exit_thread
  6. flush_thread
  7. alpha_fork
  8. copy_thread
  9. dump_thread
  10. sys_execve
  11. sys_clone

   1 /*
   2  *  linux/arch/alpha/kernel/process.c
   3  *
   4  *  Copyright (C) 1995  Linus Torvalds
   5  */
   6 
   7 /*
   8  * This file handles the architecture-dependent parts of process handling..
   9  */
  10 
  11 #include <linux/errno.h>
  12 #include <linux/sched.h>
  13 #include <linux/kernel.h>
  14 #include <linux/mm.h>
  15 #include <linux/stddef.h>
  16 #include <linux/unistd.h>
  17 #include <linux/ptrace.h>
  18 #include <linux/malloc.h>
  19 #include <linux/ldt.h>
  20 #include <linux/user.h>
  21 #include <linux/a.out.h>
  22 #include <linux/utsname.h>
  23 #include <linux/time.h>
  24 #include <linux/major.h>
  25 #include <linux/stat.h>
  26 #include <linux/mman.h>
  27 
  28 #include <asm/segment.h>
  29 #include <asm/system.h>
  30 #include <asm/io.h>
  31 
  32 asmlinkage int sys_sethae(unsigned long hae, unsigned long a1, unsigned long a2,
     /* [previous][next][first][last][top][bottom][index][help] */
  33         unsigned long a3, unsigned long a4, unsigned long a5,
  34         struct pt_regs regs)
  35 {
  36         (&regs)->hae = hae;
  37         return 0;
  38 }
  39 
  40 asmlinkage int sys_idle(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  41 {
  42         if (current->pid != 0)
  43                 return -EPERM;
  44 
  45         /* endless idle loop with no priority at all */
  46         current->counter = -100;
  47         for (;;) {
  48                 schedule();
  49         }
  50 }
  51 
  52 void hard_reset_now(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  53 {
  54         halt();
  55 }
  56 
  57 void show_regs(struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
  58 {
  59         printk("\nps: %04lx pc: %016lx\n", regs->ps, regs->pc);
  60         printk("rp: %016lx sp: %p\n", regs->r26, regs+1);
  61         printk(" r0: %016lx  r1: %016lx  r2: %016lx  r3: %016lx\n",
  62                regs->r0, regs->r1, regs->r2, regs->r3);
  63         printk(" r4: %016lx  r5: %016lx  r6: %016lx  r7: %016lx\n",
  64                regs->r4, regs->r5, regs->r6, regs->r7);
  65         printk(" r8: %016lx r16: %016lx r17: %016lx r18: %016lx\n",
  66                regs->r8, regs->r16, regs->r17, regs->r18);
  67         printk("r19: %016lx r20: %016lx r21: %016lx r22: %016lx\n",
  68                regs->r19, regs->r20, regs->r21, regs->r22);
  69         printk("r23: %016lx r24: %016lx r25: %016lx r26: %016lx\n",
  70                regs->r23, regs->r24, regs->r25, regs->r26);
  71         printk("r27: %016lx r28: %016lx r29: %016lx hae: %016lx\n",
  72                regs->r27, regs->r28, regs->gp, regs->hae);
  73 }
  74 
  75 /*
  76  * Free current thread data structures etc..
  77  */
  78 void exit_thread(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  79 {
  80 }
  81 
  82 void flush_thread(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  83 {
  84 }
  85 
  86 /*
  87  * "alpha_fork()".. By the time we get here, the
  88  * non-volatile registers have also been saved on the
  89  * stack. We do some ugly pointer stuff here.. (see
  90  * also copy_thread)
  91  */
  92 int alpha_fork(struct switch_stack * swstack)
     /* [previous][next][first][last][top][bottom][index][help] */
  93 {
  94         return do_fork(COPYVM | SIGCHLD,
  95                 rdusp(),
  96                 (struct pt_regs *) (swstack+1));
  97 }
  98 
  99 extern void ret_from_sys_call(void);
 100 /*
 101  * Copy an alpha thread..
 102  *
 103  * Note the "stack_offset" stuff: when returning to kernel mode, we need
 104  * to have some extra stack-space for the kernel stack that still exists
 105  * after the "ret_from_sys_call". When returning to user mode, we only
 106  * want the space needed by the syscall stack frame (ie "struct pt_regs").
 107  * Use the passed "regs" pointer to determine how much space we need
 108  * for a kernel fork().
 109  */
 110 void copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
     /* [previous][next][first][last][top][bottom][index][help] */
 111         struct task_struct * p, struct pt_regs * regs)
 112 {
 113         struct pt_regs * childregs;
 114         struct switch_stack * childstack, *stack;
 115         unsigned long stack_offset;
 116 
 117         stack_offset = PAGE_SIZE - sizeof(struct pt_regs);
 118         if (!(regs->ps & 8))
 119                 stack_offset = (PAGE_SIZE-1) & (unsigned long) regs;
 120         childregs = (struct pt_regs *) (p->kernel_stack_page + stack_offset);
 121                 
 122         *childregs = *regs;
 123         childregs->r0 = 0;
 124         childregs->r19 = 0;
 125         childregs->r20 = 1;     /* OSF/1 has some strange fork() semantics.. */
 126         regs->r20 = 0;
 127         stack = ((struct switch_stack *) regs) - 1;
 128         childstack = ((struct switch_stack *) childregs) - 1;
 129         *childstack = *stack;
 130         childstack->r26 = (unsigned long) ret_from_sys_call;
 131         p->tss.usp = usp;
 132         p->tss.ksp = (unsigned long) childstack;
 133         p->tss.flags = 1;
 134 }
 135 
 136 /*
 137  * fill in the user structure for a core dump..
 138  */
 139 void dump_thread(struct pt_regs * regs, struct user * dump)
     /* [previous][next][first][last][top][bottom][index][help] */
 140 {
 141 }
 142 
 143 /*
 144  * sys_execve() executes a new program.
 145  *
 146  * This works due to the alpha calling sequence: the first 6 args
 147  * are gotten from registers, while the rest is on the stack, so
 148  * we get a0-a5 for free, and then magically find "struct pt_regs"
 149  * on the stack for us..
 150  *
 151  * Don't do this at home.
 152  */
 153 asmlinkage int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
     /* [previous][next][first][last][top][bottom][index][help] */
 154         unsigned long a3, unsigned long a4, unsigned long a5,
 155         struct pt_regs regs)
 156 {
 157         int error;
 158         char * filename;
 159 
 160         error = getname((char *) a0, &filename);
 161         if (error)
 162                 return error;
 163         error = do_execve(filename, (char **) a1, (char **) a2, &regs);
 164         putname(filename);
 165         return error;
 166 }
 167 
 168 /*
 169  * This doesn't actually work correctly like this: we need to do the
 170  * same stack setups that fork() does first.
 171  */
 172 asmlinkage int sys_clone(unsigned long a0, unsigned long a1, unsigned long a2,
     /* [previous][next][first][last][top][bottom][index][help] */
 173         unsigned long a3, unsigned long a4, unsigned long a5,
 174         struct pt_regs regs)
 175 {
 176         unsigned long clone_flags = a0;
 177         unsigned long newsp;
 178 
 179         newsp = rdusp();
 180         if (newsp == a1 || !a1)
 181                 clone_flags |= COPYVM;
 182         else
 183                 newsp = a1;     
 184         return do_fork(clone_flags, newsp, &regs);
 185 }

/* [previous][next][first][last][top][bottom][index][help] */