crtat91x40_rom.S 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. .nolist
  2. .psize 0
  3. /*
  4. * Copyright (C) 2005-2006 by egnite Software GmbH
  5. * Copyright (C) 2011 by egnite GmbH
  6. *
  7. * All rights reserved.
  8. *
  9. * Redistribution and use in source and binary forms, with or without
  10. * modification, are permitted provided that the following conditions
  11. * are met:
  12. *
  13. * 1. Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions and the following disclaimer.
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in the
  17. * documentation and/or other materials provided with the distribution.
  18. * 3. Neither the name of the copyright holders nor the names of
  19. * contributors may be used to endorse or promote products derived
  20. * from this software without specific prior written permission.
  21. *
  22. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  23. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  24. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  25. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  26. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  27. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  28. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  29. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  30. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  31. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  32. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  33. * SUCH DAMAGE.
  34. *
  35. * For additional information see http://www.ethernut.de/
  36. */
  37. /*
  38. * $Id$
  39. */
  40. #include <arch/arm.h>
  41. .list
  42. /*
  43. * This file contains the runtime initialization for AT91X40 based systems.
  44. * It replaces the older crtat91_rom.S, which is now deprecated.
  45. *
  46. * The related linker file is at91x40_rom.ld.
  47. *
  48. * Code is running in Flash memory, which also contains all constant data.
  49. * Internal RAM is used for variables and may be used for functions,
  50. * which require to run at maximum speed.
  51. *
  52. * Tested on AT91R40008 only.
  53. *
  54. */
  55. /*
  56. * Stack sizes.
  57. *
  58. * Interrupt nesting is currently not supported. Therefore dedicated
  59. * stacks are used for all exceptions.
  60. */
  61. #ifndef INI_STACK_SIZE
  62. #define INI_STACK_SIZE (128 * 4)
  63. #endif
  64. #ifndef IRQ_STACK_SIZE
  65. #define IRQ_STACK_SIZE (128 * 4)
  66. #endif
  67. #ifndef FIQ_STACK_SIZE
  68. #define FIQ_STACK_SIZE (64 * 4)
  69. #endif
  70. #ifndef EXC_STACK_SIZE
  71. #define EXC_STACK_SIZE (32 * 4)
  72. #endif
  73. #define TOTAL_STACK_SIZE (INI_STACK_SIZE + IRQ_STACK_SIZE + FIQ_STACK_SIZE + EXC_STACK_SIZE)
  74. /* We start in ARM mode. */
  75. .arm
  76. /*
  77. * Vector Section: Must be copied to RAM during runtime.
  78. */
  79. .section .vectors,"ax",%progbits
  80. /*
  81. * After reset these vectors are located at the beginning of
  82. * flash memory, which starts at address 0x00000000. After
  83. * remap, flash will be relocated at 0x10000000 and these
  84. * vectors are copied to the RAM base address, which will
  85. * be remapped to address 0x00000000.
  86. *
  87. * Actually this is overdone. With weakly defined exception
  88. * pointers and auto vectoring interrupts there is no need
  89. * to modify the vector table. Keeping the Flash at address
  90. * 0x00000000 would protect the system against overwriting
  91. * exception vectors with NULL pointers. Unfortunately, the
  92. * remap command is required to configure the AT91X40 chip
  93. * selects.
  94. *
  95. * Note, that we must use relative addressing for all code
  96. * proceeding the remap. While the linker will put this
  97. * code at address 0x10000000, it will actually start
  98. * running at address 0x00000000.
  99. */
  100. .global __vectors
  101. __vectors:
  102. /* Reset entry. */
  103. b _start
  104. /* Undefined instruction exception entry. */
  105. ldr pc, [pc, #(5 * 4)]
  106. /* Software interrupt entry. */
  107. ldr pc, [pc, #(5 * 4)]
  108. /* Prefetch abort exception entry. */
  109. ldr pc, [pc, #(5 * 4)]
  110. /* Data abort exception entry. */
  111. ldr pc, [pc, #(5 * 4)]
  112. /*
  113. * Reserved entry, used by some boot loaders to store the
  114. * size of the binary image.
  115. */
  116. .word 0
  117. /*
  118. * On IRQ/FIQ the PC will be loaded from AIC_IVR, which
  119. * provides the address previously set in AIC_SVR().
  120. * The interrupt routine will be called in ARM_MODE_IRQ
  121. * with IRQ disabled and FIQ unchanged.
  122. */
  123. ldr pc, [pc, #-0xF20]
  124. ldr pc, [pc, #-0xF20]
  125. /*
  126. * Exceptions are weakly linked to endless loops.
  127. *
  128. * This may look a bit confusing. The following words contain
  129. * the jump addresses that are loaded at each entry, see above.
  130. * They contain weakly defined addresses pointing to executable
  131. * code. Each of them may be overridden by the operating system
  132. * or the application, if a function with the same name exist.
  133. * By default they simply point to endless loops.
  134. *
  135. * We intentionally use a dedicated loop with a global label
  136. * for each exception. If an unhandled exception occurs, we
  137. * can use a simple debugger (like OpenOCD) to retrieve the
  138. * current program counter and check the linker map to determine
  139. * the type of the exception.
  140. */
  141. .word __undef
  142. .word __swi
  143. .word __prefetch_abort
  144. .word __data_abort
  145. .weak __undef, __swi, __prefetch_abort, __data_abort
  146. .set __undef, __undef_stop
  147. .set __swi, __swi_stop
  148. .set __prefetch_abort, __prefetch_abort_stop
  149. .set __data_abort, __data_abort_stop
  150. /*
  151. * Init Section 0: Exception Dummies.
  152. */
  153. .section .init0,"ax",%progbits
  154. __undef_stop:
  155. b __undef_stop
  156. __swi_stop:
  157. b __swi_stop
  158. __prefetch_abort_stop:
  159. b __prefetch_abort_stop
  160. __data_abort_stop:
  161. b __data_abort_stop
  162. /* Make sure that the literal pool is empty before the section ends. */
  163. .ltorg
  164. /*
  165. * User Init Section 0
  166. *
  167. * Additional code may be added here by placing functions in
  168. * section .init0.user. Only relocatable code is allowed.
  169. *
  170. * Memory test routines are good candidates.
  171. */
  172. .global _start
  173. _start:
  174. /*
  175. * Init Section 1: Remapping.
  176. */
  177. .section .init1,"ax",%progbits
  178. /*
  179. * Disable interrupts and switch to supervisor mode. This is
  180. * actually the same state as after hardware reset. We explicitly
  181. * set it here for debugging. It may not be possible to halt the
  182. * CPU at address zero immediately after reset. In this case we
  183. * can use the debugger to reset the PC to zero or to this address
  184. * and resume.
  185. */
  186. msr CPSR_c, #ARM_MODE_SVC | ARM_CPSR_I_BIT | ARM_CPSR_F_BIT
  187. /*
  188. * Move vectors from Flash to RAM.
  189. */
  190. mov r0, #0x00000000
  191. mov r1, #0x00300000
  192. ldmia r0!, {r2-r7}
  193. stmia r1!, {r2-r7}
  194. ldmia r0!, {r2-r7}
  195. stmia r1!, {r2-r7}
  196. /*
  197. * Remapping memory.
  198. *
  199. * A bit tricky for newbies. The ldmia opcode loads the complete
  200. * table including the EBI base address in r10 and the jump
  201. * address into our remapped flash memory in r11. Immediately
  202. * after remap our code moved to 0x10000000, but the next opcode
  203. * 'move pc,r11' is still in the instruction pipeline and will
  204. * be executed.
  205. *
  206. * ARM assembler programming is wonderful, isn't it?
  207. */
  208. adr r12, _rmap_tab
  209. ldmia r12!, {r0-r11}
  210. stmia r10!, {r0-r9}
  211. /* After remap, this is still in the pipeline. */
  212. mov pc, r11
  213. _rmap_tab:
  214. /*
  215. * Chip select NCS0 enables 16-bit Flash memory at 0x10000000.
  216. * We need 4 wait states.
  217. */
  218. .word 0x10000000 | EBI_CSEN | EBI_PAGES_16M | EBI_WSE | EBI_NWS_4 | EBI_DBW_16
  219. /*
  220. * Chip select NCS1 enables 16-bit Ethernet controller at 0x20000000.
  221. * We need 3 wait states.
  222. */
  223. .word 0x20000000 | EBI_CSEN | EBI_BAT_BYTE_SELECT | EBI_PAGES_1M | EBI_WSE | EBI_NWS_3 | EBI_DBW_16
  224. /*
  225. * Chip select NCS2 selects 8-bit NPL registers at 0x21000000.
  226. * The CPLD is quite fast and may run at one or zero wait states.
  227. * This pin is shared with GPIO pin 26.
  228. */
  229. .word 0x21000000 | EBI_CSEN | EBI_PAGES_1M | EBI_WSE | EBI_NWS_2 | EBI_DBW_8
  230. /*
  231. * Chip select NCS3 is not used.
  232. * This pin os shared with GPIO pin 27 and available at the expansion port.
  233. */
  234. .word 0x30000000
  235. /*
  236. * Chip select CS4 selects the 8-bit NPL expansion bus at 0x22000000.
  237. * This pin is shared with GPIO pin 31 and address bit 23.
  238. */
  239. .word 0x22000000 | EBI_CSEN | EBI_TDF_7 | EBI_PAGES_1M | EBI_WSE | EBI_NWS_8 | EBI_DBW_8
  240. /*
  241. * Chip select CS5 is not used.
  242. * This pin is shared with GPIO pin 30 and address bit 22.
  243. */
  244. .word 0x50000000
  245. /*
  246. * Chip select CS6 is not available, but used as address bit 21.
  247. */
  248. .word 0x60000000
  249. /*
  250. * Chip select CS7 is not available, but used as address bit 20.
  251. */
  252. .word 0x70000000
  253. /*
  254. * EBI remap command.
  255. */
  256. .word EBI_RCB
  257. /*
  258. * Maximum address space of 4 MBytes per chip select.
  259. * This occupies A0 to A21.
  260. */
  261. .word EBI_ALE_4M
  262. /*
  263. * EBI base address.
  264. */
  265. .word EBI_BASE
  266. /*
  267. * Jump after relocation.
  268. */
  269. .word _init_rt
  270. /* Make sure that the literal pool is empty before the section ends. */
  271. .ltorg
  272. /*
  273. * User Init Section 1
  274. *
  275. * Additional code may be added here by placing functions in
  276. * section .init1.user. CPU is running in relocated Flash.
  277. */
  278. _init_rt:
  279. /*
  280. * Init Section 2: Set stack pointers and initialize C variables.
  281. */
  282. .section .init2,"ax",%progbits
  283. /*
  284. * Set stack pointers with disabled interrupts.
  285. */
  286. ldr r0, =__stack
  287. msr CPSR_c, #ARM_MODE_SVC | ARM_CPSR_I_BIT | ARM_CPSR_F_BIT
  288. mov sp, r0
  289. sub r0, r0, #INI_STACK_SIZE
  290. msr CPSR_c, #ARM_MODE_FIQ | ARM_CPSR_I_BIT | ARM_CPSR_F_BIT
  291. mov sp, r0
  292. sub r0, r0, #FIQ_STACK_SIZE
  293. msr CPSR_c, #ARM_MODE_IRQ | ARM_CPSR_I_BIT | ARM_CPSR_F_BIT
  294. mov sp, r0
  295. sub r0, r0, #IRQ_STACK_SIZE
  296. msr CPSR_c, #ARM_MODE_ABORT | ARM_CPSR_I_BIT | ARM_CPSR_F_BIT
  297. mov sp, r0
  298. msr CPSR_c, #ARM_MODE_UNDEF | ARM_CPSR_I_BIT | ARM_CPSR_F_BIT
  299. mov sp, r0
  300. /*
  301. * Nut/OS system and application are running in system mode.
  302. * Note, that we re-use the supervisory stack.
  303. */
  304. msr CPSR_c, #ARM_MODE_SYS | ARM_CPSR_I_BIT | ARM_CPSR_F_BIT
  305. ldr r0, =__stack
  306. mov sp, r0
  307. /*
  308. * Clear bss.
  309. */
  310. ldr r1, =__bss_start
  311. ldr r2, =__bss_end
  312. ldr r3, =0
  313. 1: cmp r1, r2
  314. strne r3, [r1], #+4
  315. bne 1b
  316. /*
  317. * Copy data and RAM functions from Flash to RAM.
  318. */
  319. ldr r0, =__data_load_start
  320. ldr r1, =__data_start
  321. ldr r2, =__data_end
  322. subs r2, r2, r1
  323. beq _init_hw
  324. 1: ldr r3, [r0], #4
  325. str r3, [r1], #4
  326. subs r2, r2, #4
  327. bne 1b
  328. /* Jump over the literal pool. */
  329. b _init_hw
  330. /* Make sure that the literal pool is empty before the section ends. */
  331. .ltorg
  332. /*
  333. * User Init Section 2
  334. *
  335. * Additional code may be added here by placing functions in
  336. * section .init2.user.
  337. *
  338. * This section may be used for early hardware initialization
  339. * routines written in C.
  340. */
  341. _init_hw:
  342. /*
  343. * Init Section 3: Hardware initialization.
  344. */
  345. .section .init3,"ax",%progbits
  346. /*
  347. * Enable all clocks.
  348. */
  349. mvn r0, #0
  350. ldr r1, =PS_BASE
  351. str r0, [r1, #(PS_PCER - PS_BASE)]
  352. /*
  353. * Initialize the interrupt controller.
  354. */
  355. add r0, pc,#-(8 + . - __aic_table)
  356. ldmia r0, {r1-r4}
  357. str r4, [r1, #AIC_SPU]
  358. mov r0, #8
  359. 1: str r1, [r1, #AIC_EOICR]
  360. subs r0, r0, #1
  361. bhi 1b
  362. str r2, [r1, #AIC_SVR(0)]
  363. add r1, r1, #AIC_SVR(0)
  364. mov r0, #31
  365. 1: str r3, [r1, r0, LSL #2]
  366. subs r0, r0, #1
  367. bhi 1b
  368. b _enter_rtos
  369. __aic_table:
  370. .word AIC_BASE
  371. .word _irq_dummy
  372. .word _irq_dummy
  373. .word _irq_dummy
  374. /* Interrupt dummy. */
  375. .global _irq_dummy
  376. _irq_dummy:
  377. b _irq_dummy
  378. /* Make sure that the literal pool is empty before the section ends. */
  379. .ltorg
  380. /*
  381. * User Init Section 3
  382. *
  383. * Additional code may be added here by placing functions in
  384. * section .init3.user.
  385. *
  386. * This section may be used for additional hardware initialization
  387. * routines written in C. Native interrupt routines may be used.
  388. */
  389. _enter_rtos:
  390. /*
  391. * Init Section 4: Enter system.
  392. */
  393. .section .init4,"ax",%progbits
  394. /* Jump to Nut/OS initialization. */
  395. ldr r0, =NutInit
  396. mov lr, pc
  397. bx r0
  398. /*
  399. * Exit Section 0: Endless loop.
  400. */
  401. .section .exit0,"ax",%progbits
  402. 1: b 1b
  403. /*
  404. * Stack Section.
  405. */
  406. .section .stack, "w", %nobits
  407. .space TOTAL_STACK_SIZE