-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhandlers.S
229 lines (213 loc) · 5.33 KB
/
handlers.S
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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
/*
* handlers.S
*
* This file supports the population of the mtvec vector table,
* and it contains opcodes of jump instructions to a specific handler.
*
*/
#include <metal/machine/platform.h>
// Add support for *_asm handler
#if __riscv_xlen == 32
#define REG_SIZE 4
#define REG_SIZE_LOG2 2
#define PTR_SIZE .word
#define STORE sw
#define LOAD lw
#elif __riscv_xlen == 64
#define REG_SIZE 8
#define REG_SIZE_LOG2 3
#define PTR_SIZE .dword
#define STORE sd
#define LOAD ld
#else // __riscv_xlen == 64
#error Unsupported XLEN
#endif // __riscv_xlen != 64
// for software ASM handler
#define CLINT_MSIP_BASE_ADDR METAL_RISCV_CLINT0_0_BASE_ADDRESS
// alignment and globals
.balign 256, 0
.global __mtvec_clint_vector_table
.global default_exception_handler
.global software_handler
.global timer_handler
.global external_handler
.global set_mip_major_handler
.global software_handler_asm
// for ASM handler
.extern software_isr_counter
// do not generate compressed code
.option norvc
// interrupt vector table starts here
__mtvec_clint_vector_table:
IRQ_0:
j default_exception_handler
IRQ_1:
j default_vector_handler
IRQ_2:
j default_vector_handler
IRQ_3:
//j software_handler
j software_handler_asm
IRQ_4:
j default_vector_handler
IRQ_5:
j default_vector_handler
IRQ_6:
j default_vector_handler
IRQ_7:
j timer_handler
IRQ_8:
j default_vector_handler
IRQ_9:
j default_vector_handler
IRQ_10:
j default_vector_handler
IRQ_11:
j external_handler
IRQ_12:
j default_vector_handler
IRQ_13:
j default_vector_handler
IRQ_14:
j default_vector_handler
IRQ_15:
j default_vector_handler
IRQ_16:
j set_mip_major_handler
IRQ_17:
j default_vector_handler
IRQ_18:
j default_vector_handler
IRQ_19:
j default_vector_handler
IRQ_20:
j default_vector_handler
IRQ_21:
j default_vector_handler
IRQ_22:
j default_vector_handler
IRQ_23:
j default_vector_handler
IRQ_24:
j default_vector_handler
IRQ_25:
j default_vector_handler
IRQ_26:
j default_vector_handler
IRQ_27:
j default_vector_handler
IRQ_28:
j default_vector_handler
IRQ_29:
j default_vector_handler
IRQ_30:
j default_vector_handler
IRQ_31:
j default_vector_handler
IRQ_32:
j default_vector_handler
IRQ_33:
j default_vector_handler
IRQ_34:
j default_vector_handler
IRQ_35:
j default_vector_handler
IRQ_36:
j default_vector_handler
IRQ_37:
j default_vector_handler
IRQ_38:
j default_vector_handler
IRQ_39:
j default_vector_handler
IRQ_40:
j default_vector_handler
IRQ_41:
j default_vector_handler
IRQ_42:
j default_vector_handler
IRQ_43:
j default_vector_handler
IRQ_44:
j default_vector_handler
IRQ_45:
j default_vector_handler
IRQ_46:
j default_vector_handler
IRQ_47:
j default_vector_handler
IRQ_48:
j default_vector_handler
IRQ_49:
j default_vector_handler
IRQ_50:
j default_vector_handler
IRQ_51:
j default_vector_handler
IRQ_52:
j default_vector_handler
IRQ_53:
j default_vector_handler
IRQ_54:
j default_vector_handler
IRQ_55:
j default_vector_handler
IRQ_56:
j default_vector_handler
IRQ_57:
j default_vector_handler
IRQ_58:
j default_vector_handler
IRQ_59:
j default_vector_handler
IRQ_60:
j default_vector_handler
IRQ_61:
j default_vector_handler
IRQ_62:
j default_vector_handler
IRQ_63:
j default_vector_handler
// ----------------------------------------------------------------------
// ASM implementation for clearing MSIP per hart for vectored interrupts
// ----------------------------------------------------------------------
software_handler_asm:
#if __riscv_xlen == 32
add sp, sp, -8
STORE t4, 0(sp)
STORE t5, 4(sp)
#else
add sp, sp, -16
STORE t4, 0(sp)
STORE t5, 8(sp)
#endif
// clear msip for this hart
li t4, CLINT_MSIP_BASE_ADDR // base address of global CLINT MMIO region
csrr t5, mhartid // get hartid
slli t5, t5, REG_SIZE_LOG2 // add offset of msip for this hart
add t5, t5, t4 // address of msip for this hart now in t5
sw x0, 0(t5) // clear msip for this hart
// increment global counter
la t4, software_isr_counter
LOAD t5, 0(t4)
addi t5, t5, 1
STORE t5, 0(t4)
1:
// do not exit until mip[3] clears, or we would get spurious s/w interrupts
csrr t4, mip
andi t5, t4, 8
bne t5, x0, 1b // branch back to the 1: label if t4 != 0
// pop stack
#if __riscv_xlen == 32
LOAD t4, 0(sp)
LOAD t5, 4(sp)
add sp, sp, 8
#else
LOAD t4, 0(sp)
LOAD t5, 8(sp)
add sp, sp, -16
#endif
mret
// -------------------------------------------------------
// end of software_handler_asm
// -------------------------------------------------------