syscall.h 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #ifndef __ASM_SPARC_SYSCALL_H
  2. #define __ASM_SPARC_SYSCALL_H
  3. #include <linux/kernel.h>
  4. #include <linux/sched.h>
  5. #include <asm/ptrace.h>
  6. /* The system call number is given by the user in %g1 */
  7. static inline long syscall_get_nr(struct task_struct *task,
  8. struct pt_regs *regs)
  9. {
  10. int syscall_p = pt_regs_is_syscall(regs);
  11. return (syscall_p ? regs->u_regs[UREG_G1] : -1L);
  12. }
  13. static inline void syscall_rollback(struct task_struct *task,
  14. struct pt_regs *regs)
  15. {
  16. /* XXX This needs some thought. On Sparc we don't
  17. * XXX save away the original %o0 value somewhere.
  18. * XXX Instead we hold it in register %l5 at the top
  19. * XXX level trap frame and pass this down to the signal
  20. * XXX dispatch code which is the only place that value
  21. * XXX ever was needed.
  22. */
  23. }
  24. #ifdef CONFIG_SPARC32
  25. static inline bool syscall_has_error(struct pt_regs *regs)
  26. {
  27. return (regs->psr & PSR_C) ? true : false;
  28. }
  29. static inline void syscall_set_error(struct pt_regs *regs)
  30. {
  31. regs->psr |= PSR_C;
  32. }
  33. static inline void syscall_clear_error(struct pt_regs *regs)
  34. {
  35. regs->psr &= ~PSR_C;
  36. }
  37. #else
  38. static inline bool syscall_has_error(struct pt_regs *regs)
  39. {
  40. return (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY)) ? true : false;
  41. }
  42. static inline void syscall_set_error(struct pt_regs *regs)
  43. {
  44. regs->tstate |= (TSTATE_XCARRY | TSTATE_ICARRY);
  45. }
  46. static inline void syscall_clear_error(struct pt_regs *regs)
  47. {
  48. regs->tstate &= ~(TSTATE_XCARRY | TSTATE_ICARRY);
  49. }
  50. #endif
  51. static inline long syscall_get_error(struct task_struct *task,
  52. struct pt_regs *regs)
  53. {
  54. long val = regs->u_regs[UREG_I0];
  55. return (syscall_has_error(regs) ? -val : 0);
  56. }
  57. static inline long syscall_get_return_value(struct task_struct *task,
  58. struct pt_regs *regs)
  59. {
  60. long val = regs->u_regs[UREG_I0];
  61. return val;
  62. }
  63. static inline void syscall_set_return_value(struct task_struct *task,
  64. struct pt_regs *regs,
  65. int error, long val)
  66. {
  67. if (error) {
  68. syscall_set_error(regs);
  69. regs->u_regs[UREG_I0] = -error;
  70. } else {
  71. syscall_clear_error(regs);
  72. regs->u_regs[UREG_I0] = val;
  73. }
  74. }
  75. static inline void syscall_get_arguments(struct task_struct *task,
  76. struct pt_regs *regs,
  77. unsigned int i, unsigned int n,
  78. unsigned long *args)
  79. {
  80. int zero_extend = 0;
  81. unsigned int j;
  82. #ifdef CONFIG_SPARC64
  83. if (test_tsk_thread_flag(task, TIF_32BIT))
  84. zero_extend = 1;
  85. #endif
  86. for (j = 0; j < n; j++) {
  87. unsigned long val = regs->u_regs[UREG_I0 + i + j];
  88. if (zero_extend)
  89. args[j] = (u32) val;
  90. else
  91. args[j] = val;
  92. }
  93. }
  94. static inline void syscall_set_arguments(struct task_struct *task,
  95. struct pt_regs *regs,
  96. unsigned int i, unsigned int n,
  97. const unsigned long *args)
  98. {
  99. unsigned int j;
  100. for (j = 0; j < n; j++)
  101. regs->u_regs[UREG_I0 + i + j] = args[j];
  102. }
  103. #endif /* __ASM_SPARC_SYSCALL_H */