start.S 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. /*
  2. * Startup Code for MIPS32 CPU-core
  3. *
  4. * Copyright (c) 2003 Wolfgang Denk <wd@denx.de>
  5. *
  6. * See file CREDITS for list of people who contributed to this
  7. * project.
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License as
  11. * published by the Free Software Foundation; either version 2 of
  12. * the License, or (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  22. * MA 02111-1307 USA
  23. */
  24. #include <config.h>
  25. #include <asm/regdef.h>
  26. #include <asm/mipsregs.h>
  27. /*
  28. * For the moment disable interrupts, mark the kernel mode and
  29. * set ST0_KX so that the CPU does not spit fire when using
  30. * 64-bit addresses.
  31. */
  32. .macro setup_c0_status set clr
  33. .set push
  34. mfc0 t0, CP0_STATUS
  35. or t0, ST0_CU0 | \set | 0x1f | \clr
  36. xor t0, 0x1f | \clr
  37. mtc0 t0, CP0_STATUS
  38. .set noreorder
  39. sll zero, 3 # ehb
  40. .set pop
  41. .endm
  42. .macro setup_c0_status_reset
  43. #ifdef CONFIG_64BIT
  44. setup_c0_status ST0_KX 0
  45. #else
  46. setup_c0_status 0 0
  47. #endif
  48. .endm
  49. #define RVECENT(f,n) \
  50. b f; nop
  51. #define XVECENT(f,bev) \
  52. b f ; \
  53. li k0,bev
  54. .set noreorder
  55. .globl _start
  56. .text
  57. _start:
  58. RVECENT(reset,0) /* U-boot entry point */
  59. RVECENT(reset,1) /* software reboot */
  60. #if defined(CONFIG_INCA_IP)
  61. .word INFINEON_EBU_BOOTCFG /* EBU init code, fetched during booting */
  62. .word 0x00000000 /* phase of the flash */
  63. #elif defined(CONFIG_PURPLE)
  64. .word INFINEON_EBU_BOOTCFG /* EBU init code, fetched during booting */
  65. .word INFINEON_EBU_BOOTCFG /* EBU init code, fetched during booting */
  66. #else
  67. RVECENT(romReserved,2)
  68. #endif
  69. RVECENT(romReserved,3)
  70. RVECENT(romReserved,4)
  71. RVECENT(romReserved,5)
  72. RVECENT(romReserved,6)
  73. RVECENT(romReserved,7)
  74. RVECENT(romReserved,8)
  75. RVECENT(romReserved,9)
  76. RVECENT(romReserved,10)
  77. RVECENT(romReserved,11)
  78. RVECENT(romReserved,12)
  79. RVECENT(romReserved,13)
  80. RVECENT(romReserved,14)
  81. RVECENT(romReserved,15)
  82. RVECENT(romReserved,16)
  83. RVECENT(romReserved,17)
  84. RVECENT(romReserved,18)
  85. RVECENT(romReserved,19)
  86. RVECENT(romReserved,20)
  87. RVECENT(romReserved,21)
  88. RVECENT(romReserved,22)
  89. RVECENT(romReserved,23)
  90. RVECENT(romReserved,24)
  91. RVECENT(romReserved,25)
  92. RVECENT(romReserved,26)
  93. RVECENT(romReserved,27)
  94. RVECENT(romReserved,28)
  95. RVECENT(romReserved,29)
  96. RVECENT(romReserved,30)
  97. RVECENT(romReserved,31)
  98. RVECENT(romReserved,32)
  99. RVECENT(romReserved,33)
  100. RVECENT(romReserved,34)
  101. RVECENT(romReserved,35)
  102. RVECENT(romReserved,36)
  103. RVECENT(romReserved,37)
  104. RVECENT(romReserved,38)
  105. RVECENT(romReserved,39)
  106. RVECENT(romReserved,40)
  107. RVECENT(romReserved,41)
  108. RVECENT(romReserved,42)
  109. RVECENT(romReserved,43)
  110. RVECENT(romReserved,44)
  111. RVECENT(romReserved,45)
  112. RVECENT(romReserved,46)
  113. RVECENT(romReserved,47)
  114. RVECENT(romReserved,48)
  115. RVECENT(romReserved,49)
  116. RVECENT(romReserved,50)
  117. RVECENT(romReserved,51)
  118. RVECENT(romReserved,52)
  119. RVECENT(romReserved,53)
  120. RVECENT(romReserved,54)
  121. RVECENT(romReserved,55)
  122. RVECENT(romReserved,56)
  123. RVECENT(romReserved,57)
  124. RVECENT(romReserved,58)
  125. RVECENT(romReserved,59)
  126. RVECENT(romReserved,60)
  127. RVECENT(romReserved,61)
  128. RVECENT(romReserved,62)
  129. RVECENT(romReserved,63)
  130. XVECENT(romExcHandle,0x200) /* bfc00200: R4000 tlbmiss vector */
  131. RVECENT(romReserved,65)
  132. RVECENT(romReserved,66)
  133. RVECENT(romReserved,67)
  134. RVECENT(romReserved,68)
  135. RVECENT(romReserved,69)
  136. RVECENT(romReserved,70)
  137. RVECENT(romReserved,71)
  138. RVECENT(romReserved,72)
  139. RVECENT(romReserved,73)
  140. RVECENT(romReserved,74)
  141. RVECENT(romReserved,75)
  142. RVECENT(romReserved,76)
  143. RVECENT(romReserved,77)
  144. RVECENT(romReserved,78)
  145. RVECENT(romReserved,79)
  146. XVECENT(romExcHandle,0x280) /* bfc00280: R4000 xtlbmiss vector */
  147. RVECENT(romReserved,81)
  148. RVECENT(romReserved,82)
  149. RVECENT(romReserved,83)
  150. RVECENT(romReserved,84)
  151. RVECENT(romReserved,85)
  152. RVECENT(romReserved,86)
  153. RVECENT(romReserved,87)
  154. RVECENT(romReserved,88)
  155. RVECENT(romReserved,89)
  156. RVECENT(romReserved,90)
  157. RVECENT(romReserved,91)
  158. RVECENT(romReserved,92)
  159. RVECENT(romReserved,93)
  160. RVECENT(romReserved,94)
  161. RVECENT(romReserved,95)
  162. XVECENT(romExcHandle,0x300) /* bfc00300: R4000 cache vector */
  163. RVECENT(romReserved,97)
  164. RVECENT(romReserved,98)
  165. RVECENT(romReserved,99)
  166. RVECENT(romReserved,100)
  167. RVECENT(romReserved,101)
  168. RVECENT(romReserved,102)
  169. RVECENT(romReserved,103)
  170. RVECENT(romReserved,104)
  171. RVECENT(romReserved,105)
  172. RVECENT(romReserved,106)
  173. RVECENT(romReserved,107)
  174. RVECENT(romReserved,108)
  175. RVECENT(romReserved,109)
  176. RVECENT(romReserved,110)
  177. RVECENT(romReserved,111)
  178. XVECENT(romExcHandle,0x380) /* bfc00380: R4000 general vector */
  179. RVECENT(romReserved,113)
  180. RVECENT(romReserved,114)
  181. RVECENT(romReserved,115)
  182. RVECENT(romReserved,116)
  183. RVECENT(romReserved,116)
  184. RVECENT(romReserved,118)
  185. RVECENT(romReserved,119)
  186. RVECENT(romReserved,120)
  187. RVECENT(romReserved,121)
  188. RVECENT(romReserved,122)
  189. RVECENT(romReserved,123)
  190. RVECENT(romReserved,124)
  191. RVECENT(romReserved,125)
  192. RVECENT(romReserved,126)
  193. RVECENT(romReserved,127)
  194. /* We hope there are no more reserved vectors!
  195. * 128 * 8 == 1024 == 0x400
  196. * so this is address R_VEC+0x400 == 0xbfc00400
  197. */
  198. #ifdef CONFIG_PURPLE
  199. /* 0xbfc00400 */
  200. .word 0xdc870000
  201. .word 0xfca70000
  202. .word 0x20840008
  203. .word 0x20a50008
  204. .word 0x20c6ffff
  205. .word 0x14c0fffa
  206. .word 0x00000000
  207. .word 0x03e00008
  208. .word 0x00000000
  209. .word 0x00000000
  210. /* 0xbfc00428 */
  211. .word 0xdc870000
  212. .word 0xfca70000
  213. .word 0x20840008
  214. .word 0x20a50008
  215. .word 0x20c6ffff
  216. .word 0x14c0fffa
  217. .word 0x00000000
  218. .word 0x03e00008
  219. .word 0x00000000
  220. .word 0x00000000
  221. #endif /* CONFIG_PURPLE */
  222. .align 4
  223. reset:
  224. /* Clear watch registers.
  225. */
  226. mtc0 zero, CP0_WATCHLO
  227. mtc0 zero, CP0_WATCHHI
  228. /* WP(Watch Pending), SW0/1 should be cleared. */
  229. mtc0 zero, CP0_CAUSE
  230. setup_c0_status_reset
  231. /* Init Timer */
  232. mtc0 zero, CP0_COUNT
  233. mtc0 zero, CP0_COMPARE
  234. /* CONFIG0 register */
  235. li t0, CONF_CM_UNCACHED
  236. mtc0 t0, CP0_CONFIG
  237. /* Initialize $gp.
  238. */
  239. bal 1f
  240. nop
  241. .word _gp
  242. 1:
  243. lw gp, 0(ra)
  244. /* Initialize any external memory.
  245. */
  246. la t9, lowlevel_init
  247. jalr t9
  248. nop
  249. /* Initialize caches...
  250. */
  251. la t9, mips_cache_reset
  252. jalr t9
  253. nop
  254. /* ... and enable them.
  255. */
  256. li t0, CONF_CM_CACHABLE_NONCOHERENT
  257. mtc0 t0, CP0_CONFIG
  258. /* Set up temporary stack.
  259. */
  260. #ifdef CFG_INIT_RAM_LOCK_MIPS
  261. li a0, CFG_INIT_SP_OFFSET
  262. la t9, mips_cache_lock
  263. jalr t9
  264. nop
  265. #endif
  266. li t0, CFG_SDRAM_BASE + CFG_INIT_SP_OFFSET
  267. la sp, 0(t0)
  268. la t9, board_init_f
  269. jr t9
  270. nop
  271. /*
  272. * void relocate_code (addr_sp, gd, addr_moni)
  273. *
  274. * This "function" does not return, instead it continues in RAM
  275. * after relocating the monitor code.
  276. *
  277. * a0 = addr_sp
  278. * a1 = gd
  279. * a2 = destination address
  280. */
  281. .globl relocate_code
  282. .ent relocate_code
  283. relocate_code:
  284. move sp, a0 /* Set new stack pointer */
  285. li t0, CFG_MONITOR_BASE
  286. la t3, in_ram
  287. lw t2, -12(t3) /* t2 <-- uboot_end_data */
  288. move t1, a2
  289. /*
  290. * Fix $gp:
  291. *
  292. * New $gp = (Old $gp - CFG_MONITOR_BASE) + Destination Address
  293. */
  294. move t6, gp
  295. sub gp, CFG_MONITOR_BASE
  296. add gp, a2 /* gp now adjusted */
  297. sub t6, gp, t6 /* t6 <-- relocation offset */
  298. /*
  299. * t0 = source address
  300. * t1 = target address
  301. * t2 = source end address
  302. */
  303. /* On the purple board we copy the code earlier in a special way
  304. * in order to solve flash problems
  305. */
  306. #ifndef CONFIG_PURPLE
  307. 1:
  308. lw t3, 0(t0)
  309. sw t3, 0(t1)
  310. addu t0, 4
  311. ble t0, t2, 1b
  312. addu t1, 4 /* delay slot */
  313. #endif
  314. /* If caches were enabled, we would have to flush them here.
  315. */
  316. /* Jump to where we've relocated ourselves.
  317. */
  318. addi t0, a2, in_ram - _start
  319. jr t0
  320. nop
  321. .word _gp
  322. .word _GLOBAL_OFFSET_TABLE_
  323. .word uboot_end_data
  324. .word uboot_end
  325. .word num_got_entries
  326. in_ram:
  327. /*
  328. * Now we want to update GOT.
  329. *
  330. * GOT[0] is reserved. GOT[1] is also reserved for the dynamic object
  331. * generated by GNU ld. Skip these reserved entries from relocation.
  332. */
  333. lw t3, -4(t0) /* t3 <-- num_got_entries */
  334. lw t4, -16(t0) /* t4 <-- _GLOBAL_OFFSET_TABLE_ */
  335. lw t5, -20(t0) /* t5 <-- _gp */
  336. sub t4, t5 /* compute offset*/
  337. add t4, t4, gp /* t4 now holds relocated _GLOBAL_OFFSET_TABLE_ */
  338. addi t4, t4, 8 /* Skipping first two entries. */
  339. li t2, 2
  340. 1:
  341. lw t1, 0(t4)
  342. beqz t1, 2f
  343. add t1, t6
  344. sw t1, 0(t4)
  345. 2:
  346. addi t2, 1
  347. blt t2, t3, 1b
  348. addi t4, 4 /* delay slot */
  349. /* Clear BSS.
  350. */
  351. lw t1, -12(t0) /* t1 <-- uboot_end_data */
  352. lw t2, -8(t0) /* t2 <-- uboot_end */
  353. add t1, t6 /* adjust pointers */
  354. add t2, t6
  355. sub t1, 4
  356. 1:
  357. addi t1, 4
  358. bltl t1, t2, 1b
  359. sw zero, 0(t1) /* delay slot */
  360. move a0, a1
  361. la t9, board_init_r
  362. jr t9
  363. move a1, a2 /* delay slot */
  364. .end relocate_code
  365. /* Exception handlers.
  366. */
  367. romReserved:
  368. b romReserved
  369. romExcHandle:
  370. b romExcHandle