1/*
2 * Copyright (C) 2016 YunOS Project. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *   http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/* Enable interrupts when returning from the handler */
18#define MSTATUS_PRV1 0x1880
19
20/******************************************************************************
21 * Functions:
22 *     size_t cpu_intrpt_save(void);
23 *     void   cpu_intrpt_restore(size_t psr);
24 ******************************************************************************/
25
26.global cpu_intrpt_save
27.type cpu_intrpt_save, %function
28cpu_intrpt_save:
29    csrr    a0, mstatus
30    csrc    mstatus, 8
31    ret
32
33.global cpu_intrpt_restore
34.type cpu_intrpt_restore, %function
35cpu_intrpt_restore:
36    csrw    mstatus, a0
37    ret
38
39/******************************************************************************
40 * Functions:
41 *     void cpu_intrpt_switch(void);
42 *     void cpu_task_switch(void);
43 ******************************************************************************/
44
45.global cpu_task_switch
46.type cpu_task_switch, %function
47cpu_task_switch:
48    li      t0, 0xE080100C
49    lb      t1, (t0)
50    li      t2, 0x01
51    or      t1, t1, t2
52    sb      t1, (t0)
53
54    ret
55
56.global cpu_intrpt_switch
57.type cpu_intrpt_switch, %function
58cpu_intrpt_switch:
59    li      t0, 0xE080100C
60    lb      t1, (t0)
61    li      t2, 0x01
62    or      t1, t1, t2
63    sb      t1, (t0)
64
65    ret
66
67/******************************************************************************
68 * Functions:
69 *     void cpu_first_task_start(void);
70 ******************************************************************************/
71.global cpu_first_task_start
72.type cpu_first_task_start, %function
73cpu_first_task_start:
74    j       __task_switch_nosave
75
76/******************************************************************************
77 * Functions:
78 *     void tspend_handler(void);
79 ******************************************************************************/
80
81.global tspend_handler
82.type tspend_handler, %function
83tspend_handler:
84    addi    sp, sp, -(128+128)
85    fsd     f31, (0  + 0 )(sp)
86    fsd     f30, (4  + 4 )(sp)
87    fsd     f29, (8  + 8 )(sp)
88    fsd     f28, (12 + 12)(sp)
89    fsd     f27, (16 + 16)(sp)
90    fsd     f26, (20 + 20)(sp)
91    fsd     f25, (24 + 24)(sp)
92    fsd     f24, (28 + 28)(sp)
93    fsd     f23, (32 + 32)(sp)
94    fsd     f22, (36 + 36)(sp)
95    fsd     f21, (40 + 40)(sp)
96    fsd     f20, (44 + 44)(sp)
97    fsd     f19, (48 + 48)(sp)
98    fsd     f18, (52 + 52)(sp)
99    fsd     f17, (56 + 56)(sp)
100    fsd     f16, (60 + 60)(sp)
101    fsd     f15, (64 + 64)(sp)
102    fsd     f14, (68 + 68)(sp)
103    fsd     f13, (72 + 72)(sp)
104    fsd     f12, (76 + 76)(sp)
105    fsd     f11, (80 + 80)(sp)
106    fsd     f10, (84 + 84)(sp)
107    fsd     f9,  (88 + 88)(sp)
108    fsd     f8,  (92 + 92)(sp)
109    fsd     f7,  (96 + 96)(sp)
110    fsd     f6,  (100+100)(sp)
111    fsd     f5,  (104+104)(sp)
112    fsd     f4,  (108+108)(sp)
113    fsd     f3,  (112+112)(sp)
114    fsd     f2,  (116+116)(sp)
115    fsd     f1,  (120+120)(sp)
116    fsd     f0,  (124+124)(sp)
117
118    addi    sp, sp, -124
119
120    sw      x1, 0(sp)
121    sw      x3, 4(sp)
122    sw      x4, 8(sp)
123    sw      x5, 12(sp)
124    sw      x6, 16(sp)
125    sw      x7, 20(sp)
126    sw      x8, 24(sp)
127    sw      x9, 28(sp)
128    sw      x10, 32(sp)
129    sw      x11, 36(sp)
130    sw      x12, 40(sp)
131    sw      x13, 44(sp)
132    sw      x14, 48(sp)
133    sw      x15, 52(sp)
134    sw      x16, 56(sp)
135    sw      x17, 60(sp)
136    sw      x18, 64(sp)
137    sw      x19, 68(sp)
138    sw      x20, 72(sp)
139    sw      x21, 76(sp)
140    sw      x22, 80(sp)
141    sw      x23, 84(sp)
142    sw      x24, 88(sp)
143    sw      x25, 92(sp)
144    sw      x26, 96(sp)
145    sw      x27, 100(sp)
146    sw      x28, 104(sp)
147    sw      x29, 108(sp)
148    sw      x30, 112(sp)
149    sw      x31, 116(sp)
150    csrr    t0, mepc
151    sw      t0, 120(sp)
152
153    la      a1, g_active_task
154    lw      a1, (a1)
155    sw      sp, (a1)
156
157    li      t0, 0xE000E100
158    lw      t1, (t0)
159    li      t2, 0xFEFFFFFF
160    and     t1, t1, t2
161    sw      t1, (t0)
162
163__task_switch_nosave:
164    la      a0, g_preferred_ready_task
165    la      a1, g_active_task
166    lw      a2, (a0)
167    sw      a2, (a1)
168
169    lw      sp, (a2)
170
171    /* Run in machine mode */
172    li      t0, MSTATUS_PRV1
173    csrs    mstatus, t0
174
175    lw      t0, 120(sp)
176    csrw    mepc, t0
177
178    lw      x1, 0(sp)
179    lw      x3, 4(sp)
180    lw      x4, 8(sp)
181    lw      x5, 12(sp)
182    lw      x6, 16(sp)
183    lw      x7, 20(sp)
184    lw      x8, 24(sp)
185    lw      x9, 28(sp)
186    lw      x10, 32(sp)
187    lw      x11, 36(sp)
188    lw      x12, 40(sp)
189    lw      x13, 44(sp)
190    lw      x14, 48(sp)
191    lw      x15, 52(sp)
192    lw      x16, 56(sp)
193    lw      x17, 60(sp)
194    lw      x18, 64(sp)
195    lw      x19, 68(sp)
196    lw      x20, 72(sp)
197    lw      x21, 76(sp)
198    lw      x22, 80(sp)
199    lw      x23, 84(sp)
200    lw      x24, 88(sp)
201    lw      x25, 92(sp)
202    lw      x26, 96(sp)
203    lw      x27, 100(sp)
204    lw      x28, 104(sp)
205    lw      x29, 108(sp)
206    lw      x30, 112(sp)
207    lw      x31, 116(sp)
208
209    addi    sp, sp, 124
210
211    fld     f31, (0  + 0 )(sp)
212    fld     f30, (4  + 4 )(sp)
213    fld     f29, (8  + 8 )(sp)
214    fld     f28, (12 + 12)(sp)
215    fld     f27, (16 + 16)(sp)
216    fld     f26, (20 + 20)(sp)
217    fld     f25, (24 + 24)(sp)
218    fld     f24, (28 + 28)(sp)
219    fld     f23, (32 + 32)(sp)
220    fld     f22, (36 + 36)(sp)
221    fld     f21, (40 + 40)(sp)
222    fld     f20, (44 + 44)(sp)
223    fld     f19, (48 + 48)(sp)
224    fld     f18, (52 + 52)(sp)
225    fld     f17, (56 + 56)(sp)
226    fld     f16, (60 + 60)(sp)
227    fld     f15, (64 + 64)(sp)
228    fld     f14, (68 + 68)(sp)
229    fld     f13, (72 + 72)(sp)
230    fld     f12, (76 + 76)(sp)
231    fld     f11, (80 + 80)(sp)
232    fld     f10, (84 + 84)(sp)
233    fld     f9,  (88 + 88)(sp)
234    fld     f8,  (92 + 92)(sp)
235    fld     f7,  (96 + 96)(sp)
236    fld     f6,  (100+100)(sp)
237    fld     f5,  (104+104)(sp)
238    fld     f4,  (108+108)(sp)
239    fld     f3,  (112+112)(sp)
240    fld     f2,  (116+116)(sp)
241    fld     f1,  (120+120)(sp)
242    fld     f0,  (124+124)(sp)
243
244    addi    sp, sp, (128+128)
245
246
247    mret
248