root/arch/ppc/kernel/process.c

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

DEFINITIONS

This source file includes following definitions.
  1. dump_fpu
  2. switch_to
  3. sys_idle
  4. hard_reset_now
  5. show_regs
  6. exit_thread
  7. flush_thread
  8. copy_thread
  9. dump_thread
  10. start_thread
  11. sys_newselect
  12. sys_fork
  13. sys_execve
  14. sys_clone
  15. print_backtrace

   1 /* * Last edited: Dec 14 17:32 1995 (cort) */
   2 /*
   3  *  linux/arch/ppc/kernel/process.c
   4  *
   5  *  Copyright (C) 1995  Linus Torvalds
   6  *  Adapted for PowerPC by Gary Thomas
   7  *  Modified by Cort Dougan
   8  */
   9 
  10 /*
  11  * This file handles the architecture-dependent parts of process handling..
  12  */
  13 
  14 #include <linux/errno.h>
  15 #include <linux/sched.h>
  16 #include <linux/kernel.h>
  17 #include <linux/mm.h>
  18 #include <linux/stddef.h>
  19 #include <linux/unistd.h>
  20 #include <linux/ptrace.h>
  21 #include <linux/malloc.h>
  22 #include <linux/ldt.h>
  23 #include <linux/user.h>
  24 #include <linux/a.out.h>
  25 
  26 #include <asm/pgtable.h>
  27 #include <asm/segment.h>
  28 #include <asm/system.h>
  29 #include <asm/io.h>
  30 
  31 #include <asm/ppc_machine.h>
  32 
  33 int dump_fpu (struct user_i387_struct* fpu)
     /* [previous][next][first][last][top][bottom][index][help] */
  34 {
  35   return 1;             /* all ppc's have a fpu */
  36 }
  37 
  38 void
  39 switch_to(struct task_struct *new)
     /* [previous][next][first][last][top][bottom][index][help] */
  40 {
  41         struct pt_regs *regs;
  42         struct thread_struct *new_tss, *old_tss;
  43         int s;
  44         regs = (struct pt_regs *)new->tss.ksp;
  45 /*
  46 printk("Task %x(%d) -> %x(%d)", current, current->pid, new, new->pid);
  47 printk(" - IP: %x, SR: %x, SP: %x\n", regs->nip, regs->msr, regs);
  48 */
  49         s = _disable_interrupts();
  50         new_tss = &new->tss;
  51         old_tss = &current->tss;
  52         current = new;
  53         _switch(old_tss, new_tss);
  54 
  55 /*      printk("Back in task %x(%d)\n", current, current->pid);*/
  56 
  57         _enable_interrupts(s);
  58 }
  59 
  60 asmlinkage int sys_idle(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  61 {
  62 
  63         if (current->pid != 0)
  64                 return -EPERM;
  65 /*panic("process.c: sys_idle()\n");*/
  66         /* endless idle loop with no priority at all */
  67         current->counter = -100;
  68         for (;;) {
  69 
  70                 schedule();
  71         }
  72 }
  73 
  74 void hard_reset_now(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  75 {
  76         halt();
  77 }
  78 
  79 void show_regs(struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
  80 {
  81         _panic("show_regs");
  82 }
  83 
  84 /*
  85  * Free current thread data structures etc..
  86  */
  87 void exit_thread(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  88 {
  89 }
  90 
  91 void flush_thread(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  92 {
  93 }
  94 
  95 /*
  96  * Copy a thread..
  97  */
  98 void copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
     /* [previous][next][first][last][top][bottom][index][help] */
  99         struct task_struct * p, struct pt_regs * regs)
 100 {
 101         int i;
 102         SEGREG *segs;
 103         struct pt_regs * childregs;
 104 
 105 /*printk("copy thread - NR: %d, Flags: %x, USP: %x, Task: %x, Regs: %x\n", nr, clone_flags, usp, p, regs);*/
 106 
 107         /* Construct segment registers */
 108         segs = (SEGREG *)p->tss.segs;
 109         for (i = 0;  i < 8;  i++)
 110         {
 111                 segs[i].ks = 0;
 112                 segs[i].kp = 1;
 113                 segs[i].vsid = i | (nr << 4);
 114         }
 115         /* Last 8 are shared with kernel & everybody else... */
 116         for (i = 8;  i < 16;  i++)
 117         {
 118                 segs[i].ks = 0;
 119                 segs[i].kp = 1;
 120                 segs[i].vsid = i;
 121         }
 122         /* Copy registers */
 123         childregs = ((struct pt_regs *) (p->kernel_stack_page + 2*PAGE_SIZE)) - 2;
 124         *childregs = *regs;     /* STRUCT COPY */
 125         childregs->gpr[3] = 0;  /* Result from fork() */
 126         p->tss.ksp = (unsigned long)childregs;
 127         if (usp >= (unsigned long)regs)
 128         { /* Stack is in kernel space - must adjust */
 129                 childregs->gpr[1] = (long)(childregs+1);
 130         } else
 131         { /* Provided stack is in user space */
 132                 childregs->gpr[1] = usp;
 133         }
 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 #if 0 /* mfisk */
 144 /*
 145  * Do necessary setup to start up a newly executed thread.
 146  */
 147 void start_thread(struct pt_regs * regs, unsigned long eip, unsigned long esp)
     /* [previous][next][first][last][top][bottom][index][help] */
 148 {
 149   regs->nip = eip;
 150   regs->gpr[1] = esp;
 151   regs->msr = MSR_USER;
 152 #if 0
 153 /*  printk("current = %x current->mm = %x\n", current, current->mm);
 154   printk("task[0] = %x task[0]->mm = %x\n", task[0],task[0]->mm);*/
 155   printk("Start thread [%x] at PC: %x, SR: %x, SP: %x\n",
 156     regs, eip, regs->msr, esp);
 157 /*  dump_buf(esp, 64);*/
 158 /*  dump_buf(eip, 64);*/
 159 #endif
 160 }
 161 #endif
 162 
 163 asmlinkage int sys_newselect(int p1, int p2, int p3, int p4, int p5, int p6, struct pt_regs *regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 164 {
 165   panic("sys_newselect unimplemented");
 166 }
 167 
 168 asmlinkage int sys_fork(int p1, int p2, int p3, int p4, int p5, int p6, struct pt_regs *regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 169 {
 170   int i;
 171   char *a;
 172 #if 0
 173   for ( i = 0 ; i <= 0x400 ; i++)
 174   {
 175     printk("going to do kmalloc(%d)\n",i);
 176     a = kmalloc(i,GFP_KERNEL);
 177     a = kmalloc(i,GFP_KERNEL);
 178     printk("a = %x\n",a);
 179   }
 180 #endif
 181   return do_fork( SIGCHLD, regs->gpr[1], regs);
 182 }
 183 
 184 asmlinkage int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
     /* [previous][next][first][last][top][bottom][index][help] */
 185         unsigned long a3, unsigned long a4, unsigned long a5,
 186         struct pt_regs *regs)
 187 {
 188         int error;
 189         char * filename;
 190 
 191 #if 1
 192         /* paranoia check.  I really don't trust head.S  -- Cort */
 193         if ( regs->marker != 0xDEADDEAD )
 194         {
 195           panic("process.c: sys_execve(): regs->marker != DEADDEAD\n");
 196         }
 197 #endif
 198         error = getname((char *) a0, &filename);
 199         if (error)
 200           return error;
 201         error = do_execve(filename, (char **) a1, (char **) a2, regs);
 202 
 203         putname(filename);
 204         return error;
 205 }
 206 
 207 
 208 asmlinkage int sys_clone(unsigned long clone_flags, unsigned long usp, unsigned long a2,
     /* [previous][next][first][last][top][bottom][index][help] */
 209         unsigned long a3, unsigned long a4, unsigned long a5,
 210         struct pt_regs *regs)
 211 {
 212   int i;
 213   
 214   if (!usp)
 215     usp = regs->gpr[1];
 216   
 217 
 218   /* I hard coded in all the arguments to clone since clone() is inlined
 219      and has trouble with its args  with our gcc -- Cort*/
 220   return do_fork(/*clone_flags*/CLONE_VM, /*usp*/ regs->gpr[1], regs);
 221 }
 222 
 223 
 224 
 225 void
 226 print_backtrace(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 227 {
 228         unsigned long *sp = (unsigned long *)_get_SP();
 229         int cnt = 0;
 230         printk("... Call backtrace:\n");
 231         while (*sp)
 232         {
 233                 printk("%08X ", sp[2]);
 234                 sp = (unsigned long *)*sp;
 235                 if (++cnt == 8)
 236                 {
 237                         printk("\n");
 238                 }
 239                 if (cnt > 16) break;
 240         }
 241         printk("\n");
 242 }
 243 

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