You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
119 lines
2.5 KiB
119 lines
2.5 KiB
/*
|
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Change Logs:
|
|
* Date Author Notes
|
|
* 2018/10/02 Bernard The first version
|
|
* 2018/12/27 Jesven Add SMP schedule
|
|
* 2021/02/02 lizhirui Add userspace support
|
|
* 2021/12/24 JasonHu Add user setting save/restore
|
|
*/
|
|
|
|
#include "cpuport.h"
|
|
#include "encoding.h"
|
|
#include "stackframe.h"
|
|
|
|
.section .text.entry
|
|
.align 2
|
|
.global trap_entry
|
|
.extern __stack_cpu0
|
|
.extern get_current_thread_kernel_stack_top
|
|
trap_entry:
|
|
//backup sp
|
|
csrrw sp, sscratch, sp
|
|
//load interrupt stack
|
|
la sp, __stack_cpu0
|
|
//backup context
|
|
SAVE_ALL
|
|
|
|
RESTORE_SYS_GP
|
|
|
|
#ifdef RT_USING_SMART
|
|
//check syscall
|
|
csrr t0, scause
|
|
li t1, 8//environment call from u-mode
|
|
beq t0, t1, syscall_entry
|
|
#endif
|
|
|
|
csrr a0, scause
|
|
csrrc a1, stval, zero
|
|
csrr a2, sepc
|
|
mv a3, sp
|
|
|
|
/* scause, stval, sepc, sp */
|
|
call handle_trap
|
|
|
|
/* need to switch new thread */
|
|
la s0, rt_thread_switch_interrupt_flag
|
|
lw s2, 0(s0)
|
|
beqz s2, spurious_interrupt
|
|
sw zero, 0(s0)
|
|
|
|
.global rt_hw_context_switch_interrupt_do
|
|
rt_hw_context_switch_interrupt_do:
|
|
|
|
#ifdef RT_USING_SMART
|
|
//swap to thread kernel stack
|
|
csrr t0, sstatus
|
|
andi t0, t0, 0x100
|
|
beqz t0, __restore_sp_from_tcb_interrupt
|
|
#endif
|
|
|
|
__restore_sp_from_sscratch_interrupt:
|
|
csrr t0, sscratch
|
|
j __move_stack_context_interrupt
|
|
|
|
#ifdef RT_USING_SMART
|
|
__restore_sp_from_tcb_interrupt:
|
|
la s0, rt_interrupt_from_thread
|
|
LOAD a0, 0(s0)
|
|
jal rt_thread_sp_to_thread
|
|
jal get_thread_kernel_stack_top
|
|
mv t0, a0
|
|
#endif
|
|
|
|
__move_stack_context_interrupt:
|
|
mv t1, sp//src
|
|
mv sp, t0//switch stack
|
|
addi sp, sp, -CTX_REG_NR * REGBYTES
|
|
//copy context
|
|
li s0, CTX_REG_NR//cnt
|
|
mv t2, sp//dst
|
|
|
|
copy_context_loop_interrupt:
|
|
LOAD t0, 0(t1)
|
|
STORE t0, 0(t2)
|
|
addi s0, s0, -1
|
|
addi t1, t1, 8
|
|
addi t2, t2, 8
|
|
bnez s0, copy_context_loop_interrupt
|
|
|
|
la s0, rt_interrupt_from_thread
|
|
LOAD s1, 0(s0)
|
|
STORE sp, 0(s1)
|
|
|
|
la s0, rt_interrupt_to_thread
|
|
LOAD s1, 0(s0)
|
|
LOAD sp, 0(s1)
|
|
|
|
#ifdef RT_USING_SMART
|
|
mv a0, s1
|
|
jal rt_thread_sp_to_thread
|
|
jal lwp_aspace_switch
|
|
#endif
|
|
|
|
spurious_interrupt:
|
|
RESTORE_ALL
|
|
sret
|
|
|
|
.global rt_hw_interrupt_enable
|
|
rt_hw_interrupt_enable:
|
|
csrs sstatus, a0 /* restore to old csr */
|
|
jr ra
|
|
|
|
.global rt_hw_interrupt_disable
|
|
rt_hw_interrupt_disable:
|
|
csrrci a0, sstatus, 2 /* clear SIE */
|
|
jr ra
|
|
|