123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- /*
- * Copyright (c) 2006-2024, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2018/10/28 Bernard The unify RISC-V porting implementation
- * 2018/12/27 Jesven Add SMP support
- * 2021/02/02 lizhirui Add userspace support
- * 2022/10/22 Shell Support User mode RVV;
- * Trimming process switch context
- */
- #include "cpuport.h"
- #include "stackframe.h"
- #define _REG_IDX(name) RT_HW_SWITCH_CONTEXT_##name
- #define REG_IDX(name) _REG_IDX(name)
- .macro SAVE_REG reg, index
- STORE \reg, \index*REGBYTES(sp)
- .endm
- .macro LOAD_REG reg, index
- LOAD \reg, \index*REGBYTES(sp)
- .endm
- .macro RESERVE_CONTEXT
- addi sp, sp, -(RT_HW_SWITCH_CONTEXT_SIZE * REGBYTES)
- SAVE_REG tp, REG_IDX(TP)
- SAVE_REG ra, REG_IDX(RA)
- SAVE_REG s0, REG_IDX(S0)
- SAVE_REG s1, REG_IDX(S1)
- SAVE_REG s2, REG_IDX(S2)
- SAVE_REG s3, REG_IDX(S3)
- SAVE_REG s4, REG_IDX(S4)
- SAVE_REG s5, REG_IDX(S5)
- SAVE_REG s6, REG_IDX(S6)
- SAVE_REG s7, REG_IDX(S7)
- SAVE_REG s8, REG_IDX(S8)
- SAVE_REG s9, REG_IDX(S9)
- SAVE_REG s10, REG_IDX(S10)
- SAVE_REG s11, REG_IDX(S11)
- csrr s11, sstatus
- li s10, (SSTATUS_SPP)
- or s11, s11, s10
- SAVE_REG s11, REG_IDX(SSTATUS)
- .endm
- .macro RESTORE_CONTEXT
- LOAD_REG s11, REG_IDX(SSTATUS)
- csrw sstatus, s11
- LOAD_REG s11, REG_IDX(S11)
- LOAD_REG s10, REG_IDX(S10)
- LOAD_REG s9, REG_IDX(S9)
- LOAD_REG s8, REG_IDX(S8)
- LOAD_REG s7, REG_IDX(S7)
- LOAD_REG s6, REG_IDX(S6)
- LOAD_REG s5, REG_IDX(S5)
- LOAD_REG s4, REG_IDX(S4)
- LOAD_REG s3, REG_IDX(S3)
- LOAD_REG s2, REG_IDX(S2)
- LOAD_REG s1, REG_IDX(S1)
- LOAD_REG s0, REG_IDX(S0)
- LOAD_REG ra, REG_IDX(RA)
- LOAD_REG tp, REG_IDX(TP)
- addi sp, sp, RT_HW_SWITCH_CONTEXT_SIZE * REGBYTES
- csrw sepc, ra
- .endm
- /*
- * void rt_hw_context_switch_to(rt_ubase_t to);
- *
- * a0 --> to SP pointer
- */
- .globl rt_hw_context_switch_to
- rt_hw_context_switch_to:
- LOAD sp, (a0)
- call rt_thread_self
- mv s1, a0
- #ifdef RT_USING_SMART
- call lwp_aspace_switch
- #endif
- RESTORE_CONTEXT
- sret
- /*
- * void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to);
- *
- * a0 --> from SP pointer
- * a1 --> to SP pointer
- *
- * It should only be used on local interrupt disable
- */
- .globl rt_hw_context_switch
- rt_hw_context_switch:
- RESERVE_CONTEXT
- STORE sp, (a0)
- // restore to thread SP
- LOAD sp, (a1)
- // restore Address Space
- call rt_thread_self
- mv s1, a0
- #ifdef RT_USING_SMART
- call lwp_aspace_switch
- #endif
- RESTORE_CONTEXT
- sret
|