1 /*
2  * @file entry.S
3  *
4  * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * @brief RISC-V trap handling and startup code.
18  *
19  */
20 #ifndef ENTRY_S
21 #define ENTRY_S
22 
23 .extern __stack_top
24 
25 #define LREG lw
26 #define SREG sw
27 #define REGBYTES 4
28 
29 #define INT_SIZE_ON_STACK  (16 * REGBYTES)
30 
31 #define MSTATUS_MPP_MACHINE       0x00001800
32 #define MCAULSE_ECALL_FROM_MMODE  11
33 #define MCAULSE_ECALL_FROM_UMODE  8
34 
35     .extern trap_entry
36     .section      .text.entry
37     .global _start
38     .option norvc
39 _start:
40     j handle_reset
41 
42 .macro push_reg
43     addi  sp, sp, -(INT_SIZE_ON_STACK)
44     SREG x1, 0 * REGBYTES(sp)
45     SREG x5, 1 * REGBYTES(sp)
46     SREG x6, 2 * REGBYTES(sp)
47     SREG x7, 3 * REGBYTES(sp)
48     SREG x10, 4 * REGBYTES(sp)
49     SREG x11, 5 * REGBYTES(sp)
50     SREG x12, 6 * REGBYTES(sp)
51     SREG x13, 7 * REGBYTES(sp)
52     SREG x14, 8 * REGBYTES(sp)
53     SREG x15, 9 * REGBYTES(sp)
54     SREG x16, 10 * REGBYTES(sp)
55     SREG x17, 11 * REGBYTES(sp)
56     SREG x28, 12 * REGBYTES(sp)
57     SREG x29, 13 * REGBYTES(sp)
58     SREG x30, 14 * REGBYTES(sp)
59     SREG x31, 15 * REGBYTES(sp)
60     addi  sp, sp, -(INT_SIZE_ON_STACK)
61 .endm
62 
63 .macro pop_reg
64     addi  sp, sp, INT_SIZE_ON_STACK
65     LREG x1, 0 * REGBYTES(sp)
66     LREG x5, 1 * REGBYTES(sp)
67     LREG x6, 2 * REGBYTES(sp)
68     LREG x7, 3 * REGBYTES(sp)
69     LREG x10, 4 * REGBYTES(sp)
70     LREG x11, 5 * REGBYTES(sp)
71     LREG x12, 6 * REGBYTES(sp)
72     LREG x13, 7 * REGBYTES(sp)
73     LREG x14, 8 * REGBYTES(sp)
74     LREG x15, 9 * REGBYTES(sp)
75     LREG x16, 10 * REGBYTES(sp)
76     LREG x17, 11 * REGBYTES(sp)
77     LREG x28, 12 * REGBYTES(sp)
78     LREG x29, 13 * REGBYTES(sp)
79     LREG x30, 14 * REGBYTES(sp)
80     LREG x31, 15 * REGBYTES(sp)
81     addi  sp, sp, INT_SIZE_ON_STACK
82 .endm
83 
84 trap_entry_wrapper:
85     j trap_entry
86 
87 trap_entry:
88     push_reg
89     csrr t0, mcause
90 #ecall from M-mode
91     li t1, MCAULSE_ECALL_FROM_MMODE
92     bne t0, t1, 1f
93     li t2, MSTATUS_MPP_MACHINE
94     csrc mstatus, t2
95     csrr t0, mepc
96     addi t0, t0, 4
97     csrw mepc, t0
98     pop_reg
99     mret
100 #ecall from U-mode
101 1:
102     li t1, MCAULSE_ECALL_FROM_UMODE
103     bne t0, t1, 2f
104     li t2, MSTATUS_MPP_MACHINE
105     csrs mstatus, t2
106     csrr t0, mepc
107     addi t0, t0, 4
108     csrw mepc, t0
109     pop_reg
110     mret
111 #Other exception.
112 2:
113     pop_reg
114     j trap_entry
115 
116 handle_reset:
117     csrwi mstatus, 0
118     csrwi mie, 0
119     csrci mstatus, 0x08
120 
121 /* initialize global pointer */
122     .option push
123     .option norelax
124     la gp, __global_pointer$
125     .option pop
126 
127 /* initialize stack pointer */
128     la sp, __stack_top
129 
130 /* perform the rest of initialization in C */
131 clear_bss:
132     la t0, __bss_begin__
133     la t1, __bss_end__
134     li t2, 0x00000000
135 
136 clear_bss_loop:
137     sw      t2, (t0)        /* clear BSS location */
138     addi t0, t0, 4          /* increment clear index pointer */
139     blt     t0, t1, clear_bss_loop  /* are we at the end yet, if not , contiue till the end */
140 
141 clear_rom_bss:
142     la t0, __rom_bss_start
143     la t1, __rom_bss_end
144     li t2, 0x00000000
145 
146 clear_rom_bss_loop:
147     sw      t2, (t0)        /* clear ROM_BSS location */
148     addi    t0, t0, 4       /* increment clear index pointer */
149     blt     t0, t1, clear_rom_bss_loop /* are we at the end yet, if not , contiue till the end */
150 
151 clear_code_rom_bss:
152     la t0, __code_rom_bss_start
153     la t1, __code_rom_bss_end
154     li t2, 0x00000000
155 
156 clear_code_rom_bss_loop:
157     sw      t2, (t0)        /* clear ROM_BSS location */
158     addi    t0, t0, 4       /* increment clear index pointer */
159     blt     t0, t1, clear_code_rom_bss_loop /* are we at the end yet, if not , contiue till the end */
160 
161 /* copy .data .sdata section  from  FIX_ROM to SRAM */
162     la t0, __rom_copy_ram_start /* SRAM addr */
163     la t1, __rom_copy_start     /* ROM addr  */
164     la t2, __rom_copy_size
165     add t2, t2, t1
166 
167 start_fixrom_data_loop:
168     lw t3, (t1)
169     sw t3, (t0)
170     addi t0, t0, 4
171     addi t1, t1, 4
172     blt t1, t2, start_fixrom_data_loop /* are we at the end yet, if not , contiue till the end */
173 end_fixrom_data_loop:
174 
175 /* copy .data .sdata section  from  CODE_ROM to SRAM */
176     la t0, __code_rom_copy_ram_start /* SRAM addr */
177     la t1, __code_rom_copy_start     /* ROM addr  */
178     la t2, __code_rom_copy_size
179     add t2, t2, t1
180 
181 start_coderom_data_loop:
182     lw t3, (t1)
183     sw t3, (t0)
184     addi t0, t0, 4
185     addi t1, t1, 4
186     blt t1, t2, start_coderom_data_loop /* are we at the end yet, if not , contiue till the end */
187 end_coderom_data_loop:
188 
189 
190 /* pmp init */
191 pmp_init:
192     li t0, 0xB00
193     csrw pmpaddr0, t0
194     li t0,0x2000
195     csrw pmpaddr1, t0 /* (1)11-32K(0x8000) fixrom: disable w;non-cacheable */
196 #ifdef HI_BOARD_ASIC
197     li t0,0x477f0
198     csrw pmpaddr2, t0 /* (2)32k(0x8000) - 0x11DFC0 RAM: disable x;non-cacheable */
199     li t0,0x47800
200     csrw pmpaddr3, t0 /* (3)0x11DFC0 - 0x11E000 checkinfo: disable w x;non-cacheable */
201 #else
202     li t0,0x7fff0
203     csrw pmpaddr2, t0 /* (2)32k(0x8000) - 0x1FFFC0 RAM: non-cacheable */
204     li t0,0x80000
205     csrw pmpaddr3, t0 /* (3)0x1FFFC0 - 0x200000 checkinfo: disable w x;non-cacheable */
206 #endif
207     li t0,0xEE000
208     csrw pmpaddr4, t0 /* (4)0x11E000 - 0x3B8000 another romboot: disable r-w-x;non-cacheable */
209     li t0,0xFF600
210     csrw pmpaddr5, t0 /* (5)0x3B8000 - 0x3FD800 kernel_rombin: diasble r-w-x;non-cacheable */
211     li t0,0x100000
212     csrw pmpaddr6, t0 /* (6)0x3FD800 - 0x400000 code_rombin(9K): diasble w;non-cacheable */
213     li t0,0x18000000
214     csrw pmpaddr7, t0 /* (7)0x400000 -> 0x60000000 REG: disable x;non-cacheable */
215 
216     li t0,0xf3333333  /* f:Write-back Read and Write-allocate; 3:Normal Non-cacheable Bufferable */
217     csrw 0x7d8,t0
218 
219     li t0,0x090f0d88  /* 0x0d:TOR-R-X; 0x0b:TOR-R-W; 0x08:TOR; 0x0c:TOR-x; 0x09:TOR-R */
220     csrw pmpcfg0,t0
221     li t0,0x0b0d0808
222     csrw pmpcfg1,t0
223 
224 /* disable Icache */
225     csrwi  0x7C0, 0x0 /* disable ICACHE */
226     fence
227 
228 /* disable Dcache */
229     csrwi  0x7C1, 0x0 /* disable DCACHE */
230     fence
231 
232     csrwi mstatus, 0
233     csrwi mie, 0
234     la t0, trap_entry_wrapper
235     addi t0, t0, 1
236     csrw mtvec, t0
237     ecall        /* ecall: M-mode -> U-mode */
238 
239 /* jump to C func. */
240     tail start_fastboot
241 #endif
242