switch_to.h 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. /*
  2. * Copyright IBM Corp. 1999, 2009
  3. *
  4. * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
  5. */
  6. #ifndef __ASM_SWITCH_TO_H
  7. #define __ASM_SWITCH_TO_H
  8. #include <linux/thread_info.h>
  9. #include <asm/fpu/api.h>
  10. #include <asm/ptrace.h>
  11. extern struct task_struct *__switch_to(void *, void *);
  12. extern void update_cr_regs(struct task_struct *task);
  13. static inline void save_access_regs(unsigned int *acrs)
  14. {
  15. typedef struct { int _[NUM_ACRS]; } acrstype;
  16. asm volatile("stam 0,15,%0" : "=Q" (*(acrstype *)acrs));
  17. }
  18. static inline void restore_access_regs(unsigned int *acrs)
  19. {
  20. typedef struct { int _[NUM_ACRS]; } acrstype;
  21. asm volatile("lam 0,15,%0" : : "Q" (*(acrstype *)acrs));
  22. }
  23. #define switch_to(prev,next,last) do { \
  24. /* save_fpu_regs() sets the CIF_FPU flag, which enforces \
  25. * a restore of the floating point / vector registers as \
  26. * soon as the next task returns to user space \
  27. */ \
  28. save_fpu_regs(); \
  29. save_access_regs(&prev->thread.acrs[0]); \
  30. save_ri_cb(prev->thread.ri_cb); \
  31. update_cr_regs(next); \
  32. restore_access_regs(&next->thread.acrs[0]); \
  33. restore_ri_cb(next->thread.ri_cb, prev->thread.ri_cb); \
  34. prev = __switch_to(prev,next); \
  35. } while (0)
  36. #endif /* __ASM_SWITCH_TO_H */