1/* 2 * Copyright (c) 2006-2018, RT-Thread Development Team 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * Change Logs: 7 * Date Author Notes 8 * 2018/10/02 Bernard The first version 9 * 2018/12/27 Jesven Add SMP schedule 10 */ 11 12#include "cpuport.h" 13 14 .section .text.entry 15 .align 2 16 .global trap_entry 17trap_entry: 18 19 /* save thread context to thread stack */ 20 addi sp, sp, -32 * REGBYTES 21 22 STORE x1, 1 * REGBYTES(sp) 23 li t0, 0x80 24 STORE t0, 2 * REGBYTES(sp) 25 26 STORE x4, 4 * REGBYTES(sp) 27 STORE x5, 5 * REGBYTES(sp) 28 STORE x6, 6 * REGBYTES(sp) 29 STORE x7, 7 * REGBYTES(sp) 30 STORE x8, 8 * REGBYTES(sp) 31 STORE x9, 9 * REGBYTES(sp) 32 STORE x10, 10 * REGBYTES(sp) 33 STORE x11, 11 * REGBYTES(sp) 34 STORE x12, 12 * REGBYTES(sp) 35 STORE x13, 13 * REGBYTES(sp) 36 STORE x14, 14 * REGBYTES(sp) 37 STORE x15, 15 * REGBYTES(sp) 38 STORE x16, 16 * REGBYTES(sp) 39 STORE x17, 17 * REGBYTES(sp) 40 STORE x18, 18 * REGBYTES(sp) 41 STORE x19, 19 * REGBYTES(sp) 42 STORE x20, 20 * REGBYTES(sp) 43 STORE x21, 21 * REGBYTES(sp) 44 STORE x22, 22 * REGBYTES(sp) 45 STORE x23, 23 * REGBYTES(sp) 46 STORE x24, 24 * REGBYTES(sp) 47 STORE x25, 25 * REGBYTES(sp) 48 STORE x26, 26 * REGBYTES(sp) 49 STORE x27, 27 * REGBYTES(sp) 50 STORE x28, 28 * REGBYTES(sp) 51 STORE x29, 29 * REGBYTES(sp) 52 STORE x30, 30 * REGBYTES(sp) 53 STORE x31, 31 * REGBYTES(sp) 54 55 /* switch to interrupt stack */ 56 move s0, sp 57 58 /* get cpu id */ 59 csrr t0, mhartid 60 61 /* switch interrupt stack of current cpu */ 62 la sp, __stack_start__ 63 addi t1, t0, 1 64 li t2, __STACKSIZE__ 65 mul t1, t1, t2 66 add sp, sp, t1 /* sp = (cpuid + 1) * __STACKSIZE__ + __stack_start__ */ 67 68 /* handle interrupt */ 69 call rt_interrupt_enter 70 csrr a0, mcause 71 csrr a1, mepc 72 mv a2, sp 73 call handle_trap 74 call rt_interrupt_leave 75 76#ifdef RT_USING_SMP 77 /* s0 --> sp */ 78 mv a0, s0 79 call rt_scheduler_do_irq_switch 80 mv sp, s0 81#else 82 83 /* switch to from_thread stack */ 84 move sp, s0 85 86 /* need to switch new thread */ 87 la s0, rt_thread_switch_interrupt_flag 88 lw s2, 0(s0) 89 beqz s2, spurious_interrupt 90 sw zero, 0(s0) 91 92 csrr a0, mepc 93 STORE a0, 0 * REGBYTES(sp) 94 95 la s0, rt_interrupt_from_thread 96 LOAD s1, 0(s0) 97 STORE sp, 0(s1) 98 99 la s0, rt_interrupt_to_thread 100 LOAD s1, 0(s0) 101 LOAD sp, 0(s1) 102 103 LOAD a0, 0 * REGBYTES(sp) 104 csrw mepc, a0 105#endif 106 107spurious_interrupt: 108 LOAD x1, 1 * REGBYTES(sp) 109 110 /* Remain in M-mode after mret */ 111 li t0, 0x00001800 112 csrs mstatus, t0 113 LOAD t0, 2 * REGBYTES(sp) 114 csrs mstatus, t0 115 116 LOAD x4, 4 * REGBYTES(sp) 117 LOAD x5, 5 * REGBYTES(sp) 118 LOAD x6, 6 * REGBYTES(sp) 119 LOAD x7, 7 * REGBYTES(sp) 120 LOAD x8, 8 * REGBYTES(sp) 121 LOAD x9, 9 * REGBYTES(sp) 122 LOAD x10, 10 * REGBYTES(sp) 123 LOAD x11, 11 * REGBYTES(sp) 124 LOAD x12, 12 * REGBYTES(sp) 125 LOAD x13, 13 * REGBYTES(sp) 126 LOAD x14, 14 * REGBYTES(sp) 127 LOAD x15, 15 * REGBYTES(sp) 128 LOAD x16, 16 * REGBYTES(sp) 129 LOAD x17, 17 * REGBYTES(sp) 130 LOAD x18, 18 * REGBYTES(sp) 131 LOAD x19, 19 * REGBYTES(sp) 132 LOAD x20, 20 * REGBYTES(sp) 133 LOAD x21, 21 * REGBYTES(sp) 134 LOAD x22, 22 * REGBYTES(sp) 135 LOAD x23, 23 * REGBYTES(sp) 136 LOAD x24, 24 * REGBYTES(sp) 137 LOAD x25, 25 * REGBYTES(sp) 138 LOAD x26, 26 * REGBYTES(sp) 139 LOAD x27, 27 * REGBYTES(sp) 140 LOAD x28, 28 * REGBYTES(sp) 141 LOAD x29, 29 * REGBYTES(sp) 142 LOAD x30, 30 * REGBYTES(sp) 143 LOAD x31, 31 * REGBYTES(sp) 144 145 addi sp, sp, 32 * REGBYTES 146 mret 147