2 ** Copyright 2001, Travis Geiselbrecht. All rights reserved.
3 ** Distributed under the terms of the NewOS License.
5 #include <kernel/kernel.h>
6 #include <kernel/syscalls.h>
7 #include <kernel/int.h>
8 #include <kernel/debug.h>
9 #include <kernel/vfs.h>
10 #include <kernel/thread.h>
11 #include <kernel/sem.h>
12 #include <kernel/port.h>
13 #include <kernel/cpu.h>
14 #include <kernel/arch/cpu.h>
15 #include <sys/resource.h>
17 #define INT32TOINT64(x, y) ((int64)(x) | ((int64)(y) << 32))
19 #define arg0 (((uint32 *)arg_buffer)[0])
20 #define arg1 (((uint32 *)arg_buffer)[1])
21 #define arg2 (((uint32 *)arg_buffer)[2])
22 #define arg3 (((uint32 *)arg_buffer)[3])
23 #define arg4 (((uint32 *)arg_buffer)[4])
24 #define arg5 (((uint32 *)arg_buffer)[5])
25 #define arg6 (((uint32 *)arg_buffer)[6])
26 #define arg7 (((uint32 *)arg_buffer)[7])
27 #define arg8 (((uint32 *)arg_buffer)[8])
28 #define arg9 (((uint32 *)arg_buffer)[9])
29 #define arg10 (((uint32 *)arg_buffer)[10])
30 #define arg11 (((uint32 *)arg_buffer)[11])
31 #define arg12 (((uint32 *)arg_buffer)[12])
32 #define arg13 (((uint32 *)arg_buffer)[13])
33 #define arg14 (((uint32 *)arg_buffer)[14])
34 #define arg15 (((uint32 *)arg_buffer)[15])
36 int syscall_dispatcher(unsigned long call_num
, void *arg_buffer
, uint64
*call_ret
)
38 // dprintf("syscall_dispatcher: thread 0x%x call 0x%x, arg0 0x%x, arg1 0x%x arg2 0x%x arg3 0x%x arg4 0x%x\n",
39 // thread_get_current_thread_id(), call_num, arg0, arg1, arg2, arg3, arg4);
46 *call_ret
= user_mount((const char *)arg0
, (const char *)arg1
, (const char *)arg2
, (void *)arg3
);
49 *call_ret
= user_unmount((const char *)arg0
);
52 *call_ret
= user_sync();
55 *call_ret
= user_open((const char *)arg0
, (stream_type
)arg1
, (int)arg2
);
58 *call_ret
= user_close((int)arg0
);
61 *call_ret
= user_fsync((int)arg0
);
64 *call_ret
= user_read((int)arg0
, (void *)arg1
, (off_t
)INT32TOINT64(arg2
, arg3
), (ssize_t
)arg4
);
67 *call_ret
= user_write((int)arg0
, (const void *)arg1
, (off_t
)INT32TOINT64(arg2
, arg3
), (ssize_t
)arg4
);
70 *call_ret
= user_seek((int)arg0
, (off_t
)INT32TOINT64(arg1
, arg2
), (seek_type
)arg3
);
73 *call_ret
= user_ioctl((int)arg0
, (int)arg1
, (void *)arg2
, (size_t)arg3
);
76 *call_ret
= user_create((const char *)arg0
, (stream_type
)arg1
);
79 *call_ret
= user_unlink((const char *)arg0
);
82 *call_ret
= user_rename((const char *)arg0
, (const char *)arg1
);
85 *call_ret
= user_rstat((const char *)arg0
, (struct file_stat
*)arg1
);
88 *call_ret
= user_wstat((const char *)arg0
, (struct file_stat
*)arg1
, (int)arg2
);
90 case SYSCALL_SYSTEM_TIME
:
91 *call_ret
= system_time();
94 *call_ret
= user_thread_snooze((bigtime_t
)INT32TOINT64(arg0
, arg1
));
96 case SYSCALL_SEM_CREATE
:
97 *call_ret
= user_sem_create((int)arg0
, (const char *)arg1
);
99 case SYSCALL_SEM_DELETE
:
100 *call_ret
= user_sem_delete((sem_id
)arg0
);
102 case SYSCALL_SEM_ACQUIRE
:
103 *call_ret
= user_sem_acquire_etc((sem_id
)arg0
, (int)arg1
, 0, 0, NULL
);
105 case SYSCALL_SEM_ACQUIRE_ETC
:
106 *call_ret
= user_sem_acquire_etc((sem_id
)arg0
, (int)arg1
, (int)arg2
, (bigtime_t
)INT32TOINT64(arg3
, arg4
), (int *)arg5
);
108 case SYSCALL_SEM_RELEASE
:
109 *call_ret
= user_sem_release((sem_id
)arg0
, (int)arg1
);
111 case SYSCALL_SEM_RELEASE_ETC
:
112 *call_ret
= user_sem_release_etc((sem_id
)arg0
, (int)arg1
, (int)arg2
);
114 case SYSCALL_GET_CURRENT_THREAD_ID
:
115 *call_ret
= thread_get_current_thread_id();
117 case SYSCALL_EXIT_THREAD
:
118 thread_exit((int)arg0
);
121 case SYSCALL_PROC_CREATE_PROC
:
122 *call_ret
= user_proc_create_proc((const char *)arg0
, (const char *)arg1
, (char **)arg2
, (int )arg3
, (int)arg4
);
124 case SYSCALL_THREAD_WAIT_ON_THREAD
:
125 *call_ret
= user_thread_wait_on_thread((thread_id
)arg0
, (int *)arg1
);
127 case SYSCALL_PROC_WAIT_ON_PROC
:
128 *call_ret
= user_proc_wait_on_proc((proc_id
)arg0
, (int *)arg1
);
130 case SYSCALL_VM_CREATE_ANONYMOUS_REGION
:
131 *call_ret
= user_vm_create_anonymous_region(
132 (char *)arg0
, (void **)arg1
, (int)arg2
,
133 (addr
)arg3
, (int)arg4
, (int)arg5
);
135 case SYSCALL_VM_CLONE_REGION
:
136 *call_ret
= user_vm_clone_region(
137 (char *)arg0
, (void **)arg1
, (int)arg2
,
138 (region_id
)arg3
, (int)arg4
, (int)arg5
);
140 case SYSCALL_VM_MAP_FILE
:
141 *call_ret
= user_vm_map_file(
142 (char *)arg0
, (void **)arg1
, (int)arg2
,
143 (addr
)arg3
, (int)arg4
, (int)arg5
, (const char *)arg6
,
144 (off_t
)INT32TOINT64(arg7
, arg8
));
147 case SYSCALL_VM_DELETE_REGION
:
148 *call_ret
= vm_delete_region(vm_get_current_user_aspace_id(), (region_id
)arg0
);
150 case SYSCALL_VM_GET_REGION_INFO
:
151 *call_ret
= user_vm_get_region_info((region_id
)arg0
, (vm_region_info
*)arg1
);
153 case SYSCALL_THREAD_CREATE_THREAD
:
154 *call_ret
= user_thread_create_user_thread((char *)arg0
, thread_get_current_thread()->proc
->id
, (addr
)arg1
, (void *)arg2
);
156 case SYSCALL_THREAD_KILL_THREAD
:
157 *call_ret
= thread_kill_thread((thread_id
)arg0
);
159 case SYSCALL_THREAD_SUSPEND_THREAD
:
160 *call_ret
= thread_suspend_thread((thread_id
)arg0
);
162 case SYSCALL_THREAD_RESUME_THREAD
:
163 *call_ret
= thread_resume_thread((thread_id
)arg0
);
165 case SYSCALL_PROC_KILL_PROC
:
166 *call_ret
= proc_kill_proc((proc_id
)arg0
);
168 case SYSCALL_GET_CURRENT_PROC_ID
:
169 *call_ret
= proc_get_current_proc_id();
172 *call_ret
= user_getcwd((char*)arg0
, (size_t)arg1
);
175 *call_ret
= user_setcwd((const char*)arg0
);
177 case SYSCALL_PORT_CREATE
:
178 *call_ret
= user_port_create((int32
)arg0
, (const char *)arg1
);
180 case SYSCALL_PORT_CLOSE
:
181 *call_ret
= user_port_close((port_id
)arg0
);
183 case SYSCALL_PORT_DELETE
:
184 *call_ret
= user_port_delete((port_id
)arg0
);
186 case SYSCALL_PORT_FIND
:
187 *call_ret
= user_port_find((const char *)arg0
);
189 case SYSCALL_PORT_GET_INFO
:
190 *call_ret
= user_port_get_info((port_id
)arg0
, (struct port_info
*)arg1
);
192 case SYSCALL_PORT_GET_NEXT_PORT_INFO
:
193 *call_ret
= user_port_get_next_port_info((port_id
)arg0
, (uint32
*)arg1
, (struct port_info
*)arg2
);
195 case SYSCALL_PORT_BUFFER_SIZE
:
196 *call_ret
= user_port_buffer_size_etc((port_id
)arg0
, PORT_FLAG_INTERRUPTABLE
, 0);
198 case SYSCALL_PORT_BUFFER_SIZE_ETC
:
199 *call_ret
= user_port_buffer_size_etc((port_id
)arg0
, (uint32
)arg1
| PORT_FLAG_INTERRUPTABLE
, (bigtime_t
)INT32TOINT64(arg2
, arg3
));
201 case SYSCALL_PORT_COUNT
:
202 *call_ret
= user_port_count((port_id
)arg0
);
204 case SYSCALL_PORT_READ
:
205 *call_ret
= user_port_read_etc((port_id
)arg0
, (int32
*)arg1
, (void*)arg2
, (size_t)arg3
, PORT_FLAG_INTERRUPTABLE
, 0);
207 case SYSCALL_PORT_READ_ETC
:
208 *call_ret
= user_port_read_etc((port_id
)arg0
, (int32
*)arg1
, (void*)arg2
, (size_t)arg3
, (uint32
)arg4
| PORT_FLAG_INTERRUPTABLE
, (bigtime_t
)INT32TOINT64(arg5
, arg6
));
210 case SYSCALL_PORT_SET_OWNER
:
211 *call_ret
= user_port_set_owner((port_id
)arg0
, (proc_id
)arg1
);
213 case SYSCALL_PORT_WRITE
:
214 *call_ret
= user_port_write_etc((port_id
)arg0
, (int32
)arg1
, (void *)arg2
, (size_t)arg3
, PORT_FLAG_INTERRUPTABLE
, 0);
216 case SYSCALL_PORT_WRITE_ETC
:
217 *call_ret
= user_port_write_etc((port_id
)arg0
, (int32
)arg1
, (void *)arg2
, (size_t)arg3
, (uint32
)arg4
| PORT_FLAG_INTERRUPTABLE
, (bigtime_t
)INT32TOINT64(arg5
, arg6
));
219 case SYSCALL_SEM_GET_COUNT
:
220 *call_ret
= user_sem_get_count((sem_id
)arg0
, (int32
*)arg1
);
222 case SYSCALL_SEM_GET_SEM_INFO
:
223 *call_ret
= user_sem_get_sem_info((sem_id
)arg0
, (struct sem_info
*)arg1
);
225 case SYSCALL_SEM_GET_NEXT_SEM_INFO
:
226 *call_ret
= user_sem_get_next_sem_info((proc_id
)arg0
, (uint32
*)arg1
, (struct sem_info
*)arg2
);
228 case SYSCALL_SEM_SET_SEM_OWNER
:
229 *call_ret
= user_set_sem_owner((sem_id
)arg0
, (proc_id
)arg1
);
232 *call_ret
= user_dup(arg0
);
235 *call_ret
= user_dup2(arg0
, arg1
);
237 case SYSCALL_GETRLIMIT
:
238 *call_ret
= user_getrlimit((int)arg0
, (struct rlimit
*)arg1
);
240 case SYSCALL_SETRLIMIT
:
241 *call_ret
= user_setrlimit((int)arg0
, (const struct rlimit
*)arg1
);
243 case SYSCALL_ATOMIC_ADD
:
244 *call_ret
= user_atomic_add((int *)arg0
, (int)arg1
);
246 case SYSCALL_ATOMIC_AND
:
247 *call_ret
= user_atomic_and((int *)arg0
, (int)arg1
);
249 case SYSCALL_ATOMIC_OR
:
250 *call_ret
= user_atomic_or((int *)arg0
, (int)arg1
);
252 case SYSCALL_ATOMIC_SET
:
253 *call_ret
= user_atomic_set((int *)arg0
, (int)arg1
);
255 case SYSCALL_TEST_AND_SET
:
256 *call_ret
= user_test_and_set((int *)arg0
, (int)arg1
, (int)arg2
);
258 case SYSCALL_THREAD_GET_THREAD_INFO
:
259 *call_ret
= user_thread_get_thread_info((thread_id
)arg0
, (struct thread_info
*)arg1
);
261 case SYSCALL_THREAD_GET_NEXT_THREAD_INFO
:
262 *call_ret
= user_thread_get_next_thread_info((uint32
*)arg0
, (proc_id
)arg1
, (struct thread_info
*)arg2
);
264 case SYSCALL_PROC_GET_PROC_INFO
:
265 *call_ret
= user_proc_get_proc_info((proc_id
)arg0
, (struct proc_info
*)arg1
);
267 case SYSCALL_PROC_GET_NEXT_PROC_INFO
:
268 *call_ret
= user_proc_get_next_proc_info((uint32
*)arg0
, (struct proc_info
*)arg1
);
274 // dprintf("syscall_dispatcher: done with syscall 0x%x\n", call_num);
276 return INT_RESCHEDULE
;