process.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * linux/arch/h8300/kernel/process.c
  4. *
  5. * Yoshinori Sato <ysato@users.sourceforge.jp>
  6. *
  7. * Based on:
  8. *
  9. * linux/arch/m68knommu/kernel/process.c
  10. *
  11. * Copyright (C) 1998 D. Jeff Dionne <jeff@ryeham.ee.ryerson.ca>,
  12. * Kenneth Albanowski <kjahds@kjahds.com>,
  13. * The Silver Hammer Group, Ltd.
  14. *
  15. * linux/arch/m68k/kernel/process.c
  16. *
  17. * Copyright (C) 1995 Hamish Macdonald
  18. *
  19. * 68060 fixes by Jesper Skov
  20. */
  21. /*
  22. * This file handles the architecture-dependent parts of process handling..
  23. */
  24. #include <linux/errno.h>
  25. #include <linux/module.h>
  26. #include <linux/sched.h>
  27. #include <linux/sched/debug.h>
  28. #include <linux/sched/task.h>
  29. #include <linux/sched/task_stack.h>
  30. #include <linux/kernel.h>
  31. #include <linux/mm.h>
  32. #include <linux/smp.h>
  33. #include <linux/stddef.h>
  34. #include <linux/unistd.h>
  35. #include <linux/ptrace.h>
  36. #include <linux/user.h>
  37. #include <linux/interrupt.h>
  38. #include <linux/reboot.h>
  39. #include <linux/fs.h>
  40. #include <linux/slab.h>
  41. #include <linux/rcupdate.h>
  42. #include <linux/uaccess.h>
  43. #include <asm/traps.h>
  44. #include <asm/setup.h>
  45. #include <asm/pgtable.h>
  46. void (*pm_power_off)(void) = NULL;
  47. EXPORT_SYMBOL(pm_power_off);
  48. asmlinkage void ret_from_fork(void);
  49. asmlinkage void ret_from_kernel_thread(void);
  50. /*
  51. * The idle loop on an H8/300..
  52. */
  53. void arch_cpu_idle(void)
  54. {
  55. local_irq_enable();
  56. __asm__("sleep");
  57. }
  58. void machine_restart(char *__unused)
  59. {
  60. local_irq_disable();
  61. __asm__("jmp @@0");
  62. }
  63. void machine_halt(void)
  64. {
  65. local_irq_disable();
  66. __asm__("sleep");
  67. for (;;)
  68. ;
  69. }
  70. void machine_power_off(void)
  71. {
  72. local_irq_disable();
  73. __asm__("sleep");
  74. for (;;)
  75. ;
  76. }
  77. void show_regs(struct pt_regs *regs)
  78. {
  79. show_regs_print_info(KERN_DEFAULT);
  80. pr_notice("\n");
  81. pr_notice("PC: %08lx Status: %02x\n",
  82. regs->pc, regs->ccr);
  83. pr_notice("ORIG_ER0: %08lx ER0: %08lx ER1: %08lx\n",
  84. regs->orig_er0, regs->er0, regs->er1);
  85. pr_notice("ER2: %08lx ER3: %08lx ER4: %08lx ER5: %08lx\n",
  86. regs->er2, regs->er3, regs->er4, regs->er5);
  87. pr_notice("ER6' %08lx ", regs->er6);
  88. if (user_mode(regs))
  89. printk("USP: %08lx\n", rdusp());
  90. else
  91. printk("\n");
  92. }
  93. void flush_thread(void)
  94. {
  95. }
  96. int copy_thread(unsigned long clone_flags,
  97. unsigned long usp, unsigned long topstk,
  98. struct task_struct *p)
  99. {
  100. struct pt_regs *childregs;
  101. childregs = (struct pt_regs *) (THREAD_SIZE + task_stack_page(p)) - 1;
  102. if (unlikely(p->flags & PF_KTHREAD)) {
  103. memset(childregs, 0, sizeof(struct pt_regs));
  104. childregs->retpc = (unsigned long) ret_from_kernel_thread;
  105. childregs->er4 = topstk; /* arg */
  106. childregs->er5 = usp; /* fn */
  107. } else {
  108. *childregs = *current_pt_regs();
  109. childregs->er0 = 0;
  110. childregs->retpc = (unsigned long) ret_from_fork;
  111. p->thread.usp = usp ?: rdusp();
  112. }
  113. p->thread.ksp = (unsigned long)childregs;
  114. return 0;
  115. }
  116. unsigned long get_wchan(struct task_struct *p)
  117. {
  118. unsigned long fp, pc;
  119. unsigned long stack_page;
  120. int count = 0;
  121. if (!p || p == current || p->state == TASK_RUNNING)
  122. return 0;
  123. stack_page = (unsigned long)p;
  124. fp = ((struct pt_regs *)p->thread.ksp)->er6;
  125. do {
  126. if (fp < stack_page+sizeof(struct thread_info) ||
  127. fp >= 8184+stack_page)
  128. return 0;
  129. pc = ((unsigned long *)fp)[1];
  130. if (!in_sched_functions(pc))
  131. return pc;
  132. fp = *(unsigned long *) fp;
  133. } while (count++ < 16);
  134. return 0;
  135. }
  136. /* generic sys_clone is not enough registers */
  137. asmlinkage int sys_clone(unsigned long __user *args)
  138. {
  139. unsigned long clone_flags;
  140. unsigned long newsp;
  141. uintptr_t parent_tidptr;
  142. uintptr_t child_tidptr;
  143. get_user(clone_flags, &args[0]);
  144. get_user(newsp, &args[1]);
  145. get_user(parent_tidptr, &args[2]);
  146. get_user(child_tidptr, &args[3]);
  147. return do_fork(clone_flags, newsp, 0,
  148. (int __user *)parent_tidptr, (int __user *)child_tidptr);
  149. }