process.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:7k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/arch/parisc/kernel/process.c
  3.  * based on the work for i386
  4.  */
  5. /*
  6.  * This file handles the architecture-dependent parts of process handling..
  7.  */
  8. #define __KERNEL_SYSCALLS__
  9. #include <stdarg.h>
  10. #include <linux/errno.h>
  11. #include <linux/sched.h>
  12. #include <linux/kernel.h>
  13. #include <linux/mm.h>
  14. #include <linux/smp.h>
  15. #include <linux/smp_lock.h>
  16. #include <linux/stddef.h>
  17. #include <linux/unistd.h>
  18. #include <linux/ptrace.h>
  19. #include <linux/slab.h>
  20. #include <linux/vmalloc.h>
  21. #include <linux/interrupt.h>
  22. #include <linux/reboot.h>
  23. #include <linux/init.h>
  24. #include <linux/version.h>
  25. #include <linux/elf.h>
  26. #include <linux/personality.h>
  27. #include <asm/machdep.h>
  28. #include <asm/offset.h>
  29. #include <asm/uaccess.h>
  30. #include <asm/pgtable.h>
  31. #include <asm/system.h>
  32. #include <asm/io.h>
  33. #include <asm/gsc.h>
  34. #include <asm/processor.h>
  35. int hlt_counter;
  36. /*
  37.  * Power off function, if any
  38.  */ 
  39. void (*pm_power_off)(void);
  40. void disable_hlt(void)
  41. {
  42. hlt_counter++;
  43. }
  44. void enable_hlt(void)
  45. {
  46. hlt_counter--;
  47. }
  48. /*
  49.  * The idle thread. There's no useful work to be
  50.  * done, so just try to conserve power and have a
  51.  * low exit latency (ie sit in a loop waiting for
  52.  * somebody to say that they'd like to reschedule)
  53.  */
  54. void cpu_idle(void)
  55. {
  56. /* endless idle loop with no priority at all */
  57. init_idle();
  58. current->nice = 20;
  59. current->counter = -100;
  60. while (1) {
  61. while (!current->need_resched) {
  62. }
  63. schedule();
  64. check_pgt_cache();
  65. }
  66. }
  67. #ifdef __LP64__
  68. #define COMMAND_GLOBAL  0xfffffffffffe0030UL
  69. #else
  70. #define COMMAND_GLOBAL  0xfffe0030
  71. #endif
  72. #define CMD_RESET       5       /* reset any module */
  73. /*
  74. ** The Wright Brothers and Gecko systems have a H/W problem
  75. ** (Lasi...'nuf said) may cause a broadcast reset to lockup
  76. ** the system. An HVERSION dependent PDC call was developed
  77. ** to perform a "safe", platform specific broadcast reset instead
  78. ** of kludging up all the code.
  79. **
  80. ** Older machines which do not implement PDC_BROADCAST_RESET will
  81. ** return (with an error) and the regular broadcast reset can be
  82. ** issued. Obviously, if the PDC does implement PDC_BROADCAST_RESET
  83. ** the PDC call will not return (the system will be reset).
  84. */
  85. void machine_restart(char *cmd)
  86. {
  87. #ifdef FASTBOOT_SELFTEST_SUPPORT
  88. /*
  89.  ** If user has modified the Firmware Selftest Bitmap,
  90.  ** run the tests specified in the bitmap after the
  91.  ** system is rebooted w/PDC_DO_RESET.
  92.  **
  93.  ** ftc_bitmap = 0x1AUL "Skip destructive memory tests"
  94.  **
  95.  ** Using "directed resets" at each processor with the MEM_TOC
  96.  ** vector cleared will also avoid running destructive
  97.  ** memory self tests. (Not implemented yet)
  98.  */
  99. if (ftc_bitmap) {
  100. pdc_do_firm_test_reset(ftc_bitmap);
  101. }
  102. #endif
  103. /* "Normal" system reset */
  104. pdc_do_reset();
  105. /* Nope...box should reset with just CMD_RESET now */
  106. gsc_writel(CMD_RESET, COMMAND_GLOBAL);
  107. /* Wait for RESET to lay us to rest. */
  108. while (1) ;
  109. }
  110. void machine_halt(void)
  111. {
  112. /*
  113. ** The LED/ChassisCodes are updated by the led_halt()
  114. ** function, called by the reboot notifier chain.
  115. */
  116. }
  117. /*
  118.  * This routine is called from sys_reboot to actually turn off the
  119.  * machine 
  120.  */
  121. void machine_power_off(void)
  122. {
  123. /* If there is a registered power off handler, call it. */
  124. if(pm_power_off)
  125. pm_power_off();
  126. /* Put the soft power button back under hardware control.
  127.  * If the user had already pressed the power button, the
  128.  * following call will immediately power off. */
  129. pdc_soft_power_button(0);
  130. /* It seems we have no way to power the system off via
  131.  * software. The user has to press the button himself. */
  132. printk(KERN_EMERG "System shut down completed.n"
  133.        KERN_EMERG "Please power this system off now.");
  134. }
  135. /*
  136.  * Create a kernel thread
  137.  */
  138. extern pid_t __kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
  139. pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
  140. {
  141. /*
  142.  * FIXME: Once we are sure we don't need any debug here,
  143.  *   kernel_thread can become a #define.
  144.  */
  145. return __kernel_thread(fn, arg, flags);
  146. }
  147. /*
  148.  * Free current thread data structures etc..
  149.  */
  150. void exit_thread(void)
  151. {
  152. }
  153. void flush_thread(void)
  154. {
  155. /* Only needs to handle fpu stuff or perf monitors.
  156. ** REVISIT: several arches implement a "lazy fpu state".
  157. */
  158. set_fs(USER_DS);
  159. }
  160. void release_thread(struct task_struct *dead_task)
  161. {
  162. }
  163. /*
  164.  * Fill in the FPU structure for a core dump.
  165.  */
  166. int dump_fpu (struct pt_regs * regs, elf_fpregset_t *r)
  167. {
  168. memcpy(r, regs->fr, sizeof *r);
  169. return 1;
  170. }
  171. /* Note that "fork()" is implemented in terms of clone, with
  172.    parameters (SIGCHLD, regs->gr[30], regs). */
  173. int
  174. sys_clone(unsigned long clone_flags, unsigned long usp,
  175.   struct pt_regs *regs)
  176. {
  177. return do_fork(clone_flags, usp, regs, 0);
  178. }
  179. int
  180. sys_vfork(struct pt_regs *regs)
  181. {
  182. return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD,
  183.        regs->gr[30], regs, 0);
  184. }
  185. int
  186. copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
  187.     unsigned long unused, /* in ia64 this is "user_stack_size" */
  188.     struct task_struct * p, struct pt_regs * pregs)
  189. {
  190. struct pt_regs * cregs = &(p->thread.regs);
  191. /* We have to use void * instead of a function pointer, because
  192.  * function pointers aren't a pointer to the function on 64-bit.
  193.  * Make them const so the compiler knows they live in .text */
  194. extern void * const ret_from_kernel_thread;
  195. extern void * const child_return;
  196. extern void * const hpux_child_return;
  197. *cregs = *pregs;
  198. /* Set the return value for the child.  Note that this is not
  199.            actually restored by the syscall exit path, but we put it
  200.            here for consistency in case of signals. */
  201. cregs->gr[28] = 0; /* child */
  202. /*
  203.  * We need to differentiate between a user fork and a
  204.  * kernel fork. We can't use user_mode, because the
  205.  * the syscall path doesn't save iaoq. Right now
  206.  * We rely on the fact that kernel_thread passes
  207.  * in zero for usp.
  208.  */
  209. if (usp == 0) {
  210. /* kernel thread */
  211. cregs->ksp = (((unsigned long)(p)) + TASK_SZ_ALGN);
  212. /* Must exit via ret_from_kernel_thread in order
  213.  * to call schedule_tail()
  214.  */
  215. cregs->kpc = (unsigned long) &ret_from_kernel_thread;
  216. /*
  217.  * Copy function and argument to be called from
  218.  * ret_from_kernel_thread.
  219.  */
  220. #ifdef __LP64__
  221. cregs->gr[27] = pregs->gr[27];
  222. #endif
  223. cregs->gr[26] = pregs->gr[26];
  224. cregs->gr[25] = pregs->gr[25];
  225. } else {
  226. /* user thread */
  227. /*
  228.  * Note that the fork wrappers are responsible
  229.  * for setting gr[21].
  230.  */
  231. /* Use same stack depth as parent */
  232. cregs->ksp = ((unsigned long)(p))
  233. + (pregs->gr[21] & (INIT_TASK_SIZE - 1));
  234. cregs->gr[30] = usp;
  235. if (p->personality == PER_HPUX) {
  236. cregs->kpc = (unsigned long) &hpux_child_return;
  237. } else {
  238. cregs->kpc = (unsigned long) &child_return;
  239. }
  240. }
  241. return 0;
  242. }
  243. /*
  244.  * sys_execve() executes a new program.
  245.  */
  246. asmlinkage int sys_execve(struct pt_regs *regs)
  247. {
  248. int error;
  249. char *filename;
  250. filename = getname((char *) regs->gr[26]);
  251. error = PTR_ERR(filename);
  252. if (IS_ERR(filename))
  253. goto out;
  254. error = do_execve(filename, (char **) regs->gr[25],
  255. (char **) regs->gr[24], regs);
  256. if (error == 0)
  257. current->ptrace &= ~PT_DTRACE;
  258. putname(filename);
  259. out:
  260. return error;
  261. }