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
|
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018/10/02 Bernard The first version
* 2018/12/27 Jesven Add SMP schedule
* 2021/02/02 lizhirui Add userspace support
*/
#define __ASSEMBLY__
#include "stackframe.h"
.equ RISCV_MSTATUS_MIE, (1<<3) /*machine-level interrupt bit*/
.section .text.entry
.align 3
#ifdef RT_USING_SMP
.global Mcoret_Handler
.type Mcoret_Handler, %function
Mcoret_Handler:
SAVE_ALL
/* switch to interrupt stack */
move s0, sp
/* get cpu id */
csrr t0, mhartid
/* switch interrupt stack of current cpu */
la sp, g_base_irqstack
addi t1, t0, 1
li t2, CONFIG_ARCH_INTERRUPTSTACK
mul t1, t1, t2
add sp, sp, t1 /* sp = (cpuid + 1) * CONFIG_ARCH_INTERRUPTSTACK + g_base_irqstack */
call CORET_IRQHandler
# /* s0 --> sp */
mv sp, s0
mv a0, s0
call rt_scheduler_do_irq_switch
RESTORE_ALL
mret
.size Mcoret_Handler, . - Mcoret_Handler
#endif
.global Mtspend_Handler
.global tspend_handler
.type Mtspend_Handler, %function
.type tspend_handler, %function
Mtspend_Handler:
tspend_handler:
SAVE_ALL
#ifdef RT_USING_SMP
/* switch to interrupt stack */
move s0, sp
/* get cpu id */
csrr t0, mhartid
/* switch interrupt stack of current cpu */
la sp, g_base_irqstack
addi t1, t0, 1
li t2, CONFIG_ARCH_INTERRUPTSTACK
mul t1, t1, t2
add sp, sp, t1 /* sp = (cpuid + 1) * CONFIG_ARCH_INTERRUPTSTACK + g_base_irqstack */
call rt_interrupt_enter
call ipi_irq
call rt_interrupt_leave
/* s0 --> sp */
mv sp, s0
mv a0, s0
call rt_scheduler_do_irq_switch
#else
/* get rt_thread_switch_interrupt_flag */
la t0, rt_thread_switch_interrupt_flag
LOAD t2, 0(t0)
beqz t2, tspend_exit /* tspend already handled */
/* clear rt_thread_switch_interrupt_flag to 0 */
STORE zero, 0(t0)
/* switch thread */
la t0, rt_interrupt_from_thread
LOAD t1, 0(t0)
STORE sp, 0(t1)
la t0, rt_interrupt_to_thread
LOAD t1, 0(t0)
LOAD sp, 0(t1)
tspend_exit:
#if CONFIG_INTC_CLIC || CONFIG_INTC_CLIC_PLIC
#else
/* clear tspend */
li t0, RISCV_VIC_TSPDR
li t2, 0x0
sw t2, 0(t0)
#endif
#endif /* RT_USING_SMP */
RESTORE_ALL
mret
.size Mtspend_Handler, . - Mtspend_Handler
.size tspend_handler, . - tspend_handler
#ifdef RT_USING_SMP
#define rt_hw_interrupt_disable rt_hw_local_irq_disable
#define rt_hw_interrupt_enable rt_hw_local_irq_enable
#endif
.global cpu_intrpt_restore
.type cpu_intrpt_restore, %function
.global rt_hw_interrupt_enable
.type rt_hw_interrupt_enable, %function
cpu_intrpt_restore:
rt_hw_interrupt_enable:
csrs mstatus, a0 /* restore to old csr */
jr ra
.size cpu_intrpt_restore, . - cpu_intrpt_restore
.size rt_hw_interrupt_enable, . - rt_hw_interrupt_enable
.global cpu_intrpt_save
.type cpu_intrpt_save, %function
.global rt_hw_interrupt_disable
.type rt_hw_interrupt_disable, %function
cpu_intrpt_save:
rt_hw_interrupt_disable:
csrrci a0, mstatus, 8 /* clear MIE */
jr ra
.size cpu_intrpt_save, . - cpu_intrpt_save
.size rt_hw_interrupt_disable, . - rt_hw_interrupt_disable
.global cpu_is_irq_enable
.type cpu_is_irq_enable, %function
cpu_is_irq_enable:
csrr a0, mstatus
andi a0, a0, RISCV_MSTATUS_MIE
ret
.size cpu_is_irq_enable, . - cpu_is_irq_enable
|