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