start.S 6.5 KB

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