start.S 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. /*
  2. * armboot - Startup Code for OMAP3530/ARM Cortex CPU-core
  3. *
  4. * Copyright (c) 2004 Texas Instruments <r-woodruff2@ti.com>
  5. *
  6. * Copyright (c) 2001 Marius Gröger <mag@sysgo.de>
  7. * Copyright (c) 2002 Alex Züpke <azu@sysgo.de>
  8. * Copyright (c) 2002 Gary Jennejohn <garyj@denx.de>
  9. * Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com>
  10. * Copyright (c) 2003 Kshitij <kshitij@ti.com>
  11. * Copyright (c) 2006-2008 Syed Mohammed Khasim <x0khasim@ti.com>
  12. *
  13. * See file CREDITS for list of people who contributed to this
  14. * project.
  15. *
  16. * This program is free software; you can redistribute it and/or
  17. * modify it under the terms of the GNU General Public License as
  18. * published by the Free Software Foundation; either version 2 of
  19. * the License, or (at your option) any later version.
  20. *
  21. * This program is distributed in the hope that it will be useful,
  22. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  23. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  24. * GNU General Public License for more details.
  25. *
  26. * You should have received a copy of the GNU General Public License
  27. * along with this program; if not, write to the Free Software
  28. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  29. * MA 02111-1307 USA
  30. */
  31. #include <config.h>
  32. #include <version.h>
  33. .globl _start
  34. _start: b reset
  35. ldr pc, _undefined_instruction
  36. ldr pc, _software_interrupt
  37. ldr pc, _prefetch_abort
  38. ldr pc, _data_abort
  39. ldr pc, _not_used
  40. ldr pc, _irq
  41. ldr pc, _fiq
  42. _undefined_instruction: .word undefined_instruction
  43. _software_interrupt: .word software_interrupt
  44. _prefetch_abort: .word prefetch_abort
  45. _data_abort: .word data_abort
  46. _not_used: .word not_used
  47. _irq: .word irq
  48. _fiq: .word fiq
  49. _pad: .word 0x12345678 /* now 16*4=64 */
  50. .global _end_vect
  51. _end_vect:
  52. .balignl 16,0xdeadbeef
  53. /*************************************************************************
  54. *
  55. * Startup Code (reset vector)
  56. *
  57. * do important init only if we don't start from memory!
  58. * setup Memory and board specific bits prior to relocation.
  59. * relocate armboot to ram
  60. * setup stack
  61. *
  62. *************************************************************************/
  63. _TEXT_BASE:
  64. .word TEXT_BASE
  65. .globl _armboot_start
  66. _armboot_start:
  67. .word _start
  68. /*
  69. * These are defined in the board-specific linker script.
  70. */
  71. .globl _bss_start
  72. _bss_start:
  73. .word __bss_start
  74. .globl _bss_end
  75. _bss_end:
  76. .word _end
  77. #ifdef CONFIG_USE_IRQ
  78. /* IRQ stack memory (calculated at run-time) */
  79. .globl IRQ_STACK_START
  80. IRQ_STACK_START:
  81. .word 0x0badc0de
  82. /* IRQ stack memory (calculated at run-time) */
  83. .globl FIQ_STACK_START
  84. FIQ_STACK_START:
  85. .word 0x0badc0de
  86. #endif
  87. /*
  88. * the actual reset code
  89. */
  90. reset:
  91. /*
  92. * set the cpu to SVC32 mode
  93. */
  94. mrs r0, cpsr
  95. bic r0, r0, #0x1f
  96. orr r0, r0, #0xd3
  97. msr cpsr,r0
  98. #if (CONFIG_OMAP34XX)
  99. /* Copy vectors to mask ROM indirect addr */
  100. adr r0, _start @ r0 <- current position of code
  101. add r0, r0, #4 @ skip reset vector
  102. mov r2, #64 @ r2 <- size to copy
  103. add r2, r0, r2 @ r2 <- source end address
  104. mov r1, #SRAM_OFFSET0 @ build vect addr
  105. mov r3, #SRAM_OFFSET1
  106. add r1, r1, r3
  107. mov r3, #SRAM_OFFSET2
  108. add r1, r1, r3
  109. next:
  110. ldmia r0!, {r3 - r10} @ copy from source address [r0]
  111. stmia r1!, {r3 - r10} @ copy to target address [r1]
  112. cmp r0, r2 @ until source end address [r2]
  113. bne next @ loop until equal */
  114. #if !defined(CONFIG_SYS_NAND_BOOT) && !defined(CONFIG_SYS_ONENAND_BOOT)
  115. /* No need to copy/exec the clock code - DPLL adjust already done
  116. * in NAND/oneNAND Boot.
  117. */
  118. bl cpy_clk_code @ put dpll adjust code behind vectors
  119. #endif /* NAND Boot */
  120. #endif
  121. /* the mask ROM code should have PLL and others stable */
  122. #ifndef CONFIG_SKIP_LOWLEVEL_INIT
  123. bl cpu_init_crit
  124. #endif
  125. #ifndef CONFIG_SKIP_RELOCATE_UBOOT
  126. relocate: @ relocate U-Boot to RAM
  127. adr r0, _start @ r0 <- current position of code
  128. ldr r1, _TEXT_BASE @ test if we run from flash or RAM
  129. cmp r0, r1 @ don't reloc during debug
  130. beq stack_setup
  131. ldr r2, _armboot_start
  132. ldr r3, _bss_start
  133. sub r2, r3, r2 @ r2 <- size of armboot
  134. add r2, r0, r2 @ r2 <- source end address
  135. copy_loop: @ copy 32 bytes at a time
  136. ldmia r0!, {r3 - r10} @ copy from source address [r0]
  137. stmia r1!, {r3 - r10} @ copy to target address [r1]
  138. cmp r0, r2 @ until source end addreee [r2]
  139. ble copy_loop
  140. #endif /* CONFIG_SKIP_RELOCATE_UBOOT */
  141. /* Set up the stack */
  142. stack_setup:
  143. ldr r0, _TEXT_BASE @ upper 128 KiB: relocated uboot
  144. sub r0, r0, #CONFIG_SYS_MALLOC_LEN @ malloc area
  145. sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE @ bdinfo
  146. #ifdef CONFIG_USE_IRQ
  147. sub r0, r0, #(CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ)
  148. #endif
  149. sub sp, r0, #12 @ leave 3 words for abort-stack
  150. and sp, sp, #~7 @ 8 byte alinged for (ldr/str)d
  151. /* Clear BSS (if any). Is below tx (watch load addr - need space) */
  152. clear_bss:
  153. ldr r0, _bss_start @ find start of bss segment
  154. ldr r1, _bss_end @ stop here
  155. mov r2, #0x00000000 @ clear value
  156. clbss_l:
  157. str r2, [r0] @ clear BSS location
  158. cmp r0, r1 @ are we at the end yet
  159. add r0, r0, #4 @ increment clear index pointer
  160. bne clbss_l @ keep clearing till at end
  161. ldr pc, _start_armboot @ jump to C code
  162. _start_armboot: .word start_armboot
  163. /*************************************************************************
  164. *
  165. * CPU_init_critical registers
  166. *
  167. * setup important registers
  168. * setup memory timing
  169. *
  170. *************************************************************************/
  171. cpu_init_crit:
  172. /*
  173. * Invalidate L1 I/D
  174. */
  175. mov r0, #0 @ set up for MCR
  176. mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs
  177. mcr p15, 0, r0, c7, c5, 0 @ invalidate icache
  178. /*
  179. * disable MMU stuff and caches
  180. */
  181. mrc p15, 0, r0, c1, c0, 0
  182. bic r0, r0, #0x00002000 @ clear bits 13 (--V-)
  183. bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM)
  184. orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align
  185. orr r0, r0, #0x00000800 @ set bit 12 (Z---) BTB
  186. mcr p15, 0, r0, c1, c0, 0
  187. /*
  188. * Jump to board specific initialization...
  189. * The Mask ROM will have already initialized
  190. * basic memory. Go here to bump up clock rate and handle
  191. * wake up conditions.
  192. */
  193. mov ip, lr @ persevere link reg across call
  194. bl lowlevel_init @ go setup pll,mux,memory
  195. mov lr, ip @ restore link
  196. mov pc, lr @ back to my caller
  197. /*
  198. *************************************************************************
  199. *
  200. * Interrupt handling
  201. *
  202. *************************************************************************
  203. */
  204. @
  205. @ IRQ stack frame.
  206. @
  207. #define S_FRAME_SIZE 72
  208. #define S_OLD_R0 68
  209. #define S_PSR 64
  210. #define S_PC 60
  211. #define S_LR 56
  212. #define S_SP 52
  213. #define S_IP 48
  214. #define S_FP 44
  215. #define S_R10 40
  216. #define S_R9 36
  217. #define S_R8 32
  218. #define S_R7 28
  219. #define S_R6 24
  220. #define S_R5 20
  221. #define S_R4 16
  222. #define S_R3 12
  223. #define S_R2 8
  224. #define S_R1 4
  225. #define S_R0 0
  226. #define MODE_SVC 0x13
  227. #define I_BIT 0x80
  228. /*
  229. * use bad_save_user_regs for abort/prefetch/undef/swi ...
  230. * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
  231. */
  232. .macro bad_save_user_regs
  233. sub sp, sp, #S_FRAME_SIZE @ carve out a frame on current
  234. @ user stack
  235. stmia sp, {r0 - r12} @ Save user registers (now in
  236. @ svc mode) r0-r12
  237. ldr r2, _armboot_start
  238. sub r2, r2, #(CONFIG_SYS_MALLOC_LEN)
  239. sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE + 8) @ set base 2 words into abort
  240. @ stack
  241. ldmia r2, {r2 - r3} @ get values for "aborted" pc
  242. @ and cpsr (into parm regs)
  243. add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack
  244. add r5, sp, #S_SP
  245. mov r1, lr
  246. stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
  247. mov r0, sp @ save current stack into r0
  248. @ (param register)
  249. .endm
  250. .macro irq_save_user_regs
  251. sub sp, sp, #S_FRAME_SIZE
  252. stmia sp, {r0 - r12} @ Calling r0-r12
  253. add r8, sp, #S_PC @ !! R8 NEEDS to be saved !!
  254. @ a reserved stack spot would
  255. @ be good.
  256. stmdb r8, {sp, lr}^ @ Calling SP, LR
  257. str lr, [r8, #0] @ Save calling PC
  258. mrs r6, spsr
  259. str r6, [r8, #4] @ Save CPSR
  260. str r0, [r8, #8] @ Save OLD_R0
  261. mov r0, sp
  262. .endm
  263. .macro irq_restore_user_regs
  264. ldmia sp, {r0 - lr}^ @ Calling r0 - lr
  265. mov r0, r0
  266. ldr lr, [sp, #S_PC] @ Get PC
  267. add sp, sp, #S_FRAME_SIZE
  268. subs pc, lr, #4 @ return & move spsr_svc into
  269. @ cpsr
  270. .endm
  271. .macro get_bad_stack
  272. ldr r13, _armboot_start @ setup our mode stack (enter
  273. @ in banked mode)
  274. sub r13, r13, #(CONFIG_SYS_MALLOC_LEN) @ move past malloc pool
  275. sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE + 8) @ move to reserved a couple
  276. @ spots for abort stack
  277. str lr, [r13] @ save caller lr in position 0
  278. @ of saved stack
  279. mrs lr, spsr @ get the spsr
  280. str lr, [r13, #4] @ save spsr in position 1 of
  281. @ saved stack
  282. mov r13, #MODE_SVC @ prepare SVC-Mode
  283. @ msr spsr_c, r13
  284. msr spsr, r13 @ switch modes, make sure
  285. @ moves will execute
  286. mov lr, pc @ capture return pc
  287. movs pc, lr @ jump to next instruction &
  288. @ switch modes.
  289. .endm
  290. .macro get_bad_stack_swi
  291. sub r13, r13, #4 @ space on current stack for
  292. @ scratch reg.
  293. str r0, [r13] @ save R0's value.
  294. ldr r0, _armboot_start @ get data regions start
  295. sub r0, r0, #(CONFIG_SYS_MALLOC_LEN) @ move past malloc pool
  296. sub r0, r0, #(CONFIG_SYS_GBL_DATA_SIZE + 8) @ move past gbl and a couple
  297. @ spots for abort stack
  298. str lr, [r0] @ save caller lr in position 0
  299. @ of saved stack
  300. mrs r0, spsr @ get the spsr
  301. str lr, [r0, #4] @ save spsr in position 1 of
  302. @ saved stack
  303. ldr r0, [r13] @ restore r0
  304. add r13, r13, #4 @ pop stack entry
  305. .endm
  306. .macro get_irq_stack @ setup IRQ stack
  307. ldr sp, IRQ_STACK_START
  308. .endm
  309. .macro get_fiq_stack @ setup FIQ stack
  310. ldr sp, FIQ_STACK_START
  311. .endm
  312. /*
  313. * exception handlers
  314. */
  315. .align 5
  316. undefined_instruction:
  317. get_bad_stack
  318. bad_save_user_regs
  319. bl do_undefined_instruction
  320. .align 5
  321. software_interrupt:
  322. get_bad_stack_swi
  323. bad_save_user_regs
  324. bl do_software_interrupt
  325. .align 5
  326. prefetch_abort:
  327. get_bad_stack
  328. bad_save_user_regs
  329. bl do_prefetch_abort
  330. .align 5
  331. data_abort:
  332. get_bad_stack
  333. bad_save_user_regs
  334. bl do_data_abort
  335. .align 5
  336. not_used:
  337. get_bad_stack
  338. bad_save_user_regs
  339. bl do_not_used
  340. #ifdef CONFIG_USE_IRQ
  341. .align 5
  342. irq:
  343. get_irq_stack
  344. irq_save_user_regs
  345. bl do_irq
  346. irq_restore_user_regs
  347. .align 5
  348. fiq:
  349. get_fiq_stack
  350. /* someone ought to write a more effective fiq_save_user_regs */
  351. irq_save_user_regs
  352. bl do_fiq
  353. irq_restore_user_regs
  354. #else
  355. .align 5
  356. irq:
  357. get_bad_stack
  358. bad_save_user_regs
  359. bl do_irq
  360. .align 5
  361. fiq:
  362. get_bad_stack
  363. bad_save_user_regs
  364. bl do_fiq
  365. #endif