start.S 6.7 KB

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