1/* 2 * Copyright (c) 2006-2023, RT-Thread Development Team 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * Change Logs: 7 * Date Author Notes 8 * 2023/01/17 WangShun The first version 9 * 2023/03/19 Flyingcys Add riscv_32e support 10 * 2023/08/09 HPMicro Fix the issue t0 was modified unexpectedly before being saved 11 */ 12#define __ASSEMBLY__ 13#include "cpuport.h" 14 15 .section .text.entry, "ax" 16#if defined(SOC_SERIES_GD32VF103V) 17 .align 6 18#else 19 .align 2 20#endif 21 .global SW_handler 22 23SW_handler: 24 csrci mstatus, 0x8 25#ifdef ARCH_RISCV_FPU 26 addi sp, sp, -32 * FREGBYTES 27 FSTORE f0, 0 * FREGBYTES(sp) 28 FSTORE f1, 1 * FREGBYTES(sp) 29 FSTORE f2, 2 * FREGBYTES(sp) 30 FSTORE f3, 3 * FREGBYTES(sp) 31 FSTORE f4, 4 * FREGBYTES(sp) 32 FSTORE f5, 5 * FREGBYTES(sp) 33 FSTORE f6, 6 * FREGBYTES(sp) 34 FSTORE f7, 7 * FREGBYTES(sp) 35 FSTORE f8, 8 * FREGBYTES(sp) 36 FSTORE f9, 9 * FREGBYTES(sp) 37 FSTORE f10, 10 * FREGBYTES(sp) 38 FSTORE f11, 11 * FREGBYTES(sp) 39 FSTORE f12, 12 * FREGBYTES(sp) 40 FSTORE f13, 13 * FREGBYTES(sp) 41 FSTORE f14, 14 * FREGBYTES(sp) 42 FSTORE f15, 15 * FREGBYTES(sp) 43 FSTORE f16, 16 * FREGBYTES(sp) 44 FSTORE f17, 17 * FREGBYTES(sp) 45 FSTORE f18, 18 * FREGBYTES(sp) 46 FSTORE f19, 19 * FREGBYTES(sp) 47 FSTORE f20, 20 * FREGBYTES(sp) 48 FSTORE f21, 21 * FREGBYTES(sp) 49 FSTORE f22, 22 * FREGBYTES(sp) 50 FSTORE f23, 23 * FREGBYTES(sp) 51 FSTORE f24, 24 * FREGBYTES(sp) 52 FSTORE f25, 25 * FREGBYTES(sp) 53 FSTORE f26, 26 * FREGBYTES(sp) 54 FSTORE f27, 27 * FREGBYTES(sp) 55 FSTORE f28, 28 * FREGBYTES(sp) 56 FSTORE f29, 29 * FREGBYTES(sp) 57 FSTORE f30, 30 * FREGBYTES(sp) 58 FSTORE f31, 31 * FREGBYTES(sp) 59#endif 60 /* save all from thread context */ 61#ifndef __riscv_32e 62 addi sp, sp, -32 * REGBYTES 63#else 64 addi sp, sp, -16 * REGBYTES 65#endif 66 STORE x5, 5 * REGBYTES(sp) 67 STORE x1, 1 * REGBYTES(sp) 68 /* Mandatory set the MPIE of mstatus */ 69 li t0, 0x80 70 STORE t0, 2 * REGBYTES(sp) 71 STORE x4, 4 * REGBYTES(sp) 72 STORE x6, 6 * REGBYTES(sp) 73 STORE x7, 7 * REGBYTES(sp) 74 STORE x8, 8 * REGBYTES(sp) 75 STORE x9, 9 * REGBYTES(sp) 76 STORE x10, 10 * REGBYTES(sp) 77 STORE x11, 11 * REGBYTES(sp) 78 STORE x12, 12 * REGBYTES(sp) 79 STORE x13, 13 * REGBYTES(sp) 80 STORE x14, 14 * REGBYTES(sp) 81 STORE x15, 15 * REGBYTES(sp) 82#ifndef __riscv_32e 83 STORE x16, 16 * REGBYTES(sp) 84 STORE x17, 17 * REGBYTES(sp) 85 STORE x18, 18 * REGBYTES(sp) 86 STORE x19, 19 * REGBYTES(sp) 87 STORE x20, 20 * REGBYTES(sp) 88 STORE x21, 21 * REGBYTES(sp) 89 STORE x22, 22 * REGBYTES(sp) 90 STORE x23, 23 * REGBYTES(sp) 91 STORE x24, 24 * REGBYTES(sp) 92 STORE x25, 25 * REGBYTES(sp) 93 STORE x26, 26 * REGBYTES(sp) 94 STORE x27, 27 * REGBYTES(sp) 95 STORE x28, 28 * REGBYTES(sp) 96 STORE x29, 29 * REGBYTES(sp) 97 STORE x30, 30 * REGBYTES(sp) 98 STORE x31, 31 * REGBYTES(sp) 99#endif 100 /* switch to interrupt stack */ 101 csrrw sp,mscratch,sp 102 /* interrupt handle */ 103 call rt_interrupt_enter 104 /* Do the work after saving the above */ 105 jal rt_hw_do_after_save_above 106 107 call rt_interrupt_leave 108 /* switch to from thread stack */ 109 csrrw sp,mscratch,sp 110 111 /* Determine whether to trigger scheduling at the interrupt function */ 112 la t0, rt_thread_switch_interrupt_flag 113 lw t2, 0(t0) 114 beqz t2, 1f 115 /* clear the flag of rt_thread_switch_interrupt_flag */ 116 sw zero, 0(t0) 117 118 csrr a0, mepc 119 STORE a0, 0 * REGBYTES(sp) 120 121 la t0, rt_interrupt_from_thread 122 LOAD t1, 0(t0) 123 STORE sp, 0(t1) 124 125 la t0, rt_interrupt_to_thread 126 LOAD t1, 0(t0) 127 LOAD sp, 0(t1) 128 129 LOAD a0, 0 * REGBYTES(sp) 130 csrw mepc, a0 131 1321: 133 LOAD x1, 1 * REGBYTES(sp) 134 135 /* Set the mode after MRET */ 136 li t0, 0x1800 137 csrs mstatus, t0 138 LOAD t0, 2 * REGBYTES(sp) 139 csrs mstatus, t0 140 141 LOAD x4, 4 * REGBYTES(sp) 142 LOAD x5, 5 * REGBYTES(sp) 143 LOAD x6, 6 * REGBYTES(sp) 144 LOAD x7, 7 * REGBYTES(sp) 145 LOAD x8, 8 * REGBYTES(sp) 146 LOAD x9, 9 * REGBYTES(sp) 147 LOAD x10, 10 * REGBYTES(sp) 148 LOAD x11, 11 * REGBYTES(sp) 149 LOAD x12, 12 * REGBYTES(sp) 150 LOAD x13, 13 * REGBYTES(sp) 151 LOAD x14, 14 * REGBYTES(sp) 152 LOAD x15, 15 * REGBYTES(sp) 153#ifndef __riscv_32e 154 LOAD x16, 16 * REGBYTES(sp) 155 LOAD x17, 17 * REGBYTES(sp) 156 LOAD x18, 18 * REGBYTES(sp) 157 LOAD x19, 19 * REGBYTES(sp) 158 LOAD x20, 20 * REGBYTES(sp) 159 LOAD x21, 21 * REGBYTES(sp) 160 LOAD x22, 22 * REGBYTES(sp) 161 LOAD x23, 23 * REGBYTES(sp) 162 LOAD x24, 24 * REGBYTES(sp) 163 LOAD x25, 25 * REGBYTES(sp) 164 LOAD x26, 26 * REGBYTES(sp) 165 LOAD x27, 27 * REGBYTES(sp) 166 LOAD x28, 28 * REGBYTES(sp) 167 LOAD x29, 29 * REGBYTES(sp) 168 LOAD x30, 30 * REGBYTES(sp) 169 LOAD x31, 31 * REGBYTES(sp) 170 171 addi sp, sp, 32 * REGBYTES 172#else 173 addi sp, sp, 16 * REGBYTES 174#endif 175 176#ifdef ARCH_RISCV_FPU 177 FLOAD f0, 0 * FREGBYTES(sp) 178 FLOAD f1, 1 * FREGBYTES(sp) 179 FLOAD f2, 2 * FREGBYTES(sp) 180 FLOAD f3, 3 * FREGBYTES(sp) 181 FLOAD f4, 4 * FREGBYTES(sp) 182 FLOAD f5, 5 * FREGBYTES(sp) 183 FLOAD f6, 6 * FREGBYTES(sp) 184 FLOAD f7, 7 * FREGBYTES(sp) 185 FLOAD f8, 8 * FREGBYTES(sp) 186 FLOAD f9, 9 * FREGBYTES(sp) 187 FLOAD f10, 10 * FREGBYTES(sp) 188 FLOAD f11, 11 * FREGBYTES(sp) 189 FLOAD f12, 12 * FREGBYTES(sp) 190 FLOAD f13, 13 * FREGBYTES(sp) 191 FLOAD f14, 14 * FREGBYTES(sp) 192 FLOAD f15, 15 * FREGBYTES(sp) 193 FLOAD f16, 16 * FREGBYTES(sp) 194 FLOAD f17, 17 * FREGBYTES(sp) 195 FLOAD f18, 18 * FREGBYTES(sp) 196 FLOAD f19, 19 * FREGBYTES(sp) 197 FLOAD f20, 20 * FREGBYTES(sp) 198 FLOAD f21, 21 * FREGBYTES(sp) 199 FLOAD f22, 22 * FREGBYTES(sp) 200 FLOAD f23, 23 * FREGBYTES(sp) 201 FLOAD f24, 24 * FREGBYTES(sp) 202 FLOAD f25, 25 * FREGBYTES(sp) 203 FLOAD f26, 26 * FREGBYTES(sp) 204 FLOAD f27, 27 * FREGBYTES(sp) 205 FLOAD f28, 28 * FREGBYTES(sp) 206 FLOAD f29, 29 * FREGBYTES(sp) 207 FLOAD f30, 30 * FREGBYTES(sp) 208 FLOAD f31, 31 * FREGBYTES(sp) 209 210 addi sp, sp, 32 * FREGBYTES 211#endif 212 mret 213 214 215 .section .text.trap_entry 216 .align 2 217 .weak trap_entry 218 .global trap_entry 219trap_entry: 220#ifdef ARCH_RISCV_FPU 221 addi sp, sp, -32 * FREGBYTES 222 223 FSTORE f0, 0 * FREGBYTES(sp) 224 FSTORE f1, 1 * FREGBYTES(sp) 225 FSTORE f2, 2 * FREGBYTES(sp) 226 FSTORE f3, 3 * FREGBYTES(sp) 227 FSTORE f4, 4 * FREGBYTES(sp) 228 FSTORE f5, 5 * FREGBYTES(sp) 229 FSTORE f6, 6 * FREGBYTES(sp) 230 FSTORE f7, 7 * FREGBYTES(sp) 231 FSTORE f8, 8 * FREGBYTES(sp) 232 FSTORE f9, 9 * FREGBYTES(sp) 233 FSTORE f10, 10 * FREGBYTES(sp) 234 FSTORE f11, 11 * FREGBYTES(sp) 235 FSTORE f12, 12 * FREGBYTES(sp) 236 FSTORE f13, 13 * FREGBYTES(sp) 237 FSTORE f14, 14 * FREGBYTES(sp) 238 FSTORE f15, 15 * FREGBYTES(sp) 239 FSTORE f16, 16 * FREGBYTES(sp) 240 FSTORE f17, 17 * FREGBYTES(sp) 241 FSTORE f18, 18 * FREGBYTES(sp) 242 FSTORE f19, 19 * FREGBYTES(sp) 243 FSTORE f20, 20 * FREGBYTES(sp) 244 FSTORE f21, 21 * FREGBYTES(sp) 245 FSTORE f22, 22 * FREGBYTES(sp) 246 FSTORE f23, 23 * FREGBYTES(sp) 247 FSTORE f24, 24 * FREGBYTES(sp) 248 FSTORE f25, 25 * FREGBYTES(sp) 249 FSTORE f26, 26 * FREGBYTES(sp) 250 FSTORE f27, 27 * FREGBYTES(sp) 251 FSTORE f28, 28 * FREGBYTES(sp) 252 FSTORE f29, 29 * FREGBYTES(sp) 253 FSTORE f30, 30 * FREGBYTES(sp) 254 FSTORE f31, 31 * FREGBYTES(sp) 255 256#endif 257 258 /* save thread context to thread stack */ 259#ifndef __riscv_32e 260 addi sp, sp, -32 * REGBYTES 261#else 262 addi sp, sp, -16 * REGBYTES 263#endif 264 STORE x1, 1 * REGBYTES(sp) 265 266 csrr x1, mstatus 267 STORE x1, 2 * REGBYTES(sp) 268 269 csrr x1, mepc 270 STORE x1, 0 * REGBYTES(sp) 271 272 STORE x4, 4 * REGBYTES(sp) 273 STORE x5, 5 * REGBYTES(sp) 274 STORE x6, 6 * REGBYTES(sp) 275 STORE x7, 7 * REGBYTES(sp) 276 STORE x8, 8 * REGBYTES(sp) 277 STORE x9, 9 * REGBYTES(sp) 278 STORE x10, 10 * REGBYTES(sp) 279 STORE x11, 11 * REGBYTES(sp) 280 STORE x12, 12 * REGBYTES(sp) 281 STORE x13, 13 * REGBYTES(sp) 282 STORE x14, 14 * REGBYTES(sp) 283 STORE x15, 15 * REGBYTES(sp) 284#ifndef __riscv_32e 285 STORE x16, 16 * REGBYTES(sp) 286 STORE x17, 17 * REGBYTES(sp) 287 STORE x18, 18 * REGBYTES(sp) 288 STORE x19, 19 * REGBYTES(sp) 289 STORE x20, 20 * REGBYTES(sp) 290 STORE x21, 21 * REGBYTES(sp) 291 STORE x22, 22 * REGBYTES(sp) 292 STORE x23, 23 * REGBYTES(sp) 293 STORE x24, 24 * REGBYTES(sp) 294 STORE x25, 25 * REGBYTES(sp) 295 STORE x26, 26 * REGBYTES(sp) 296 STORE x27, 27 * REGBYTES(sp) 297 STORE x28, 28 * REGBYTES(sp) 298 STORE x29, 29 * REGBYTES(sp) 299 STORE x30, 30 * REGBYTES(sp) 300 STORE x31, 31 * REGBYTES(sp) 301#endif 302 303 /* switch to interrupt stack */ 304 move s0, sp 305 306#ifdef RT_USING_SMP 307 /* get cpu id */ 308 csrr t0, mhartid 309 310 /* switch interrupt stack of current cpu */ 311 la sp, __stack_start__ 312 addi t1, t0, 1 313 li t2, __STACKSIZE__ 314 mul t1, t1, t2 315 add sp, sp, t1 /* sp = (cpuid + 1) * __STACKSIZE__ + __stack_start__ */ 316#endif 317 318 /* handle interrupt */ 319 call rt_interrupt_enter 320 csrr a0, mcause 321 csrr a1, mepc 322 mv a2, s0 323 call handle_trap 324 call rt_interrupt_leave 325 326#ifdef RT_USING_SMP 327 /* s0 --> sp */ 328 mv sp, s0 329 mv a0, s0 330 call rt_scheduler_do_irq_switch 331 tail rt_hw_context_switch_exit 332 333#else 334 335 /* switch to from_thread stack */ 336 move sp, s0 337 338 /* need to switch new thread */ 339 la s0, rt_thread_switch_interrupt_flag 340 lw s1, 0(s0) 341 beqz s1, spurious_interrupt 342 sw zero, 0(s0) 343 344 la s0, rt_interrupt_from_thread 345 LOAD s1, 0(s0) 346 STORE sp, 0(s1) 347 348 la s0, rt_interrupt_to_thread 349 LOAD s1, 0(s0) 350 LOAD sp, 0(s1) 351 352#endif 353 354spurious_interrupt: 355 tail rt_hw_context_switch_exit 356