• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
43trap_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
191trap_entry_wrapper:
192    j trap_entry
193
194nmi_entry_wrapper:
195    j nmi_entry
196
197trap_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
2111:
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.
2222:
223    pop_reg
224    j trap_entry
225
226.align 4
227nmi_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
242handle_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 */
262clear_bss:
263    la t0, __bss_begin__
264    la t1, __bss_end__
265    li t2, 0x00000000
266
267clear_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
272clear_rom_bss:
273    la t0, __rom_bss_start
274    la t1, __rom_bss_end
275    li t2, 0x00000000
276
277clear_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
282clear_code_rom_bss:
283    la t0, __code_rom_bss_start
284    la t1, __code_rom_bss_end
285    li t2, 0x00000000
286
287clear_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
298start_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 */
304end_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
312start_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 */
318end_coderom_data_loop:
319
320
321/* pmp init */
322pmp_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