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 * 2021-02-02 lizhirui first version 9 * 2021-02-11 lizhirui fixed gp save/store bug 10 * 2021-11-18 JasonHu add fpu registers save/restore 11 * 2022-10-22 Shell Support kernel mode RVV 12 */ 13 14 #ifndef __STACKFRAME_H__ 15 #define __STACKFRAME_H__ 16 17 #include <rtconfig.h> 18 #include "encoding.h" 19 20 /* bytes of register width */ 21 #ifdef ARCH_CPU_64BIT 22 #define STORE sd 23 #define LOAD ld 24 #define FSTORE fsd 25 #define FLOAD fld 26 #define REGBYTES 8 27 #else 28 // error here, not portable 29 #error "Not supported XLEN" 30 #endif 31 32 #include "ext_context.h" 33 34 /* 33 general register + 1 padding */ 35 #define CTX_GENERAL_REG_NR 34 36 37 /* all context registers */ 38 #define CTX_REG_NR (CTX_GENERAL_REG_NR + CTX_FPU_REG_NR + CTX_VECTOR_REG_NR) 39 40 #define BYTES(idx) ((idx) * REGBYTES) 41 #define FRAME_OFF_SSTATUS BYTES(2) 42 #define FRAME_OFF_SP BYTES(32) 43 #define FRAME_OFF_GP BYTES(3) 44 #define FRAME_OFF_TP BYTES(4) 45 46 /* switch frame */ 47 #define RT_HW_SWITCH_CONTEXT_SSTATUS 0 48 #define RT_HW_SWITCH_CONTEXT_S11 1 49 #define RT_HW_SWITCH_CONTEXT_S10 2 50 #define RT_HW_SWITCH_CONTEXT_S9 3 51 #define RT_HW_SWITCH_CONTEXT_S8 4 52 #define RT_HW_SWITCH_CONTEXT_S7 5 53 #define RT_HW_SWITCH_CONTEXT_S6 6 54 #define RT_HW_SWITCH_CONTEXT_S5 7 55 #define RT_HW_SWITCH_CONTEXT_S4 8 56 #define RT_HW_SWITCH_CONTEXT_S3 9 57 #define RT_HW_SWITCH_CONTEXT_S2 10 58 #define RT_HW_SWITCH_CONTEXT_S1 11 59 #define RT_HW_SWITCH_CONTEXT_S0 12 60 #define RT_HW_SWITCH_CONTEXT_RA 13 61 #define RT_HW_SWITCH_CONTEXT_TP 14 62 #define RT_HW_SWITCH_CONTEXT_ALIGNMENT 15 // Padding for alignment 63 #define RT_HW_SWITCH_CONTEXT_SIZE 16 // Total size of the structure 64 65 #ifdef __ASSEMBLY__ 66 67 .macro SAVE_ALL 68 69 #ifdef ARCH_RISCV_FPU 70 /* reserve float registers */ 71 addi sp, sp, -CTX_FPU_REG_NR * REGBYTES 72 #endif /* ARCH_RISCV_FPU */ 73 #ifdef ARCH_RISCV_VECTOR 74 /* reserve float registers */ 75 addi sp, sp, -CTX_VECTOR_REG_NR * REGBYTES 76 #endif /* ARCH_RISCV_VECTOR */ 77 78 /* save general registers */ 79 addi sp, sp, -CTX_GENERAL_REG_NR * REGBYTES 80 STORE x1, 1 * REGBYTES(sp) 81 82 csrr x1, sstatus 83 STORE x1, FRAME_OFF_SSTATUS(sp) 84 85 csrr x1, sepc 86 STORE x1, 0 * REGBYTES(sp) 87 88 STORE x3, 3 * REGBYTES(sp) 89 STORE x4, 4 * REGBYTES(sp) /* save tp */ 90 STORE x5, 5 * REGBYTES(sp) 91 STORE x6, 6 * REGBYTES(sp) 92 STORE x7, 7 * REGBYTES(sp) 93 STORE x8, 8 * REGBYTES(sp) 94 STORE x9, 9 * REGBYTES(sp) 95 STORE x10, 10 * REGBYTES(sp) 96 STORE x11, 11 * REGBYTES(sp) 97 STORE x12, 12 * REGBYTES(sp) 98 STORE x13, 13 * REGBYTES(sp) 99 STORE x14, 14 * REGBYTES(sp) 100 STORE x15, 15 * REGBYTES(sp) 101 STORE x16, 16 * REGBYTES(sp) 102 STORE x17, 17 * REGBYTES(sp) 103 STORE x18, 18 * REGBYTES(sp) 104 STORE x19, 19 * REGBYTES(sp) 105 STORE x20, 20 * REGBYTES(sp) 106 STORE x21, 21 * REGBYTES(sp) 107 STORE x22, 22 * REGBYTES(sp) 108 STORE x23, 23 * REGBYTES(sp) 109 STORE x24, 24 * REGBYTES(sp) 110 STORE x25, 25 * REGBYTES(sp) 111 STORE x26, 26 * REGBYTES(sp) 112 STORE x27, 27 * REGBYTES(sp) 113 STORE x28, 28 * REGBYTES(sp) 114 STORE x29, 29 * REGBYTES(sp) 115 STORE x30, 30 * REGBYTES(sp) 116 STORE x31, 31 * REGBYTES(sp) 117 csrr t0, sscratch 118 STORE t0, 32 * REGBYTES(sp) 119 120 #ifdef ARCH_RISCV_FPU 121 /* backup sp and adjust sp to save float registers */ 122 mv t1, sp 123 addi t1, t1, CTX_GENERAL_REG_NR * REGBYTES 124 125 li t0, SSTATUS_FS 126 csrs sstatus, t0 127 FSTORE f0, FPU_CTX_F0_OFF(t1) 128 FSTORE f1, FPU_CTX_F1_OFF(t1) 129 FSTORE f2, FPU_CTX_F2_OFF(t1) 130 FSTORE f3, FPU_CTX_F3_OFF(t1) 131 FSTORE f4, FPU_CTX_F4_OFF(t1) 132 FSTORE f5, FPU_CTX_F5_OFF(t1) 133 FSTORE f6, FPU_CTX_F6_OFF(t1) 134 FSTORE f7, FPU_CTX_F7_OFF(t1) 135 FSTORE f8, FPU_CTX_F8_OFF(t1) 136 FSTORE f9, FPU_CTX_F9_OFF(t1) 137 FSTORE f10, FPU_CTX_F10_OFF(t1) 138 FSTORE f11, FPU_CTX_F11_OFF(t1) 139 FSTORE f12, FPU_CTX_F12_OFF(t1) 140 FSTORE f13, FPU_CTX_F13_OFF(t1) 141 FSTORE f14, FPU_CTX_F14_OFF(t1) 142 FSTORE f15, FPU_CTX_F15_OFF(t1) 143 FSTORE f16, FPU_CTX_F16_OFF(t1) 144 FSTORE f17, FPU_CTX_F17_OFF(t1) 145 FSTORE f18, FPU_CTX_F18_OFF(t1) 146 FSTORE f19, FPU_CTX_F19_OFF(t1) 147 FSTORE f20, FPU_CTX_F20_OFF(t1) 148 FSTORE f21, FPU_CTX_F21_OFF(t1) 149 FSTORE f22, FPU_CTX_F22_OFF(t1) 150 FSTORE f23, FPU_CTX_F23_OFF(t1) 151 FSTORE f24, FPU_CTX_F24_OFF(t1) 152 FSTORE f25, FPU_CTX_F25_OFF(t1) 153 FSTORE f26, FPU_CTX_F26_OFF(t1) 154 FSTORE f27, FPU_CTX_F27_OFF(t1) 155 FSTORE f28, FPU_CTX_F28_OFF(t1) 156 FSTORE f29, FPU_CTX_F29_OFF(t1) 157 FSTORE f30, FPU_CTX_F30_OFF(t1) 158 FSTORE f31, FPU_CTX_F31_OFF(t1) 159 160 /* clr FS domain */ 161 csrc sstatus, t0 162 163 /* clean status would clr sr_sd; */ 164 li t0, SSTATUS_FS_CLEAN 165 csrs sstatus, t0 166 167 #endif /* ARCH_RISCV_FPU */ 168 169 #ifdef ARCH_RISCV_VECTOR 170 csrr t0, sstatus 171 andi t0, t0, SSTATUS_VS 172 beqz t0, 0f 173 174 /* push vector frame */ 175 addi t1, sp, (CTX_GENERAL_REG_NR + CTX_FPU_REG_NR) * REGBYTES 176 177 SAVE_VECTOR t1 178 0: 179 #endif /* ARCH_RISCV_VECTOR */ 180 .endm 181 182 /** 183 * @brief Restore All General Registers, for interrupt handling 184 * 185 */ 186 .macro RESTORE_ALL 187 188 #ifdef ARCH_RISCV_VECTOR 189 // skip on close 190 ld t0, 2 * REGBYTES(sp) 191 // cannot use vector on initial 192 andi t0, t0, SSTATUS_VS_CLEAN 193 beqz t0, 0f 194 195 /* push vector frame */ 196 addi t1, sp, (CTX_GENERAL_REG_NR + CTX_FPU_REG_NR) * REGBYTES 197 198 RESTORE_VECTOR t1 199 0: 200 #endif /* ARCH_RISCV_VECTOR */ 201 202 #ifdef ARCH_RISCV_FPU 203 /* restore float register */ 204 addi t2, sp, CTX_GENERAL_REG_NR * REGBYTES 205 206 li t0, SSTATUS_FS 207 csrs sstatus, t0 208 FLOAD f0, FPU_CTX_F0_OFF(t2) 209 FLOAD f1, FPU_CTX_F1_OFF(t2) 210 FLOAD f2, FPU_CTX_F2_OFF(t2) 211 FLOAD f3, FPU_CTX_F3_OFF(t2) 212 FLOAD f4, FPU_CTX_F4_OFF(t2) 213 FLOAD f5, FPU_CTX_F5_OFF(t2) 214 FLOAD f6, FPU_CTX_F6_OFF(t2) 215 FLOAD f7, FPU_CTX_F7_OFF(t2) 216 FLOAD f8, FPU_CTX_F8_OFF(t2) 217 FLOAD f9, FPU_CTX_F9_OFF(t2) 218 FLOAD f10, FPU_CTX_F10_OFF(t2) 219 FLOAD f11, FPU_CTX_F11_OFF(t2) 220 FLOAD f12, FPU_CTX_F12_OFF(t2) 221 FLOAD f13, FPU_CTX_F13_OFF(t2) 222 FLOAD f14, FPU_CTX_F14_OFF(t2) 223 FLOAD f15, FPU_CTX_F15_OFF(t2) 224 FLOAD f16, FPU_CTX_F16_OFF(t2) 225 FLOAD f17, FPU_CTX_F17_OFF(t2) 226 FLOAD f18, FPU_CTX_F18_OFF(t2) 227 FLOAD f19, FPU_CTX_F19_OFF(t2) 228 FLOAD f20, FPU_CTX_F20_OFF(t2) 229 FLOAD f21, FPU_CTX_F21_OFF(t2) 230 FLOAD f22, FPU_CTX_F22_OFF(t2) 231 FLOAD f23, FPU_CTX_F23_OFF(t2) 232 FLOAD f24, FPU_CTX_F24_OFF(t2) 233 FLOAD f25, FPU_CTX_F25_OFF(t2) 234 FLOAD f26, FPU_CTX_F26_OFF(t2) 235 FLOAD f27, FPU_CTX_F27_OFF(t2) 236 FLOAD f28, FPU_CTX_F28_OFF(t2) 237 FLOAD f29, FPU_CTX_F29_OFF(t2) 238 FLOAD f30, FPU_CTX_F30_OFF(t2) 239 FLOAD f31, FPU_CTX_F31_OFF(t2) 240 241 /* clr FS domain */ 242 csrc sstatus, t0 243 244 /* clean status would clr sr_sd; */ 245 li t0, SSTATUS_FS_CLEAN 246 csrs sstatus, t0 247 248 #endif /* ARCH_RISCV_FPU */ 249 250 /* restore general register */ 251 addi t0, sp, CTX_REG_NR * REGBYTES 252 csrw sscratch, t0 253 254 /* resw ra to sepc */ 255 LOAD x1, 0 * REGBYTES(sp) 256 csrw sepc, x1 257 258 LOAD x1, 2 * REGBYTES(sp) 259 csrw sstatus, x1 260 261 LOAD x1, 1 * REGBYTES(sp) 262 263 LOAD x3, 3 * REGBYTES(sp) 264 LOAD x4, 4 * REGBYTES(sp) /* restore tp */ 265 LOAD x5, 5 * REGBYTES(sp) 266 LOAD x6, 6 * REGBYTES(sp) 267 LOAD x7, 7 * REGBYTES(sp) 268 LOAD x8, 8 * REGBYTES(sp) 269 LOAD x9, 9 * REGBYTES(sp) 270 LOAD x10, 10 * REGBYTES(sp) 271 LOAD x11, 11 * REGBYTES(sp) 272 LOAD x12, 12 * REGBYTES(sp) 273 LOAD x13, 13 * REGBYTES(sp) 274 LOAD x14, 14 * REGBYTES(sp) 275 LOAD x15, 15 * REGBYTES(sp) 276 LOAD x16, 16 * REGBYTES(sp) 277 LOAD x17, 17 * REGBYTES(sp) 278 LOAD x18, 18 * REGBYTES(sp) 279 LOAD x19, 19 * REGBYTES(sp) 280 LOAD x20, 20 * REGBYTES(sp) 281 LOAD x21, 21 * REGBYTES(sp) 282 LOAD x22, 22 * REGBYTES(sp) 283 LOAD x23, 23 * REGBYTES(sp) 284 LOAD x24, 24 * REGBYTES(sp) 285 LOAD x25, 25 * REGBYTES(sp) 286 LOAD x26, 26 * REGBYTES(sp) 287 LOAD x27, 27 * REGBYTES(sp) 288 LOAD x28, 28 * REGBYTES(sp) 289 LOAD x29, 29 * REGBYTES(sp) 290 LOAD x30, 30 * REGBYTES(sp) 291 LOAD x31, 31 * REGBYTES(sp) 292 293 /* restore user sp */ 294 LOAD sp, 32 * REGBYTES(sp) 295 .endm 296 297 .macro RESTORE_SYS_GP 298 .option push 299 .option norelax 300 la gp, __global_pointer$ 301 .option pop 302 .endm 303 304 .macro OPEN_INTERRUPT 305 csrsi sstatus, 2 306 .endm 307 308 .macro CLOSE_INTERRUPT 309 csrci sstatus, 2 310 .endm 311 312 #endif /* __ASSEMBLY__ */ 313 314 #endif /* __STACKFRAME_H__ */ 315