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 * 2018/10/02     Bernard      The first version
9 * 2018/12/27     Jesven       Add SMP schedule
10 * 2021/02/02     lizhirui     Add userspace support
11 * 2021/12/24     JasonHu      Add user setting save/restore
12 * 2022/10/22     Shell        Support kernel mode RVV;
13 *                             Rewrite trap handling routine
14 */
15
16#include "cpuport.h"
17#include "encoding.h"
18#include "stackframe.h"
19
20    .align 2
21    .global trap_entry
22    .global debug_check_sp
23trap_entry:
24    // distingush exception from kernel or user
25    csrrw   sp, sscratch, sp
26    bnez    sp, _save_context
27
28    // BE REALLY careful with sscratch,
29    // if it's wrong, we could looping here forever
30    // or accessing random memory and seeing things totally
31    // messy after a long time and don't even know why
32_from_kernel:
33    csrr    sp, sscratch
34    j _save_context
35
36_save_context:
37    SAVE_ALL
38    // clear sscratch to say 'now in kernel mode'
39    csrw    sscratch, zero
40
41    RESTORE_SYS_GP
42
43    // now we are ready to enter interrupt / excepiton handler
44_distinguish_syscall:
45    csrr    t0, scause
46#ifdef RT_USING_SMART
47    // TODO swap 8 with config macro name
48    li      t1, 8
49    bne     t0, t1, _handle_interrupt_and_exception
50    call syscall_entry
51    // syscall never return here
52#endif
53
54_handle_interrupt_and_exception:
55    mv      a0, t0
56    csrrc   a1, stval, zero
57    csrr    a2, sepc
58    // sp as exception frame pointer
59    mv      a3, sp
60    call    handle_trap
61
62_interrupt_exit:
63    la      s0, rt_thread_switch_interrupt_flag
64    lw      s2, 0(s0)
65    beqz    s2, _resume_execution
66    sw      zero, 0(s0)
67
68_context_switch:
69    la      t0, rt_interrupt_from_thread
70    LOAD    a0, 0(t0)
71    la      t0, rt_interrupt_to_thread
72    LOAD    a1, 0(t0)
73    csrr    t0, sstatus
74    andi    t0, t0, ~SSTATUS_SPIE
75    csrw    sstatus, t0
76    jal     rt_hw_context_switch
77
78_resume_execution:
79#ifdef RT_USING_SMART
80    LOAD    t0, FRAME_OFF_SSTATUS(sp)
81    andi    t0, t0, SSTATUS_SPP
82    bnez    t0, _resume_kernel
83    call arch_ret_to_user
84#endif
85
86_resume_kernel:
87    RESTORE_ALL
88    csrw    sscratch, zero
89    sret
90
91.global rt_hw_interrupt_enable
92rt_hw_interrupt_enable:
93    csrs sstatus, a0    /* restore to old csr */
94    jr ra
95
96.global rt_hw_interrupt_disable
97rt_hw_interrupt_disable:
98    csrrci a0, sstatus, 2   /* clear SIE */
99    jr ra
100