start.S 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. /*
  2. * Copyright (C) 2005-2008 Atmel Corporation
  3. *
  4. * See file CREDITS for list of people who contributed to this
  5. * project.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License as
  9. * published by the Free Software Foundation; either version 2 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  20. * MA 02111-1307 USA
  21. */
  22. #include <config.h>
  23. #include <asm/ptrace.h>
  24. #include <asm/sysreg.h>
  25. #define SYSREG_MMUCR_I_OFFSET 2
  26. #define SYSREG_MMUCR_S_OFFSET 4
  27. #define SR_INIT (SYSREG_BIT(GM) | SYSREG_BIT(EM) | SYSREG_BIT(M0))
  28. /* due to errata (unreliable branch folding) clear FE bit explicitly */
  29. #define CPUCR_INIT ((SYSREG_BIT(BI) | SYSREG_BIT(BE) \
  30. | SYSREG_BIT(RE) | SYSREG_BIT(IBE) \
  31. | SYSREG_BIT(IEE)) & ~SYSREG_BIT(FE))
  32. /*
  33. * To save some space, we use the same entry point for
  34. * exceptions and reset. This avoids lots of alignment padding
  35. * since the reset vector is always suitably aligned.
  36. */
  37. .section .exception.text, "ax", @progbits
  38. .global _start
  39. .global _evba
  40. .type _start, @function
  41. .type _evba, @function
  42. _start:
  43. .size _start, 0
  44. _evba:
  45. .org 0x00
  46. rjmp unknown_exception /* Unrecoverable exception */
  47. .org 0x04
  48. rjmp unknown_exception /* TLB multiple hit */
  49. .org 0x08
  50. rjmp unknown_exception /* Bus error data fetch */
  51. .org 0x0c
  52. rjmp unknown_exception /* Bus error instruction fetch */
  53. .org 0x10
  54. rjmp unknown_exception /* NMI */
  55. .org 0x14
  56. rjmp unknown_exception /* Instruction address */
  57. .org 0x18
  58. rjmp unknown_exception /* ITLB protection */
  59. .org 0x1c
  60. rjmp unknown_exception /* Breakpoint */
  61. .org 0x20
  62. rjmp unknown_exception /* Illegal opcode */
  63. .org 0x24
  64. rjmp unknown_exception /* Unimplemented instruction */
  65. .org 0x28
  66. rjmp unknown_exception /* Privilege violation */
  67. .org 0x2c
  68. rjmp unknown_exception /* Floating-point */
  69. .org 0x30
  70. rjmp unknown_exception /* Coprocessor absent */
  71. .org 0x34
  72. rjmp unknown_exception /* Data Address (read) */
  73. .org 0x38
  74. rjmp unknown_exception /* Data Address (write) */
  75. .org 0x3c
  76. rjmp unknown_exception /* DTLB Protection (read) */
  77. .org 0x40
  78. rjmp unknown_exception /* DTLB Protection (write) */
  79. .org 0x44
  80. rjmp unknown_exception /* DTLB Modified */
  81. .org 0x50
  82. rjmp unknown_exception /* ITLB Miss */
  83. .org 0x60
  84. rjmp unknown_exception /* DTLB Miss (read) */
  85. .org 0x70
  86. rjmp unknown_exception /* DTLB Miss (write) */
  87. .size _evba, . - _evba
  88. .align 2
  89. .type unknown_exception, @function
  90. unknown_exception:
  91. /* Figure out whether we're handling an exception (Exception
  92. * mode) or just booting (Supervisor mode). */
  93. csrfcz SYSREG_M1_OFFSET
  94. brcc at32ap_cpu_bootstrap
  95. /* This is an exception. Complain. */
  96. pushm r0-r12
  97. sub r8, sp, REG_R12 - REG_R0 - 4
  98. mov r9, lr
  99. mfsr r10, SYSREG_RAR_EX
  100. mfsr r11, SYSREG_RSR_EX
  101. pushm r8-r11
  102. mfsr r12, SYSREG_ECR
  103. mov r11, sp
  104. rcall do_unknown_exception
  105. 1: rjmp 1b
  106. /* The COUNT/COMPARE timer interrupt handler */
  107. .global timer_interrupt_handler
  108. .type timer_interrupt_handler,@function
  109. .align 2
  110. timer_interrupt_handler:
  111. /*
  112. * Increment timer_overflow and re-write COMPARE with 0xffffffff.
  113. *
  114. * We're running at interrupt level 3, so we don't need to save
  115. * r8-r12 or lr to the stack.
  116. */
  117. lda.w r8, timer_overflow
  118. ld.w r9, r8[0]
  119. mov r10, -1
  120. mtsr SYSREG_COMPARE, r10
  121. sub r9, -1
  122. st.w r8[0], r9
  123. rete
  124. /*
  125. * CPU bootstrap after reset is handled here. SoC code may
  126. * override this in case they need to initialize oscillators,
  127. * etc.
  128. */
  129. .section .text.at32ap_cpu_bootstrap, "ax", @progbits
  130. .global at32ap_cpu_bootstrap
  131. .weak at32ap_cpu_bootstrap
  132. .type at32ap_cpu_bootstrap, @function
  133. .align 2
  134. at32ap_cpu_bootstrap:
  135. /* Reset the Status Register */
  136. mov r0, lo(SR_INIT)
  137. orh r0, hi(SR_INIT)
  138. mtsr SYSREG_SR, r0
  139. /* Reset CPUCR and invalidate the BTB */
  140. mov r2, CPUCR_INIT
  141. mtsr SYSREG_CPUCR, r2
  142. /* Flush the caches */
  143. mov r1, 0
  144. cache r1[4], 8
  145. cache r1[0], 0
  146. sync 0
  147. /* Reset the MMU to default settings */
  148. mov r0, SYSREG_BIT(MMUCR_S) | SYSREG_BIT(MMUCR_I)
  149. mtsr SYSREG_MMUCR, r0
  150. /* Internal RAM should not need any initialization. We might
  151. have to initialize external RAM here if the part doesn't
  152. have internal RAM (or we may use the data cache) */
  153. /* Jump to cacheable segment */
  154. lddpc pc, 1f
  155. .align 2
  156. 1: .long at32ap_low_level_init
  157. .size _start, . - _start
  158. /* Common CPU bootstrap code after oscillator/cache/etc. init */
  159. .section .text.avr32ap_low_level_init, "ax", @progbits
  160. .global at32ap_low_level_init
  161. .type at32ap_low_level_init, @function
  162. .align 2
  163. at32ap_low_level_init:
  164. lddpc sp, sp_init
  165. /* Initialize the GOT pointer */
  166. lddpc r6, got_init
  167. 3: rsub r6, pc
  168. /* Let's go */
  169. rjmp board_init_f
  170. .align 2
  171. .type sp_init,@object
  172. sp_init:
  173. .long CONFIG_SYS_INIT_SP_ADDR
  174. got_init:
  175. .long 3b - _GLOBAL_OFFSET_TABLE_
  176. /*
  177. * void relocate_code(new_sp, new_gd, monitor_addr)
  178. *
  179. * Relocate the u-boot image into RAM and continue from there.
  180. * Does not return.
  181. */
  182. .section .text.relocate_code,"ax",@progbits
  183. .global relocate_code
  184. .type relocate_code,@function
  185. relocate_code:
  186. mov sp, r12 /* use new stack */
  187. mov r12, r11 /* save new_gd */
  188. mov r11, r10 /* save destination address */
  189. /* copy .text section and flush the cache along the way */
  190. lda.w r8, _text
  191. lda.w r9, _etext
  192. sub lr, r10, r8 /* relocation offset */
  193. 1: ldm r8++, r0-r3
  194. stm r10, r0-r3
  195. sub r10, -16
  196. ldm r8++, r0-r3
  197. stm r10, r0-r3
  198. sub r10, -16
  199. cp.w r8, r9
  200. cache r10[-4], 0x0d /* dcache clean/invalidate */
  201. cache r10[-4], 0x01 /* icache invalidate */
  202. brlt 1b
  203. /* flush write buffer */
  204. sync 0
  205. /* copy data sections */
  206. lda.w r9, _edata
  207. 1: ld.d r0, r8++
  208. st.d r10++, r0
  209. cp.w r8, r9
  210. brlt 1b
  211. /* zero out .bss */
  212. mov r0, 0
  213. mov r1, 0
  214. lda.w r9, _end
  215. sub r9, r8
  216. 1: st.d r10++, r0
  217. sub r9, 8
  218. brgt 1b
  219. /* jump to RAM */
  220. sub r0, pc, . - in_ram
  221. add pc, r0, lr
  222. .align 2
  223. in_ram:
  224. /* find the new GOT and relocate it */
  225. lddpc r6, got_init_reloc
  226. 3: rsub r6, pc
  227. mov r8, r6
  228. lda.w r9, _egot
  229. lda.w r10, _got
  230. sub r9, r10
  231. 1: ld.w r0, r8[0]
  232. add r0, lr
  233. st.w r8++, r0
  234. sub r9, 4
  235. brgt 1b
  236. /* Move the exception handlers */
  237. mfsr r2, SYSREG_EVBA
  238. add r2, lr
  239. mtsr SYSREG_EVBA, r2
  240. /* Do the rest of the initialization sequence */
  241. call board_init_r
  242. .align 2
  243. got_init_reloc:
  244. .long 3b - _GLOBAL_OFFSET_TABLE_
  245. .size relocate_code, . - relocate_code