start.S 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. /* SPDX-License-Identifier: GPL-2.0+ */
  2. /*
  3. * Startup Code for RISC-V Core
  4. *
  5. * Copyright (c) 2017 Microsemi Corporation.
  6. * Copyright (c) 2017 Padmarao Begari <Padmarao.Begari@microsemi.com>
  7. *
  8. * Copyright (C) 2017 Andes Technology Corporation
  9. * Rick Chen, Andes Technology Corporation <rick@andestech.com>
  10. */
  11. #include <asm-offsets.h>
  12. #include <config.h>
  13. #include <common.h>
  14. #include <elf.h>
  15. #include <asm/encoding.h>
  16. #ifdef CONFIG_32BIT
  17. #define LREG lw
  18. #define SREG sw
  19. #define REGBYTES 4
  20. #define RELOC_TYPE R_RISCV_32
  21. #define SYM_INDEX 0x8
  22. #define SYM_SIZE 0x10
  23. #else
  24. #define LREG ld
  25. #define SREG sd
  26. #define REGBYTES 8
  27. #define RELOC_TYPE R_RISCV_64
  28. #define SYM_INDEX 0x20
  29. #define SYM_SIZE 0x18
  30. #endif
  31. .section .text
  32. .globl _start
  33. _start:
  34. /* save hart id and dtb pointer */
  35. mv s0, a0
  36. mv s1, a1
  37. li t0, CONFIG_SYS_SDRAM_BASE
  38. SREG a2, 0(t0)
  39. la t0, trap_entry
  40. csrw mtvec, t0
  41. /* mask all interrupts */
  42. csrw mie, zero
  43. /* Enable cache */
  44. jal icache_enable
  45. jal dcache_enable
  46. /*
  47. * Set stackpointer in internal/ex RAM to call board_init_f
  48. */
  49. call_board_init_f:
  50. li t0, -16
  51. li t1, CONFIG_SYS_INIT_SP_ADDR
  52. and sp, t1, t0 /* force 16 byte alignment */
  53. #ifdef CONFIG_DEBUG_UART
  54. jal debug_uart_init
  55. #endif
  56. call_board_init_f_0:
  57. mv a0, sp
  58. jal board_init_f_alloc_reserve
  59. mv sp, a0
  60. la t0, prior_stage_fdt_address
  61. SREG s1, 0(t0)
  62. jal board_init_f_init_reserve
  63. mv a0, zero /* a0 <-- boot_flags = 0 */
  64. la t5, board_init_f
  65. jr t5 /* jump to board_init_f() */
  66. /*
  67. * void relocate_code (addr_sp, gd, addr_moni)
  68. *
  69. * This "function" does not return, instead it continues in RAM
  70. * after relocating the monitor code.
  71. *
  72. */
  73. .globl relocate_code
  74. relocate_code:
  75. mv s2, a0 /* save addr_sp */
  76. mv s3, a1 /* save addr of gd */
  77. mv s4, a2 /* save addr of destination */
  78. /*
  79. *Set up the stack
  80. */
  81. stack_setup:
  82. mv sp, s2
  83. la t0, _start
  84. sub t6, s4, t0 /* t6 <- relocation offset */
  85. beq t0, s4, clear_bss /* skip relocation */
  86. mv t1, s4 /* t1 <- scratch for copy_loop */
  87. la t3, __bss_start
  88. sub t3, t3, t0 /* t3 <- __bss_start_ofs */
  89. add t2, t0, t3 /* t2 <- source end address */
  90. copy_loop:
  91. LREG t5, 0(t0)
  92. addi t0, t0, REGBYTES
  93. SREG t5, 0(t1)
  94. addi t1, t1, REGBYTES
  95. blt t0, t2, copy_loop
  96. /*
  97. * Update dynamic relocations after board_init_f
  98. */
  99. fix_rela_dyn:
  100. la t1, __rel_dyn_start
  101. la t2, __rel_dyn_end
  102. beq t1, t2, clear_bss
  103. add t1, t1, t6 /* t1 <- rela_dyn_start in RAM */
  104. add t2, t2, t6 /* t2 <- rela_dyn_end in RAM */
  105. /*
  106. * skip first reserved entry: address, type, addend
  107. */
  108. bne t1, t2, 7f
  109. 6:
  110. LREG t5, -(REGBYTES*2)(t1) /* t5 <-- relocation info:type */
  111. li t3, R_RISCV_RELATIVE /* reloc type R_RISCV_RELATIVE */
  112. bne t5, t3, 8f /* skip non-RISCV_RELOC entries */
  113. LREG t3, -(REGBYTES*3)(t1)
  114. LREG t5, -(REGBYTES)(t1) /* t5 <-- addend */
  115. add t5, t5, t6 /* t5 <-- location to fix up in RAM */
  116. add t3, t3, t6 /* t3 <-- location to fix up in RAM */
  117. SREG t5, 0(t3)
  118. 7:
  119. addi t1, t1, (REGBYTES*3)
  120. ble t1, t2, 6b
  121. 8:
  122. la t4, __dyn_sym_start
  123. add t4, t4, t6
  124. 9:
  125. LREG t5, -(REGBYTES*2)(t1) /* t5 <-- relocation info:type */
  126. srli t0, t5, SYM_INDEX /* t0 <--- sym table index */
  127. andi t5, t5, 0xFF /* t5 <--- relocation type */
  128. li t3, RELOC_TYPE
  129. bne t5, t3, 10f /* skip non-addned entries */
  130. LREG t3, -(REGBYTES*3)(t1)
  131. li t5, SYM_SIZE
  132. mul t0, t0, t5
  133. add s5, t4, t0
  134. LREG t5, REGBYTES(s5)
  135. add t5, t5, t6 /* t5 <-- location to fix up in RAM */
  136. add t3, t3, t6 /* t3 <-- location to fix up in RAM */
  137. SREG t5, 0(t3)
  138. 10:
  139. addi t1, t1, (REGBYTES*3)
  140. ble t1, t2, 9b
  141. /*
  142. * trap update
  143. */
  144. la t0, trap_entry
  145. add t0, t0, t6
  146. csrw mtvec, t0
  147. clear_bss:
  148. la t0, __bss_start /* t0 <- rel __bss_start in FLASH */
  149. add t0, t0, t6 /* t0 <- rel __bss_start in RAM */
  150. la t1, __bss_end /* t1 <- rel __bss_end in FLASH */
  151. add t1, t1, t6 /* t1 <- rel __bss_end in RAM */
  152. beq t0, t1, call_board_init_r
  153. clbss_l:
  154. SREG zero, 0(t0) /* clear loop... */
  155. addi t0, t0, REGBYTES
  156. bne t0, t1, clbss_l
  157. /*
  158. * We are done. Do not return, instead branch to second part of board
  159. * initialization, now running from RAM.
  160. */
  161. call_board_init_r:
  162. jal invalidate_icache_all
  163. jal flush_dcache_all
  164. la t0, board_init_r
  165. mv t4, t0 /* offset of board_init_r() */
  166. add t4, t4, t6 /* real address of board_init_r() */
  167. /*
  168. * setup parameters for board_init_r
  169. */
  170. mv a0, s3 /* gd_t */
  171. mv a1, s4 /* dest_addr */
  172. /*
  173. * jump to it ...
  174. */
  175. jr t4 /* jump to board_init_r() */
  176. /*
  177. * trap entry
  178. */
  179. .align 2
  180. trap_entry:
  181. addi sp, sp, -32*REGBYTES
  182. SREG x1, 1*REGBYTES(sp)
  183. SREG x2, 2*REGBYTES(sp)
  184. SREG x3, 3*REGBYTES(sp)
  185. SREG x4, 4*REGBYTES(sp)
  186. SREG x5, 5*REGBYTES(sp)
  187. SREG x6, 6*REGBYTES(sp)
  188. SREG x7, 7*REGBYTES(sp)
  189. SREG x8, 8*REGBYTES(sp)
  190. SREG x9, 9*REGBYTES(sp)
  191. SREG x10, 10*REGBYTES(sp)
  192. SREG x11, 11*REGBYTES(sp)
  193. SREG x12, 12*REGBYTES(sp)
  194. SREG x13, 13*REGBYTES(sp)
  195. SREG x14, 14*REGBYTES(sp)
  196. SREG x15, 15*REGBYTES(sp)
  197. SREG x16, 16*REGBYTES(sp)
  198. SREG x17, 17*REGBYTES(sp)
  199. SREG x18, 18*REGBYTES(sp)
  200. SREG x19, 19*REGBYTES(sp)
  201. SREG x20, 20*REGBYTES(sp)
  202. SREG x21, 21*REGBYTES(sp)
  203. SREG x22, 22*REGBYTES(sp)
  204. SREG x23, 23*REGBYTES(sp)
  205. SREG x24, 24*REGBYTES(sp)
  206. SREG x25, 25*REGBYTES(sp)
  207. SREG x26, 26*REGBYTES(sp)
  208. SREG x27, 27*REGBYTES(sp)
  209. SREG x28, 28*REGBYTES(sp)
  210. SREG x29, 29*REGBYTES(sp)
  211. SREG x30, 30*REGBYTES(sp)
  212. SREG x31, 31*REGBYTES(sp)
  213. csrr a0, mcause
  214. csrr a1, mepc
  215. mv a2, sp
  216. jal handle_trap
  217. csrw mepc, a0
  218. /*
  219. * Remain in M-mode after mret
  220. */
  221. li t0, MSTATUS_MPP
  222. csrs mstatus, t0
  223. LREG x1, 1*REGBYTES(sp)
  224. LREG x2, 2*REGBYTES(sp)
  225. LREG x3, 3*REGBYTES(sp)
  226. LREG x4, 4*REGBYTES(sp)
  227. LREG x5, 5*REGBYTES(sp)
  228. LREG x6, 6*REGBYTES(sp)
  229. LREG x7, 7*REGBYTES(sp)
  230. LREG x8, 8*REGBYTES(sp)
  231. LREG x9, 9*REGBYTES(sp)
  232. LREG x10, 10*REGBYTES(sp)
  233. LREG x11, 11*REGBYTES(sp)
  234. LREG x12, 12*REGBYTES(sp)
  235. LREG x13, 13*REGBYTES(sp)
  236. LREG x14, 14*REGBYTES(sp)
  237. LREG x15, 15*REGBYTES(sp)
  238. LREG x16, 16*REGBYTES(sp)
  239. LREG x17, 17*REGBYTES(sp)
  240. LREG x18, 18*REGBYTES(sp)
  241. LREG x19, 19*REGBYTES(sp)
  242. LREG x20, 20*REGBYTES(sp)
  243. LREG x21, 21*REGBYTES(sp)
  244. LREG x22, 22*REGBYTES(sp)
  245. LREG x23, 23*REGBYTES(sp)
  246. LREG x24, 24*REGBYTES(sp)
  247. LREG x25, 25*REGBYTES(sp)
  248. LREG x26, 26*REGBYTES(sp)
  249. LREG x27, 27*REGBYTES(sp)
  250. LREG x28, 28*REGBYTES(sp)
  251. LREG x29, 29*REGBYTES(sp)
  252. LREG x30, 30*REGBYTES(sp)
  253. LREG x31, 31*REGBYTES(sp)
  254. addi sp, sp, 32*REGBYTES
  255. mret