process.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /*
  2. * linux/arch/h8300/kernel/process.c
  3. *
  4. * Yoshinori Sato <ysato@users.sourceforge.jp>
  5. *
  6. * Based on:
  7. *
  8. * linux/arch/m68knommu/kernel/process.c
  9. *
  10. * Copyright (C) 1998 D. Jeff Dionne <jeff@ryeham.ee.ryerson.ca>,
  11. * Kenneth Albanowski <kjahds@kjahds.com>,
  12. * The Silver Hammer Group, Ltd.
  13. *
  14. * linux/arch/m68k/kernel/process.c
  15. *
  16. * Copyright (C) 1995 Hamish Macdonald
  17. *
  18. * 68060 fixes by Jesper Skov
  19. */
  20. /*
  21. * This file handles the architecture-dependent parts of process handling..
  22. */
  23. #include <linux/errno.h>
  24. #include <linux/module.h>
  25. #include <linux/sched.h>
  26. #include <linux/kernel.h>
  27. #include <linux/mm.h>
  28. #include <linux/smp.h>
  29. #include <linux/stddef.h>
  30. #include <linux/unistd.h>
  31. #include <linux/ptrace.h>
  32. #include <linux/user.h>
  33. #include <linux/interrupt.h>
  34. #include <linux/reboot.h>
  35. #include <linux/fs.h>
  36. #include <linux/slab.h>
  37. #include <linux/rcupdate.h>
  38. #include <asm/uaccess.h>
  39. #include <asm/traps.h>
  40. #include <asm/setup.h>
  41. #include <asm/pgtable.h>
  42. void (*pm_power_off)(void) = NULL;
  43. EXPORT_SYMBOL(pm_power_off);
  44. asmlinkage void ret_from_fork(void);
  45. asmlinkage void ret_from_kernel_thread(void);
  46. /*
  47. * The idle loop on an H8/300..
  48. */
  49. #if !defined(CONFIG_H8300H_SIM) && !defined(CONFIG_H8S_SIM)
  50. static void default_idle(void)
  51. {
  52. local_irq_disable();
  53. if (!need_resched()) {
  54. local_irq_enable();
  55. /* XXX: race here! What if need_resched() gets set now? */
  56. __asm__("sleep");
  57. } else
  58. local_irq_enable();
  59. }
  60. #else
  61. static void default_idle(void)
  62. {
  63. cpu_relax();
  64. }
  65. #endif
  66. void (*idle)(void) = default_idle;
  67. /*
  68. * The idle thread. There's no useful work to be
  69. * done, so just try to conserve power and have a
  70. * low exit latency (ie sit in a loop waiting for
  71. * somebody to say that they'd like to reschedule)
  72. */
  73. void cpu_idle(void)
  74. {
  75. while (1) {
  76. rcu_idle_enter();
  77. while (!need_resched())
  78. idle();
  79. rcu_idle_exit();
  80. schedule_preempt_disabled();
  81. }
  82. }
  83. void machine_restart(char * __unused)
  84. {
  85. local_irq_disable();
  86. __asm__("jmp @@0");
  87. }
  88. void machine_halt(void)
  89. {
  90. local_irq_disable();
  91. __asm__("sleep");
  92. for (;;);
  93. }
  94. void machine_power_off(void)
  95. {
  96. local_irq_disable();
  97. __asm__("sleep");
  98. for (;;);
  99. }
  100. void show_regs(struct pt_regs * regs)
  101. {
  102. printk("\nPC: %08lx Status: %02x",
  103. regs->pc, regs->ccr);
  104. printk("\nORIG_ER0: %08lx ER0: %08lx ER1: %08lx",
  105. regs->orig_er0, regs->er0, regs->er1);
  106. printk("\nER2: %08lx ER3: %08lx ER4: %08lx ER5: %08lx",
  107. regs->er2, regs->er3, regs->er4, regs->er5);
  108. printk("\nER6' %08lx ",regs->er6);
  109. if (user_mode(regs))
  110. printk("USP: %08lx\n", rdusp());
  111. else
  112. printk("\n");
  113. }
  114. void flush_thread(void)
  115. {
  116. }
  117. int copy_thread(unsigned long clone_flags,
  118. unsigned long usp, unsigned long topstk,
  119. struct task_struct * p)
  120. {
  121. struct pt_regs * childregs;
  122. childregs = (struct pt_regs *) (THREAD_SIZE + task_stack_page(p)) - 1;
  123. if (unlikely(p->flags & PF_KTHREAD)) {
  124. memset(childregs, 0, sizeof(struct pt_regs));
  125. childregs->retpc = (unsigned long) ret_from_kernel_thread;
  126. childregs->er4 = topstk; /* arg */
  127. childregs->er5 = usp; /* fn */
  128. p->thread.ksp = (unsigned long)childregs;
  129. }
  130. *childregs = *current_pt_regs();
  131. childregs->retpc = (unsigned long) ret_from_fork;
  132. childregs->er0 = 0;
  133. p->thread.usp = usp ?: rdusp();
  134. p->thread.ksp = (unsigned long)childregs;
  135. return 0;
  136. }
  137. unsigned long thread_saved_pc(struct task_struct *tsk)
  138. {
  139. return ((struct pt_regs *)tsk->thread.esp0)->pc;
  140. }
  141. unsigned long get_wchan(struct task_struct *p)
  142. {
  143. unsigned long fp, pc;
  144. unsigned long stack_page;
  145. int count = 0;
  146. if (!p || p == current || p->state == TASK_RUNNING)
  147. return 0;
  148. stack_page = (unsigned long)p;
  149. fp = ((struct pt_regs *)p->thread.ksp)->er6;
  150. do {
  151. if (fp < stack_page+sizeof(struct thread_info) ||
  152. fp >= 8184+stack_page)
  153. return 0;
  154. pc = ((unsigned long *)fp)[1];
  155. if (!in_sched_functions(pc))
  156. return pc;
  157. fp = *(unsigned long *) fp;
  158. } while (count++ < 16);
  159. return 0;
  160. }