syscalls.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. /*
  2. * Copyright (C) 2016 Andes Technology, Inc.
  3. * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  4. */
  5. /*
  6. * For nds32 ISA, the syscall number(SWID) shall be determined at compile time.
  7. * (ex: asm("syscall SWID"); )
  8. * If the value of syscall number is determined at run time, we shall issue
  9. * this syscall through sys_syscall.
  10. * (ex:
  11. * asm("move $r0, SYSCALL_number"
  12. * "syscall 0x5071");
  13. * where 0x5071 is syscall number for sys_syscall
  14. * )
  15. *
  16. * The following two macros are implemented according that syscall number
  17. * is determined in compiler time or run time,
  18. *
  19. * 1. INTERNAL_SYSCALL_NCS: the syscall number is determined at run time
  20. * 2. INTERNAL_SYSCALL: the syscall number is determined at compile time
  21. *
  22. */
  23. #ifndef _BITS_SYSCALLS_H
  24. #define _BITS_SYSCALLS_H
  25. #ifndef _SYSCALL_H
  26. # error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
  27. #endif
  28. #ifndef __ASSEMBLER__
  29. #include <errno.h>
  30. #include <common/sysdep.h>
  31. #define X(x) #x
  32. #define Y(x) X(x)
  33. #define LIB_SYSCALL __NR_syscall
  34. #define __issue_syscall(syscall_name) \
  35. " syscall " Y(syscall_name) "; \n"
  36. #undef INTERNAL_SYSCALL_ERROR_P
  37. #define INTERNAL_SYSCALL_ERROR_P(val, err) ((unsigned int) (val) >= 0xfffff001u)
  38. #undef INTERNAL_SYSCALL_ERRNO
  39. #define INTERNAL_SYSCALL_ERRNO(val, err) (-(val))
  40. #undef INLINE_SYSCALL
  41. #define INLINE_SYSCALL(name, nr, args...) \
  42. ({ \
  43. INTERNAL_SYSCALL_DECL (err); \
  44. long result_var = INTERNAL_SYSCALL (name, err, nr, args); \
  45. if (INTERNAL_SYSCALL_ERROR_P (result_var, err)) \
  46. { \
  47. __set_errno (INTERNAL_SYSCALL_ERRNO (result_var, err)); \
  48. result_var = -1 ; \
  49. } \
  50. result_var; \
  51. })
  52. #undef INTERNAL_SYSCALL_DECL
  53. #define INTERNAL_SYSCALL_DECL(err) do { } while (0)
  54. #undef INTERNAL_SYSCALL
  55. #define INTERNAL_SYSCALL(name, err, nr, args...) internal_syscall##nr(__NR_##name, err, args)
  56. /*
  57. The _NCS variant allows non-constant syscall numbers but it is not
  58. possible to use more than four parameters.
  59. */
  60. #undef INTERNAL_SYSCALL_NCS
  61. #define INTERNAL_SYSCALL_NCS(name, err, nr, args...) internal_syscall_ncs##nr(name, err, args)
  62. #define internal_syscall0(name, err, dummy...) \
  63. ({ \
  64. register long ___res __asm__("$r0"); \
  65. __asm__ volatile ( \
  66. __issue_syscall (name) \
  67. : "=r" (___res) /* output operands */ \
  68. : \
  69. : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
  70. ___res; \
  71. })
  72. #define internal_syscall1(name, err, arg1) \
  73. ({ \
  74. register long ___res __asm__("$r0"); \
  75. register long __arg1 __asm__("$r0") = (long) (arg1); \
  76. __asm__ volatile ( \
  77. __issue_syscall (name) \
  78. : "=r" (___res) /* output operands */ \
  79. : "r" (__arg1) /* input operands */ \
  80. : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
  81. ___res; \
  82. })
  83. #define internal_syscall2(name, err, arg1, arg2) \
  84. ({ \
  85. register long ___res __asm__("$r0"); \
  86. register long __arg1 __asm__("$r0") = (long) (arg1); \
  87. register long __arg2 __asm__("$r1") = (long) (arg2); \
  88. __asm__ volatile ( \
  89. __issue_syscall (name) \
  90. : "=r" (___res) /* output operands */ \
  91. : "r" (__arg1) /* input operands */ \
  92. , "r" (__arg2) /* input operands */ \
  93. : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
  94. ___res; \
  95. })
  96. #define internal_syscall3(name, err, arg1, arg2, arg3) \
  97. ({ \
  98. register long ___res __asm__("$r0"); \
  99. register long __arg1 __asm__("$r0") = (long) (arg1); \
  100. register long __arg2 __asm__("$r1") = (long) (arg2); \
  101. register long __arg3 __asm__("$r2") = (long) (arg3); \
  102. __asm__ volatile ( \
  103. __issue_syscall (name) \
  104. : "=r" (___res) /* output operands */ \
  105. : "r" (__arg1) /* input operands */ \
  106. , "r" (__arg2) /* input operands */ \
  107. , "r" (__arg3) /* input operands */ \
  108. : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
  109. ___res; \
  110. })
  111. #define internal_syscall4(name, err, arg1, arg2, arg3, arg4) \
  112. ({ \
  113. register long ___res __asm__("$r0"); \
  114. register long __arg1 __asm__("$r0") = (long) (arg1); \
  115. register long __arg2 __asm__("$r1") = (long) (arg2); \
  116. register long __arg3 __asm__("$r2") = (long) (arg3); \
  117. register long __arg4 __asm__("$r3") = (long) (arg4); \
  118. __asm__ volatile ( \
  119. __issue_syscall (name) \
  120. : "=r" (___res) /* output operands */ \
  121. : "r" (__arg1) /* input operands */ \
  122. , "r" (__arg2) /* input operands */ \
  123. , "r" (__arg3) /* input operands */ \
  124. , "r" (__arg4) /* input operands */ \
  125. : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
  126. ___res; \
  127. })
  128. #define internal_syscall5(name, err, arg1, arg2, arg3, arg4, arg5) \
  129. ({ \
  130. register long ___res __asm__("$r0"); \
  131. register long __arg1 __asm__("$r0") = (long) (arg1); \
  132. register long __arg2 __asm__("$r1") = (long) (arg2); \
  133. register long __arg3 __asm__("$r2") = (long) (arg3); \
  134. register long __arg4 __asm__("$r3") = (long) (arg4); \
  135. register long __arg5 __asm__("$r4") = (long) (arg5); \
  136. __asm__ volatile ( \
  137. __issue_syscall (name) \
  138. : "=r" (___res) /* output operands */ \
  139. : "r" (__arg1) /* input operands */ \
  140. , "r" (__arg2) /* input operands */ \
  141. , "r" (__arg3) /* input operands */ \
  142. , "r" (__arg4) /* input operands */ \
  143. , "r" (__arg5) /* input operands */ \
  144. : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
  145. ___res; \
  146. })
  147. #define internal_syscall6(name, err, arg1, arg2, arg3, arg4, arg5, arg6) \
  148. ({ \
  149. register long ___res __asm__("$r0"); \
  150. register long __arg1 __asm__("$r0") = (long) (arg1); \
  151. register long __arg2 __asm__("$r1") = (long) (arg2); \
  152. register long __arg3 __asm__("$r2") = (long) (arg3); \
  153. register long __arg4 __asm__("$r3") = (long) (arg4); \
  154. register long __arg5 __asm__("$r4") = (long) (arg5); \
  155. register long __arg6 __asm__("$r5") = (long) (arg6); \
  156. __asm__ volatile ( \
  157. __issue_syscall (name) \
  158. : "=r" (___res) /* output operands */ \
  159. : "r" (__arg1) /* input operands */ \
  160. , "r" (__arg2) /* input operands */ \
  161. , "r" (__arg3) /* input operands */ \
  162. , "r" (__arg4) /* input operands */ \
  163. , "r" (__arg5) /* input operands */ \
  164. , "r" (__arg6) /* input operands */ \
  165. : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
  166. ___res; \
  167. })
  168. #define internal_syscall7(name, err, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
  169. ({ \
  170. register long ___res __asm__("$r0"); \
  171. register long __arg1 __asm__("$r0") = (long) (arg1); \
  172. register long __arg2 __asm__("$r1") = (long) (arg2); \
  173. register long __arg3 __asm__("$r2") = (long) (arg3); \
  174. register long __arg4 __asm__("$r3") = (long) (arg4); \
  175. register long __arg5 __asm__("$r4") = (long) (arg5); \
  176. register long __arg6 __asm__("$r5") = (long) (arg6); \
  177. __asm__ volatile ( \
  178. "addi10.sp\t #-4\n\t" \
  179. CFI_ADJUST_CFA_OFFSET(4)"\n\t" \
  180. "push\t %7\n\t" \
  181. CFI_ADJUST_CFA_OFFSET(4)"\n\t" \
  182. __issue_syscall (name) \
  183. "addi10.sp\t #4\n\t" \
  184. CFI_ADJUST_CFA_OFFSET(-4)"\n\t" \
  185. "pop\t %7\n\t" \
  186. CFI_ADJUST_CFA_OFFSET(-4)"\n\t" \
  187. : "=r" (___res) /* output operands */ \
  188. : "r" (__arg1) /* input operands */ \
  189. , "r" (__arg2) /* input operands */ \
  190. , "r" (__arg3) /* input operands */ \
  191. , "r" (__arg4) /* input operands */ \
  192. , "r" (__arg5) /* input operands */ \
  193. , "r" (__arg6) /* input operands */ \
  194. , "r" (arg7) /* input operands */ \
  195. : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
  196. ___res; \
  197. })
  198. #define internal_syscall_ncs0(name, err, dummy...) \
  199. ({ \
  200. register long __res __asm__("$r0"); \
  201. register long __no __asm__("$r0") = (long) (name); \
  202. __asm__ volatile ( \
  203. __issue_syscall (LIB_SYSCALL) \
  204. : "=r" (__res) /* output operands */ \
  205. : "r" (__no) /* input operands */ \
  206. : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
  207. __res; \
  208. })
  209. #define internal_syscall_ncs1(name, err, arg1) \
  210. ({ \
  211. register long __res __asm__("$r0"); \
  212. register long __no __asm__("$r0") = (long) (name); \
  213. register long __arg1 __asm__("$r1") = (long) (arg1); \
  214. __asm__ volatile ( \
  215. __issue_syscall (LIB_SYSCALL) \
  216. : "=r" (__res) /* output operands */ \
  217. : "r" (__arg1) /* input operands */ \
  218. , "r" (__no) /* input operands */ \
  219. : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
  220. __res; \
  221. })
  222. #define internal_syscall_ncs2(name, err, arg1, arg2) \
  223. ({ \
  224. register long __res __asm__("$r0"); \
  225. register long __no __asm__("$r0") = (long) (name); \
  226. register long __arg1 __asm__("$r1") = (long) (arg1); \
  227. register long __arg2 __asm__("$r2") = (long) (arg2); \
  228. __asm__ volatile ( \
  229. __issue_syscall (LIB_SYSCALL) \
  230. : "=r" (__res) /* output operands */ \
  231. : "r" (__arg1) /* input operands */ \
  232. , "r" (__arg2) /* input operands */ \
  233. , "r" (__no) /* input operands */ \
  234. : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
  235. __res; \
  236. })
  237. #define internal_syscall_ncs3(name, err, arg1, arg2, arg3) \
  238. ({ \
  239. register long __res __asm__("$r0"); \
  240. register long __no __asm__("$r0") = (long) (name); \
  241. register long __arg1 __asm__("$r1") = (long) (arg1); \
  242. register long __arg2 __asm__("$r2") = (long) (arg2); \
  243. register long __arg3 __asm__("$r3") = (long) (arg3); \
  244. __asm__ volatile ( \
  245. __issue_syscall (LIB_SYSCALL) \
  246. : "=r" (__res) /* output operands */ \
  247. : "r" (__arg1) /* input operands */ \
  248. , "r" (__arg2) /* input operands */ \
  249. , "r" (__arg3) /* input operands */ \
  250. , "r" (__no) /* input operands */ \
  251. : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
  252. __res; \
  253. })
  254. #define internal_syscall_ncs4(name, err, arg1, arg2, arg3, arg4) \
  255. ({ \
  256. register long __res __asm__("$r0"); \
  257. register long __no __asm__("$r0") = (long) (name); \
  258. register long __arg1 __asm__("$r1") = (long) (arg1); \
  259. register long __arg2 __asm__("$r2") = (long) (arg2); \
  260. register long __arg3 __asm__("$r3") = (long) (arg3); \
  261. register long __arg4 __asm__("$r4") = (long) (arg4); \
  262. __asm__ volatile ( \
  263. __issue_syscall (LIB_SYSCALL) \
  264. : "=r" (__res) /* output operands */ \
  265. : "r" (__arg1) /* input operands */ \
  266. , "r" (__arg2) /* input operands */ \
  267. , "r" (__arg3) /* input operands */ \
  268. , "r" (__arg4) /* input operands */ \
  269. , "r" (__no) /* input operands */ \
  270. : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
  271. __res; \
  272. })
  273. #define __SYSCALL_CLOBBERS "$lp", "memory"
  274. #endif /* ! __ASSEMBLER__ */
  275. #endif /* _BITS_SYSCALLS_H */