1 /*
2  * @file entry.S
3  * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * @brief RISC-V trap handling and startup code.
17  */
18 #ifndef ENTRY_S
19 #define ENTRY_S
20 
21 .extern __stack_top
22 .extern g_nmi_stack_end
23 
24 #define LREG lw
25 #define SREG sw
26 #define REGBYTES 4
27 
28 #define INT_SIZE_ON_STACK  (16 * REGBYTES)
29 
30 #define MSTATUS_MPP_MACHINE       0x00001800
31 #define MCAULSE_ECALL_FROM_MMODE  11
32 #define MCAULSE_ECALL_FROM_UMODE  8
33 #define EXC_SIZE_ON_STACK         (160)
34 
35     .extern trap_entry
36     .extern nmi_entry
37     .section      .text.entry
38     .global _start
39     .option norvc
40 _start:
41     j handle_reset
42 
43 trap_vector:
44     j trap_entry_wrapper
45     j trap_entry_wrapper    /* 1 */
46     j trap_entry_wrapper    /* 2 */
47     j trap_entry_wrapper    /* 3 Software_IRQHandler, NIY(not implemented yet) */
48     j trap_entry_wrapper    /* 4 */
49     j trap_entry_wrapper    /* 5 */
50     j trap_entry_wrapper    /* 6 */
51     j trap_entry_wrapper    /* 7 handle_timer_interrupt, use external clock */
52     j trap_entry_wrapper    /* 8 */
53     j trap_entry_wrapper    /* 9 */
54     j trap_entry_wrapper    /* 10 */
55     j trap_entry_wrapper    /* 11 handle_external_interrupt, NIY(not implemented yet) */
56     j nmi_entry_wrapper     /* 12 nmi entry*/
57     j trap_entry_wrapper    /* 13 */
58     j trap_entry_wrapper    /* 14 */
59     .option rvc
60 
61 .macro push_reg
62     addi  sp, sp, -(INT_SIZE_ON_STACK)
63     SREG x1, 0 * REGBYTES(sp)
64     SREG x5, 1 * REGBYTES(sp)
65     SREG x6, 2 * REGBYTES(sp)
66     SREG x7, 3 * REGBYTES(sp)
67     SREG x10, 4 * REGBYTES(sp)
68     SREG x11, 5 * REGBYTES(sp)
69     SREG x12, 6 * REGBYTES(sp)
70     SREG x13, 7 * REGBYTES(sp)
71     SREG x14, 8 * REGBYTES(sp)
72     SREG x15, 9 * REGBYTES(sp)
73     SREG x16, 10 * REGBYTES(sp)
74     SREG x17, 11 * REGBYTES(sp)
75     SREG x28, 12 * REGBYTES(sp)
76     SREG x29, 13 * REGBYTES(sp)
77     SREG x30, 14 * REGBYTES(sp)
78     SREG x31, 15 * REGBYTES(sp)
79     addi  sp, sp, -(INT_SIZE_ON_STACK)
80 .endm
81 
82 .macro pop_reg
83     addi  sp, sp, INT_SIZE_ON_STACK
84     LREG x1, 0 * REGBYTES(sp)
85     LREG x5, 1 * REGBYTES(sp)
86     LREG x6, 2 * REGBYTES(sp)
87     LREG x7, 3 * REGBYTES(sp)
88     LREG x10, 4 * REGBYTES(sp)
89     LREG x11, 5 * REGBYTES(sp)
90     LREG x12, 6 * REGBYTES(sp)
91     LREG x13, 7 * REGBYTES(sp)
92     LREG x14, 8 * REGBYTES(sp)
93     LREG x15, 9 * REGBYTES(sp)
94     LREG x16, 10 * REGBYTES(sp)
95     LREG x17, 11 * REGBYTES(sp)
96     LREG x28, 12 * REGBYTES(sp)
97     LREG x29, 13 * REGBYTES(sp)
98     LREG x30, 14 * REGBYTES(sp)
99     LREG x31, 15 * REGBYTES(sp)
100     addi  sp, sp, INT_SIZE_ON_STACK
101 .endm
102 
103 .macro SAVE_ALL
104     addi sp, sp, -(EXC_SIZE_ON_STACK)
105     SREG x1, 1 * REGBYTES(sp)
106     SREG x2, 2 * REGBYTES(sp)
107     SREG x3, 3 * REGBYTES(sp)
108     SREG x4, 4 * REGBYTES(sp)
109     SREG x5, 5 * REGBYTES(sp)
110     SREG x6, 6 * REGBYTES(sp)
111     SREG x7, 7 * REGBYTES(sp)
112     SREG x8, 8 * REGBYTES(sp)
113     SREG x9, 9 * REGBYTES(sp)
114     SREG x10, 10 * REGBYTES(sp)
115     SREG x11, 11 * REGBYTES(sp)
116     SREG x12, 12 * REGBYTES(sp)
117     SREG x13, 13 * REGBYTES(sp)
118     SREG x14, 14 * REGBYTES(sp)
119     SREG x15, 15 * REGBYTES(sp)
120     SREG x16, 16 * REGBYTES(sp)
121     SREG x17, 17 * REGBYTES(sp)
122     SREG x18, 18 * REGBYTES(sp)
123     SREG x19, 19 * REGBYTES(sp)
124     SREG x20, 20 * REGBYTES(sp)
125     SREG x21, 21 * REGBYTES(sp)
126     SREG x22, 22 * REGBYTES(sp)
127     SREG x23, 23 * REGBYTES(sp)
128     SREG x24, 24 * REGBYTES(sp)
129     SREG x25, 25 * REGBYTES(sp)
130     SREG x26, 26 * REGBYTES(sp)
131     SREG x27, 27 * REGBYTES(sp)
132     SREG x28, 28 * REGBYTES(sp)
133     SREG x29, 29 * REGBYTES(sp)
134     SREG x30, 30 * REGBYTES(sp)
135     SREG x31, 31 * REGBYTES(sp)
136 
137     csrr s0, mepc
138     csrr s1, mstatus
139     csrr s2, mbadaddr
140     csrr s3, mcause
141     /* csrr s4, ccause */
142 
143     SREG s0, 0 * REGBYTES(sp)
144     SREG s1, 32 * REGBYTES(sp)
145     SREG s2, 33 * REGBYTES(sp)
146     SREG s3, 34 * REGBYTES(sp)
147     /* SREG s4, 35 * REGBYTES(sp) */
148 .endm
149 
150 .macro RESTORE_ALL
151     LREG a0, 32 * REGBYTES(sp)
152     LREG a1, 0 * REGBYTES(sp)
153     csrw mstatus, a0
154     csrw mepc, a1
155 
156     LREG x1, 1 * REGBYTES(sp)
157     LREG x3, 3 * REGBYTES(sp)
158     LREG x4, 4 * REGBYTES(sp)
159     LREG x5, 5 * REGBYTES(sp)
160     LREG x6, 6 * REGBYTES(sp)
161     LREG x7, 7 * REGBYTES(sp)
162     LREG x8, 8 * REGBYTES(sp)
163     LREG x9, 9 * REGBYTES(sp)
164     LREG x10, 10 * REGBYTES(sp)
165     LREG x11, 11 * REGBYTES(sp)
166     LREG x12, 12 * REGBYTES(sp)
167     LREG x13, 13 * REGBYTES(sp)
168     LREG x14, 14 * REGBYTES(sp)
169     LREG x15, 15 * REGBYTES(sp)
170     LREG x16, 16 * REGBYTES(sp)
171     LREG x17, 17 * REGBYTES(sp)
172     LREG x18, 18 * REGBYTES(sp)
173     LREG x19, 19 * REGBYTES(sp)
174     LREG x20, 20 * REGBYTES(sp)
175     LREG x21, 21 * REGBYTES(sp)
176     LREG x22, 22 * REGBYTES(sp)
177     LREG x23, 23 * REGBYTES(sp)
178     LREG x24, 24 * REGBYTES(sp)
179     LREG x25, 25 * REGBYTES(sp)
180     LREG x26, 26 * REGBYTES(sp)
181     LREG x27, 27 * REGBYTES(sp)
182     LREG x28, 28 * REGBYTES(sp)
183     LREG x29, 29 * REGBYTES(sp)
184     LREG x30, 30 * REGBYTES(sp)
185     LREG x31, 31 * REGBYTES(sp)
186 
187     LREG x2, 2 * REGBYTES(sp)
188     addi sp, sp, (EXC_SIZE_ON_STACK)
189 .endm
190 
191 trap_entry_wrapper:
192     j trap_entry
193 
194 nmi_entry_wrapper:
195     j nmi_entry
196 
197 trap_entry:
198     push_reg
199     csrr t0, mcause
200 #ecall from M-mode
201     li t1, MCAULSE_ECALL_FROM_MMODE
202     bne t0, t1, 1f
203     li t2, MSTATUS_MPP_MACHINE
204     csrc mstatus, t2
205     csrr t0, mepc
206     addi t0, t0, 4
207     csrw mepc, t0
208     pop_reg
209     mret
210 #ecall from U-mode
211 1:
212     li t1, MCAULSE_ECALL_FROM_UMODE
213     bne t0, t1, 2f
214     li t2, MSTATUS_MPP_MACHINE
215     csrs mstatus, t2
216     csrr t0, mepc
217     addi t0, t0, 4
218     csrw mepc, t0
219     pop_reg
220     mret
221 #Other exception.
222 2:
223     pop_reg
224     j trap_entry
225 
226 .align 4
227 nmi_entry:
228     SAVE_ALL
229 
230     csrw mscratch, sp
231     lw sp, g_nmi_stack_end
232     csrr a0, mscratch
233     call boot_nmi_handler
234     csrr sp, mscratch
235 
236 # Remain in M-mode after mret.
237     li t0, MSTATUS_MPP_MACHINE
238     csrs mstatus, t0
239     RESTORE_ALL
240     mret
241 
242 handle_reset:
243     csrwi mstatus, 0
244     csrwi mie, 0
245     csrci mstatus, 0x08
246     la t0, trap_vector
247     addi t0, t0, 1
248     csrw mtvec, t0
249 /* lock mtvec */
250     csrwi 0x7EF, 0x1
251 
252 /* initialize global pointer */
253     .option push
254     .option norelax
255     la gp, __global_pointer$
256     .option pop
257 
258 /* initialize stack pointer */
259     la sp, __stack_top
260 
261 /* perform the rest of initialization in C */
262 clear_bss:
263     la t0, __bss_begin__
264     la t1, __bss_end__
265     li t2, 0x00000000
266 
267 clear_bss_loop:
268     sw      t2, (t0)        /* clear BSS location */
269     addi t0, t0, 4          /* increment clear index pointer */
270     blt     t0, t1, clear_bss_loop /* are we at the end yet, if not , contiue till the end */
271 
272 clear_rom_bss:
273     la t0, __rom_bss_start
274     la t1, __rom_bss_end
275     li t2, 0x00000000
276 
277 clear_rom_bss_loop:
278     sw      t2, (t0)        /* clear ROM_BSS location */
279     addi    t0, t0, 4       /* increment clear index pointer */
280     blt     t0, t1, clear_rom_bss_loop /* are we at the end yet, if not , contiue till the end */
281 
282 clear_code_rom_bss:
283     la t0, __code_rom_bss_start
284     la t1, __code_rom_bss_end
285     li t2, 0x00000000
286 
287 clear_code_rom_bss_loop:
288     sw      t2, (t0)        /* clear ROM_BSS location */
289     addi    t0, t0, 4       /* increment clear index pointer */
290     blt     t0, t1, clear_code_rom_bss_loop /* are we at the end yet, if not , contiue till the end */
291 
292 /* copy .data .sdata section  from  FIX_ROM to SRAM */
293     la t0, __rom_copy_ram_start /* SRAM addr */
294     la t1, __rom_copy_start     /* ROM addr  */
295     la t2, __rom_copy_size
296     add t2, t2, t1
297 
298 start_fixrom_data_loop:
299     lw t3, (t1)
300     sw t3, (t0)
301     addi t0, t0, 4
302     addi t1, t1, 4
303     blt t1, t2, start_fixrom_data_loop /* are we at the end yet, if not , contiue till the end */
304 end_fixrom_data_loop:
305 
306 /* copy .data .sdata section  from  CODE_ROM to SRAM */
307     la t0, __code_rom_copy_ram_start /* SRAM addr */
308     la t1, __code_rom_copy_start     /* ROM addr  */
309     la t2, __code_rom_copy_size
310     add t2, t2, t1
311 
312 start_coderom_data_loop:
313     lw t3, (t1)
314     sw t3, (t0)
315     addi t0, t0, 4
316     addi t1, t1, 4
317     blt t1, t2, start_coderom_data_loop /* are we at the end yet, if not , contiue till the end */
318 end_coderom_data_loop:
319 
320 
321 /* pmp init */
322 pmp_init:
323     li t0, 0xB00
324     csrw pmpaddr0, t0
325     li t0,0x2000
326     csrw pmpaddr1, t0 /* (1)11-32K(0x8000) fixrom: disable w;non-cacheable */
327 #ifdef HI_BOARD_FPGA
328     li t0,0x7fff0
329     csrw pmpaddr2, t0 /* (2)32k(0x8000) - 0x1FFFC0 RAM: non-cacheable */
330     li t0,0x80000
331     csrw pmpaddr3, t0 /* (3)0x1FFFC0 - 0x200000 checkinfo: disable w x;non-cacheable */
332 #else
333     li t0,0x477f0
334     csrw pmpaddr2, t0 /* (2)32k(0x8000) - 0x11DFC0 RAM: disable x;non-cacheable */
335     li t0,0x47800
336     csrw pmpaddr3, t0 /* (3)0x11DFC0 - 0x11E000 checkinfo: disable w x;non-cacheable */
337 #endif
338     li t0,0xEE000
339     csrw pmpaddr4, t0 /* (4)0x11E000 - 0x3B8000 another romboot: disable r-w-x;non-cacheable */
340     li t0,0xFF600
341     csrw pmpaddr5, t0 /* (5)0x3B8000 - 0x3FD800 kernel_rombin: diasble r-w-x;non-cacheable */
342     li t0,0x100000
343     csrw pmpaddr6, t0 /* (6)0x3FD800 - 0x400000 code_rombin(9K): diasble w;non-cacheable */
344     li t0,0x18000000
345     csrw pmpaddr7, t0 /* (7)0x400000 -> 0x60000000 REG: disable x;non-cacheable */
346 
347     li t0,0xf3333333  /* f:Write-back Read and Write-allocate; 3:Normal Non-cacheable Bufferable */
348     csrw 0x7d8,t0
349 
350     li t0,0x090f0d88  /* 0x0d:TOR-R-X; 0x0b:TOR-R-W; 0x08:TOR; 0x0c:TOR-x; 0x09:TOR-R */
351     csrw pmpcfg0,t0
352     li t0,0x0b0d0808
353     csrw pmpcfg1,t0
354 
355 /* disable Icache */
356     csrwi  0x7C0, 0x0 /* disable ICACHE */
357     fence
358 
359 /* disable Dcache */
360     csrwi  0x7C1, 0x0 /* disable DCACHE */
361     fence
362 
363     csrwi mstatus, 0
364     csrwi mie, 0
365     la t0, trap_entry_wrapper
366     addi t0, t0, 1
367     csrw mtvec, t0
368     ecall        /* ecall: M-mode -> U-mode */
369 
370 /* jump to C func. */
371     tail start_loaderboot
372 #endif
373