1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018/10/28 Bernard The unify RISC-V porting implementation
* 2018/12/27 Jesven Add SMP support
* 2021/02/02 lizhirui Add userspace support
*/
#define __ASSEMBLY__
#include "cpuport.h"
#include "stackframe.h"
.global rt_hw_context_switch_to
.type rt_hw_context_switch_to, %function
rt_hw_context_switch_to:
LOAD sp, (a0)
#ifdef RT_USING_SMP
mv a0, a1
call rt_cpus_lock_status_restore
#endif
RESTORE_ALL
mret
.size rt_hw_context_switch_to, . - rt_hw_context_switch_to
#ifdef RT_USING_SMP
/*
* void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to, struct rt_thread *to_thread);
*
* a0 --> from
* a1 --> to
* a2 --> to_thread
*/
.global rt_hw_context_switch
.type rt_hw_context_switch, %function
rt_hw_context_switch:
/* set mstatus.mpp */
csrr t0, mxstatus
srli t0, t0, 30
andi t0, t0, 0x3
slli t0, t0, 11
csrs mstatus, t0//if enter here,caller must be in system thread
csrw mepc, ra//return address
//saved from thread context
SAVE_ALL
STORE sp, (a0)
//restore to thread context
LOAD sp, (a1)
mv a0, a2
call rt_cpus_lock_status_restore
RESTORE_ALL
mret
.size rt_hw_context_switch, . - rt_hw_context_switch
/*
* void rt_hw_context_switch_interrupt(void *context, rt_ubase_t from, rt_ubase_t to, struct rt_thread *to_thread);
*
* a0 --> context
* a1 --> from
* a2 --> to
* a3 --> to_thread
*/
.global rt_hw_context_switch_interrupt
.type rt_hw_context_switch_interrupt, %function
rt_hw_context_switch_interrupt:
STORE a0, 0(a1)
LOAD sp, 0(a2)
move a0, a3
call rt_cpus_lock_status_restore
RESTORE_ALL
mret
.size rt_hw_context_switch_interrupt, . - rt_hw_context_switch_interrupt
#else
/*
* void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to);
*
* a0 --> from
* a1 --> to
*/
/*
* void rt_hw_context_switch_interrupt(rt_ubase_t from, rt_ubase_t to, rt_thread_t from_thread, rt_thread_t to_thread);
*
* a0 --> from
* a1 --> to
* a2 --> from_thread
* a3 --> to_thread
*/
.global rt_hw_context_switch
.type rt_hw_context_switch, %function
.global rt_hw_context_switch_interrupt
.type rt_hw_context_switch_interrupt, %function
rt_hw_context_switch:
rt_hw_context_switch_interrupt:
/* set rt_thread_switch_interrupt_flag to 1 */
la t0, rt_thread_switch_interrupt_flag
LOAD t2, 0(t0)
bnez t2, _reswitch
li t1, 1
STORE t1, 0(t0)
/* set rt_interrupt_from_thread */
la t0, rt_interrupt_from_thread
STORE a0, 0(t0)
_reswitch:
/* set rt_interrupt_to_thread */
la t0, rt_interrupt_to_thread
STORE a1, 0(t0)
#if CONFIG_INTC_CLIC || CONFIG_INTC_CLIC_PLIC
/* trigger the tspend exception (causes context switch) */
li t0, 0xE080100C
lb t1, (t0)
li t2, 0x01
or t1, t1, t2
sb t1, (t0)
fence
nop
nop
nop
nop
nop
ret
#else
/* trigger the tspend exception (causes context switch) */
li t0, RISCV_VIC_TSPDR
li t2, 0x1
sw t2, 0(t0)
__loop:
lw t2, 0(t0)
seqz t1, t2
#if defined(CONFIG_RISCV_SMODE) && CONFIG_RISCV_SMODE
csrr t2, sip
andi t2, t2, 0x2
#else
csrr t2, mip
andi t2, t2, 0x8
#endif
snez t3, t2
add t2, t3, t1
beqz t2, __loop
ret
#endif
.size rt_hw_context_switch, . - rt_hw_context_switch
.size rt_hw_context_switch_interrupt, . - rt_hw_context_switch_interrupt
#endif /* RT_USING_SMP */
|