root/arch/alpha/kernel/process.c

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

DEFINITIONS

This source file includes following definitions.
  1. sys_idle
  2. hard_reset_now
  3. show_regs
  4. exit_thread
  5. flush_thread
  6. alpha_fork
  7. copy_thread
  8. dump_thread
  9. sys_execve
  10. 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 
  23 #include <asm/segment.h>
  24 #include <asm/system.h>
  25 #include <asm/io.h>
  26 
  27 asmlinkage int sys_idle(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  28 {
  29         if (current->pid != 0)
  30                 return -EPERM;
  31 
  32         /* endless idle loop with no priority at all */
  33         current->counter = -100;
  34         for (;;) {
  35                 schedule();
  36         }
  37 }
  38 
  39 void hard_reset_now(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  40 {
  41         halt();
  42 }
  43 
  44 void show_regs(struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
  45 {
  46         printk("\nps: %04lx pc: %016lx\n", regs->ps, regs->pc);
  47         printk("rp: %04lx sp: %p\n", regs->r26, regs+1);
  48 }
  49 
  50 /*
  51  * Free current thread data structures etc..
  52  */
  53 void exit_thread(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  54 {
  55 }
  56 
  57 void flush_thread(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  58 {
  59 }
  60 
  61 struct alpha_switch_stack {
  62         unsigned long r9;
  63         unsigned long r10;
  64         unsigned long r11;
  65         unsigned long r12;
  66         unsigned long r13;
  67         unsigned long r14;
  68         unsigned long r15;
  69         unsigned long r26;
  70 };
  71 
  72 /*
  73  * "alpha_switch_to()".. Done completely in assembly, due to the
  74  * fact that we obviously don't returns to the caller directly.
  75  * Also, we have to save the regs that the C compiler expects to be
  76  * saved across a function call.. (9-15)
  77  *
  78  * NOTE! The stack switches from under us when we do the swpctx call:
  79  * this *looks* like it restores the same registers that it just saved,
  80  * but it actually restores the new context regs and return address.
  81  */
  82 __asm__(".align 3\n\t"
  83         ".globl alpha_switch_to\n\t"
  84         ".ent alpha_switch_to\n"
  85         "alpha_switch_to:\n\t"
  86         "subq $30,64,$30\n\t"
  87         "stq  $9,0($30)\n\t"
  88         "stq $10,8($30)\n\t"
  89         "stq $11,16($30)\n\t"
  90         "stq $12,24($30)\n\t"
  91         "stq $13,32($30)\n\t"
  92         "stq $14,40($30)\n\t"
  93         "stq $15,48($30)\n\t"
  94         "stq $26,56($30)\n\t"
  95         "call_pal 48\n\t"
  96         "ldq  $9,0($30)\n\t"
  97         "ldq $10,8($30)\n\t"
  98         "ldq $11,16($30)\n\t"
  99         "ldq $12,24($30)\n\t"
 100         "ldq $13,32($30)\n\t"
 101         "ldq $14,40($30)\n\t"
 102         "ldq $15,48($30)\n\t"
 103         "ldq $26,56($30)\n\t"
 104         "addq $30,64,$30\n\t"
 105         "ret $31,($26),1\n\t"
 106         ".end alpha_switch_to");
 107 
 108 /*
 109  * "alpha_fork()".. By the time we get here, the
 110  * non-volatile registers have also been saved on the
 111  * stack. We do some ugly pointer stuff here.. (see
 112  * also copy_thread)
 113  */
 114 int alpha_fork(struct alpha_switch_stack * swstack)
     /* [previous][next][first][last][top][bottom][index][help] */
 115 {
 116         return do_fork(COPYVM | SIGCHLD, 0, (struct pt_regs *) (swstack+1));
 117 }
 118 
 119 /*
 120  * Copy an alpha thread..
 121  */
 122 void copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
     /* [previous][next][first][last][top][bottom][index][help] */
 123         struct task_struct * p, struct pt_regs * regs)
 124 {
 125         struct pt_regs * childregs;
 126         struct alpha_switch_stack * childstack, *stack;
 127 
 128         childregs = ((struct pt_regs *) (p->kernel_stack_page + PAGE_SIZE)) - 1;
 129         *childregs = *regs;
 130         childregs->r0 = 0;
 131         regs->r0 = p->pid;
 132         stack = ((struct alpha_switch_stack *) regs) - 1;
 133         childstack = ((struct alpha_switch_stack *) childregs) - 1;
 134         *childstack = *stack;
 135         p->tss.usp = usp;
 136         p->tss.ksp = (unsigned long) childstack;
 137 }
 138 
 139 /*
 140  * fill in the user structure for a core dump..
 141  */
 142 void dump_thread(struct pt_regs * regs, struct user * dump)
     /* [previous][next][first][last][top][bottom][index][help] */
 143 {
 144 }
 145 
 146 /*
 147  * sys_execve() executes a new program.
 148  *
 149  * This works due to the alpha calling sequence: the first 6 args
 150  * are gotten from registers, while the rest is on the stack, so
 151  * we get a0-a5 for free, and then magically find "struct pt_regs"
 152  * on the stack for us..
 153  *
 154  * Don't do this at home.
 155  */
 156 asmlinkage int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
     /* [previous][next][first][last][top][bottom][index][help] */
 157         unsigned long a3, unsigned long a4, unsigned long a5,
 158         struct pt_regs regs)
 159 {
 160         int error;
 161         char * filename;
 162 
 163         error = getname((char *) a0, &filename);
 164         if (error)
 165                 return error;
 166         error = do_execve(filename, (char **) a1, (char **) a2, &regs);
 167         putname(filename);
 168         return error;
 169 }
 170 
 171 /*
 172  * This doesn't actually work correctly like this: we need to do the
 173  * same stack setups that fork() does first.
 174  */
 175 asmlinkage int sys_clone(unsigned long a0, unsigned long a1, unsigned long a2,
     /* [previous][next][first][last][top][bottom][index][help] */
 176         unsigned long a3, unsigned long a4, unsigned long a5,
 177         struct pt_regs regs)
 178 {
 179         unsigned long clone_flags = a0;
 180         unsigned long newsp;
 181 
 182         newsp = rdusp();
 183         if (newsp == a1 || !a1)
 184                 clone_flags |= COPYVM;
 185         else
 186                 newsp = a1;     
 187         return do_fork(clone_flags, newsp, &regs);
 188 }

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