crtat91sam7se_xram.S 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. /*
  2. * Copyright (C) 2005-2008 by egnite Software GmbH
  3. * Copyright (C) 2011 by egnite GmbH
  4. *
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in the
  15. * documentation and/or other materials provided with the distribution.
  16. * 3. Neither the name of the copyright holders nor the names of
  17. * contributors may be used to endorse or promote products derived
  18. * from this software without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  23. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  24. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  25. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  26. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  27. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  28. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  29. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  30. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31. * SUCH DAMAGE.
  32. *
  33. * For additional information see http://www.ethernut.de/
  34. */
  35. /*
  36. * $Id$
  37. *
  38. * This file contains the runtime initialization of the AT91SAM7SE
  39. * family for code loaded into external RAM, typically SDRAM. It
  40. * has been written for GNU binutils and definitely needs to be
  41. * rewritten for other toolchains.
  42. *
  43. * Loading and running code in external RAM may be mainly used for
  44. * debugging, because the executable can be loaded faster than
  45. * programming flash memory and the number of breakpoints is not
  46. * limited by the debug hardware. Another application is to use a boot
  47. * loader running in internal flash, which loads very large executables,
  48. * which won't fit in internal flash, from external flash memory, e.g.
  49. * serial flash or memory card.
  50. *
  51. * In any case, the loader, either the debug tool or the boot loader,
  52. * must properly initialize the hardware upfront. This may include
  53. * various clocks, SDRAM, watchdog timer, reset controller etc. This
  54. * initialization code is intentionally kept simple and will not do any
  55. * hardware initialization that could be done by the loader. As a
  56. * result, some options provided by the Configurator like watchdog, PLL
  57. * or SDRAM settings are ignored here, but may be honored by the loader.
  58. */
  59. #include <cfg/clock.h>
  60. #include <cfg/memory.h>
  61. #include <arch/arm.h>
  62. /*
  63. * By default, the internal RAM will be mapped to address zero and is
  64. * used for the exception vectors, RAM functions, exception stacks and
  65. * the system initialization stack.
  66. *
  67. * +-----------+ Top of internal RAM
  68. * | FIQ stack | (System initialization stack)
  69. * | |
  70. * +-----------+
  71. * | ABT stack |
  72. * +-----------+
  73. * | UND stack |
  74. * +-----------+
  75. * | IRQ stack |
  76. * ~ ~
  77. * | |
  78. * +-----------+ Top of relocation area (__reloc_end)
  79. * | RAM funct |
  80. * ~ ~
  81. * | |
  82. * +-----------+
  83. * | Vectors |
  84. * +-----------+ Address 0x00000000 (__reloc_start)
  85. *
  86. * System routines as well as application code are executed in system
  87. * mode. During system initialization, the related stack pointer is set
  88. * to the top of internal RAM, overlaying the fast interrupt stack, and
  89. * possibly any following exception stack. This is usually no problem,
  90. * because no interrupts will be enabled before entering the idle thread.
  91. * Threads will allocate their own stacks from heap memory, located in
  92. * external RAM.
  93. */
  94. /*
  95. * Exception stack sizes.
  96. *
  97. * No explicit size is given for the interrupt stack. As long as there
  98. * are a few small RAM functions only, almost all internal RAM will be
  99. * available.
  100. *
  101. * The supervisory mode is currently not used in Nut/OS and no stack
  102. * space is allocated for this mode. System routines as well as
  103. */
  104. #ifndef FIQ_STACK_SIZE
  105. #define FIQ_STACK_SIZE (128 * 4)
  106. #endif
  107. #ifndef ABT_STACK_SIZE
  108. #define ABT_STACK_SIZE (64 * 4)
  109. #endif
  110. #ifndef UND_STACK_SIZE
  111. #define UND_STACK_SIZE (64 * 4)
  112. #endif
  113. #ifndef SVC_STACK_SIZE
  114. #define SVC_STACK_SIZE (0 * 4)
  115. #endif
  116. /* =======================================================================
  117. * Vector table section
  118. * ======================================================================= */
  119. .section .vectors, "ax", %progbits
  120. .code 32
  121. /*
  122. * Note, that this section is implemented in relocatable code.
  123. * It will be loaded into and executed in external RAM and will
  124. * then be moved to remapped internal RAM.
  125. */
  126. ldr pc, [pc, #24] /* Reset */
  127. ldr pc, [pc, #24] /* Undefined instruction */
  128. ldr pc, [pc, #24] /* Software interrupt */
  129. ldr pc, [pc, #24] /* Prefetch abort */
  130. ldr pc, [pc, #24] /* Data abort */
  131. .word 0 /* Reserved */
  132. /*
  133. * On IRQ the PC will be loaded from AIC_IVR, which
  134. * provides the address previously set in AIC_SVR.
  135. * The interrupt routine will be called in ARM_MODE_IRQ
  136. * with IRQ disabled and FIQ unchanged.
  137. */
  138. ldr pc, [pc, #-0xF20] /* Interrupt request, auto vectoring. */
  139. ldr pc, [pc, #-0xF20] /* Fast interrupt request, auto vectoring. */
  140. .word _start
  141. .word __undef
  142. .word __swi
  143. .word __prefetch_abort
  144. .word __data_abort
  145. /*
  146. * We use weakly defined default handlers for exceptions. They
  147. * consist of endless loops and can be overridden by the appli-
  148. * cation. Although a single loop may serve all exceptions, we
  149. * intentionally use individual loops. This allows us to easily
  150. * determine the type of exception by halting the trapped CPU
  151. * and querying the program counter.
  152. */
  153. .weak __undef
  154. .set __undef, __undef_dummy
  155. .global __undef_dummy
  156. __undef_dummy:
  157. b __undef_dummy
  158. .weak __swi
  159. .set __swi, __swi_dummy
  160. .global __swi_dummy
  161. __swi_dummy:
  162. b __swi_dummy
  163. .weak __prefetch_abort
  164. .set __prefetch_abort, __prefetch_abort_dummy
  165. .global __prefetch_abort_dummy
  166. __prefetch_abort_dummy:
  167. b __prefetch_abort_dummy
  168. .weak __data_abort
  169. .set __data_abort, __data_abort_dummy
  170. .global __data_abort_dummy
  171. __data_abort_dummy:
  172. b __data_abort_dummy
  173. .ltorg
  174. /* =======================================================================
  175. * Initialization section
  176. * ======================================================================= */
  177. .section .init0, "ax", %progbits
  178. .code 32
  179. /*
  180. * Weakly define the stack top at the end of internal RAM.
  181. */
  182. .weak __stack
  183. .set __stack, 0x00200000 + MCU_IRAM_SIZE
  184. _start:
  185. /*
  186. * Disable all interrupts. Useful for debugging w/o target reset.
  187. */
  188. ldr r1, =AIC_BASE
  189. mvn r0, #0
  190. str r0, [r1, #AIC_EOICR_OFF]
  191. str r0, [r1, #AIC_IDCR_OFF]
  192. /*
  193. * Set exception stack pointers and enable interrupts.
  194. */
  195. ldr r1, =__stack
  196. msr CPSR_c, #ARM_MODE_FIQ | ARM_CPSR_I_BIT | ARM_CPSR_F_BIT
  197. mov sp, r1
  198. sub r0, r1, #FIQ_STACK_SIZE
  199. msr CPSR_c, #ARM_MODE_ABORT | ARM_CPSR_I_BIT | ARM_CPSR_F_BIT
  200. mov sp, r0
  201. sub r0, r0, #ABT_STACK_SIZE
  202. msr CPSR_c, #ARM_MODE_UNDEF | ARM_CPSR_I_BIT | ARM_CPSR_F_BIT
  203. mov sp, r0
  204. sub r0, r0, #UND_STACK_SIZE
  205. msr CPSR_c, #ARM_MODE_SVC | ARM_CPSR_I_BIT | ARM_CPSR_F_BIT
  206. mov sp, r0
  207. sub r0, r0, #SVC_STACK_SIZE
  208. msr CPSR_c, #ARM_MODE_IRQ | ARM_CPSR_I_BIT | ARM_CPSR_F_BIT
  209. mov sp, r0
  210. /*
  211. * Enter system mode and initialize the system stack pointer.
  212. * The stack will use the same memory as the exception stacks
  213. * that had been setup above. It will be used only until the
  214. * system enters the idle thread.
  215. */
  216. msr CPSR_c, #ARM_MODE_SYS | ARM_CPSR_I_BIT | ARM_CPSR_F_BIT
  217. mov sp, r1
  218. /*
  219. * Remap internal RAM to address zero.
  220. */
  221. mov r0, #1
  222. ldr r1, =MC_BASE
  223. str r0, [r1, #MC_RCR_OFF]
  224. /*
  225. * The .init section contains code (and possibly data), which
  226. * has been loaded into external RAM and needs to be moved to
  227. * internal RAM.
  228. *
  229. * The load address __data_end and the target addresses
  230. * __reloc_start and __reloc_end must be provided by the linker
  231. * script.
  232. */
  233. ldr r1, =__data_end
  234. ldr r2, =__reloc_start
  235. ldr r3, =__reloc_end
  236. 1: cmp r2, r3
  237. ldrne r0, [r1], #4
  238. strne r0, [r2], #4
  239. bne 1b
  240. /*
  241. * The .bss section keeps all data, that must be initialized to
  242. * zero. It typically contains uninitialized global and static
  243. * variables.
  244. *
  245. * Note, that __bss_start and __bss_end must be provided by the
  246. * linker script.
  247. */
  248. ldr r1, =__bss_start
  249. ldr r2, =__bss_end
  250. mov r3, #0
  251. 1: cmp r1, r2
  252. strne r3, [r1], #4
  253. bne 1b
  254. /*
  255. * Set return address and jump to Nut/OS initialization.
  256. */
  257. ldr lr, =_exit
  258. ldr r0, =NutInit
  259. bx r0
  260. /*
  261. * Usually neither the system initialization nor the application
  262. * will ever return. If it does, we will keep the CPU in an
  263. * endless loop.
  264. */
  265. .weak _exit
  266. .set _exit, _exit_loop
  267. .global _exit
  268. _exit_loop:
  269. b _exit
  270. .ltorg