syscalls.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. #ifndef _BITS_SYSCALLS_H
  2. #define _BITS_SYSCALLS_H
  3. #ifndef _SYSCALL_H
  4. # error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
  5. #endif
  6. #ifndef __ASSEMBLER__
  7. /* Define a macro which expands inline into the wrapper code for a system
  8. call. This use is for internal calls that do not need to handle errors
  9. normally. It will never touch errno.
  10. On powerpc a system call basically clobbers the same registers like a
  11. function call, with the exception of LR (which is needed for the
  12. "sc; bnslr+" sequence) and CR (where only CR0.SO is clobbered to signal
  13. an error return status). */
  14. #include <errno.h>
  15. #define SYS_ify(syscall_name) (__NR_##syscall_name)
  16. # undef INLINE_SYSCALL
  17. #if 1
  18. # define INLINE_SYSCALL(name, nr, args...) \
  19. ({ \
  20. INTERNAL_SYSCALL_DECL (sc_err); \
  21. long int sc_ret = INTERNAL_SYSCALL (name, sc_err, nr, args); \
  22. if (INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err)) \
  23. { \
  24. __set_errno (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err)); \
  25. sc_ret = -1L; \
  26. } \
  27. sc_ret; \
  28. })
  29. #else
  30. # define INLINE_SYSCALL(name, nr, args...) \
  31. ({ \
  32. INTERNAL_SYSCALL_DECL (sc_err); \
  33. long int sc_ret = INTERNAL_SYSCALL (name, sc_err, nr, args); \
  34. if (INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err)) \
  35. { \
  36. sc_ret = __syscall_error(INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err));\
  37. } \
  38. sc_ret; \
  39. })
  40. #endif
  41. /* Define a macro which expands inline into the wrapper code for a system
  42. call. This use is for internal calls that do not need to handle errors
  43. normally. It will never touch errno.
  44. On powerpc a system call basically clobbers the same registers like a
  45. function call, with the exception of LR (which is needed for the
  46. "sc; bnslr+" sequence) and CR (where only CR0.SO is clobbered to signal
  47. an error return status). */
  48. # undef INTERNAL_SYSCALL_DECL
  49. # define INTERNAL_SYSCALL_DECL(err) long int err
  50. # undef INTERNAL_SYSCALL
  51. # define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
  52. ({ \
  53. register long int r0 __asm__ ("r0"); \
  54. register long int r3 __asm__ ("r3"); \
  55. register long int r4 __asm__ ("r4"); \
  56. register long int r5 __asm__ ("r5"); \
  57. register long int r6 __asm__ ("r6"); \
  58. register long int r7 __asm__ ("r7"); \
  59. register long int r8 __asm__ ("r8"); \
  60. register long int r9 __asm__ ("r9"); \
  61. register long int r10 __asm__ ("r10"); \
  62. register long int r11 __asm__ ("r11"); \
  63. register long int r12 __asm__ ("r12"); \
  64. LOADARGS_##nr(name, args); \
  65. __asm__ __volatile__ \
  66. ("sc \n\t" \
  67. "mfcr %0" \
  68. : "=&r" (r0), \
  69. "=&r" (r3), "=&r" (r4), "=&r" (r5), "=&r" (r6), "=&r" (r7), \
  70. "=&r" (r8), "=&r" (r9), "=&r" (r10), "=&r" (r11), "=&r" (r12) \
  71. : ASM_INPUT_##nr \
  72. : "cr0", "ctr", "memory"); \
  73. err = r0; \
  74. (int) r3; \
  75. })
  76. # define INTERNAL_SYSCALL(name, err, nr, args...) \
  77. INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, ##args)
  78. # undef INTERNAL_SYSCALL_ERROR_P
  79. # define INTERNAL_SYSCALL_ERROR_P(val, err) \
  80. ((void) (val), __builtin_expect ((err) & (1 << 28), 0))
  81. # undef INTERNAL_SYSCALL_ERRNO
  82. # define INTERNAL_SYSCALL_ERRNO(val, err) (val)
  83. # define LOADARGS_0(name, dummy) \
  84. r0 = (long int)name
  85. # define LOADARGS_1(name, __arg1) \
  86. LOADARGS_0(name, 0); \
  87. r3 = (long int)__arg1
  88. # define LOADARGS_2(name, __arg1, __arg2) \
  89. LOADARGS_1(name, __arg1); \
  90. r4 = (long int)__arg2
  91. # define LOADARGS_3(name, __arg1, __arg2, __arg3) \
  92. LOADARGS_2(name, __arg1, __arg2); \
  93. r5 = (long int)__arg3
  94. # define LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4) \
  95. LOADARGS_3(name, __arg1, __arg2, __arg3); \
  96. r6 = (long int)__arg4
  97. # define LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5) \
  98. LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4); \
  99. r7 = (long int)__arg5
  100. # define LOADARGS_6(name, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6) \
  101. LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5); \
  102. r8 = (long int)__arg6
  103. # define ASM_INPUT_0 "0" (r0)
  104. # define ASM_INPUT_1 ASM_INPUT_0, "1" (r3)
  105. # define ASM_INPUT_2 ASM_INPUT_1, "2" (r4)
  106. # define ASM_INPUT_3 ASM_INPUT_2, "3" (r5)
  107. # define ASM_INPUT_4 ASM_INPUT_3, "4" (r6)
  108. # define ASM_INPUT_5 ASM_INPUT_4, "5" (r7)
  109. # define ASM_INPUT_6 ASM_INPUT_5, "6" (r8)
  110. #undef _syscall0
  111. #define _syscall0(type,name) \
  112. type name(void){ \
  113. return (type) INLINE_SYSCALL(name, 0); \
  114. }
  115. #undef _syscall1
  116. #define _syscall1(type,name,type1,arg1) \
  117. type name(type1 arg1){ \
  118. return (type) INLINE_SYSCALL(name, 1, arg1); \
  119. }
  120. #undef _syscall2
  121. #define _syscall2(type,name,type1,arg1,type2,arg2) \
  122. type name(type1 arg1, type2 arg2){ \
  123. return (type) INLINE_SYSCALL(name, 2, arg1, arg2); \
  124. }
  125. #undef _syscall3
  126. #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
  127. type name(type1 arg1, type2 arg2, type3 arg3){ \
  128. return (type) INLINE_SYSCALL(name, 3, arg1, arg2, arg3); \
  129. }
  130. #undef _syscall4
  131. #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
  132. type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4){ \
  133. return (type) INLINE_SYSCALL(name, 4, arg1, arg2, arg3, arg4); \
  134. }
  135. #undef _syscall5
  136. #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
  137. type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5){ \
  138. return (type) INLINE_SYSCALL(name, 5, arg1, arg2, arg3, arg4, arg5); \
  139. }
  140. #undef _syscall6
  141. #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \
  142. type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6){ \
  143. return (type) INLINE_SYSCALL(name, 6, arg1, arg2, arg3, arg4, arg5, arg6); \
  144. }
  145. #endif /* __ASSEMBLER__ */
  146. #endif /* _BITS_SYSCALLS_H */