home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.2 / LINUX-1.2 / LINUX-1 / linux / arch / alpha / kernel / process.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-24  |  4.3 KB  |  189 lines

  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)
  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)
  40. {
  41.     halt();
  42. }
  43.  
  44. void show_regs(struct pt_regs * regs)
  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)
  54. {
  55. }
  56.  
  57. void flush_thread(void)
  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)
  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,
  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)
  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,
  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, ®s);
  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,
  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, ®s);
  188. }
  189.