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, -60
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    csrr    t0, mepc
101    sw      t0, 56(sp)
102
103    la      a1, g_active_task
104    lw      a1, (a1)
105    sw      sp, (a1)
106
107    li      t0, 0xE000E100
108    lw      t1, (t0)
109    li      t2, 0xFEFFFFFF
110    and     t1, t1, t2
111    sw      t1, (t0)
112
113__task_switch_nosave:
114    la      a0, g_preferred_ready_task
115    la      a1, g_active_task
116    lw      a2, (a0)
117    sw      a2, (a1)
118
119    lw      sp, (a2)
120
121    /* Run in machine mode */
122    li      t0, MSTATUS_PRV1
123    csrs    mstatus, t0
124
125    lw      t0, 56(sp)
126    csrw    mepc, t0
127
128    lw      x1, 0(sp)
129    lw      x3, 4(sp)
130    lw      x4, 8(sp)
131    lw      x5, 12(sp)
132    lw      x6, 16(sp)
133    lw      x7, 20(sp)
134    lw      x8, 24(sp)
135    lw      x9, 28(sp)
136    lw      x10, 32(sp)
137    lw      x11, 36(sp)
138    lw      x12, 40(sp)
139    lw      x13, 44(sp)
140    lw      x14, 48(sp)
141    lw      x15, 52(sp)
142
143    addi    sp, sp, 60
144    mret
145