more kernel elf loader hacking.
[newos.git] / kernel / syscalls.c
blob5635744330c81d09bf24066cf53645b669249322
1 /*
2 ** Copyright 2001, Travis Geiselbrecht. All rights reserved.
3 ** Distributed under the terms of the NewOS License.
4 */
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);
41 switch(call_num) {
42 case SYSCALL_NULL:
43 *call_ret = 0;
44 break;
45 case SYSCALL_MOUNT:
46 *call_ret = user_mount((const char *)arg0, (const char *)arg1, (const char *)arg2, (void *)arg3);
47 break;
48 case SYSCALL_UNMOUNT:
49 *call_ret = user_unmount((const char *)arg0);
50 break;
51 case SYSCALL_SYNC:
52 *call_ret = user_sync();
53 break;
54 case SYSCALL_OPEN:
55 *call_ret = user_open((const char *)arg0, (stream_type)arg1, (int)arg2);
56 break;
57 case SYSCALL_CLOSE:
58 *call_ret = user_close((int)arg0);
59 break;
60 case SYSCALL_FSYNC:
61 *call_ret = user_fsync((int)arg0);
62 break;
63 case SYSCALL_READ:
64 *call_ret = user_read((int)arg0, (void *)arg1, (off_t)INT32TOINT64(arg2, arg3), (ssize_t)arg4);
65 break;
66 case SYSCALL_WRITE:
67 *call_ret = user_write((int)arg0, (const void *)arg1, (off_t)INT32TOINT64(arg2, arg3), (ssize_t)arg4);
68 break;
69 case SYSCALL_SEEK:
70 *call_ret = user_seek((int)arg0, (off_t)INT32TOINT64(arg1, arg2), (seek_type)arg3);
71 break;
72 case SYSCALL_IOCTL:
73 *call_ret = user_ioctl((int)arg0, (int)arg1, (void *)arg2, (size_t)arg3);
74 break;
75 case SYSCALL_CREATE:
76 *call_ret = user_create((const char *)arg0, (stream_type)arg1);
77 break;
78 case SYSCALL_UNLINK:
79 *call_ret = user_unlink((const char *)arg0);
80 break;
81 case SYSCALL_RENAME:
82 *call_ret = user_rename((const char *)arg0, (const char *)arg1);
83 break;
84 case SYSCALL_RSTAT:
85 *call_ret = user_rstat((const char *)arg0, (struct file_stat *)arg1);
86 break;
87 case SYSCALL_WSTAT:
88 *call_ret = user_wstat((const char *)arg0, (struct file_stat *)arg1, (int)arg2);
89 break;
90 case SYSCALL_SYSTEM_TIME:
91 *call_ret = system_time();
92 break;
93 case SYSCALL_SNOOZE:
94 *call_ret = user_thread_snooze((bigtime_t)INT32TOINT64(arg0, arg1));
95 break;
96 case SYSCALL_SEM_CREATE:
97 *call_ret = user_sem_create((int)arg0, (const char *)arg1);
98 break;
99 case SYSCALL_SEM_DELETE:
100 *call_ret = user_sem_delete((sem_id)arg0);
101 break;
102 case SYSCALL_SEM_ACQUIRE:
103 *call_ret = user_sem_acquire_etc((sem_id)arg0, (int)arg1, 0, 0, NULL);
104 break;
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);
107 break;
108 case SYSCALL_SEM_RELEASE:
109 *call_ret = user_sem_release((sem_id)arg0, (int)arg1);
110 break;
111 case SYSCALL_SEM_RELEASE_ETC:
112 *call_ret = user_sem_release_etc((sem_id)arg0, (int)arg1, (int)arg2);
113 break;
114 case SYSCALL_GET_CURRENT_THREAD_ID:
115 *call_ret = thread_get_current_thread_id();
116 break;
117 case SYSCALL_EXIT_THREAD:
118 thread_exit((int)arg0);
119 *call_ret = 0;
120 break;
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);
123 break;
124 case SYSCALL_THREAD_WAIT_ON_THREAD:
125 *call_ret = user_thread_wait_on_thread((thread_id)arg0, (int *)arg1);
126 break;
127 case SYSCALL_PROC_WAIT_ON_PROC:
128 *call_ret = user_proc_wait_on_proc((proc_id)arg0, (int *)arg1);
129 break;
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);
134 break;
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);
139 break;
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));
145 break;
146 break;
147 case SYSCALL_VM_DELETE_REGION:
148 *call_ret = vm_delete_region(vm_get_current_user_aspace_id(), (region_id)arg0);
149 break;
150 case SYSCALL_VM_GET_REGION_INFO:
151 *call_ret = user_vm_get_region_info((region_id)arg0, (vm_region_info *)arg1);
152 break;
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);
155 break;
156 case SYSCALL_THREAD_KILL_THREAD:
157 *call_ret = thread_kill_thread((thread_id)arg0);
158 break;
159 case SYSCALL_THREAD_SUSPEND_THREAD:
160 *call_ret = thread_suspend_thread((thread_id)arg0);
161 break;
162 case SYSCALL_THREAD_RESUME_THREAD:
163 *call_ret = thread_resume_thread((thread_id)arg0);
164 break;
165 case SYSCALL_PROC_KILL_PROC:
166 *call_ret = proc_kill_proc((proc_id)arg0);
167 break;
168 case SYSCALL_GET_CURRENT_PROC_ID:
169 *call_ret = proc_get_current_proc_id();
170 break;
171 case SYSCALL_GETCWD:
172 *call_ret = user_getcwd((char*)arg0, (size_t)arg1);
173 break;
174 case SYSCALL_SETCWD:
175 *call_ret = user_setcwd((const char*)arg0);
176 break;
177 case SYSCALL_PORT_CREATE:
178 *call_ret = user_port_create((int32)arg0, (const char *)arg1);
179 break;
180 case SYSCALL_PORT_CLOSE:
181 *call_ret = user_port_close((port_id)arg0);
182 break;
183 case SYSCALL_PORT_DELETE:
184 *call_ret = user_port_delete((port_id)arg0);
185 break;
186 case SYSCALL_PORT_FIND:
187 *call_ret = user_port_find((const char *)arg0);
188 break;
189 case SYSCALL_PORT_GET_INFO:
190 *call_ret = user_port_get_info((port_id)arg0, (struct port_info *)arg1);
191 break;
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);
194 break;
195 case SYSCALL_PORT_BUFFER_SIZE:
196 *call_ret = user_port_buffer_size_etc((port_id)arg0, PORT_FLAG_INTERRUPTABLE, 0);
197 break;
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));
200 break;
201 case SYSCALL_PORT_COUNT:
202 *call_ret = user_port_count((port_id)arg0);
203 break;
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);
206 break;
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));
209 break;
210 case SYSCALL_PORT_SET_OWNER:
211 *call_ret = user_port_set_owner((port_id)arg0, (proc_id)arg1);
212 break;
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);
215 break;
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));
218 break;
219 case SYSCALL_SEM_GET_COUNT:
220 *call_ret = user_sem_get_count((sem_id)arg0, (int32*)arg1);
221 break;
222 case SYSCALL_SEM_GET_SEM_INFO:
223 *call_ret = user_sem_get_sem_info((sem_id)arg0, (struct sem_info *)arg1);
224 break;
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);
227 break;
228 case SYSCALL_SEM_SET_SEM_OWNER:
229 *call_ret = user_set_sem_owner((sem_id)arg0, (proc_id)arg1);
230 break;
231 case SYSCALL_FDDUP:
232 *call_ret = user_dup(arg0);
233 break;
234 case SYSCALL_FDDUP2:
235 *call_ret = user_dup2(arg0, arg1);
236 break;
237 case SYSCALL_GETRLIMIT:
238 *call_ret = user_getrlimit((int)arg0, (struct rlimit *)arg1);
239 break;
240 case SYSCALL_SETRLIMIT:
241 *call_ret = user_setrlimit((int)arg0, (const struct rlimit *)arg1);
242 break;
243 case SYSCALL_ATOMIC_ADD:
244 *call_ret = user_atomic_add((int *)arg0, (int)arg1);
245 break;
246 case SYSCALL_ATOMIC_AND:
247 *call_ret = user_atomic_and((int *)arg0, (int)arg1);
248 break;
249 case SYSCALL_ATOMIC_OR:
250 *call_ret = user_atomic_or((int *)arg0, (int)arg1);
251 break;
252 case SYSCALL_ATOMIC_SET:
253 *call_ret = user_atomic_set((int *)arg0, (int)arg1);
254 break;
255 case SYSCALL_TEST_AND_SET:
256 *call_ret = user_test_and_set((int *)arg0, (int)arg1, (int)arg2);
257 break;
258 case SYSCALL_THREAD_GET_THREAD_INFO:
259 *call_ret = user_thread_get_thread_info((thread_id)arg0, (struct thread_info *)arg1);
260 break;
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);
263 break;
264 case SYSCALL_PROC_GET_PROC_INFO:
265 *call_ret = user_proc_get_proc_info((proc_id)arg0, (struct proc_info *)arg1);
266 break;
267 case SYSCALL_PROC_GET_NEXT_PROC_INFO:
268 *call_ret = user_proc_get_next_proc_info((uint32 *)arg0, (struct proc_info *)arg1);
269 break;
270 default:
271 *call_ret = -1;
274 // dprintf("syscall_dispatcher: done with syscall 0x%x\n", call_num);
276 return INT_RESCHEDULE;