1/* 2 * Copyright (c) 2006-2024, RT-Thread Development Team 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * Change Logs: 7 * Date Author Notes 8 * 2018/10/28 Bernard The unify RISC-V porting implementation 9 * 2018/12/27 Jesven Add SMP support 10 * 2021/02/02 lizhirui Add userspace support 11 * 2022/10/22 Shell Support User mode RVV; 12 * Trimming process switch context 13 */ 14 15#include "cpuport.h" 16#include "stackframe.h" 17#define _REG_IDX(name) RT_HW_SWITCH_CONTEXT_##name 18#define REG_IDX(name) _REG_IDX(name) 19 20.macro SAVE_REG reg, index 21 STORE \reg, \index*REGBYTES(sp) 22.endm 23 24.macro LOAD_REG reg, index 25 LOAD \reg, \index*REGBYTES(sp) 26.endm 27 28.macro RESERVE_CONTEXT 29 addi sp, sp, -(RT_HW_SWITCH_CONTEXT_SIZE * REGBYTES) 30 SAVE_REG tp, REG_IDX(TP) 31 SAVE_REG ra, REG_IDX(RA) 32 SAVE_REG s0, REG_IDX(S0) 33 SAVE_REG s1, REG_IDX(S1) 34 SAVE_REG s2, REG_IDX(S2) 35 SAVE_REG s3, REG_IDX(S3) 36 SAVE_REG s4, REG_IDX(S4) 37 SAVE_REG s5, REG_IDX(S5) 38 SAVE_REG s6, REG_IDX(S6) 39 SAVE_REG s7, REG_IDX(S7) 40 SAVE_REG s8, REG_IDX(S8) 41 SAVE_REG s9, REG_IDX(S9) 42 SAVE_REG s10, REG_IDX(S10) 43 SAVE_REG s11, REG_IDX(S11) 44 csrr s11, sstatus 45 li s10, (SSTATUS_SPP) 46 or s11, s11, s10 47 SAVE_REG s11, REG_IDX(SSTATUS) 48.endm 49 50.macro RESTORE_CONTEXT 51 LOAD_REG s11, REG_IDX(SSTATUS) 52 csrw sstatus, s11 53 LOAD_REG s11, REG_IDX(S11) 54 LOAD_REG s10, REG_IDX(S10) 55 LOAD_REG s9, REG_IDX(S9) 56 LOAD_REG s8, REG_IDX(S8) 57 LOAD_REG s7, REG_IDX(S7) 58 LOAD_REG s6, REG_IDX(S6) 59 LOAD_REG s5, REG_IDX(S5) 60 LOAD_REG s4, REG_IDX(S4) 61 LOAD_REG s3, REG_IDX(S3) 62 LOAD_REG s2, REG_IDX(S2) 63 LOAD_REG s1, REG_IDX(S1) 64 LOAD_REG s0, REG_IDX(S0) 65 LOAD_REG ra, REG_IDX(RA) 66 LOAD_REG tp, REG_IDX(TP) 67 addi sp, sp, RT_HW_SWITCH_CONTEXT_SIZE * REGBYTES 68 csrw sepc, ra 69.endm 70 71/* 72 * void rt_hw_context_switch_to(rt_ubase_t to); 73 * 74 * a0 --> to SP pointer 75 */ 76.globl rt_hw_context_switch_to 77rt_hw_context_switch_to: 78 LOAD sp, (a0) 79 80 call rt_thread_self 81 mv s1, a0 82 83 #ifdef RT_USING_SMART 84 call lwp_aspace_switch 85 #endif 86 87 RESTORE_CONTEXT 88 sret 89 90/* 91 * void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to); 92 * 93 * a0 --> from SP pointer 94 * a1 --> to SP pointer 95 * 96 * It should only be used on local interrupt disable 97 */ 98.globl rt_hw_context_switch 99rt_hw_context_switch: 100 RESERVE_CONTEXT 101 STORE sp, (a0) 102 103 // restore to thread SP 104 LOAD sp, (a1) 105 106 // restore Address Space 107 call rt_thread_self 108 mv s1, a0 109 110 #ifdef RT_USING_SMART 111 call lwp_aspace_switch 112 #endif 113 114 RESTORE_CONTEXT 115 sret 116