xref: /nrf52832-nimble/rt-thread/libcpu/risc-v/common/context_gcc.S (revision 104654410c56c573564690304ae786df310c91fc)
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/28     Bernard      The unify RISC-V porting implementation
9 * 2018/12/27     Jesven       Add SMP support
10 */
11
12#include "cpuport.h"
13
14#ifdef RT_USING_SMP
15#define rt_hw_interrupt_disable rt_hw_local_irq_disable
16#define rt_hw_interrupt_enable  rt_hw_local_irq_enable
17#endif
18
19/*
20 * rt_base_t rt_hw_interrupt_disable(void);
21 */
22    .globl rt_hw_interrupt_disable
23rt_hw_interrupt_disable:
24    csrrci a0, mstatus, 8
25    ret
26
27/*
28 * void rt_hw_interrupt_enable(rt_base_t level);
29 */
30    .globl rt_hw_interrupt_enable
31rt_hw_interrupt_enable:
32    csrw mstatus, a0
33    ret
34
35/*
36 * #ifdef RT_USING_SMP
37 * void rt_hw_context_switch_to(rt_ubase_t to, stuct rt_thread *to_thread);
38 * #else
39 * void rt_hw_context_switch_to(rt_ubase_t to);
40 * #endif
41 * a0 --> to
42 * a1 --> to_thread
43 */
44    .globl rt_hw_context_switch_to
45rt_hw_context_switch_to:
46    LOAD sp, (a0)
47
48#ifdef RT_USING_SMP
49    mv   a0,   a1
50    jal  rt_cpus_lock_status_restore
51#endif
52
53    /* load epc from stack */
54    LOAD a0,   0 * REGBYTES(sp)
55    csrw mepc, a0
56    LOAD x1,   1 * REGBYTES(sp)
57    /* load mstatus from stack */
58    LOAD a0,   2 * REGBYTES(sp)
59    csrw mstatus, a0
60    LOAD x4,   4 * REGBYTES(sp)
61    LOAD x5,   5 * REGBYTES(sp)
62    LOAD x6,   6 * REGBYTES(sp)
63    LOAD x7,   7 * REGBYTES(sp)
64    LOAD x8,   8 * REGBYTES(sp)
65    LOAD x9,   9 * REGBYTES(sp)
66    LOAD x10, 10 * REGBYTES(sp)
67    LOAD x11, 11 * REGBYTES(sp)
68    LOAD x12, 12 * REGBYTES(sp)
69    LOAD x13, 13 * REGBYTES(sp)
70    LOAD x14, 14 * REGBYTES(sp)
71    LOAD x15, 15 * REGBYTES(sp)
72    LOAD x16, 16 * REGBYTES(sp)
73    LOAD x17, 17 * REGBYTES(sp)
74    LOAD x18, 18 * REGBYTES(sp)
75    LOAD x19, 19 * REGBYTES(sp)
76    LOAD x20, 20 * REGBYTES(sp)
77    LOAD x21, 21 * REGBYTES(sp)
78    LOAD x22, 22 * REGBYTES(sp)
79    LOAD x23, 23 * REGBYTES(sp)
80    LOAD x24, 24 * REGBYTES(sp)
81    LOAD x25, 25 * REGBYTES(sp)
82    LOAD x26, 26 * REGBYTES(sp)
83    LOAD x27, 27 * REGBYTES(sp)
84    LOAD x28, 28 * REGBYTES(sp)
85    LOAD x29, 29 * REGBYTES(sp)
86    LOAD x30, 30 * REGBYTES(sp)
87    LOAD x31, 31 * REGBYTES(sp)
88
89    addi sp,  sp, 32 * REGBYTES
90    mret
91
92/*
93 * #ifdef RT_USING_SMP
94 * void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to, struct rt_thread *to_thread);
95 * #else
96 * void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to);
97 * #endif
98 *
99 * a0 --> from
100 * a1 --> to
101 * a2 --> to_thread
102 */
103    .globl rt_hw_context_switch
104rt_hw_context_switch:
105
106    /* saved from thread context
107     *     x1/ra       -> sp(0)
108     *     x1/ra       -> sp(1)
109     *     mstatus.mie -> sp(2)
110     *     x(i)        -> sp(i-4)
111     */
112    addi  sp,  sp, -32 * REGBYTES
113    STORE sp,  (a0)
114
115    STORE x1,   0 * REGBYTES(sp)
116    STORE x1,   1 * REGBYTES(sp)
117
118    csrr a0, mstatus
119    andi a0, a0, 8
120    beqz a0, save_mpie
121    li   a0, 0x80
122save_mpie:
123    STORE a0,   2 * REGBYTES(sp)
124
125    STORE x4,   4 * REGBYTES(sp)
126    STORE x5,   5 * REGBYTES(sp)
127    STORE x6,   6 * REGBYTES(sp)
128    STORE x7,   7 * REGBYTES(sp)
129    STORE x8,   8 * REGBYTES(sp)
130    STORE x9,   9 * REGBYTES(sp)
131    STORE x10, 10 * REGBYTES(sp)
132    STORE x11, 11 * REGBYTES(sp)
133    STORE x12, 12 * REGBYTES(sp)
134    STORE x13, 13 * REGBYTES(sp)
135    STORE x14, 14 * REGBYTES(sp)
136    STORE x15, 15 * REGBYTES(sp)
137    STORE x16, 16 * REGBYTES(sp)
138    STORE x17, 17 * REGBYTES(sp)
139    STORE x18, 18 * REGBYTES(sp)
140    STORE x19, 19 * REGBYTES(sp)
141    STORE x20, 20 * REGBYTES(sp)
142    STORE x21, 21 * REGBYTES(sp)
143    STORE x22, 22 * REGBYTES(sp)
144    STORE x23, 23 * REGBYTES(sp)
145    STORE x24, 24 * REGBYTES(sp)
146    STORE x25, 25 * REGBYTES(sp)
147    STORE x26, 26 * REGBYTES(sp)
148    STORE x27, 27 * REGBYTES(sp)
149    STORE x28, 28 * REGBYTES(sp)
150    STORE x29, 29 * REGBYTES(sp)
151    STORE x30, 30 * REGBYTES(sp)
152    STORE x31, 31 * REGBYTES(sp)
153
154    /* restore to thread context
155     * sp(0) -> epc;
156     * sp(1) -> ra;
157     * sp(i) -> x(i+2)
158     */
159    LOAD sp,  (a1)
160
161#ifdef RT_USING_SMP
162    mv   a0,   a2
163    jal  rt_cpus_lock_status_restore
164#endif /*RT_USING_SMP*/
165
166    /* resw ra to mepc */
167    LOAD a1,   0 * REGBYTES(sp)
168    csrw mepc, a1
169    LOAD x1,   1 * REGBYTES(sp)
170
171    /* force to machin mode(MPP=11) */
172    li a1, 0x00001800;
173    csrs mstatus, a1
174    LOAD a1,   2 * REGBYTES(sp)
175    csrs mstatus, a1
176
177    LOAD x4,   4 * REGBYTES(sp)
178    LOAD x5,   5 * REGBYTES(sp)
179    LOAD x6,   6 * REGBYTES(sp)
180    LOAD x7,   7 * REGBYTES(sp)
181    LOAD x8,   8 * REGBYTES(sp)
182    LOAD x9,   9 * REGBYTES(sp)
183    LOAD x10, 10 * REGBYTES(sp)
184    LOAD x11, 11 * REGBYTES(sp)
185    LOAD x12, 12 * REGBYTES(sp)
186    LOAD x13, 13 * REGBYTES(sp)
187    LOAD x14, 14 * REGBYTES(sp)
188    LOAD x15, 15 * REGBYTES(sp)
189    LOAD x16, 16 * REGBYTES(sp)
190    LOAD x17, 17 * REGBYTES(sp)
191    LOAD x18, 18 * REGBYTES(sp)
192    LOAD x19, 19 * REGBYTES(sp)
193    LOAD x20, 20 * REGBYTES(sp)
194    LOAD x21, 21 * REGBYTES(sp)
195    LOAD x22, 22 * REGBYTES(sp)
196    LOAD x23, 23 * REGBYTES(sp)
197    LOAD x24, 24 * REGBYTES(sp)
198    LOAD x25, 25 * REGBYTES(sp)
199    LOAD x26, 26 * REGBYTES(sp)
200    LOAD x27, 27 * REGBYTES(sp)
201    LOAD x28, 28 * REGBYTES(sp)
202    LOAD x29, 29 * REGBYTES(sp)
203    LOAD x30, 30 * REGBYTES(sp)
204    LOAD x31, 31 * REGBYTES(sp)
205
206    addi sp,  sp, 32 * REGBYTES
207    mret
208
209#ifdef RT_USING_SMP
210/*
211 * void rt_hw_context_switch_interrupt(void *context, rt_ubase_t from, rt_ubase_t to, struct rt_thread *to_thread);
212 *
213 * a0 --> context
214 * a1 --> from
215 * a2 --> to
216 * a3 --> to_thread
217 */
218    .globl rt_hw_context_switch_interrupt
219rt_hw_context_switch_interrupt:
220
221    STORE a0, 0(a1)
222
223    csrr  a1, mepc
224    STORE a1, 0 * REGBYTES(a0)
225
226    csrr  a1, mstatus
227    STORE a1, 2 * REGBYTES(a0)
228
229    LOAD  sp, 0(a2)
230    move  a0, a3
231    call rt_cpus_lock_status_restore
232
233    /* resw ra to mepc */
234    LOAD a1,   0 * REGBYTES(sp)
235    csrw mepc, a1
236    LOAD x1,   1 * REGBYTES(sp)
237
238    /* force to machin mode(MPP=11) */
239    li a1, 0x00001800;
240    csrs mstatus, a1
241    LOAD a1,   2 * REGBYTES(sp)
242    csrs mstatus, a1
243
244    LOAD x4,   4 * REGBYTES(sp)
245    LOAD x5,   5 * REGBYTES(sp)
246    LOAD x6,   6 * REGBYTES(sp)
247    LOAD x7,   7 * REGBYTES(sp)
248    LOAD x8,   8 * REGBYTES(sp)
249    LOAD x9,   9 * REGBYTES(sp)
250    LOAD x10, 10 * REGBYTES(sp)
251    LOAD x11, 11 * REGBYTES(sp)
252    LOAD x12, 12 * REGBYTES(sp)
253    LOAD x13, 13 * REGBYTES(sp)
254    LOAD x14, 14 * REGBYTES(sp)
255    LOAD x15, 15 * REGBYTES(sp)
256    LOAD x16, 16 * REGBYTES(sp)
257    LOAD x17, 17 * REGBYTES(sp)
258    LOAD x18, 18 * REGBYTES(sp)
259    LOAD x19, 19 * REGBYTES(sp)
260    LOAD x20, 20 * REGBYTES(sp)
261    LOAD x21, 21 * REGBYTES(sp)
262    LOAD x22, 22 * REGBYTES(sp)
263    LOAD x23, 23 * REGBYTES(sp)
264    LOAD x24, 24 * REGBYTES(sp)
265    LOAD x25, 25 * REGBYTES(sp)
266    LOAD x26, 26 * REGBYTES(sp)
267    LOAD x27, 27 * REGBYTES(sp)
268    LOAD x28, 28 * REGBYTES(sp)
269    LOAD x29, 29 * REGBYTES(sp)
270    LOAD x30, 30 * REGBYTES(sp)
271    LOAD x31, 31 * REGBYTES(sp)
272
273    addi sp,  sp, 32 * REGBYTES
274    mret
275
276#endif
277