dsemul.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /* SPDX-License-Identifier: GPL-2.0-or-later */
  2. /*
  3. * Copyright (C) 2016 Imagination Technologies
  4. * Author: Paul Burton <[email protected]>
  5. */
  6. #ifndef __MIPS_ASM_DSEMUL_H__
  7. #define __MIPS_ASM_DSEMUL_H__
  8. #include <asm/break.h>
  9. #include <asm/inst.h>
  10. /* Break instruction with special math emu break code set */
  11. #define BREAK_MATH(micromips) (((micromips) ? 0x7 : 0xd) | (BRK_MEMU << 16))
  12. /* When used as a frame index, indicates the lack of a frame */
  13. #define BD_EMUFRAME_NONE ((int)BIT(31))
  14. struct mm_struct;
  15. struct pt_regs;
  16. struct task_struct;
  17. /**
  18. * mips_dsemul() - 'Emulate' an instruction from a branch delay slot
  19. * @regs: User thread register context.
  20. * @ir: The instruction to be 'emulated'.
  21. * @branch_pc: The PC of the branch instruction.
  22. * @cont_pc: The PC to continue at following 'emulation'.
  23. *
  24. * Emulate or execute an arbitrary MIPS instruction within the context of
  25. * the current user thread. This is used primarily to handle instructions
  26. * in the delay slots of emulated branch instructions, for example FP
  27. * branch instructions on systems without an FPU.
  28. *
  29. * Return: Zero on success, negative if ir is a NOP, signal number on failure.
  30. */
  31. extern int mips_dsemul(struct pt_regs *regs, mips_instruction ir,
  32. unsigned long branch_pc, unsigned long cont_pc);
  33. /**
  34. * do_dsemulret() - Return from a delay slot 'emulation' frame
  35. * @xcp: User thread register context.
  36. *
  37. * Call in response to the BRK_MEMU break instruction used to return to
  38. * the kernel from branch delay slot 'emulation' frames following a call
  39. * to mips_dsemul(). Restores the user thread PC to the value that was
  40. * passed as the cpc parameter to mips_dsemul().
  41. *
  42. * Return: True if an emulation frame was returned from, else false.
  43. */
  44. #ifdef CONFIG_MIPS_FP_SUPPORT
  45. extern bool do_dsemulret(struct pt_regs *xcp);
  46. #else
  47. static inline bool do_dsemulret(struct pt_regs *xcp)
  48. {
  49. return false;
  50. }
  51. #endif
  52. /**
  53. * dsemul_thread_cleanup() - Cleanup thread 'emulation' frame
  54. * @tsk: The task structure associated with the thread
  55. *
  56. * If the thread @tsk has a branch delay slot 'emulation' frame
  57. * allocated to it then free that frame.
  58. *
  59. * Return: True if a frame was freed, else false.
  60. */
  61. #ifdef CONFIG_MIPS_FP_SUPPORT
  62. extern bool dsemul_thread_cleanup(struct task_struct *tsk);
  63. #else
  64. static inline bool dsemul_thread_cleanup(struct task_struct *tsk)
  65. {
  66. return false;
  67. }
  68. #endif
  69. /**
  70. * dsemul_thread_rollback() - Rollback from an 'emulation' frame
  71. * @regs: User thread register context.
  72. *
  73. * If the current thread, whose register context is represented by @regs,
  74. * is executing within a delay slot 'emulation' frame then exit that
  75. * frame. The PC will be rolled back to the branch if the instruction
  76. * that was being 'emulated' has not yet executed, or advanced to the
  77. * continuation PC if it has.
  78. *
  79. * Return: True if a frame was exited, else false.
  80. */
  81. #ifdef CONFIG_MIPS_FP_SUPPORT
  82. extern bool dsemul_thread_rollback(struct pt_regs *regs);
  83. #else
  84. static inline bool dsemul_thread_rollback(struct pt_regs *regs)
  85. {
  86. return false;
  87. }
  88. #endif
  89. /**
  90. * dsemul_mm_cleanup() - Cleanup per-mm delay slot 'emulation' state
  91. * @mm: The struct mm_struct to cleanup state for.
  92. *
  93. * Cleanup state for the given @mm, ensuring that any memory allocated
  94. * for delay slot 'emulation' book-keeping is freed. This is to be called
  95. * before @mm is freed in order to avoid memory leaks.
  96. */
  97. #ifdef CONFIG_MIPS_FP_SUPPORT
  98. extern void dsemul_mm_cleanup(struct mm_struct *mm);
  99. #else
  100. static inline void dsemul_mm_cleanup(struct mm_struct *mm)
  101. {
  102. /* no-op */
  103. }
  104. #endif
  105. #endif /* __MIPS_ASM_DSEMUL_H__ */