-
Notifications
You must be signed in to change notification settings - Fork 24
/
Copy patheclic-mode-hack.S
343 lines (318 loc) · 7.27 KB
/
eclic-mode-hack.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
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
/*
The code is based on vendor provided HAL libraries.
Most code come from Firmware\RISCV\env_Eclipse\start.S
*/
#define STORE sw
#define LOAD lw
#define LOG_REGBYTES 2
#define REGBYTES (1 << LOG_REGBYTES)
#define CSR_MSTATUS 0x300
#define CSR_MTVT 0x307
#define CSR_MEPC 0x341
#define CSR_MCAUSE 0x342
#define CSR_MTVT2 0x7EC
#define CSR_JALMNXTI 0x7ED
#define CSR_PUSHMCAUSE 0x7EE
#define CSR_PUSHMEPC 0x7EF
#define CSR_PUSHMSUBM 0x7EB
#define CSR_MMISC_CTL 0x7d0
#define CSR_MSUBM 0x7c4
#define MSTATUS_MIE 0x00000008
.macro DISABLE_MIE
csrc CSR_MSTATUS, MSTATUS_MIE
.endm
.macro SAVE_CONTEXT
addi sp, sp, -20*REGBYTES
STORE x1, 0*REGBYTES(sp)
STORE x4, 1*REGBYTES(sp)
STORE x5, 2*REGBYTES(sp)
STORE x6, 3*REGBYTES(sp)
STORE x7, 4*REGBYTES(sp)
STORE x10, 5*REGBYTES(sp)
STORE x11, 6*REGBYTES(sp)
STORE x12, 7*REGBYTES(sp)
STORE x13, 8*REGBYTES(sp)
STORE x14, 9*REGBYTES(sp)
STORE x15, 10*REGBYTES(sp)
STORE x16, 11*REGBYTES(sp)
STORE x17, 12*REGBYTES(sp)
STORE x28, 13*REGBYTES(sp)
STORE x29, 14*REGBYTES(sp)
STORE x30, 15*REGBYTES(sp)
STORE x31, 16*REGBYTES(sp)
.endm
.macro RESTORE_CONTEXT
LOAD x1, 0*REGBYTES(sp)
LOAD x4, 1*REGBYTES(sp)
LOAD x5, 2*REGBYTES(sp)
LOAD x6, 3*REGBYTES(sp)
LOAD x7, 4*REGBYTES(sp)
LOAD x10, 5*REGBYTES(sp)
LOAD x11, 6*REGBYTES(sp)
LOAD x12, 7*REGBYTES(sp)
LOAD x13, 8*REGBYTES(sp)
LOAD x14, 9*REGBYTES(sp)
LOAD x15, 10*REGBYTES(sp)
LOAD x16, 11*REGBYTES(sp)
LOAD x17, 12*REGBYTES(sp)
LOAD x28, 13*REGBYTES(sp)
LOAD x29, 14*REGBYTES(sp)
LOAD x30, 15*REGBYTES(sp)
LOAD x31, 16*REGBYTES(sp)
// De-allocate the stack space
addi sp, sp, 20*REGBYTES
.endm
// IRQ entry point
.section .text.irq
.option push
.option norelax
.align 2
.option pop
.global _irq_handler
_irq_handler:
SAVE_CONTEXT
// The special CSR read operation, which is actually use mcause as operand to
// directly store it to memory
csrrwi x0, CSR_PUSHMCAUSE, 17
// The special CSR read operation, which is actually use mepc as operand to
// directly store it to memory
csrrwi x0, CSR_PUSHMEPC, 18
// The special CSR read operation, which is actually use Msubm as operand to
// directly store it to memory
csrrwi x0, CSR_PUSHMSUBM, 19
// The special CSR read/write operation, which is actually Claim the CLIC to
// find its pending highest ID, if the ID is not 0, then automatically enable
// the mstatus.MIE, and jump to its vector-entry-label, and update the link register.
csrrw ra, CSR_JALMNXTI, ra
DISABLE_MIE
LOAD x5, 19*REGBYTES(sp)
csrw CSR_MSUBM, x5
LOAD x5, 18*REGBYTES(sp)
csrw CSR_MEPC, x5
LOAD x5, 17*REGBYTES(sp)
csrw CSR_MCAUSE, x5
RESTORE_CONTEXT
mret
.section .text.vectors, "ax"
.option push
.option norelax
.align 9
.option pop
vectors:
.word 0
.word 0
.word 0
.word INT_SFT
.word 0
.word 0
.word 0
.word INT_TMR
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word INT_BWEI
.word INT_PMOVI
.word WWDGT
.word EXTI_LVD
.word TAMPER
.word RTC
.word FMC
.word RCU
.word EXTI_LINE0
.word EXTI_LINE1
.word EXTI_LINE2
.word EXTI_LINE3
.word EXTI_LINE4
.word DMA0_CHANNEL0
.word DMA0_CHANNEL1
.word DMA0_CHANNEL2
.word DMA0_CHANNEL3
.word DMA0_CHANNEL4
.word DMA0_CHANNEL5
.word DMA0_CHANNEL6
.word ADC0_1
.word CAN0_TX
.word CAN0_RX0
.word CAN0_RX1
.word CAN0_EWMC
.word EXTI_LINE9_5
.word TIMER0_BRK
.word TIMER0_UP
.word TIMER0_TRG_CMT
.word TIMER0_CHANNEL
.word TIMER1
.word TIMER2
.word TIMER3
.word I2C0_EV
.word I2C0_ER
.word I2C1_EV
.word I2C1_ER
.word SPI0
.word SPI1
.word USART0
.word USART1
.word USART2
.word EXTI_LINE15_10
.word RTC_ALARM
.word USBFS_WKUP
.word 0
.word 0
.word 0
.word 0
.word 0
.word EXMC // not present in Reference Manual but present in vendor HAL
.word 0
.word TIMER4
.word SPI2
.word UART3
.word UART4
.word TIMER5
.word TIMER6
.word DMA1_CHANNEL0
.word DMA1_CHANNEL1
.word DMA1_CHANNEL2
.word DMA1_CHANNEL3
.word DMA1_CHANNEL4
.word 0
.word 0
.word CAN1_TX
.word CAN1_RX0
.word CAN1_RX1
.word CAN1_EWMC
.word USBFS
/*
Trap entry point (_start_trap)
*/
.section .trap, "ax"
.option push
.option norelax
.align 6
.option pop
.global _start_trap
_start_trap:
addi sp, sp, -16*REGBYTES
STORE ra, 0*REGBYTES(sp)
STORE t0, 1*REGBYTES(sp)
STORE t1, 2*REGBYTES(sp)
STORE t2, 3*REGBYTES(sp)
STORE t3, 4*REGBYTES(sp)
STORE t4, 5*REGBYTES(sp)
STORE t5, 6*REGBYTES(sp)
STORE t6, 7*REGBYTES(sp)
STORE a0, 8*REGBYTES(sp)
STORE a1, 9*REGBYTES(sp)
STORE a2, 10*REGBYTES(sp)
STORE a3, 11*REGBYTES(sp)
STORE a4, 12*REGBYTES(sp)
STORE a5, 13*REGBYTES(sp)
STORE a6, 14*REGBYTES(sp)
STORE a7, 15*REGBYTES(sp)
add a0, sp, zero
jal ra, _start_trap_rust
LOAD ra, 0*REGBYTES(sp)
LOAD t0, 1*REGBYTES(sp)
LOAD t1, 2*REGBYTES(sp)
LOAD t2, 3*REGBYTES(sp)
LOAD t3, 4*REGBYTES(sp)
LOAD t4, 5*REGBYTES(sp)
LOAD t5, 6*REGBYTES(sp)
LOAD t6, 7*REGBYTES(sp)
LOAD a0, 8*REGBYTES(sp)
LOAD a1, 9*REGBYTES(sp)
LOAD a2, 10*REGBYTES(sp)
LOAD a3, 11*REGBYTES(sp)
LOAD a4, 12*REGBYTES(sp)
LOAD a5, 13*REGBYTES(sp)
LOAD a6, 14*REGBYTES(sp)
LOAD a7, 15*REGBYTES(sp)
addi sp, sp, 16*REGBYTES
mret
.section .text
.global _setup_interrupts
_setup_interrupts:
// Set the the NMI base to share with mtvec by setting CSR_MMISC_CTL
li t0, 0x200
csrs CSR_MMISC_CTL, t0
// Set the mtvt
la t0, vectors
csrw CSR_MTVT, t0
// Set the mtvt2 and enable it
la t0, _irq_handler
csrw CSR_MTVT2, t0
csrs CSR_MTVT2, 0x1
// Enable ECLIC and set trap handler
la t0, _start_trap
andi t0, t0, -64
ori t0, t0, 3
csrw mtvec, t0
ret
.weak INT_SFT
.weak INT_TMR
.weak INT_BWEI
.weak INT_PMOVI
.weak WWDGT
.weak EXTI_LVD
.weak TAMPER
.weak RTC
.weak FMC
.weak RCU
.weak EXTI_LINE0
.weak EXTI_LINE1
.weak EXTI_LINE2
.weak EXTI_LINE3
.weak EXTI_LINE4
.weak DMA0_CHANNEL0
.weak DMA0_CHANNEL1
.weak DMA0_CHANNEL2
.weak DMA0_CHANNEL3
.weak DMA0_CHANNEL4
.weak DMA0_CHANNEL5
.weak DMA0_CHANNEL6
.weak ADC0_1
.weak CAN0_TX
.weak CAN0_RX0
.weak CAN0_RX1
.weak CAN0_EWMC
.weak EXTI_LINE9_5
.weak TIMER0_BRK
.weak TIMER0_UP
.weak TIMER0_TRG_CMT
.weak TIMER0_CHANNEL
.weak TIMER1
.weak TIMER2
.weak TIMER3
.weak I2C0_EV
.weak I2C0_ER
.weak I2C1_EV
.weak I2C1_ER
.weak SPI0
.weak SPI1
.weak USART0
.weak USART1
.weak USART2
.weak EXTI_LINE15_10
.weak RTC_ALARM
.weak USBFS_WKUP
.weak EXMC
.weak TIMER4
.weak SPI2
.weak UART3
.weak UART4
.weak TIMER5
.weak TIMER6
.weak DMA1_CHANNEL0
.weak DMA1_CHANNEL1
.weak DMA1_CHANNEL2
.weak DMA1_CHANNEL3
.weak DMA1_CHANNEL4
.weak CAN1_TX
.weak CAN1_RX0
.weak CAN1_RX1
.weak CAN1_EWMC
.weak USBFS