process.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. /*
  2. * OpenRISC process.c
  3. *
  4. * Linux architectural port borrowing liberally from similar works of
  5. * others. All original copyrights apply as per the original source
  6. * declaration.
  7. *
  8. * Modifications for the OpenRISC architecture:
  9. * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
  10. * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
  11. *
  12. * This program is free software; you can redistribute it and/or
  13. * modify it under the terms of the GNU General Public License
  14. * as published by the Free Software Foundation; either version
  15. * 2 of the License, or (at your option) any later version.
  16. *
  17. * This file handles the architecture-dependent parts of process handling...
  18. */
  19. #define __KERNEL_SYSCALLS__
  20. #include <stdarg.h>
  21. #include <linux/errno.h>
  22. #include <linux/sched.h>
  23. #include <linux/sched/debug.h>
  24. #include <linux/sched/task.h>
  25. #include <linux/sched/task_stack.h>
  26. #include <linux/kernel.h>
  27. #include <linux/export.h>
  28. #include <linux/mm.h>
  29. #include <linux/stddef.h>
  30. #include <linux/unistd.h>
  31. #include <linux/ptrace.h>
  32. #include <linux/slab.h>
  33. #include <linux/elfcore.h>
  34. #include <linux/interrupt.h>
  35. #include <linux/delay.h>
  36. #include <linux/init_task.h>
  37. #include <linux/mqueue.h>
  38. #include <linux/fs.h>
  39. #include <linux/uaccess.h>
  40. #include <asm/pgtable.h>
  41. #include <asm/io.h>
  42. #include <asm/processor.h>
  43. #include <asm/spr_defs.h>
  44. #include <linux/smp.h>
  45. /*
  46. * Pointer to Current thread info structure.
  47. *
  48. * Used at user space -> kernel transitions.
  49. */
  50. struct thread_info *current_thread_info_set[NR_CPUS] = { &init_thread_info, };
  51. void machine_restart(void)
  52. {
  53. printk(KERN_INFO "*** MACHINE RESTART ***\n");
  54. __asm__("l.nop 1");
  55. }
  56. /*
  57. * Similar to machine_power_off, but don't shut off power. Add code
  58. * here to freeze the system for e.g. post-mortem debug purpose when
  59. * possible. This halt has nothing to do with the idle halt.
  60. */
  61. void machine_halt(void)
  62. {
  63. printk(KERN_INFO "*** MACHINE HALT ***\n");
  64. __asm__("l.nop 1");
  65. }
  66. /* If or when software power-off is implemented, add code here. */
  67. void machine_power_off(void)
  68. {
  69. printk(KERN_INFO "*** MACHINE POWER OFF ***\n");
  70. __asm__("l.nop 1");
  71. }
  72. /*
  73. * Send the doze signal to the cpu if available.
  74. * Make sure, that all interrupts are enabled
  75. */
  76. void arch_cpu_idle(void)
  77. {
  78. local_irq_enable();
  79. if (mfspr(SPR_UPR) & SPR_UPR_PMP)
  80. mtspr(SPR_PMR, mfspr(SPR_PMR) | SPR_PMR_DME);
  81. }
  82. void (*pm_power_off) (void) = machine_power_off;
  83. EXPORT_SYMBOL(pm_power_off);
  84. /*
  85. * When a process does an "exec", machine state like FPU and debug
  86. * registers need to be reset. This is a hook function for that.
  87. * Currently we don't have any such state to reset, so this is empty.
  88. */
  89. void flush_thread(void)
  90. {
  91. }
  92. void show_regs(struct pt_regs *regs)
  93. {
  94. extern void show_registers(struct pt_regs *regs);
  95. show_regs_print_info(KERN_DEFAULT);
  96. /* __PHX__ cleanup this mess */
  97. show_registers(regs);
  98. }
  99. void release_thread(struct task_struct *dead_task)
  100. {
  101. }
  102. /*
  103. * Copy the thread-specific (arch specific) info from the current
  104. * process to the new one p
  105. */
  106. extern asmlinkage void ret_from_fork(void);
  107. /*
  108. * copy_thread
  109. * @clone_flags: flags
  110. * @usp: user stack pointer or fn for kernel thread
  111. * @arg: arg to fn for kernel thread; always NULL for userspace thread
  112. * @p: the newly created task
  113. * @regs: CPU context to copy for userspace thread; always NULL for kthread
  114. *
  115. * At the top of a newly initialized kernel stack are two stacked pt_reg
  116. * structures. The first (topmost) is the userspace context of the thread.
  117. * The second is the kernelspace context of the thread.
  118. *
  119. * A kernel thread will not be returning to userspace, so the topmost pt_regs
  120. * struct can be uninitialized; it _does_ need to exist, though, because
  121. * a kernel thread can become a userspace thread by doing a kernel_execve, in
  122. * which case the topmost context will be initialized and used for 'returning'
  123. * to userspace.
  124. *
  125. * The second pt_reg struct needs to be initialized to 'return' to
  126. * ret_from_fork. A kernel thread will need to set r20 to the address of
  127. * a function to call into (with arg in r22); userspace threads need to set
  128. * r20 to NULL in which case ret_from_fork will just continue a return to
  129. * userspace.
  130. *
  131. * A kernel thread 'fn' may return; this is effectively what happens when
  132. * kernel_execve is called. In that case, the userspace pt_regs must have
  133. * been initialized (which kernel_execve takes care of, see start_thread
  134. * below); ret_from_fork will then continue its execution causing the
  135. * 'kernel thread' to return to userspace as a userspace thread.
  136. */
  137. int
  138. copy_thread(unsigned long clone_flags, unsigned long usp,
  139. unsigned long arg, struct task_struct *p)
  140. {
  141. struct pt_regs *userregs;
  142. struct pt_regs *kregs;
  143. unsigned long sp = (unsigned long)task_stack_page(p) + THREAD_SIZE;
  144. unsigned long top_of_kernel_stack;
  145. top_of_kernel_stack = sp;
  146. /* Locate userspace context on stack... */
  147. sp -= STACK_FRAME_OVERHEAD; /* redzone */
  148. sp -= sizeof(struct pt_regs);
  149. userregs = (struct pt_regs *) sp;
  150. /* ...and kernel context */
  151. sp -= STACK_FRAME_OVERHEAD; /* redzone */
  152. sp -= sizeof(struct pt_regs);
  153. kregs = (struct pt_regs *)sp;
  154. if (unlikely(p->flags & PF_KTHREAD)) {
  155. memset(kregs, 0, sizeof(struct pt_regs));
  156. kregs->gpr[20] = usp; /* fn, kernel thread */
  157. kregs->gpr[22] = arg;
  158. } else {
  159. *userregs = *current_pt_regs();
  160. if (usp)
  161. userregs->sp = usp;
  162. /*
  163. * For CLONE_SETTLS set "tp" (r10) to the TLS pointer passed to sys_clone.
  164. *
  165. * The kernel entry is:
  166. * int clone (long flags, void *child_stack, int *parent_tid,
  167. * int *child_tid, struct void *tls)
  168. *
  169. * This makes the source r7 in the kernel registers.
  170. */
  171. if (clone_flags & CLONE_SETTLS)
  172. userregs->gpr[10] = userregs->gpr[7];
  173. userregs->gpr[11] = 0; /* Result from fork() */
  174. kregs->gpr[20] = 0; /* Userspace thread */
  175. }
  176. /*
  177. * _switch wants the kernel stack page in pt_regs->sp so that it
  178. * can restore it to thread_info->ksp... see _switch for details.
  179. */
  180. kregs->sp = top_of_kernel_stack;
  181. kregs->gpr[9] = (unsigned long)ret_from_fork;
  182. task_thread_info(p)->ksp = (unsigned long)kregs;
  183. return 0;
  184. }
  185. /*
  186. * Set up a thread for executing a new program
  187. */
  188. void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long sp)
  189. {
  190. unsigned long sr = mfspr(SPR_SR) & ~SPR_SR_SM;
  191. memset(regs, 0, sizeof(struct pt_regs));
  192. regs->pc = pc;
  193. regs->sr = sr;
  194. regs->sp = sp;
  195. }
  196. /* Fill in the fpu structure for a core dump. */
  197. int dump_fpu(struct pt_regs *regs, elf_fpregset_t * fpu)
  198. {
  199. /* TODO */
  200. return 0;
  201. }
  202. extern struct thread_info *_switch(struct thread_info *old_ti,
  203. struct thread_info *new_ti);
  204. extern int lwa_flag;
  205. struct task_struct *__switch_to(struct task_struct *old,
  206. struct task_struct *new)
  207. {
  208. struct task_struct *last;
  209. struct thread_info *new_ti, *old_ti;
  210. unsigned long flags;
  211. local_irq_save(flags);
  212. /* current_set is an array of saved current pointers
  213. * (one for each cpu). we need them at user->kernel transition,
  214. * while we save them at kernel->user transition
  215. */
  216. new_ti = new->stack;
  217. old_ti = old->stack;
  218. lwa_flag = 0;
  219. current_thread_info_set[smp_processor_id()] = new_ti;
  220. last = (_switch(old_ti, new_ti))->task;
  221. local_irq_restore(flags);
  222. return last;
  223. }
  224. /*
  225. * Write out registers in core dump format, as defined by the
  226. * struct user_regs_struct
  227. */
  228. void dump_elf_thread(elf_greg_t *dest, struct pt_regs* regs)
  229. {
  230. dest[0] = 0; /* r0 */
  231. memcpy(dest+1, regs->gpr+1, 31*sizeof(unsigned long));
  232. dest[32] = regs->pc;
  233. dest[33] = regs->sr;
  234. dest[34] = 0;
  235. dest[35] = 0;
  236. }
  237. unsigned long get_wchan(struct task_struct *p)
  238. {
  239. /* TODO */
  240. return 0;
  241. }