start.S 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. /* SPDX-License-Identifier: GPL-2.0+ */
  2. /*
  3. * Startup Code for MIPS32 CPU-core
  4. *
  5. * Copyright (c) 2003 Wolfgang Denk <wd@denx.de>
  6. */
  7. #include <asm-offsets.h>
  8. #include <config.h>
  9. #include <asm/asm.h>
  10. #include <asm/regdef.h>
  11. #include <asm/mipsregs.h>
  12. #ifndef CONFIG_SYS_INIT_SP_ADDR
  13. #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + \
  14. CONFIG_SYS_INIT_SP_OFFSET)
  15. #endif
  16. #ifdef CONFIG_32BIT
  17. # define MIPS_RELOC 3
  18. # define STATUS_SET 0
  19. #endif
  20. #ifdef CONFIG_64BIT
  21. # ifdef CONFIG_SYS_LITTLE_ENDIAN
  22. # define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \
  23. (((r_type) << 24) | ((r_type2) << 16) | ((r_type3) << 8) | (ssym))
  24. # else
  25. # define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \
  26. ((r_type) | ((r_type2) << 8) | ((r_type3) << 16) | (ssym) << 24)
  27. # endif
  28. # define MIPS_RELOC MIPS64_R_INFO(0x00, 0x00, 0x12, 0x03)
  29. # define STATUS_SET ST0_KX
  30. #endif
  31. .set noreorder
  32. .macro init_wr sel
  33. MTC0 zero, CP0_WATCHLO,\sel
  34. mtc0 t1, CP0_WATCHHI,\sel
  35. mfc0 t0, CP0_WATCHHI,\sel
  36. bgez t0, wr_done
  37. nop
  38. .endm
  39. .macro uhi_mips_exception
  40. move k0, t9 # preserve t9 in k0
  41. move k1, a0 # preserve a0 in k1
  42. li t9, 15 # UHI exception operation
  43. li a0, 0 # Use hard register context
  44. sdbbp 1 # Invoke UHI operation
  45. .endm
  46. .macro setup_stack_gd
  47. li t0, -16
  48. PTR_LI t1, CONFIG_SYS_INIT_SP_ADDR
  49. and sp, t1, t0 # force 16 byte alignment
  50. PTR_SUBU \
  51. sp, sp, GD_SIZE # reserve space for gd
  52. and sp, sp, t0 # force 16 byte alignment
  53. move k0, sp # save gd pointer
  54. #if CONFIG_VAL(SYS_MALLOC_F_LEN)
  55. li t2, CONFIG_VAL(SYS_MALLOC_F_LEN)
  56. PTR_SUBU \
  57. sp, sp, t2 # reserve space for early malloc
  58. and sp, sp, t0 # force 16 byte alignment
  59. #endif
  60. move fp, sp
  61. /* Clear gd */
  62. move t0, k0
  63. 1:
  64. PTR_S zero, 0(t0)
  65. blt t0, t1, 1b
  66. PTR_ADDIU t0, PTRSIZE
  67. #if CONFIG_VAL(SYS_MALLOC_F_LEN)
  68. PTR_S sp, GD_MALLOC_BASE(k0) # gd->malloc_base offset
  69. #endif
  70. .endm
  71. ENTRY(_start)
  72. /* U-Boot entry point */
  73. b reset
  74. mtc0 zero, CP0_COUNT # clear cp0 count for most accurate boot timing
  75. #if defined(CONFIG_MIPS_INSERT_BOOT_CONFIG)
  76. /*
  77. * Store some board-specific boot configuration. This is used by some
  78. * MIPS systems like Malta.
  79. */
  80. .org 0x10
  81. .word CONFIG_MIPS_BOOT_CONFIG_WORD0
  82. .word CONFIG_MIPS_BOOT_CONFIG_WORD1
  83. #endif
  84. #if defined(CONFIG_ROM_EXCEPTION_VECTORS)
  85. /*
  86. * Exception vector entry points. When running from ROM, an exception
  87. * cannot be handled. Halt execution and transfer control to debugger,
  88. * if one is attached.
  89. */
  90. .org 0x200
  91. /* TLB refill, 32 bit task */
  92. uhi_mips_exception
  93. .org 0x280
  94. /* XTLB refill, 64 bit task */
  95. uhi_mips_exception
  96. .org 0x300
  97. /* Cache error exception */
  98. uhi_mips_exception
  99. .org 0x380
  100. /* General exception */
  101. uhi_mips_exception
  102. .org 0x400
  103. /* Catch interrupt exceptions */
  104. uhi_mips_exception
  105. .org 0x480
  106. /* EJTAG debug exception */
  107. 1: b 1b
  108. nop
  109. .org 0x500
  110. #endif
  111. reset:
  112. #if __mips_isa_rev >= 6
  113. mfc0 t0, CP0_CONFIG, 5
  114. and t0, t0, MIPS_CONF5_VP
  115. beqz t0, 1f
  116. nop
  117. b 2f
  118. mfc0 t0, CP0_GLOBALNUMBER
  119. #endif
  120. #ifdef CONFIG_ARCH_BMIPS
  121. 1: mfc0 t0, CP0_DIAGNOSTIC, 3
  122. and t0, t0, (1 << 31)
  123. #else
  124. 1: mfc0 t0, CP0_EBASE
  125. and t0, t0, EBASE_CPUNUM
  126. #endif
  127. /* Hang if this isn't the first CPU in the system */
  128. 2: beqz t0, 4f
  129. nop
  130. 3: wait
  131. b 3b
  132. nop
  133. /* Init CP0 Status */
  134. 4: mfc0 t0, CP0_STATUS
  135. and t0, ST0_IMPL
  136. or t0, ST0_BEV | ST0_ERL | STATUS_SET
  137. mtc0 t0, CP0_STATUS
  138. /*
  139. * Check whether CP0 Config1 is implemented. If not continue
  140. * with legacy Watch register initialization.
  141. */
  142. mfc0 t0, CP0_CONFIG
  143. bgez t0, wr_legacy
  144. nop
  145. /*
  146. * Check WR bit in CP0 Config1 to determine if Watch registers
  147. * are implemented.
  148. */
  149. mfc0 t0, CP0_CONFIG, 1
  150. andi t0, (1 << 3)
  151. beqz t0, wr_done
  152. nop
  153. /* Clear Watch Status bits and disable watch exceptions */
  154. li t1, 0x7 # Clear I, R and W conditions
  155. init_wr 0
  156. init_wr 1
  157. init_wr 2
  158. init_wr 3
  159. init_wr 4
  160. init_wr 5
  161. init_wr 6
  162. init_wr 7
  163. b wr_done
  164. nop
  165. wr_legacy:
  166. MTC0 zero, CP0_WATCHLO
  167. mtc0 zero, CP0_WATCHHI
  168. wr_done:
  169. /* Clear WP, IV and SW interrupts */
  170. mtc0 zero, CP0_CAUSE
  171. /* Clear timer interrupt (CP0_COUNT cleared on branch to 'reset') */
  172. mtc0 zero, CP0_COMPARE
  173. #ifndef CONFIG_SKIP_LOWLEVEL_INIT
  174. mfc0 t0, CP0_CONFIG
  175. and t0, t0, MIPS_CONF_IMPL
  176. or t0, t0, CONF_CM_UNCACHED
  177. mtc0 t0, CP0_CONFIG
  178. ehb
  179. #endif
  180. #ifdef CONFIG_MIPS_CM
  181. PTR_LA t9, mips_cm_map
  182. jalr t9
  183. nop
  184. #endif
  185. #ifdef CONFIG_MIPS_INIT_STACK_IN_SRAM
  186. /* Set up initial stack and global data */
  187. setup_stack_gd
  188. # ifdef CONFIG_DEBUG_UART
  189. /* Earliest point to set up debug uart */
  190. PTR_LA t9, debug_uart_init
  191. jalr t9
  192. nop
  193. # endif
  194. #endif
  195. #ifndef CONFIG_SKIP_LOWLEVEL_INIT
  196. # ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
  197. /* Initialize any external memory */
  198. PTR_LA t9, lowlevel_init
  199. jalr t9
  200. nop
  201. # endif
  202. /* Initialize caches... */
  203. PTR_LA t9, mips_cache_reset
  204. jalr t9
  205. nop
  206. # ifndef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
  207. /* Initialize any external memory */
  208. PTR_LA t9, lowlevel_init
  209. jalr t9
  210. nop
  211. # endif
  212. #endif
  213. #ifndef CONFIG_MIPS_INIT_STACK_IN_SRAM
  214. /* Set up initial stack and global data */
  215. setup_stack_gd
  216. # ifdef CONFIG_DEBUG_UART
  217. /* Earliest point to set up debug uart */
  218. PTR_LA t9, debug_uart_init
  219. jalr t9
  220. nop
  221. # endif
  222. #endif
  223. move a0, zero # a0 <-- boot_flags = 0
  224. PTR_LA t9, board_init_f
  225. jr t9
  226. move ra, zero
  227. END(_start)