1 /*
2 * Copyright (c) 2023 Institute of Parallel And Distributed Systems (IPADS), Shanghai Jiao Tong University (SJTU)
3 * Licensed under the Mulan PSL v2.
4 * You can use this software according to the terms and conditions of the Mulan PSL v2.
5 * You may obtain a copy of Mulan PSL v2 at:
6 * http://license.coscl.org.cn/MulanPSL2
7 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9 * PURPOSE.
10 * See the Mulan PSL v2 for more details.
11 */
12 #include <common/types.h>
13 #include <io/uart.h>
14 #include <mm/uaccess.h>
15 #include <mm/kmalloc.h>
16 #include <mm/mm.h>
17 #include <common/kprint.h>
18 #include <common/debug.h>
19 #include <common/lock.h>
20 #include <object/memory.h>
21 #include <object/thread.h>
22 #include <object/cap_group.h>
23 #include <object/recycle.h>
24 #include <object/object.h>
25 #include <object/irq.h>
26 #include <object/user_fault.h>
27 #include <sched/sched.h>
28 #include <ipc/connection.h>
29 #include <irq/timer.h>
30 #include <irq/irq.h>
31 #ifdef CHCORE_OH_TEE
32 #include <arch/trustzone/smc.h>
33 #include <arch/trustzone/tlogger.h>
34 #endif /* CHCORE_OH_TEE */
35 #include <common/poweroff.h>
36 #ifdef CHCORE_OH_TEE
37 #include <ipc/channel.h>
38 #endif /* CHCORE_OH_TEE */
39 #ifdef CHCORE_ARCH_X86_64
40 #include <arch/pci.h>
41 #endif /* CHCORE_ARCH_X86_64 */
42
43 #include "syscall_num.h"
44
45 #if ENABLE_HOOKING_SYSCALL == ON
hook_syscall(long n)46 void hook_syscall(long n)
47 {
48 if ((n != SYS_putstr) && (n != SYS_getc) && (n != SYS_yield)
49 && (n != SYS_handle_brk))
50 kinfo("[SYSCALL TRACING] hook_syscall num: %ld\n", n);
51 }
52 #endif
53
54 /* Placeholder for system calls that are not implemented */
sys_null_placeholder(void)55 int sys_null_placeholder(void)
56 {
57 kwarn("Invoke non-implemented syscall\n");
58 return -EBADSYSCALL;
59 }
60
61 #if ENABLE_PRINT_LOCK == ON
62
63 struct lock global_print_lock = {0};
64 #endif
65
sys_putstr(char * str,size_t len)66 void sys_putstr(char *str, size_t len)
67 {
68 if (check_user_addr_range((vaddr_t)str, len) != 0)
69 return;
70
71 if (is_tlogger_on()) {
72 char log_buf[512];
73 if (len >= 512) {
74 return;
75 }
76 if (copy_from_user(log_buf, str, len)) {
77 return;
78 }
79 (void)append_chcore_log(log_buf, len, false);
80 return;
81 }
82
83 #define PRINT_BUFSZ 64
84 char buf[PRINT_BUFSZ];
85 size_t copy_len;
86 size_t i;
87 int r;
88
89 do {
90 copy_len = (len > PRINT_BUFSZ) ? PRINT_BUFSZ : len;
91 r = copy_from_user(buf, str, copy_len);
92 if (r)
93 return;
94
95 #if ENABLE_PRINT_LOCK == ON
96 lock(&global_print_lock);
97 #endif
98 for (i = 0; i < copy_len; ++i) {
99 uart_send((unsigned int)buf[i]);
100 if (graphic_putc)
101 graphic_putc(buf[i]);
102 }
103
104 #if ENABLE_PRINT_LOCK == ON
105 unlock(&global_print_lock);
106 #endif
107 len -= copy_len;
108 str += copy_len;
109 } while (len != 0);
110 }
111
sys_getc(void)112 char sys_getc(void)
113 {
114 return nb_uart_recv();
115 }
116
117 /* Arch-specific declarations */
118 void arch_flush_cache(vaddr_t, size_t, int);
119 u64 plat_get_current_tick(void);
120
121 /* Helper system calls for user-level drivers to use. */
sys_cache_flush(unsigned long start,long len,int op_type)122 int sys_cache_flush(unsigned long start, long len, int op_type)
123 {
124 arch_flush_cache(start, len, op_type);
125 return 0;
126 }
127
sys_get_current_tick(void)128 unsigned long sys_get_current_tick(void)
129 {
130 return plat_get_current_tick();
131 }
132
133 /* DELETE */
134 /* Syscalls for perfromance benchmark */
135 /* A debugging function which can be used for adding trace points in apps */
sys_debug_log(long arg)136 void sys_debug_log(long arg)
137 {
138 kinfo("%s: %ld\n", __func__, arg);
139 }
140
sys_perf_start(void)141 void sys_perf_start(void)
142 {
143 kdebug("Disable TIMER\n");
144 plat_disable_timer();
145 }
146
sys_perf_end(void)147 void sys_perf_end(void)
148 {
149 kdebug("Enable TIMER\n");
150 plat_enable_timer();
151 }
152
sys_perf_null(void)153 void sys_perf_null(void)
154 {
155 }
156 /* DELETE */
157
sys_get_pci_device(int class,u64 pci_dev_uaddr)158 void sys_get_pci_device(int class, u64 pci_dev_uaddr)
159 {
160 #if defined(CHCORE_ARCH_X86_64)
161 arch_get_pci_device(class, pci_dev_uaddr);
162 #else
163 kwarn("PCI is not supported on current architecture.\n");
164 #endif
165 }
166
sys_poweroff(void)167 void sys_poweroff(void)
168 {
169 plat_poweroff();
170 }
171
172 const void *syscall_table[NR_SYSCALL] = {
173 [0 ... NR_SYSCALL - 1] = sys_null_placeholder,
174
175 /* Character */
176 [SYS_putstr] = sys_putstr,
177 [SYS_getc] = sys_getc,
178
179 [SYS_tee_push_rdr_update_addr] = sys_tee_push_rdr_update_addr,
180 [SYS_debug_rdr_logitem] = sys_debug_rdr_logitem,
181
182 /* PMO */
183 /* - single */
184 [SYS_create_pmo] = sys_create_pmo,
185 [SYS_create_device_pmo] = sys_create_device_pmo,
186 [SYS_map_pmo] = sys_map_pmo,
187 [SYS_unmap_pmo] = sys_unmap_pmo,
188 [SYS_write_pmo] = sys_write_pmo,
189 [SYS_read_pmo] = sys_read_pmo,
190 #ifdef CHCORE_OH_TEE
191 [SYS_create_ns_pmo] = sys_create_ns_pmo,
192 [SYS_destroy_ns_pmo] = sys_destroy_ns_pmo,
193 [SYS_create_tee_shared_pmo] = sys_create_tee_shared_pmo,
194 [SYS_transfer_pmo_owner] = sys_transfer_pmo_owner,
195 #endif /* CHCORE_OH_TEE */
196
197 /* - address translation */
198 [SYS_get_phys_addr] = sys_get_phys_addr,
199
200 /* Capability */
201 [SYS_revoke_cap] = sys_revoke_cap,
202 [SYS_transfer_caps] = sys_transfer_caps,
203
204 /* Multitask */
205 /* - create & exit */
206 [SYS_create_cap_group] = sys_create_cap_group,
207 [SYS_exit_group] = sys_exit_group,
208 [SYS_create_thread] = sys_create_thread,
209 [SYS_thread_exit] = sys_thread_exit,
210 [SYS_kill_group] = sys_kill_group,
211 #ifdef CHCORE_OH_TEE
212 [SYS_get_thread_id] = sys_get_thread_id,
213 [SYS_terminate_thread] = sys_terminate_thread,
214 [SYS_disable_local_irq] = sys_disable_local_irq,
215 [SYS_enable_local_irq] = sys_enable_local_irq,
216 #endif /* CHCORE_OH_TEE */
217 /* - recycle */
218 [SYS_register_recycle] = sys_register_recycle,
219 [SYS_cap_group_recycle] = sys_cap_group_recycle,
220 [SYS_ipc_close_connection] = sys_ipc_close_connection,
221 /* - schedule */
222 [SYS_yield] = sys_yield,
223 [SYS_set_affinity] = sys_set_affinity,
224 [SYS_get_affinity] = sys_get_affinity,
225 [SYS_set_prio] = sys_set_prio,
226 [SYS_get_prio] = sys_get_prio,
227 /* IPC */
228 /* - procedure call */
229 [SYS_register_server] = sys_register_server,
230 [SYS_register_client] = sys_register_client,
231 [SYS_ipc_register_cb_return] = sys_ipc_register_cb_return,
232 [SYS_ipc_call] = sys_ipc_call,
233 [SYS_ipc_return] = sys_ipc_return,
234 [SYS_ipc_exit_routine_return] = sys_ipc_exit_routine_return,
235 /* - notification */
236 [SYS_create_notifc] = sys_create_notifc,
237 [SYS_wait] = sys_wait,
238 [SYS_notify] = sys_notify,
239 #ifdef CHCORE_OH_TEE
240 /* - oh-tee-ipc */
241 [SYS_tee_msg_create_msg_hdl] = sys_tee_msg_create_msg_hdl,
242 [SYS_tee_msg_create_channel] = sys_tee_msg_create_channel,
243 [SYS_tee_msg_receive] = sys_tee_msg_receive,
244 [SYS_tee_msg_call] = sys_tee_msg_call,
245 [SYS_tee_msg_reply] = sys_tee_msg_reply,
246 [SYS_tee_msg_notify] = sys_tee_msg_notify,
247 [SYS_tee_msg_stop_channel] = sys_tee_msg_stop_channel,
248 #endif /* CHCORE_OH_TEE */
249
250 /* Exception */
251 /* - irq */
252 [SYS_irq_register] = sys_irq_register,
253 [SYS_irq_wait] = sys_irq_wait,
254 [SYS_irq_ack] = sys_irq_ack,
255 [SYS_disable_irqno] = sys_disable_irqno,
256 [SYS_enable_irqno] = sys_enable_irqno,
257 [SYS_irq_op] = sys_irq_op,
258 [SYS_irq_stop] = sys_irq_stop,
259
260 #ifdef CHCORE_ENABLE_FMAP
261 /* - page fault */
262 [SYS_user_fault_register] = sys_user_fault_register,
263 [SYS_user_fault_map] = sys_user_fault_map,
264 #endif
265
266 /* Hardware Access (Privileged Instruction) */
267 /* - cache */
268 [SYS_cache_flush] = sys_cache_flush,
269 /* - timer */
270 [SYS_get_current_tick] = sys_get_current_tick,
271
272 /* POSIX */
273 /* - time */
274 [SYS_clock_gettime] = sys_clock_gettime,
275 [SYS_clock_nanosleep] = sys_clock_nanosleep,
276 /* - memory */
277 [SYS_handle_brk] = sys_handle_brk,
278 [SYS_handle_mprotect] = sys_handle_mprotect,
279
280 /* Debug */
281 [SYS_debug_log] = sys_debug_log,
282 [SYS_top] = sys_top,
283 [SYS_get_free_mem_size] = sys_get_free_mem_size,
284
285 /* Performance Benchmark */
286 [SYS_perf_start] = sys_perf_start,
287 [SYS_perf_end] = sys_perf_end,
288 [SYS_perf_null] = sys_perf_null,
289
290 [SYS_get_pci_device] = sys_get_pci_device,
291 [SYS_poweroff] = sys_poweroff,
292
293 #ifdef CHCORE_OH_TEE
294 /* TrustZone */
295 [SYS_tee_wait_switch_req] = sys_tee_wait_switch_req,
296 [SYS_tee_switch_req] = sys_tee_switch_req,
297 [SYS_tee_create_ns_pmo] = sys_tee_create_ns_pmo,
298 [SYS_tee_pull_kernel_var] = sys_tee_pull_kernel_var,
299 #endif /* CHCORE_OH_TEE */
300 };
301