summaryrefslogtreecommitdiff
path: root/libcpu/risc-v/common/syscall.c
blob: c8df566c4c26c9cc8c7cab81cff951a653f18127 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2021-02-03     lizhirui     first version
 * 2022-11-10     WangXiaoyao  Add readable syscall tracing
 */

#include <rthw.h>
#include <rtthread.h>

#define DBG_TAG "syscall"
#define DBG_LVL DBG_WARNING
#include <rtdbg.h>

#include <mmu.h>
#include <page.h>
#include <stack.h>
#include <lwp_user_mm.h>

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);

void syscall_handler(struct rt_hw_stack_frame *regs)
{
    const char *syscall_name;
    int syscallid = regs->a7;

    if (syscallid == 0)
    {
        LOG_E("syscall id = 0!\n");

        while (RT_TRUE)
        {
            rt_hw_cpu_relax();
        }
    }

    syscallfunc_t syscallfunc = (syscallfunc_t)lwp_get_sys_api(syscallid);

    if (syscallfunc == RT_NULL)
    {
        LOG_E("unsupported syscall!\n");
        sys_exit_group(-1);
    }

#if DBG_LVL >= DBG_INFO
    syscall_name = lwp_get_syscall_name(syscallid);
#else
    RT_UNUSED(syscall_name);
#endif

    LOG_I("[0x%lx] %s(0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)", rt_thread_self(), syscall_name,
        regs->a0, regs->a1, regs->a2, regs->a3, regs->a4, regs->a5, regs->a6);
    regs->a0 = syscallfunc(regs->a0, regs->a1, regs->a2, regs->a3, regs->a4, regs->a5, regs->a6);
    regs->a7 = 0;
    regs->epc += 4; // skip ecall instruction
    LOG_I("[0x%lx] %s ret: 0x%lx", rt_thread_self(), syscall_name, regs->a0);
}