syscall.h 3.0 KB

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