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
85    fsw      f31, 0(sp)
86    fsw      f30, 4(sp)
87    fsw      f29, 8(sp)
88    fsw      f28, 12(sp)
89    fsw      f27, 16(sp)
90    fsw      f26, 20(sp)
91    fsw      f25, 24(sp)
92    fsw      f24, 28(sp)
93    fsw      f23, 32(sp)
94    fsw      f22, 36(sp)
95    fsw      f21, 40(sp)
96    fsw      f20, 44(sp)
97    fsw      f19, 48(sp)
98    fsw      f18, 52(sp)
99    fsw      f17, 56(sp)
100    fsw      f16, 60(sp)
101    fsw      f15, 64(sp)
102    fsw      f14, 68(sp)
103    fsw      f13, 72(sp)
104    fsw      f12, 76(sp)
105    fsw      f11, 80(sp)
106    fsw      f10, 84(sp)
107    fsw      f9, 88(sp)
108    fsw      f8, 92(sp)
109    fsw      f7, 96(sp)
110    fsw      f6, 100(sp)
111    fsw      f5, 104(sp)
112    fsw      f4, 108(sp)
113    fsw      f3, 112(sp)
114    fsw      f2, 116(sp)
115    fsw      f1, 120(sp)
116    fsw      f0, 124(sp)
117
118
119    addi    sp, sp, -124
120
121    sw      x1, 0(sp)
122    sw      x3, 4(sp)
123    sw      x4, 8(sp)
124    sw      x5, 12(sp)
125    sw      x6, 16(sp)
126    sw      x7, 20(sp)
127    sw      x8, 24(sp)
128    sw      x9, 28(sp)
129    sw      x10, 32(sp)
130    sw      x11, 36(sp)
131    sw      x12, 40(sp)
132    sw      x13, 44(sp)
133    sw      x14, 48(sp)
134    sw      x15, 52(sp)
135    sw      x16, 56(sp)
136    sw      x17, 60(sp)
137    sw      x18, 64(sp)
138    sw      x19, 68(sp)
139    sw      x20, 72(sp)
140    sw      x21, 76(sp)
141    sw      x22, 80(sp)
142    sw      x23, 84(sp)
143    sw      x24, 88(sp)
144    sw      x25, 92(sp)
145    sw      x26, 96(sp)
146    sw      x27, 100(sp)
147    sw      x28, 104(sp)
148    sw      x29, 108(sp)
149    sw      x30, 112(sp)
150    sw      x31, 116(sp)
151    csrr    t0, mepc
152    sw      t0, 120(sp)
153
154    la      a1, g_active_task
155    lw      a1, (a1)
156    sw      sp, (a1)
157
158    li      t0, 0xE000E100
159    lw      t1, (t0)
160    li      t2, 0xFEFFFFFF
161    and     t1, t1, t2
162    sw      t1, (t0)
163
164__task_switch_nosave:
165    la      a0, g_preferred_ready_task
166    la      a1, g_active_task
167    lw      a2, (a0)
168    sw      a2, (a1)
169
170    lw      sp, (a2)
171
172    /* Run in machine mode */
173    li      t0, MSTATUS_PRV1
174    csrs    mstatus, t0
175
176    lw      t0, 120(sp)
177    csrw    mepc, t0
178
179    lw      x1, 0(sp)
180    lw      x3, 4(sp)
181    lw      x4, 8(sp)
182    lw      x5, 12(sp)
183    lw      x6, 16(sp)
184    lw      x7, 20(sp)
185    lw      x8, 24(sp)
186    lw      x9, 28(sp)
187    lw      x10, 32(sp)
188    lw      x11, 36(sp)
189    lw      x12, 40(sp)
190    lw      x13, 44(sp)
191    lw      x14, 48(sp)
192    lw      x15, 52(sp)
193    lw      x16, 56(sp)
194    lw      x17, 60(sp)
195    lw      x18, 64(sp)
196    lw      x19, 68(sp)
197    lw      x20, 72(sp)
198    lw      x21, 76(sp)
199    lw      x22, 80(sp)
200    lw      x23, 84(sp)
201    lw      x24, 88(sp)
202    lw      x25, 92(sp)
203    lw      x26, 96(sp)
204    lw      x27, 100(sp)
205    lw      x28, 104(sp)
206    lw      x29, 108(sp)
207    lw      x30, 112(sp)
208    lw      x31, 116(sp)
209
210    addi    sp, sp, 124
211
212    flw      f31, 0(sp)
213    flw      f30, 4(sp)
214    flw      f29, 8(sp)
215    flw      f28, 12(sp)
216    flw      f27, 16(sp)
217    flw      f26, 20(sp)
218    flw      f25, 24(sp)
219    flw      f24, 28(sp)
220    flw      f23, 32(sp)
221    flw      f22, 36(sp)
222    flw      f21, 40(sp)
223    flw      f20, 44(sp)
224    flw      f19, 48(sp)
225    flw      f18, 52(sp)
226    flw      f17, 56(sp)
227    flw      f16, 60(sp)
228    flw      f15, 64(sp)
229    flw      f14, 68(sp)
230    flw      f13, 72(sp)
231    flw      f12, 76(sp)
232    flw      f11, 80(sp)
233    flw      f10, 84(sp)
234    flw      f9, 88(sp)
235    flw      f8, 92(sp)
236    flw      f7, 96(sp)
237    flw      f6, 100(sp)
238    flw      f5, 104(sp)
239    flw      f4, 108(sp)
240    flw      f3, 112(sp)
241    flw      f2, 116(sp)
242    flw      f1, 120(sp)
243    flw      f0, 124(sp)
244
245    addi    sp, sp, 128
246
247
248    mret
249