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