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