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, -124
85
86    sw      x1, 0(sp)
87    sw      x3, 4(sp)
88    sw      x4, 8(sp)
89    sw      x5, 12(sp)
90    sw      x6, 16(sp)
91    sw      x7, 20(sp)
92    sw      x8, 24(sp)
93    sw      x9, 28(sp)
94    sw      x10, 32(sp)
95    sw      x11, 36(sp)
96    sw      x12, 40(sp)
97    sw      x13, 44(sp)
98    sw      x14, 48(sp)
99    sw      x15, 52(sp)
100    sw      x16, 56(sp)
101    sw      x17, 60(sp)
102    sw      x18, 64(sp)
103    sw      x19, 68(sp)
104    sw      x20, 72(sp)
105    sw      x21, 76(sp)
106    sw      x22, 80(sp)
107    sw      x23, 84(sp)
108    sw      x24, 88(sp)
109    sw      x25, 92(sp)
110    sw      x26, 96(sp)
111    sw      x27, 100(sp)
112    sw      x28, 104(sp)
113    sw      x29, 108(sp)
114    sw      x30, 112(sp)
115    sw      x31, 116(sp)
116    csrr    t0, mepc
117    sw      t0, 120(sp)
118
119    la      a1, g_active_task
120    lw      a1, (a1)
121    sw      sp, (a1)
122
123    li      t0, 0xE000E100
124    lw      t1, (t0)
125    li      t2, 0xFEFFFFFF
126    and     t1, t1, t2
127    sw      t1, (t0)
128
129__task_switch_nosave:
130    la      a0, g_preferred_ready_task
131    la      a1, g_active_task
132    lw      a2, (a0)
133    sw      a2, (a1)
134
135    lw      sp, (a2)
136
137    /* Run in machine mode */
138    li      t0, MSTATUS_PRV1
139    csrs    mstatus, t0
140
141    lw      t0, 120(sp)
142    csrw    mepc, t0
143
144    lw      x1, 0(sp)
145    lw      x3, 4(sp)
146    lw      x4, 8(sp)
147    lw      x5, 12(sp)
148    lw      x6, 16(sp)
149    lw      x7, 20(sp)
150    lw      x8, 24(sp)
151    lw      x9, 28(sp)
152    lw      x10, 32(sp)
153    lw      x11, 36(sp)
154    lw      x12, 40(sp)
155    lw      x13, 44(sp)
156    lw      x14, 48(sp)
157    lw      x15, 52(sp)
158    lw      x16, 56(sp)
159    lw      x17, 60(sp)
160    lw      x18, 64(sp)
161    lw      x19, 68(sp)
162    lw      x20, 72(sp)
163    lw      x21, 76(sp)
164    lw      x22, 80(sp)
165    lw      x23, 84(sp)
166    lw      x24, 88(sp)
167    lw      x25, 92(sp)
168    lw      x26, 96(sp)
169    lw      x27, 100(sp)
170    lw      x28, 104(sp)
171    lw      x29, 108(sp)
172    lw      x30, 112(sp)
173    lw      x31, 116(sp)
174
175    addi    sp, sp, 124
176    mret
177