123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- /*
- * 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
- */
- #define __ASSEMBLY__
- #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
- //check syscall
- csrr t0, scause
- li t1, 8//environment call from u-mode
- beq t0, t1, syscall_entry
- 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:
- //swap to thread kernel stack
- csrr t0, sstatus
- andi t0, t0, 0x100
- beqz t0, __restore_sp_from_tcb_interrupt
- __restore_sp_from_sscratch_interrupt:
- csrr t0, sscratch
- j __move_stack_context_interrupt
- __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
- __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_USERSPACE
- mv a0, s1
- jal rt_thread_sp_to_thread
- jal lwp_mmu_switch
- #endif
- spurious_interrupt:
- LOAD t0, 2 * REGBYTES(sp)
- andi t0, t0, 0x100
- beqz t0, ret_to_user
- RESTORE_ALL
- sret
- syscall_entry:
- //swap to thread kernel stack
- csrr t0, sstatus
- andi t0, t0, 0x100
- beqz t0, __restore_sp_from_tcb
- __restore_sp_from_sscratch:
- csrr t0, sscratch
- j __move_stack_context
- __restore_sp_from_tcb:
- la a0, rt_current_thread
- LOAD a0, 0(a0)
- jal get_thread_kernel_stack_top
- mv t0, a0
- __move_stack_context:
- 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:
- 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
- LOAD s0, 7 * REGBYTES(sp)
- addi s0, s0, -0xfe
- beqz s0, lwp_signal_quit
- #ifdef RT_USING_USERSPACE
- /* save setting when syscall enter */
- call rt_thread_self
- call lwp_user_setting_save
- #endif
- mv a0, sp
- OPEN_INTERRUPT
- call syscall_handler
- CLOSE_INTERRUPT
- .global syscall_exit
- syscall_exit:
- #if defined(RT_USING_USERSPACE)
- LOAD s0, 2 * REGBYTES(sp)
- andi s0, s0, 0x100
- bnez s0, dont_ret_to_user
- li s0, 0
- j ret_to_user
- dont_ret_to_user:
- #endif
- #ifdef RT_USING_USERSPACE
- /* restore setting when syscall exit */
- call rt_thread_self
- call lwp_user_setting_restore
- /* after restore the reg `tp`, need modify context */
- STORE tp, 4 * REGBYTES(sp)
- #endif
- //restore context
- RESTORE_ALL
- sret
- .global rt_hw_interrupt_enable
- rt_hw_interrupt_enable:
- fence.i
- csrs sstatus, a0 /* restore to old csr */
- jr ra
- .global rt_hw_interrupt_disable
- rt_hw_interrupt_disable:
- csrrci a0, sstatus, 2 /* clear SIE */
- fence.i
- jr ra
|