syscalls.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  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
  58. */
  59. #undef INTERNAL_SYSCALL_NCS
  60. #define INTERNAL_SYSCALL_NCS(name, err, nr, args...) internal_syscall_ncs##nr(name, err, args)
  61. #define internal_syscall0(name, err, dummy...) \
  62. ({ \
  63. register long ___res __asm__("$r0"); \
  64. __asm__ volatile ( \
  65. __issue_syscall (name) \
  66. : "=r" (___res) /* output operands */ \
  67. : \
  68. : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
  69. ___res; \
  70. })
  71. #define internal_syscall1(name, err, arg1) \
  72. ({ \
  73. register long ___res __asm__("$r0"); \
  74. register long __arg1 __asm__("$r0") = (long) (arg1); \
  75. __asm__ volatile ( \
  76. __issue_syscall (name) \
  77. : "=r" (___res) /* output operands */ \
  78. : "r" (__arg1) /* input operands */ \
  79. : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
  80. ___res; \
  81. })
  82. #define internal_syscall2(name, err, arg1, arg2) \
  83. ({ \
  84. register long ___res __asm__("$r0"); \
  85. register long __arg1 __asm__("$r0") = (long) (arg1); \
  86. register long __arg2 __asm__("$r1") = (long) (arg2); \
  87. __asm__ volatile ( \
  88. __issue_syscall (name) \
  89. : "=r" (___res) /* output operands */ \
  90. : "r" (__arg1) /* input operands */ \
  91. , "r" (__arg2) /* input operands */ \
  92. : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
  93. ___res; \
  94. })
  95. #define internal_syscall3(name, err, arg1, arg2, arg3) \
  96. ({ \
  97. register long ___res __asm__("$r0"); \
  98. register long __arg1 __asm__("$r0") = (long) (arg1); \
  99. register long __arg2 __asm__("$r1") = (long) (arg2); \
  100. register long __arg3 __asm__("$r2") = (long) (arg3); \
  101. __asm__ volatile ( \
  102. __issue_syscall (name) \
  103. : "=r" (___res) /* output operands */ \
  104. : "r" (__arg1) /* input operands */ \
  105. , "r" (__arg2) /* input operands */ \
  106. , "r" (__arg3) /* input operands */ \
  107. : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
  108. ___res; \
  109. })
  110. #define internal_syscall4(name, err, arg1, arg2, arg3, arg4) \
  111. ({ \
  112. register long ___res __asm__("$r0"); \
  113. register long __arg1 __asm__("$r0") = (long) (arg1); \
  114. register long __arg2 __asm__("$r1") = (long) (arg2); \
  115. register long __arg3 __asm__("$r2") = (long) (arg3); \
  116. register long __arg4 __asm__("$r3") = (long) (arg4); \
  117. __asm__ volatile ( \
  118. __issue_syscall (name) \
  119. : "=r" (___res) /* output operands */ \
  120. : "r" (__arg1) /* input operands */ \
  121. , "r" (__arg2) /* input operands */ \
  122. , "r" (__arg3) /* input operands */ \
  123. , "r" (__arg4) /* input operands */ \
  124. : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
  125. ___res; \
  126. })
  127. #define internal_syscall5(name, err, arg1, arg2, arg3, arg4, arg5) \
  128. ({ \
  129. register long ___res __asm__("$r0"); \
  130. register long __arg1 __asm__("$r0") = (long) (arg1); \
  131. register long __arg2 __asm__("$r1") = (long) (arg2); \
  132. register long __arg3 __asm__("$r2") = (long) (arg3); \
  133. register long __arg4 __asm__("$r3") = (long) (arg4); \
  134. register long __arg5 __asm__("$r4") = (long) (arg5); \
  135. __asm__ volatile ( \
  136. __issue_syscall (name) \
  137. : "=r" (___res) /* output operands */ \
  138. : "r" (__arg1) /* input operands */ \
  139. , "r" (__arg2) /* input operands */ \
  140. , "r" (__arg3) /* input operands */ \
  141. , "r" (__arg4) /* input operands */ \
  142. , "r" (__arg5) /* input operands */ \
  143. : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
  144. ___res; \
  145. })
  146. #define internal_syscall6(name, err, arg1, arg2, arg3, arg4, arg5, arg6) \
  147. ({ \
  148. register long ___res __asm__("$r0"); \
  149. register long __arg1 __asm__("$r0") = (long) (arg1); \
  150. register long __arg2 __asm__("$r1") = (long) (arg2); \
  151. register long __arg3 __asm__("$r2") = (long) (arg3); \
  152. register long __arg4 __asm__("$r3") = (long) (arg4); \
  153. register long __arg5 __asm__("$r4") = (long) (arg5); \
  154. register long __arg6 __asm__("$r5") = (long) (arg6); \
  155. __asm__ volatile ( \
  156. __issue_syscall (name) \
  157. : "=r" (___res) /* output operands */ \
  158. : "r" (__arg1) /* input operands */ \
  159. , "r" (__arg2) /* input operands */ \
  160. , "r" (__arg3) /* input operands */ \
  161. , "r" (__arg4) /* input operands */ \
  162. , "r" (__arg5) /* input operands */ \
  163. , "r" (__arg6) /* input operands */ \
  164. : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
  165. ___res; \
  166. })
  167. #define internal_syscall7(name, err, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
  168. ({ \
  169. register long ___res __asm__("$r0"); \
  170. register long __arg1 __asm__("$r0") = (long) (arg1); \
  171. register long __arg2 __asm__("$r1") = (long) (arg2); \
  172. register long __arg3 __asm__("$r2") = (long) (arg3); \
  173. register long __arg4 __asm__("$r3") = (long) (arg4); \
  174. register long __arg5 __asm__("$r4") = (long) (arg5); \
  175. register long __arg6 __asm__("$r5") = (long) (arg6); \
  176. __asm__ volatile ( \
  177. "addi10.sp\t #-4\n\t" \
  178. CFI_ADJUST_CFA_OFFSET(4)"\n\t" \
  179. "push\t %7\n\t" \
  180. CFI_ADJUST_CFA_OFFSET(4)"\n\t" \
  181. __issue_syscall (name) \
  182. "addi10.sp\t #4\n\t" \
  183. CFI_ADJUST_CFA_OFFSET(-4)"\n\t" \
  184. "pop\t %7\n\t" \
  185. CFI_ADJUST_CFA_OFFSET(-4)"\n\t" \
  186. : "=r" (___res) /* output operands */ \
  187. : "r" (__arg1) /* input operands */ \
  188. , "r" (__arg2) /* input operands */ \
  189. , "r" (__arg3) /* input operands */ \
  190. , "r" (__arg4) /* input operands */ \
  191. , "r" (__arg5) /* input operands */ \
  192. , "r" (__arg6) /* input operands */ \
  193. , "r" (arg7) /* input operands */ \
  194. : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
  195. ___res; \
  196. })
  197. #define internal_syscall_ncs0(name, err, dummy...) \
  198. ({ \
  199. register long __res __asm__("$r0"); \
  200. register long __no __asm__("$r0") = (long) (name); \
  201. __asm__ volatile ( \
  202. __issue_syscall (LIB_SYSCALL) \
  203. : "=r" (__res) /* output operands */ \
  204. : "r" (__no) /* input operands */ \
  205. : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
  206. __res; \
  207. })
  208. #define internal_syscall_ncs1(name, err, arg1) \
  209. ({ \
  210. register long __res __asm__("$r0"); \
  211. register long __no __asm__("$r0") = (long) (name); \
  212. register long __arg1 __asm__("$r1") = (long) (arg1); \
  213. __asm__ volatile ( \
  214. __issue_syscall (LIB_SYSCALL) \
  215. : "=r" (__res) /* output operands */ \
  216. : "r" (__arg1) /* input operands */ \
  217. , "r" (__no) /* input operands */ \
  218. : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
  219. __res; \
  220. })
  221. #define internal_syscall_ncs2(name, err, arg1, arg2) \
  222. ({ \
  223. register long __res __asm__("$r0"); \
  224. register long __no __asm__("$r0") = (long) (name); \
  225. register long __arg1 __asm__("$r1") = (long) (arg1); \
  226. register long __arg2 __asm__("$r2") = (long) (arg2); \
  227. __asm__ volatile ( \
  228. __issue_syscall (LIB_SYSCALL) \
  229. : "=r" (__res) /* output operands */ \
  230. : "r" (__arg1) /* input operands */ \
  231. , "r" (__arg2) /* input operands */ \
  232. , "r" (__no) /* input operands */ \
  233. : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
  234. __res; \
  235. })
  236. #define internal_syscall_ncs3(name, err, arg1, arg2, arg3) \
  237. ({ \
  238. register long __res __asm__("$r0"); \
  239. register long __no __asm__("$r0") = (long) (name); \
  240. register long __arg1 __asm__("$r1") = (long) (arg1); \
  241. register long __arg2 __asm__("$r2") = (long) (arg2); \
  242. register long __arg3 __asm__("$r3") = (long) (arg3); \
  243. __asm__ volatile ( \
  244. __issue_syscall (LIB_SYSCALL) \
  245. : "=r" (__res) /* output operands */ \
  246. : "r" (__arg1) /* input operands */ \
  247. , "r" (__arg2) /* input operands */ \
  248. , "r" (__arg3) /* input operands */ \
  249. , "r" (__no) /* input operands */ \
  250. : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
  251. __res; \
  252. })
  253. #define internal_syscall_ncs4(name, err, arg1, arg2, arg3, arg4) \
  254. ({ \
  255. register long __res __asm__("$r0"); \
  256. register long __no __asm__("$r0") = (long) (name); \
  257. register long __arg1 __asm__("$r1") = (long) (arg1); \
  258. register long __arg2 __asm__("$r2") = (long) (arg2); \
  259. register long __arg3 __asm__("$r3") = (long) (arg3); \
  260. register long __arg4 __asm__("$r4") = (long) (arg4); \
  261. __asm__ volatile ( \
  262. __issue_syscall (LIB_SYSCALL) \
  263. : "=r" (__res) /* output operands */ \
  264. : "r" (__arg1) /* input operands */ \
  265. , "r" (__arg2) /* input operands */ \
  266. , "r" (__arg3) /* input operands */ \
  267. , "r" (__arg4) /* input operands */ \
  268. , "r" (__no) /* input operands */ \
  269. : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
  270. __res; \
  271. })
  272. #define internal_syscall_ncs5(name, err, arg1, arg2, arg3, arg4, arg5) \
  273. ({ \
  274. register long ___res __asm__("$r0"); \
  275. register long __no __asm__("$r0") = (long) (name); \
  276. register long __arg1 __asm__("$r1") = (long) (arg1); \
  277. register long __arg2 __asm__("$r2") = (long) (arg2); \
  278. register long __arg3 __asm__("$r3") = (long) (arg3); \
  279. register long __arg4 __asm__("$r4") = (long) (arg4); \
  280. register long __arg5 __asm__("$r5") = (long) (arg5); \
  281. __asm__ volatile ( \
  282. __issue_syscall (LIB_SYSCALL) \
  283. : "=r" (___res) /* output operands */ \
  284. : "r" (__arg1) /* input operands */ \
  285. , "r" (__arg2) /* input operands */ \
  286. , "r" (__arg3) /* input operands */ \
  287. , "r" (__arg4) /* input operands */ \
  288. , "r" (__arg5) /* input operands */ \
  289. : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
  290. ___res; \
  291. })
  292. #define internal_syscall_ncs6(name, err, arg1, arg2, arg3, arg4, arg5, arg6) \
  293. ({ \
  294. register long __res __asm__("$r0"); \
  295. register long __no __asm__("$r0") = (long) (name); \
  296. register long __arg1 __asm__("$r1") = (long) (arg1); \
  297. register long __arg2 __asm__("$r2") = (long) (arg2); \
  298. register long __arg3 __asm__("$r3") = (long) (arg3); \
  299. register long __arg4 __asm__("$r4") = (long) (arg4); \
  300. register long __arg5 __asm__("$r5") = (long) (arg5); \
  301. __asm__ volatile ( \
  302. "addi10.sp\t #-4\n\t" \
  303. CFI_ADJUST_CFA_OFFSET(4)"\n\t" \
  304. "push\t %7\n\t" \
  305. CFI_ADJUST_CFA_OFFSET(4)"\n\t" \
  306. __issue_syscall (LIB_SYSCALL) \
  307. "pop\t %7\n\t" \
  308. CFI_ADJUST_CFA_OFFSET(-4)"\n\t" \
  309. "addi10.sp\t #4\n\t" \
  310. CFI_ADJUST_CFA_OFFSET(-4)"\n\t" \
  311. : "=r" (__res) /* output operands */ \
  312. : "r" (__no) /* input operands */ \
  313. , "r" (__arg1) /* input operands */ \
  314. , "r" (__arg2) /* input operands */ \
  315. , "r" (__arg3) /* input operands */ \
  316. , "r" (__arg4) /* input operands */ \
  317. , "r" (__arg5) /* input operands */ \
  318. , "r" (arg6) /* input operands */ \
  319. : __SYSCALL_CLOBBERS); /* list of clobbered registers */ \
  320. __res; \
  321. })
  322. #define __SYSCALL_CLOBBERS "$lp", "memory"
  323. #endif /* ! __ASSEMBLER__ */
  324. #endif /* _BITS_SYSCALLS_H */