1/*
2 * Copyright (C) 2017-2019 Alibaba Group Holding Limited
3 */
4 /******************************************************************************
5 * @file     vectors.S
6 * @brief    define default vector handlers. Should use with
7 *           GCC for CSKY Embedded Processors
8 * @version  V1.0
9 * @date     28. Nove 2017
10 ******************************************************************************/
11#define __ASSEMBLY__
12#include "irq_ctx.h"
13
14/* Enable interrupts when returning from the handler */
15#define MSTATUS_PRV1 0x1880
16
17.section .bss.g_trap_stack
18
19    .align 4
20    .global g_trap_sp_base
21    .global g_trap_sp
22g_trap_sp_base:
23#if defined(__riscv_flen)
24    .space 1024
25#else
26    .space 512
27#endif
28g_trap_sp:
29#if 0
30.section .bss.g_irq_stack
31    .align 4
32    .global g_irq_sp_base
33    .global g_irq_sp
34g_irq_sp_base:
35    .space 1024
36g_irq_sp:
37#endif
38/******************************************************************************
39 * Functions:
40 *     void default_interrupt_handler(void);
41 * default handler for all the vector mode IRQs
42 ******************************************************************************/
43
44    .section .text.vectors.default_interrupt_handler, "ax", %progbits
45    .align  6
46    .global default_interrupt_handler
47    .weak   default_interrupt_handler
48    /* FreeRTOS will define tspend_handler for context switch */
49    .type   default_interrupt_handler, %function
50default_interrupt_handler:
51    /* ipush */
52    addi  sp, sp, -76
53
54    /* save x5 x6 then save mepc mcause */
55    sw    x5, 4(sp)
56    sw    x6, 8(sp)
57    csrr  t0, mepc
58    csrr  t1, mcause
59    sw    t1, 64(sp)
60    sw    t0, 68(sp)
61    csrr  t0, mscratch
62    sw    t0, 72(sp)
63    /* save regs */
64    sw      x1, 0(sp)
65    sw      x7, 12(sp)
66    sw      x10, 16(sp)
67    sw      x11, 20(sp)
68    sw      x12, 24(sp)
69    sw      x13, 28(sp)
70    sw      x14, 32(sp)
71    sw      x15, 36(sp)
72    sw      x16, 40(sp)
73    sw      x17, 44(sp)
74    sw      x28, 48(sp)
75    sw      x29, 52(sp)
76    sw      x30, 56(sp)
77    sw      x31, 60(sp)
78
79    /*
80     * IRQ stack contents after ipush:
81     * ~mem addr high:
82     * +  0:  <--- init IRQ sp (mscratch)
83     * -  4:  mepc
84     * -  8:  mcause
85     * - 12:  x1  (ra)
86     * - 16:  x5  (t0)
87     * - 20:  x6  (t1)
88     * - 24:  x7  (t2)
89     * - 28:  x10 (a0)
90     * - 32:  x11 (a1)
91     * - 36:  x12 (a2)
92     * - 40:  x13 (a3)
93     * - 44:  x14 (a4)
94     * - 48:  x15 (a5)
95     * - 52:  x16 (a6)
96     * - 56:  x17 (a7)
97     * - 60:  x28 (t3)
98     * - 64:  x29 (t4)
99     * - 68:  x30 (t5)
100     * - 72:  x31 (t6)   <--- current IRQ sp
101     * ~mem addr low:
102     */
103    /* WARNING: global IRQ enabled by ipush */
104    csrs    mstatus, 8
105
106    /* keep stack 16bytes aligned */
107    addi    sp, sp, -88
108
109    /* - 76:  mstatus  */
110    csrr    t1, mstatus
111    sw      t1, 84(sp)
112    srli    t2, t1, 13
113    andi    t2, t2, 0x3
114    li      t0, 0x3
115    bne     t2, t0,  .F_RegNotSave1
116
117    fsw     ft0, 0(sp)
118    fsw     ft1, 4(sp)
119    fsw     ft2, 8(sp)
120    fsw     ft3, 12(sp)
121    fsw     ft4, 16(sp)
122    fsw     ft5, 20(sp)
123    fsw     ft6, 24(sp)
124    fsw     ft7, 28(sp)
125    fsw     fa0, 32(sp)
126    fsw     fa1, 36(sp)
127    fsw     fa2, 40(sp)
128    fsw     fa3, 44(sp)
129    fsw     fa4, 48(sp)
130    fsw     fa5, 52(sp)
131    fsw     fa6, 56(sp)
132    fsw     fa7, 60(sp)
133    fsw     ft8, 64(sp)
134    fsw     ft9, 68(sp)
135    fsw     ft10,72(sp)
136    fsw     ft11,76(sp)
137.F_RegNotSave1:
138
139    csrr    a0, mcause
140    andi    t1, a0, 0x3FF
141    /* get ISR */
142    la      t2, interrupt_entry
143    jalr    t2
144
145    lw      t1, 84(sp)
146    srli    t2, t1, 13
147    andi    t2, t2, 0x3
148    li      t0, 0x3
149    bne     t2, t0,  .F_RegNotLoad
150
151    flw     ft0, 0(sp)
152    flw     ft1, 4(sp)
153    flw     ft2, 8(sp)
154    flw     ft3, 12(sp)
155    flw     ft4, 16(sp)
156    flw     ft5, 20(sp)
157    flw     ft6, 24(sp)
158    flw     ft7, 28(sp)
159    flw     fa0, 32(sp)
160    flw     fa1, 36(sp)
161    flw     fa2, 40(sp)
162    flw     fa3, 44(sp)
163    flw     fa4, 48(sp)
164    flw     fa5, 52(sp)
165    flw     fa6, 56(sp)
166    flw     fa7, 60(sp)
167    flw     ft8, 64(sp)
168    flw     ft9, 68(sp)
169    flw     ft10,72(sp)
170    flw     ft11,76(sp)
171
172.F_RegNotLoad:
173    addi    sp, sp, 88
174    /* mret included, and IRQ tail-chain may happen */
175    /* ipop */
176
177    csrc    mstatus, 8
178    /* restore mepc mcause mscrath */
179    lw      t0, 68(sp)
180    csrw    mepc, t0
181    lw      t0, 64(sp)
182    csrw    mcause, t0
183    lw      t0, 72(sp)
184    csrw    mscratch, t0
185    /* restore regs */
186    lw      x1, 0(sp)
187    lw      x5, 4(sp)
188    lw      x6, 8(sp)
189    lw      x7, 12(sp)
190    lw      x10, 16(sp)
191    lw      x11, 20(sp)
192    lw      x12, 24(sp)
193    lw      x13, 28(sp)
194    lw      x14, 32(sp)
195    lw      x15, 36(sp)
196    lw      x16, 40(sp)
197    lw      x17, 44(sp)
198    lw      x28, 48(sp)
199    lw      x29, 52(sp)
200    lw      x30, 56(sp)
201    lw      x31, 60(sp)
202
203    addi    sp, sp, 76
204    mret
205
206    .size   default_interrupt_handler, . - default_interrupt_handler
207
208/******************************************************************************
209 * Functions:
210 *     void trap(void);
211 * default handler for exceptions and non-vector mode IRQs
212 ******************************************************************************/
213    .section .text.vectors.default_trap_handler, "ax", %progbits
214    .align  6
215    .global trap
216    .type   trap, %function
217    .weak   default_trap_handler
218    .global default_trap_handler
219    .type   default_trap_handler, %function
220default_trap_handler:
221trap:
222    /* Check for interrupt */
223    sw      t0, -4(sp)
224    csrr    t0, mcause
225
226    /* IRQ, but in non-vector mode */
227    blt     t0, x0, .Lirq
228
229    la      t0, g_trap_sp
230    addi    t0, t0, -XCPTCONTEXT_SIZE
231    sw      x1, REG_X1(t0)
232    sw      x2, REG_X2(t0)
233    sw      x3, REG_X3(t0)
234    sw      x4, REG_X4(t0)
235    sw      x6, REG_X6(t0)
236    sw      x7, REG_X7(t0)
237    sw      x8, REG_X8(t0)
238    sw      x9, REG_X9(t0)
239    sw      x10, REG_X10(t0)
240    sw      x11, REG_X11(t0)
241    sw      x12, REG_X12(t0)
242    sw      x13, REG_X13(t0)
243    sw      x14, REG_X14(t0)
244    sw      x15, REG_X15(t0)
245    sw      x16, REG_X16(t0)
246    sw      x17, REG_X17(t0)
247    sw      x18, REG_X18(t0)
248    sw      x19, REG_X19(t0)
249    sw      x20, REG_X20(t0)
250    sw      x21, REG_X21(t0)
251    sw      x22, REG_X22(t0)
252    sw      x23, REG_X23(t0)
253    sw      x24, REG_X24(t0)
254    sw      x25, REG_X25(t0)
255    sw      x26, REG_X26(t0)
256    sw      x27, REG_X27(t0)
257    sw      x28, REG_X28(t0)
258    sw      x29, REG_X29(t0)
259    sw      x30, REG_X30(t0)
260    sw      x31, REG_X31(t0)
261    csrr    a0, mepc
262    sw      a0, REG_EPC(t0)
263    csrr    a0, mstatus
264    sw      a0, REG_INT_CTX(t0)
265
266    mv      a0, t0
267    lw      t0, -4(sp)
268    mv      sp, a0
269    sw      t0, REG_X5(sp)
270
271    jal     exception_entry
272
273    lw      t0, REG_INT_CTX(sp)
274    csrw    mstatus, t0
275    lw      t0, REG_EPC(sp)
276    csrw    mepc, t0
277
278    lw      x31, REG_X31(sp)
279    lw      x30, REG_X30(sp)
280    lw      x29, REG_X29(sp)
281    lw      x28, REG_X28(sp)
282    lw      x27, REG_X27(sp)
283    lw      x26, REG_X26(sp)
284    lw      x25, REG_X25(sp)
285    lw      x24, REG_X24(sp)
286    lw      x23, REG_X23(sp)
287    lw      x22, REG_X22(sp)
288    lw      x21, REG_X21(sp)
289    lw      x20, REG_X20(sp)
290    lw      x19, REG_X19(sp)
291    lw      x18, REG_X18(sp)
292    lw      x17, REG_X17(sp)
293    lw      x16, REG_X16(sp)
294    lw      x15, REG_X15(sp)
295    lw      x14, REG_X14(sp)
296    lw      x13, REG_X13(sp)
297    lw      x12, REG_X12(sp)
298    lw      x11, REG_X11(sp)
299    lw      x10, REG_X10(sp)
300    lw      x9,  REG_X9(sp)
301    lw      x8,  REG_X8(sp)
302    lw      x7,  REG_X7(sp)
303    lw      x6,  REG_X6(sp)
304    lw      x5,  REG_X5(sp)
305    lw      x4,  REG_X4(sp)
306    lw      x3,  REG_X3(sp)
307    lw      x1,  REG_X1(sp)
308    lw      x2,  REG_X2(sp)
309
310    mret
311
312.Lirq:
313    lw      t0, -4(sp)
314/* MSOFT IRQ for FreeRTOS context switch
315 * Config MSOFT IRQ to non-vector mode
316 * tspend_handler is a weak alias to default_interrupt_handler
317 */
318    j       default_interrupt_handler
319
320    .size   default_trap_handler, . - default_trap_handler