syscalls.h 19 KB

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