start.S 6.3 KB

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