1// See LICENSE for license details
2
3#ifndef ENTRY_S
4#define ENTRY_S
5
6#include "riscv_encoding.h"
7#include "riscv_bits.h"
8#include "n200_eclic.h"
9#include "n200_timer.h"
10
11###############################################
12###############################################
13# Disable Interrupt
14#
15.macro DISABLE_MIE
16  csrc CSR_MSTATUS, MSTATUS_MIE
17.endm
18
19
20###############################################
21###############################################
22#Save caller registers
23.macro SAVE_CONTEXT
24
25#ifdef __riscv_flen
26  #if (__riscv_flen==64 )
27    addi sp, sp, -20*REGBYTES - 20*FPREGBYTES
28  #else
29    addi sp, sp, -20*REGBYTES
30  #endif
31#else
32  addi sp, sp, -20*REGBYTES
33#endif
34  STORE x1, 0*REGBYTES(sp)
35	STORE x4, 1*REGBYTES(sp)
36	STORE x5, 2*REGBYTES(sp)
37	STORE x6, 3*REGBYTES(sp)
38	STORE x7, 4*REGBYTES(sp)
39	STORE x10, 5*REGBYTES(sp)
40	STORE x11, 6*REGBYTES(sp)
41	STORE x12, 7*REGBYTES(sp)
42	STORE x13, 8*REGBYTES(sp)
43	STORE x14, 9*REGBYTES(sp)
44	STORE x15, 10*REGBYTES(sp)
45#ifndef __riscv_32e
46  STORE x16, 11*REGBYTES(sp)
47	STORE x17, 12*REGBYTES(sp)
48	STORE x28, 13*REGBYTES(sp)
49	STORE x29, 14*REGBYTES(sp)
50	STORE x30, 15*REGBYTES(sp)
51	STORE x31, 16*REGBYTES(sp)
52#endif
53
54#ifdef __riscv_flen
55  #if (__riscv_flen == 64)
56  FPSTORE f0, (20*REGBYTES + 0*FPREGBYTES)(sp)
57	FPSTORE f1, (20*REGBYTES + 1*FPREGBYTES)(sp)
58	FPSTORE f2, (20*REGBYTES + 2*FPREGBYTES)(sp)
59	FPSTORE f3, (20*REGBYTES + 3*FPREGBYTES)(sp)
60	FPSTORE f4, (20*REGBYTES + 4*FPREGBYTES)(sp)
61	FPSTORE f5, (20*REGBYTES + 5*FPREGBYTES)(sp)
62	FPSTORE f6, (20*REGBYTES + 6*FPREGBYTES)(sp)
63	FPSTORE f7, (20*REGBYTES + 7*FPREGBYTES)(sp)
64	FPSTORE f10, (20*REGBYTES + 8*FPREGBYTES)(sp)
65	FPSTORE f11, (20*REGBYTES + 9*FPREGBYTES)(sp)
66	FPSTORE f12, (20*REGBYTES + 10*FPREGBYTES)(sp)
67	FPSTORE f13, (20*REGBYTES + 11*FPREGBYTES)(sp)
68	FPSTORE f14, (20*REGBYTES + 12*FPREGBYTES)(sp)
69	FPSTORE f15, (20*REGBYTES + 13*FPREGBYTES)(sp)
70	FPSTORE f16, (20*REGBYTES + 14*FPREGBYTES)(sp)
71	FPSTORE f17, (20*REGBYTES + 15*FPREGBYTES)(sp)
72	FPSTORE f28, (20*REGBYTES + 16*FPREGBYTES)(sp)
73	FPSTORE f29, (20*REGBYTES + 17*FPREGBYTES)(sp)
74	FPSTORE f30, (20*REGBYTES + 18*FPREGBYTES)(sp)
75	FPSTORE f31, (20*REGBYTES + 19*FPREGBYTES)(sp)
76  #endif
77#endif
78
79
80.endm
81
82
83###############################################
84###############################################
85#restore caller registers
86.macro RESTORE_CONTEXT
87  LOAD x1, 0*REGBYTES(sp)
88	LOAD x4, 1*REGBYTES(sp)
89	LOAD x5, 2*REGBYTES(sp)
90	LOAD x6, 3*REGBYTES(sp)
91	LOAD x7, 4*REGBYTES(sp)
92	LOAD x10, 5*REGBYTES(sp)
93	LOAD x11, 6*REGBYTES(sp)
94	LOAD x12, 7*REGBYTES(sp)
95	LOAD x13, 8*REGBYTES(sp)
96	LOAD x14, 9*REGBYTES(sp)
97	LOAD x15, 10*REGBYTES(sp)
98#ifndef __riscv_32e
99  LOAD x16, 11*REGBYTES(sp)
100	LOAD x17, 12*REGBYTES(sp)
101	LOAD x28, 13*REGBYTES(sp)
102	LOAD x29, 14*REGBYTES(sp)
103	LOAD x30, 15*REGBYTES(sp)
104	LOAD x31, 16*REGBYTES(sp)
105#endif
106
107
108#ifdef __riscv_flen
109  #if (__riscv_flen==64)
110/* Restore fp caller registers */
111	FPLOAD f0, (20*REGBYTES + 0*FPREGBYTES)(sp)
112	FPLOAD f1, (20*REGBYTES + 1*FPREGBYTES)(sp)
113	FPLOAD f2, (20*REGBYTES + 2*FPREGBYTES)(sp)
114	FPLOAD f3, (20*REGBYTES + 3*FPREGBYTES)(sp)
115	FPLOAD f4, (20*REGBYTES + 4*FPREGBYTES)(sp)
116	FPLOAD f5, (20*REGBYTES + 5*FPREGBYTES)(sp)
117	FPLOAD f6, (20*REGBYTES + 6*FPREGBYTES)(sp)
118	FPLOAD f7, (20*REGBYTES + 7*FPREGBYTES)(sp)
119	FPLOAD f10, (20*REGBYTES + 8*FPREGBYTES)(sp)
120	FPLOAD f11, (20*REGBYTES + 9*FPREGBYTES)(sp)
121	FPLOAD f12, (20*REGBYTES + 10*FPREGBYTES)(sp)
122	FPLOAD f13, (20*REGBYTES + 11*FPREGBYTES)(sp)
123	FPLOAD f14, (20*REGBYTES + 12*FPREGBYTES)(sp)
124	FPLOAD f15, (20*REGBYTES + 13*FPREGBYTES)(sp)
125	FPLOAD f16, (20*REGBYTES + 14*FPREGBYTES)(sp)
126	FPLOAD f17, (20*REGBYTES + 15*FPREGBYTES)(sp)
127	FPLOAD f28, (20*REGBYTES + 16*FPREGBYTES)(sp)
128	FPLOAD f29, (20*REGBYTES + 17*FPREGBYTES)(sp)
129	FPLOAD f30, (20*REGBYTES + 18*FPREGBYTES)(sp)
130	FPLOAD f31, (20*REGBYTES + 19*FPREGBYTES)(sp)
131  #endif
132#endif
133
134
135#ifdef __riscv_flen
136  #if(__riscv_flen == 64 )
137    addi sp, sp, 20*REGBYTES  + 20*FPREGBYTES
138  #else
139    addi sp, sp, 20*REGBYTES
140  #endif
141#else
142// De-allocate the stack space
143 addi sp, sp, 20*REGBYTES
144#endif
145.endm
146
147###############################################
148###############################################
149#restore caller registers
150.macro RESTORE_CONTEXT_EXCPT_X5
151  LOAD x1,  0*REGBYTES(sp)
152  LOAD x6,  2*REGBYTES(sp)
153  LOAD x7,  3*REGBYTES(sp)
154  LOAD x10, 4*REGBYTES(sp)
155  LOAD x11, 5*REGBYTES(sp)
156  LOAD x12, 6*REGBYTES(sp)
157  LOAD x13, 7*REGBYTES(sp)
158  LOAD x14, 8*REGBYTES(sp)
159  LOAD x15, 9*REGBYTES(sp)
160#ifndef __riscv_32e
161  LOAD x16, 10*REGBYTES(sp)
162  LOAD x17, 11*REGBYTES(sp)
163  LOAD x28, 12*REGBYTES(sp)
164  LOAD x29, 13*REGBYTES(sp)
165  LOAD x30, 14*REGBYTES(sp)
166  LOAD x31, 15*REGBYTES(sp)
167#endif
168.endm
169
170###############################################
171###############################################
172#restore caller registers
173.macro RESTORE_CONTEXT_ONLY_X5
174  LOAD x5,  1*REGBYTES(sp)
175.endm
176
177###############################################
178###############################################
179# Save the mepc and mstatus
180#
181.macro SAVE_EPC_STATUS
182  csrr x5, CSR_MEPC
183  STORE x5,  16*REGBYTES(sp)
184  csrr x5, CSR_MSTATUS
185  STORE x5,  17*REGBYTES(sp)
186  csrr x5, CSR_MSUBM
187  STORE x5,  18*REGBYTES(sp)
188.endm
189
190###############################################
191###############################################
192# Restore the mepc and mstatus
193#
194.macro RESTORE_EPC_STATUS
195  LOAD x5,  16*REGBYTES(sp)
196  csrw CSR_MEPC, x5
197  LOAD x5,  17*REGBYTES(sp)
198  csrw CSR_MSTATUS, x5
199  LOAD x5,  18*REGBYTES(sp)
200  csrw CSR_MSUBM, x5
201.endm
202
203
204
205###############################################
206###############################################
207// Trap entry point
208//
209  .section      .text.trap
210  .align 6// In CLIC mode, the trap entry must be 64bytes aligned
211  .global trap_entry
212.weak trap_entry
213trap_entry:
214  // Allocate the stack space
215 // addi sp, sp, -19*REGBYTES
216
217  // Save the caller saving registers (context)
218  SAVE_CONTEXT
219  // Save the MEPC/Mstatus/Msubm reg
220  SAVE_EPC_STATUS
221
222     // Set the function argument
223  csrr a0, mcause
224  mv a1, sp
225     // Call the function
226  call handle_trap
227
228  // Restore the MEPC/Mstatus/Msubm reg
229  RESTORE_EPC_STATUS
230  // Restore the caller saving registers (context)
231  RESTORE_CONTEXT
232
233  // De-allocate the stack space
234 // addi sp, sp, 19*REGBYTES
235  // Return to regular code
236  mret
237
238
239###############################################
240###############################################
241// IRQ entry point
242//
243  .section      .text.irq
244  .align 2
245  .global irq_entry
246.weak irq_entry
247irq_entry: // -------------> This label will be set to MTVT2 register
248  // Allocate the stack space
249
250
251  SAVE_CONTEXT// Save 16 regs
252
253  //------This special CSR read operation, which is actually use mcause as operand to directly store it to memory
254  csrrwi  x0, CSR_PUSHMCAUSE, 17
255  //------This special CSR read operation, which is actually use mepc as operand to directly store it to memory
256  csrrwi  x0, CSR_PUSHMEPC, 18
257  //------This special CSR read operation, which is actually use Msubm as operand to directly store it to memory
258  csrrwi  x0, CSR_PUSHMSUBM, 19
259
260service_loop:
261  //------This special CSR read/write operation, which is actually Claim the CLIC to find its pending highest
262  // ID, if the ID is not 0, then automatically enable the mstatus.MIE, and jump to its vector-entry-label, and
263  // update the link register
264  csrrw ra, CSR_JALMNXTI, ra
265
266  //RESTORE_CONTEXT_EXCPT_X5
267
268  #---- Critical section with interrupts disabled -----------------------
269  DISABLE_MIE # Disable interrupts
270
271  LOAD x5,  19*REGBYTES(sp)
272  csrw CSR_MSUBM, x5
273  LOAD x5,  18*REGBYTES(sp)
274  csrw CSR_MEPC, x5
275  LOAD x5,  17*REGBYTES(sp)
276  csrw CSR_MCAUSE, x5
277
278
279  RESTORE_CONTEXT
280
281
282  // Return to regular code
283  mret
284
285
286#endif