switch_to.h 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. /*
  2. * Copyright (C) 2012 Regents of the University of California
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation, version 2.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. */
  13. #ifndef _ASM_RISCV_SWITCH_TO_H
  14. #define _ASM_RISCV_SWITCH_TO_H
  15. #include <asm/processor.h>
  16. #include <asm/ptrace.h>
  17. #include <asm/csr.h>
  18. extern void __fstate_save(struct task_struct *save_to);
  19. extern void __fstate_restore(struct task_struct *restore_from);
  20. static inline void __fstate_clean(struct pt_regs *regs)
  21. {
  22. regs->sstatus = (regs->sstatus & ~SR_FS) | SR_FS_CLEAN;
  23. }
  24. static inline void fstate_save(struct task_struct *task,
  25. struct pt_regs *regs)
  26. {
  27. if ((regs->sstatus & SR_FS) == SR_FS_DIRTY) {
  28. __fstate_save(task);
  29. __fstate_clean(regs);
  30. }
  31. }
  32. static inline void fstate_restore(struct task_struct *task,
  33. struct pt_regs *regs)
  34. {
  35. if ((regs->sstatus & SR_FS) != SR_FS_OFF) {
  36. __fstate_restore(task);
  37. __fstate_clean(regs);
  38. }
  39. }
  40. static inline void __switch_to_aux(struct task_struct *prev,
  41. struct task_struct *next)
  42. {
  43. struct pt_regs *regs;
  44. regs = task_pt_regs(prev);
  45. if (unlikely(regs->sstatus & SR_SD))
  46. fstate_save(prev, regs);
  47. fstate_restore(next, task_pt_regs(next));
  48. }
  49. extern struct task_struct *__switch_to(struct task_struct *,
  50. struct task_struct *);
  51. #define switch_to(prev, next, last) \
  52. do { \
  53. struct task_struct *__prev = (prev); \
  54. struct task_struct *__next = (next); \
  55. __switch_to_aux(__prev, __next); \
  56. ((last) = __switch_to(__prev, __next)); \
  57. } while (0)
  58. #endif /* _ASM_RISCV_SWITCH_TO_H */