lwp_syscall.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. /*
  2. * Copyright (c) 2006-2018, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2018-06-10 Bernard first version
  9. */
  10. /* RT-Thread System call */
  11. #include <lwp.h>
  12. #include <lwp_mem.h>
  13. #include <lwp_syscall.h>
  14. #include <dfs_poll.h>
  15. #include <dfs_select.h>
  16. #if (defined(RT_USING_SAL) && defined(SAL_USING_POSIX))
  17. #include <sys/socket.h>
  18. #define SYSCALL_NET(f) ((void*)(f))
  19. #else
  20. #define SYSCALL_NET(f) ((void*)sys_notimpl)
  21. #endif
  22. #define DBG_ENABLE
  23. #define DBG_SECTION_NAME "LWP_CALL"
  24. #define DBG_COLOR
  25. #define DBG_LEVEL DBG_WARNING
  26. #include <rtdbg.h>
  27. static void __exit_files(rt_thread_t tid)
  28. {
  29. struct rt_lwp *lwp;
  30. lwp = (struct rt_lwp *)tid->lwp;
  31. while (lwp->fdt.maxfd > 0)
  32. {
  33. lwp->fdt.maxfd --;
  34. close(lwp->fdt.maxfd);
  35. }
  36. }
  37. /* thread/process */
  38. void sys_exit(int value)
  39. {
  40. rt_thread_t tid;
  41. /* TODO: handle the return_value */
  42. dbg_log(DBG_LOG, "enter sys_exit\n");
  43. tid = rt_thread_self();
  44. __exit_files(tid);
  45. rt_thread_delete(tid);
  46. rt_schedule();
  47. return;
  48. }
  49. /* syscall: "read" ret: "ssize_t" args: "int" "void *" "size_t" */
  50. ssize_t sys_read(int fd, void *buf, size_t nbyte)
  51. {
  52. return read(fd, buf, nbyte);
  53. }
  54. /* syscall: "write" ret: "ssize_t" args: "int" "const void *" "size_t" */
  55. ssize_t sys_write(int fd, const void *buf, size_t nbyte)
  56. {
  57. return write(fd, buf, nbyte);
  58. }
  59. /* syscall: "lseek" ret: "off_t" args: "int" "off_t" "int" */
  60. off_t sys_lseek(int fd, off_t offset, int whence)
  61. {
  62. return lseek(fd, offset, whence);
  63. }
  64. /* syscall: "open" ret: "int" args: "const char *" "int" "..." */
  65. int sys_open(const char *name, int mode, ...)
  66. {
  67. return open(name, mode, 0);
  68. }
  69. /* syscall: "close" ret: "int" args: "int" */
  70. int sys_close(int fd)
  71. {
  72. return close(fd);
  73. }
  74. /* syscall: "ioctl" ret: "int" args: "int" "u_long" "..." */
  75. int sys_ioctl(int fd, unsigned long cmd, void* data)
  76. {
  77. return ioctl(fd, cmd, data);
  78. }
  79. /* syscall: "nanosleep" ret: "int" args: "const struct timespec *" "struct timespec *" */
  80. int sys_nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
  81. {
  82. rt_tick_t tick;
  83. dbg_log(DBG_LOG, "sys_nanosleep\n");
  84. tick = rqtp->tv_sec * RT_TICK_PER_SECOND + (rqtp->tv_nsec * RT_TICK_PER_SECOND)/ 1000000000;
  85. rt_thread_delay(tick);
  86. if (rmtp)
  87. {
  88. tick = rt_tick_get() - tick;
  89. /* get the passed time */
  90. rmtp->tv_sec = tick/RT_TICK_PER_SECOND;
  91. rmtp->tv_nsec = (tick%RT_TICK_PER_SECOND) * (1000000000/RT_TICK_PER_SECOND);
  92. }
  93. return 0;
  94. }
  95. /* syscall: "getpriority" ret: "int" args: "int" "id_t" */
  96. int sys_getpriority(int which, id_t who)
  97. {
  98. if (which == PRIO_PROCESS)
  99. {
  100. rt_thread_t tid;
  101. tid = rt_thread_self();
  102. if (who == (id_t)tid || who == 0xff)
  103. {
  104. return tid->current_priority;
  105. }
  106. }
  107. return 0xff;
  108. }
  109. /* syscall: "setpriority" ret: "int" args: "int" "id_t" "int" */
  110. int sys_setpriority(int which, id_t who, int prio)
  111. {
  112. if (which == PRIO_PROCESS)
  113. {
  114. rt_thread_t tid;
  115. tid = rt_thread_self();
  116. if ((who == (id_t)tid || who == 0xff) && (prio >= 0 && prio < RT_THREAD_PRIORITY_MAX))
  117. {
  118. rt_thread_control(tid, RT_THREAD_CTRL_CHANGE_PRIORITY, &prio);
  119. return 0;
  120. }
  121. }
  122. return -1;
  123. }
  124. /* syscall: "gettimeofday" ret: "int" args: "struct timeval *" "struct timezone *" */
  125. int sys_gettimeofday(struct timeval *tp, struct timezone *tzp)
  126. {
  127. if (tp)
  128. {
  129. tp->tv_sec = rt_tick_get() / RT_TICK_PER_SECOND;
  130. tp->tv_usec = (rt_tick_get() % RT_TICK_PER_SECOND) * (1000000 / RT_TICK_PER_SECOND);
  131. }
  132. return 0;
  133. }
  134. /* syscall: "settimeofday" ret: "int" args: "const struct timeval *" "const struct timezone *" */
  135. int sys_settimeofday(const struct timeval *tv, const struct timezone *tzp)
  136. {
  137. return 0;
  138. }
  139. /* syscall: "msgget" ret: "int" args: "key_t" "int" */
  140. int sys_msgget(key_t key, int msgflg)
  141. {
  142. return -1;
  143. }
  144. /* syscall: "msgsnd" ret: "int" args: "int" "const void *" "size_t" "int" */
  145. int sys_msgsend(int msqid, const void *msgp, size_t msgsz, int msgflg)
  146. {
  147. return -1;
  148. }
  149. /* syscall: "msgrcv" ret: "int" args: "int" "void *" "size_t" "long" "int" */
  150. int sys_msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg)
  151. {
  152. return -1;
  153. }
  154. /* syscall: "sys_log" ret: "int" args: "const char*" "size" */
  155. int sys_log(const char* log, int size)
  156. {
  157. rt_device_t console = rt_console_get_device();
  158. if (console) rt_device_write(console, -1, log, size);
  159. return 0;
  160. }
  161. void *sys_malloc(size_t size)
  162. {
  163. return rt_lwp_mem_malloc(size);
  164. }
  165. void sys_free(void *addr)
  166. {
  167. rt_lwp_mem_free(addr);
  168. }
  169. void *sys_realloc(void *rmem, size_t newsize)
  170. {
  171. return rt_lwp_mem_realloc(rmem, newsize);
  172. }
  173. int sys_fstat(int file, struct stat *buf)
  174. {
  175. return fstat(file, buf);
  176. }
  177. int sys_notimpl(void)
  178. {
  179. return -ENOSYS;
  180. }
  181. const static void* func_table[] =
  182. {
  183. (void *)sys_exit, // 0x01
  184. (void *)sys_read, // 0x02
  185. (void *)sys_write, // 0x03
  186. (void *)sys_lseek, // 0x04
  187. (void *)sys_open, // 0x05
  188. (void *)sys_close, // 0x06
  189. (void *)sys_ioctl, // 0x07
  190. (void *)sys_nanosleep, // 0x08
  191. (void *)sys_getpriority, // 0x09
  192. (void *)sys_setpriority, // 0x0a
  193. (void *)sys_gettimeofday, // 0x0b
  194. (void *)sys_settimeofday, // 0x0c
  195. (void *)sys_malloc, // 0x0d
  196. (void *)sys_free, // 0x0e
  197. (void *)sys_realloc, //0x0f
  198. (void *)sys_fstat, // 0x10
  199. (void *)poll, // 0x11
  200. SYSCALL_NET(accept), // 0x12
  201. SYSCALL_NET(bind), // 0x13
  202. SYSCALL_NET(shutdown), // 0x14
  203. SYSCALL_NET(getpeername),// 0x15
  204. SYSCALL_NET(getsockname),// 0x16
  205. SYSCALL_NET(getsockopt), // 0x17
  206. SYSCALL_NET(setsockopt), // 0x18
  207. SYSCALL_NET(connect), // 0x19
  208. SYSCALL_NET(listen), // 0x1a
  209. SYSCALL_NET(recv), // 0x1b
  210. SYSCALL_NET(recvfrom), // 0x1c
  211. SYSCALL_NET(send), // 0x1d
  212. SYSCALL_NET(sendto), // 0x1e
  213. SYSCALL_NET(socket), // 0x1f
  214. (void *)select, // 0x20
  215. };
  216. const void *lwp_get_sys_api(rt_uint32_t number)
  217. {
  218. const void *func = (const void*)sys_notimpl;
  219. if (number == 0xff)
  220. {
  221. func = (void *)sys_log;
  222. }
  223. else
  224. {
  225. number -= 1;
  226. if (number < sizeof(func_table)/sizeof(func_table[0]))
  227. {
  228. func = func_table[number];
  229. }
  230. }
  231. return func;
  232. }