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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/arch/alpha/kernel/process.c
  3.  *
  4.  *  Copyright (C) 1995  Linus Torvalds
  5.  */
  6. /*
  7.  * This file handles the architecture-dependent parts of process handling.
  8.  */
  9. #include <linux/config.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/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. #include <linux/elfcore.h>
  28. #include <linux/reboot.h>
  29. #include <linux/tty.h>
  30. #include <linux/console.h>
  31. #include <asm/reg.h>
  32. #include <asm/uaccess.h>
  33. #include <asm/system.h>
  34. #include <asm/io.h>
  35. #include <asm/pgtable.h>
  36. #include <asm/hwrpb.h>
  37. #include <asm/fpu.h>
  38. #include "proto.h"
  39. #include "pci_impl.h"
  40. /*
  41.  * Initial task structure. Make this a per-architecture thing,
  42.  * because different architectures tend to have different
  43.  * alignment requirements and potentially different initial
  44.  * setup.
  45.  */
  46. unsigned long init_user_stack[1024] = { STACK_MAGIC, };
  47. static struct fs_struct init_fs = INIT_FS;
  48. static struct files_struct init_files = INIT_FILES;
  49. static struct signal_struct init_signals = INIT_SIGNALS;
  50. struct mm_struct init_mm = INIT_MM(init_mm);
  51. union task_union init_task_union __attribute__((section("init_task")))
  52.  = { task: INIT_TASK(init_task_union.task) };
  53. /*
  54.  * No need to acquire the kernel lock, we're entirely local..
  55.  */
  56. asmlinkage int
  57. sys_sethae(unsigned long hae, unsigned long a1, unsigned long a2,
  58.    unsigned long a3, unsigned long a4, unsigned long a5,
  59.    struct pt_regs regs)
  60. {
  61. (&regs)->hae = hae;
  62. return 0;
  63. }
  64. void
  65. cpu_idle(void)
  66. {
  67. /* An endless idle loop with no priority at all.  */
  68. current->nice = 20;
  69. current->counter = -100;
  70. while (1) {
  71. /* FIXME -- EV6 and LCA45 know how to power down
  72.    the CPU.  */
  73. /* Although we are an idle CPU, we do not want to 
  74.    get into the scheduler unnecessarily.  */
  75. long oldval = xchg(&current->need_resched, -1UL);
  76. if (!oldval)
  77. while (current->need_resched < 0);
  78. schedule();
  79. check_pgt_cache();
  80. }
  81. }
  82. struct halt_info {
  83. int mode;
  84. char *restart_cmd;
  85. };
  86. static void
  87. common_shutdown_1(void *generic_ptr)
  88. {
  89. struct halt_info *how = (struct halt_info *)generic_ptr;
  90. struct percpu_struct *cpup;
  91. unsigned long *pflags, flags;
  92. int cpuid = smp_processor_id();
  93. /* No point in taking interrupts anymore. */
  94. __cli();
  95. cpup = (struct percpu_struct *)
  96. ((unsigned long)hwrpb + hwrpb->processor_offset
  97.  + hwrpb->processor_size * cpuid);
  98. pflags = &cpup->flags;
  99. flags = *pflags;
  100. /* Clear reason to "default"; clear "bootstrap in progress". */
  101. flags &= ~0x00ff0001UL;
  102. #ifdef CONFIG_SMP
  103. /* Secondaries halt here. */
  104. if (cpuid != boot_cpuid) {
  105. flags |= 0x00040000UL; /* "remain halted" */
  106. *pflags = flags;
  107. clear_bit(cpuid, &cpu_present_mask);
  108. halt();
  109. }
  110. #endif
  111. if (how->mode == LINUX_REBOOT_CMD_RESTART) {
  112. if (!how->restart_cmd) {
  113. flags |= 0x00020000UL; /* "cold bootstrap" */
  114. } else {
  115. /* For SRM, we could probably set environment
  116.    variables to get this to work.  We'd have to
  117.    delay this until after srm_paging_stop unless
  118.    we ever got srm_fixup working.
  119.    At the moment, SRM will use the last boot device,
  120.    but the file and flags will be the defaults, when
  121.    doing a "warm" bootstrap.  */
  122. flags |= 0x00030000UL; /* "warm bootstrap" */
  123. }
  124. } else {
  125. flags |= 0x00040000UL; /* "remain halted" */
  126. }
  127. *pflags = flags;
  128. #ifdef CONFIG_SMP
  129. /* Wait for the secondaries to halt. */
  130. clear_bit(boot_cpuid, &cpu_present_mask);
  131. while (cpu_present_mask)
  132. barrier();
  133. #endif
  134.         /* If booted from SRM, reset some of the original environment. */
  135. if (alpha_using_srm) {
  136. #ifdef CONFIG_DUMMY_CONSOLE
  137. /* This has the effect of resetting the VGA video origin.  */
  138. take_over_console(&dummy_con, 0, MAX_NR_CONSOLES-1, 1);
  139. #endif
  140. /* reset_for_srm(); */
  141. set_hae(srm_hae);
  142. }
  143. if (alpha_mv.kill_arch)
  144. alpha_mv.kill_arch(how->mode);
  145. if (! alpha_using_srm && how->mode != LINUX_REBOOT_CMD_RESTART) {
  146. /* Unfortunately, since MILO doesn't currently understand
  147.    the hwrpb bits above, we can't reliably halt the 
  148.    processor and keep it halted.  So just loop.  */
  149. return;
  150. }
  151. if (alpha_using_srm)
  152. srm_paging_stop();
  153. halt();
  154. }
  155. static void
  156. common_shutdown(int mode, char *restart_cmd)
  157. {
  158. struct halt_info args;
  159. args.mode = mode;
  160. args.restart_cmd = restart_cmd;
  161. #ifdef CONFIG_SMP
  162. smp_call_function(common_shutdown_1, &args, 1, 0);
  163. #endif
  164. common_shutdown_1(&args);
  165. }
  166. void
  167. machine_restart(char *restart_cmd)
  168. {
  169. common_shutdown(LINUX_REBOOT_CMD_RESTART, restart_cmd);
  170. }
  171. void
  172. machine_halt(void)
  173. {
  174. common_shutdown(LINUX_REBOOT_CMD_HALT, NULL);
  175. }
  176. void
  177. machine_power_off(void)
  178. {
  179. common_shutdown(LINUX_REBOOT_CMD_POWER_OFF, NULL);
  180. }
  181. void
  182. show_regs(struct pt_regs * regs)
  183. {
  184. printk("n");
  185. printk("Pid: %d, comm: %20sn", current->pid, current->comm);
  186. printk("ps: %04lx pc: [<%016lx>] CPU %d    %sn",
  187.        regs->ps, regs->pc, smp_processor_id(), print_tainted());
  188. printk("rp: [<%016lx>] sp: %pn", regs->r26, regs+1);
  189. printk(" r0: %016lx  r1: %016lx  r2: %016lx  r3: %016lxn",
  190.        regs->r0, regs->r1, regs->r2, regs->r3);
  191. printk(" r4: %016lx  r5: %016lx  r6: %016lx  r7: %016lxn",
  192.        regs->r4, regs->r5, regs->r6, regs->r7);
  193. printk(" r8: %016lx r16: %016lx r17: %016lx r18: %016lxn",
  194.        regs->r8, regs->r16, regs->r17, regs->r18);
  195. printk("r19: %016lx r20: %016lx r21: %016lx r22: %016lxn",
  196.        regs->r19, regs->r20, regs->r21, regs->r22);
  197. printk("r23: %016lx r24: %016lx r25: %016lx r26: %016lxn",
  198.        regs->r23, regs->r24, regs->r25, regs->r26);
  199. printk("r27: %016lx r28: %016lx r29: %016lx hae: %016lxn",
  200.        regs->r27, regs->r28, regs->gp, regs->hae);
  201. }
  202. /*
  203.  * Re-start a thread when doing execve()
  204.  */
  205. void
  206. start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
  207. {
  208. set_fs(USER_DS);
  209. regs->pc = pc;
  210. regs->ps = 8;
  211. wrusp(sp);
  212. }
  213. /*
  214.  * Free current thread data structures etc..
  215.  */
  216. void
  217. exit_thread(void)
  218. {
  219. }
  220. void
  221. flush_thread(void)
  222. {
  223. /* Arrange for each exec'ed process to start off with a clean slate
  224.    with respect to the FPU.  This is all exceptions disabled.  */
  225. current->thread.flags &= ~IEEE_SW_MASK;
  226. wrfpcr(FPCR_DYN_NORMAL | ieee_swcr_to_fpcr(0));
  227. }
  228. void
  229. release_thread(struct task_struct *dead_task)
  230. {
  231. }
  232. /*
  233.  * "alpha_clone()".. By the time we get here, the
  234.  * non-volatile registers have also been saved on the
  235.  * stack. We do some ugly pointer stuff here.. (see
  236.  * also copy_thread)
  237.  *
  238.  * Notice that "fork()" is implemented in terms of clone,
  239.  * with parameters (SIGCHLD, 0).
  240.  */
  241. int
  242. alpha_clone(unsigned long clone_flags, unsigned long usp,
  243.     struct switch_stack * swstack)
  244. {
  245. if (!usp)
  246. usp = rdusp();
  247. return do_fork(clone_flags, usp, (struct pt_regs *) (swstack+1), 0);
  248. }
  249. int
  250. alpha_vfork(struct switch_stack * swstack)
  251. {
  252. return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(),
  253. (struct pt_regs *) (swstack+1), 0);
  254. }
  255. /*
  256.  * Copy an alpha thread..
  257.  *
  258.  * Note the "stack_offset" stuff: when returning to kernel mode, we need
  259.  * to have some extra stack-space for the kernel stack that still exists
  260.  * after the "ret_from_sys_call". When returning to user mode, we only
  261.  * want the space needed by the syscall stack frame (ie "struct pt_regs").
  262.  * Use the passed "regs" pointer to determine how much space we need
  263.  * for a kernel fork().
  264.  */
  265. int
  266. copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
  267.     unsigned long unused,
  268.     struct task_struct * p, struct pt_regs * regs)
  269. {
  270. extern void ret_from_sys_call(void);
  271. extern void ret_from_fork(void);
  272. struct pt_regs * childregs;
  273. struct switch_stack * childstack, *stack;
  274. unsigned long stack_offset;
  275. stack_offset = PAGE_SIZE - sizeof(struct pt_regs);
  276. if (!(regs->ps & 8))
  277. stack_offset = (PAGE_SIZE-1) & (unsigned long) regs;
  278. childregs = (struct pt_regs *) (stack_offset + PAGE_SIZE + (long)p);
  279. *childregs = *regs;
  280. childregs->r0 = 0;
  281. childregs->r19 = 0;
  282. childregs->r20 = 1; /* OSF/1 has some strange fork() semantics.  */
  283. regs->r20 = 0;
  284. stack = ((struct switch_stack *) regs) - 1;
  285. childstack = ((struct switch_stack *) childregs) - 1;
  286. *childstack = *stack;
  287. childstack->r26 = (unsigned long) ret_from_fork;
  288. p->thread.usp = usp;
  289. p->thread.ksp = (unsigned long) childstack;
  290. p->thread.pal_flags = 1; /* set FEN, clear everything else */
  291. p->thread.flags = current->thread.flags;
  292. return 0;
  293. }
  294. /*
  295.  * fill in the user structure for a core dump..
  296.  */
  297. void
  298. dump_thread(struct pt_regs * pt, struct user * dump)
  299. {
  300. /* switch stack follows right below pt_regs: */
  301. struct switch_stack * sw = ((struct switch_stack *) pt) - 1;
  302. dump->magic = CMAGIC;
  303. dump->start_code  = current->mm->start_code;
  304. dump->start_data  = current->mm->start_data;
  305. dump->start_stack = rdusp() & ~(PAGE_SIZE - 1);
  306. dump->u_tsize = ((current->mm->end_code - dump->start_code)
  307.  >> PAGE_SHIFT);
  308. dump->u_dsize = ((current->mm->brk + PAGE_SIZE-1 - dump->start_data)
  309.  >> PAGE_SHIFT);
  310. dump->u_ssize = (current->mm->start_stack - dump->start_stack
  311.  + PAGE_SIZE-1) >> PAGE_SHIFT;
  312. /*
  313.  * We store the registers in an order/format that is
  314.  * compatible with DEC Unix/OSF/1 as this makes life easier
  315.  * for gdb.
  316.  */
  317. dump->regs[EF_V0]  = pt->r0;
  318. dump->regs[EF_T0]  = pt->r1;
  319. dump->regs[EF_T1]  = pt->r2;
  320. dump->regs[EF_T2]  = pt->r3;
  321. dump->regs[EF_T3]  = pt->r4;
  322. dump->regs[EF_T4]  = pt->r5;
  323. dump->regs[EF_T5]  = pt->r6;
  324. dump->regs[EF_T6]  = pt->r7;
  325. dump->regs[EF_T7]  = pt->r8;
  326. dump->regs[EF_S0]  = sw->r9;
  327. dump->regs[EF_S1]  = sw->r10;
  328. dump->regs[EF_S2]  = sw->r11;
  329. dump->regs[EF_S3]  = sw->r12;
  330. dump->regs[EF_S4]  = sw->r13;
  331. dump->regs[EF_S5]  = sw->r14;
  332. dump->regs[EF_S6]  = sw->r15;
  333. dump->regs[EF_A3]  = pt->r19;
  334. dump->regs[EF_A4]  = pt->r20;
  335. dump->regs[EF_A5]  = pt->r21;
  336. dump->regs[EF_T8]  = pt->r22;
  337. dump->regs[EF_T9]  = pt->r23;
  338. dump->regs[EF_T10] = pt->r24;
  339. dump->regs[EF_T11] = pt->r25;
  340. dump->regs[EF_RA]  = pt->r26;
  341. dump->regs[EF_T12] = pt->r27;
  342. dump->regs[EF_AT]  = pt->r28;
  343. dump->regs[EF_SP]  = rdusp();
  344. dump->regs[EF_PS]  = pt->ps;
  345. dump->regs[EF_PC]  = pt->pc;
  346. dump->regs[EF_GP]  = pt->gp;
  347. dump->regs[EF_A0]  = pt->r16;
  348. dump->regs[EF_A1]  = pt->r17;
  349. dump->regs[EF_A2]  = pt->r18;
  350. memcpy((char *)dump->regs + EF_SIZE, sw->fp, 32 * 8);
  351. }
  352. int
  353. dump_fpu(struct pt_regs * regs, elf_fpregset_t *r)
  354. {
  355. /* switch stack follows right below pt_regs: */
  356. struct switch_stack * sw = ((struct switch_stack *) regs) - 1;
  357. memcpy(r, sw->fp, 32 * 8);
  358. return 1;
  359. }
  360. /*
  361.  * sys_execve() executes a new program.
  362.  *
  363.  * This works due to the alpha calling sequence: the first 6 args
  364.  * are gotten from registers, while the rest is on the stack, so
  365.  * we get a0-a5 for free, and then magically find "struct pt_regs"
  366.  * on the stack for us..
  367.  *
  368.  * Don't do this at home.
  369.  */
  370. asmlinkage int
  371. sys_execve(char *ufilename, char **argv, char **envp,
  372.    unsigned long a3, unsigned long a4, unsigned long a5,
  373.    struct pt_regs regs)
  374. {
  375. int error;
  376. char *filename;
  377. filename = getname(ufilename);
  378. error = PTR_ERR(filename);
  379. if (IS_ERR(filename))
  380. goto out;
  381. error = do_execve(filename, argv, envp, &regs);
  382. putname(filename);
  383. out:
  384. return error;
  385. }
  386. /*
  387.  * These bracket the sleeping functions..
  388.  */
  389. extern void scheduling_functions_start_here(void);
  390. extern void scheduling_functions_end_here(void);
  391. #define first_sched ((unsigned long) scheduling_functions_start_here)
  392. #define last_sched ((unsigned long) scheduling_functions_end_here)
  393. unsigned long
  394. get_wchan(struct task_struct *p)
  395. {
  396. unsigned long schedule_frame;
  397. unsigned long pc;
  398. if (!p || p == current || p->state == TASK_RUNNING)
  399. return 0;
  400. /*
  401.  * This one depends on the frame size of schedule().  Do a
  402.  * "disass schedule" in gdb to find the frame size.  Also, the
  403.  * code assumes that sleep_on() follows immediately after
  404.  * interruptible_sleep_on() and that add_timer() follows
  405.  * immediately after interruptible_sleep().  Ugly, isn't it?
  406.  * Maybe adding a wchan field to task_struct would be better,
  407.  * after all...
  408.  */
  409. pc = thread_saved_pc(&p->thread);
  410. if (pc >= first_sched && pc < last_sched) {
  411. schedule_frame = ((unsigned long *)p->thread.ksp)[6];
  412. return ((unsigned long *)schedule_frame)[12];
  413. }
  414. return pc;
  415. }