1 /*
2  * Copyright (c) 2006-2021, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2021-02-03     lizhirui     first version
9  * 2022-11-10     WangXiaoyao  Add readable syscall tracing
10  */
11 
12 #include <rthw.h>
13 #include <rtthread.h>
14 
15 #ifdef RT_USING_SMART
16 
17 #define DBG_TAG "syscall"
18 #define DBG_LVL DBG_WARNING
19 #include <rtdbg.h>
20 
21 #include <stdint.h>
22 #include <mmu.h>
23 #include <page.h>
24 #include <lwp_user_mm.h>
25 
26 #include "riscv_mmu.h"
27 #include "stack.h"
28 
29 typedef rt_ubase_t (*syscallfunc_t)(rt_ubase_t, rt_ubase_t, rt_ubase_t, rt_ubase_t, rt_ubase_t, rt_ubase_t, rt_ubase_t);
30 
syscall_handler(struct rt_hw_stack_frame * regs)31 void syscall_handler(struct rt_hw_stack_frame *regs)
32 {
33     const char *syscall_name;
34     int syscallid = regs->a7;
35 
36     if (syscallid == 0)
37     {
38         LOG_E("syscall id = 0!\n");
39         while (1)
40             ;
41     }
42 
43     syscallfunc_t syscallfunc = (syscallfunc_t)lwp_get_sys_api(syscallid);
44 
45     if (syscallfunc == RT_NULL)
46     {
47         LOG_E("unsupported syscall!\n");
48         sys_exit_group(-1);
49     }
50 
51 #if DBG_LVL >= DBG_INFO
52     syscall_name = lwp_get_syscall_name(syscallid);
53 #endif
54 
55     LOG_I("[0x%lx] %s(0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)", rt_thread_self(), syscall_name,
56         regs->a0, regs->a1, regs->a2, regs->a3, regs->a4, regs->a5, regs->a6);
57     regs->a0 = syscallfunc(regs->a0, regs->a1, regs->a2, regs->a3, regs->a4, regs->a5, regs->a6);
58     regs->a7 = 0;
59     regs->epc += 4; // skip ecall instruction
60     LOG_I("[0x%lx] %s ret: 0x%lx", rt_thread_self(), syscall_name, regs->a0);
61 }
62 #endif /* RT_USING_SMART */
63