crtat91sam9g45_ram.S 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613
  1. /*
  2. * Copyright (C) 2006-2007 by egnite Software GmbH. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 3. Neither the name of the copyright holders nor the names of
  14. * contributors may be used to endorse or promote products derived
  15. * from this software without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  18. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  19. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  20. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  21. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  22. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  23. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  24. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  25. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  26. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  27. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  28. * SUCH DAMAGE.
  29. *
  30. * For additional information see http://www.ethernut.de/
  31. *
  32. */
  33. /*
  34. * $Log$
  35. * Revision 1.7 2009/02/17 09:32:25 haraldkipp
  36. * A lot of clean-up had been done with SAM9260 initialization.
  37. * Clock configurations should now work as expected. Note, that
  38. * the CPU is running now at 198.6560 MHz with peripheral clock
  39. * at 99.3280 MHz.
  40. *
  41. * Revision 1.6 2009/01/16 19:45:42 haraldkipp
  42. * All ARM code is now running in system mode.
  43. *
  44. * Revision 1.5 2008/01/16 00:19:42 olereinhardt
  45. * Changed backslash to slash in include path names
  46. *
  47. * Revision 1.4 2007/02/15 16:18:22 haraldkipp
  48. * Configurable runtime initialization.
  49. *
  50. * Revision 1.3 2006/09/07 09:02:27 haraldkipp
  51. * Instruction cache is now enabled. Many thanks to Dany Nativel for
  52. * providing this patch.
  53. *
  54. * Revision 1.2 2006/09/05 12:29:17 haraldkipp
  55. * Dedicated loops for each exception allows to determine its type.
  56. * Applications fail to run when laoded via SAM-BA fro two reasons.
  57. * First, internal RAM was not mapped to address 0x00000000.
  58. * Second, interrupts were disabled.
  59. *
  60. * Revision 1.1 2006/08/31 19:19:55 haraldkipp
  61. * No time to write comments. ;-)
  62. *
  63. */
  64. #include <cfg/clock.h>
  65. #include <cfg/memory.h>
  66. #include <arch/arm.h>
  67. #ifndef PLL_MUL_VAL
  68. #define PLL_MUL_VAL 96
  69. #endif
  70. #ifndef PLL_DIV_VAL
  71. #define PLL_DIV_VAL 9
  72. #endif
  73. #if MASTER_CLOCK_PRES == 2
  74. #define AT91MCK_PRES PMC_PRES_CLK
  75. #elif MASTER_CLOCK_PRES == 4
  76. #define AT91MCK_PRES PMC_PRES_CLK_4
  77. #elif MASTER_CLOCK_PRES == 8
  78. #define AT91MCK_PRES PMC_PRES_CLK_8
  79. #elif MASTER_CLOCK_PRES == 16
  80. #define AT91MCK_PRES PMC_PRES_CLK_16
  81. #elif MASTER_CLOCK_PRES == 32
  82. #define AT91MCK_PRES PMC_PRES_CLK_32
  83. #elif MASTER_CLOCK_PRES == 64
  84. #define AT91MCK_PRES PMC_PRES_CLK_64
  85. #else
  86. #define AT91MCK_PRES PMC_PRES_CLK
  87. #endif
  88. #if PERIPHERAL_CLOCK_DIV == 1
  89. #define AT91MCK_MDIV PMC_MDIV_1
  90. #elif PERIPHERAL_CLOCK_DIV == 4
  91. #define AT91MCK_MDIV PMC_MDIV_4
  92. #else
  93. #define AT91MCK_MDIV PMC_MDIV_2
  94. #endif
  95. #ifndef IRQ_STACK_SIZE
  96. #define IRQ_STACK_SIZE 512
  97. #endif
  98. #ifndef FIQ_STACK_SIZE
  99. #define FIQ_STACK_SIZE 256
  100. #endif
  101. #ifndef ABT_STACK_SIZE
  102. #define ABT_STACK_SIZE 128
  103. #endif
  104. #ifndef UND_STACK_SIZE
  105. #define UND_STACK_SIZE 128
  106. #endif
  107. #ifdef NUTMEM_SDRAM_BASE
  108. /* Tested on AT91SAM9260-EK without success. */
  109. #ifndef NUTMEM_SDRAM_COLBITS
  110. #define NUTMEM_SDRAM_COLBITS 9
  111. #endif
  112. #ifndef NUTMEM_SDRAM_ROWBITS
  113. #define NUTMEM_SDRAM_ROWBITS 13
  114. #endif
  115. #ifndef NUTMEM_SDRAM_CASLAT
  116. #define NUTMEM_SDRAM_CASLAT 2
  117. #endif
  118. #ifndef NUTMEM_SDRAM_BANKS
  119. #define NUTMEM_SDRAM_BANKS 4
  120. #endif
  121. #ifndef NUTMEM_SDRAM_TWR
  122. #define NUTMEM_SDRAM_TWR 2
  123. #endif
  124. #ifndef NUTMEM_SDRAM_TRC
  125. #define NUTMEM_SDRAM_TRC 7
  126. #endif
  127. #ifndef NUTMEM_SDRAM_TRP
  128. #define NUTMEM_SDRAM_TRP 2
  129. #endif
  130. #ifndef NUTMEM_SDRAM_TRCD
  131. #define NUTMEM_SDRAM_TRCD 2
  132. #endif
  133. #ifndef NUTMEM_SDRAM_TRAS
  134. #define NUTMEM_SDRAM_TRAS 5
  135. #endif
  136. #ifndef NUTMEM_SDRAM_TXSR
  137. #define NUTMEM_SDRAM_TXSR 8
  138. #endif
  139. #if NUTMEM_SDRAM_BANKS == 2
  140. #define SDRAMC_CFG_NB 0
  141. #else
  142. #define SDRAMC_CFG_NB SDRAMC_NB
  143. #endif
  144. #if NUTMEM_SDRAM_COLBITS == 8
  145. #define SDRAMC_CFG_NC SDRAMC_NC_8
  146. #elif NUTMEM_SDRAM_COLBITS == 9
  147. #define SDRAMC_CFG_NC SDRAMC_NC_9
  148. #elif NUTMEM_SDRAM_COLBITS == 10
  149. #define SDRAMC_CFG_NC SDRAMC_NC_10
  150. #else
  151. #define SDRAMC_CFG_NC SDRAMC_NC_11
  152. #endif
  153. #if NUTMEM_SDRAM_ROWBITS == 11
  154. #define SDRAMC_CFG_NR SDRAMC_NR_11
  155. #elif NUTMEM_SDRAM_ROWBITS == 12
  156. #define SDRAMC_CFG_NR SDRAMC_NR_12
  157. #else
  158. #define SDRAMC_CFG_NR SDRAMC_NR_13
  159. #endif
  160. #if NUTMEM_SDRAM_CASLAT == 1
  161. #define SDRAMC_CFG_CAS SDRAMC_CAS_1
  162. #elif NUTMEM_SDRAM_CASLAT == 2
  163. #define SDRAMC_CFG_CAS SDRAMC_CAS_2
  164. #else
  165. #define SDRAMC_CFG_CAS SDRAMC_CAS_3
  166. #endif
  167. #endif /* NUTMEM_SDRAM_BASE */
  168. .macro DELAY_1MS
  169. mov r3, #0x200000
  170. 1:
  171. subs r3, r3, #1
  172. bne 1b
  173. .endm
  174. .macro DEBUG_CHAR
  175. DELAY_1MS
  176. ldr r1, =DBGU_BASE
  177. mov r0, #88
  178. str r0, [r1, #US_THR_OFF]
  179. .endm
  180. .macro STOP_EXEC
  181. 1:
  182. b 1b
  183. .endm
  184. /*
  185. * Section 0: Vector table and reset entry.
  186. */
  187. .section .init0,"ax",%progbits
  188. .global __vectors
  189. __vectors:
  190. ldr pc, [pc, #24] /* Reset */
  191. ldr pc, [pc, #24] /* Undefined instruction */
  192. ldr pc, [pc, #24] /* Software interrupt */
  193. ldr pc, [pc, #24] /* Prefetch abort */
  194. ldr pc, [pc, #24] /* Data abort */
  195. /* The following vector is reserved. Atmel obviously interpreted
  196. this as "reserved for Atmel", because SAM-BA uses it to store
  197. the size of the boot image. */
  198. .word 0
  199. /*
  200. * On IRQ the PC will be loaded from AIC_IVR, which
  201. * provides the address previously set in AIC_SVR.
  202. * The interrupt routine will be called in ARM_MODE_IRQ
  203. * with IRQ disabled and FIQ unchanged.
  204. */
  205. ldr pc, [pc, #-0xF20] /* Interrupt request, auto vectoring. */
  206. ldr pc, [pc, #-0xF20] /* Fast interrupt request, auto vectoring. */
  207. .word _start
  208. .word __undef
  209. .word __swi
  210. .word __prefetch_abort
  211. .word __data_abort
  212. .weak __undef
  213. .set __undef, __xcpt_dummy
  214. .weak __swi
  215. .set __swi, __xcpt_dummy
  216. .weak __prefetch_abort
  217. .set __prefetch_abort, __xcpt_dummy
  218. .weak __data_abort
  219. .set __data_abort, __xcpt_dummy
  220. .global __xcpt_dummy
  221. __xcpt_dummy:
  222. DEBUG_CHAR
  223. b __xcpt_dummy
  224. .ltorg
  225. /*
  226. * Section 1: Hardware initialization.
  227. */
  228. .section .init1, "ax", %progbits
  229. .global _start
  230. _start:
  231. /*
  232. * Disable all interrupts and clear any pending ones.
  233. * Useful for debugging w/o target reset.
  234. */
  235. ldr r1, =AIC_BASE
  236. mvn r0, #0
  237. str r0, [r1, #AIC_IDCR_OFF]
  238. str r0, [r1, #AIC_ICCR_OFF]
  239. /*
  240. * Perform 8 "End Of Interrupt" commands to make sure that
  241. * the AIC will not lock out nIRQ.
  242. */
  243. str r0, [r1, #AIC_EOICR_OFF]
  244. str r0, [r1, #AIC_EOICR_OFF]
  245. str r0, [r1, #AIC_EOICR_OFF]
  246. str r0, [r1, #AIC_EOICR_OFF]
  247. str r0, [r1, #AIC_EOICR_OFF]
  248. str r0, [r1, #AIC_EOICR_OFF]
  249. str r0, [r1, #AIC_EOICR_OFF]
  250. str r0, [r1, #AIC_EOICR_OFF]
  251. /*
  252. * Debug!?
  253. */
  254. DEBUG_CHAR
  255. /*
  256. * The watchdog is enabled after processor reset.
  257. */
  258. #ifdef USE_WDT
  259. #ifdef NUT_WDT_START
  260. #if NUT_WDT_START
  261. /* Configure the watchdog. */
  262. ldr r1, =WDT_BASE
  263. ldr r0, =NUT_WDT_START
  264. str r0, [r1, #WDT_MR_OFF]
  265. #endif /* if NUT_WDT_START */
  266. #else /* ifdef NUT_WDT_START */
  267. /* Disable the watchdog. */
  268. ldr r1, =WDT_BASE
  269. ldr r0, =WDT_WDDIS
  270. str r0, [r1, #WDT_MR_OFF]
  271. #endif /* ifdef NUT_WDT_START */
  272. #endif /* ifdef USE_WDT */
  273. #ifdef INIT_MAIN_OSCILLATOR_CLOCK
  274. /* Test if the main oscillator is running. */
  275. ldr r1, =PMC_BASE
  276. ldr r0, [r1, #PMC_SR_OFF]
  277. tst r0, #PMC_MOSCS
  278. bne sel_mainck
  279. /*
  280. * If not running, enable the main oscillator. Set startup time
  281. * of 64 * 8 slow clock cycles and wait until oscillator is stable.
  282. */
  283. mov r0, #(64 << CKGR_OSCOUNT_LSB)
  284. orr r0, r0, #CKGR_MOSCEN
  285. str r0, [r1, #CKGR_MOR_OFF]
  286. 1:
  287. ldr r0, [r1, #CKGR_MCFR_OFF]
  288. tst r0, #CKGR_MAINRDY
  289. beq 1b
  290. /*
  291. * CKGR_MCFR contains the number of main clock cycles within
  292. * 16 slow clock cycles. Use this value to test if the main
  293. * clock is running at higher frequency than the slow clock.
  294. * If yes, select the main clock.
  295. */
  296. sel_mainck:
  297. ldr r0, [r1, #CKGR_MCFR_OFF]
  298. mov r0, r0, asl #16 /* Main clock is in lower 16 bits. */
  299. mov r0, r0, lsr #16
  300. cmp r0, #16
  301. bls set_pll
  302. mov r0, #PMC_CSS_MAIN_CLK
  303. str r0, [r1, #PMC_MCKR_OFF]
  304. /*
  305. * Configure PLL A.
  306. * PLLfreq = crystal / divider * (multiplier + 1)
  307. * Wait max clock cycles until PLL is locked.
  308. */
  309. set_pll:
  310. ldr r0, =(_BV(29) | CKGR_OUT_2 | (63 << CKGR_PLLCOUNT_LSB) | (PLL_MUL_VAL << CKGR_MUL_LSB) | (PLL_DIV_VAL << CKGR_DIV_LSB))
  311. str r0, [r1, #CKGR_PLLAR_OFF]
  312. 1:
  313. ldr r0, [r1, #PMC_SR_OFF]
  314. and r0, r0, #PMC_LOCKA
  315. cmp r0, #0
  316. beq 1b
  317. /*
  318. * Select PLL A for the processor clock (PCK) and set the master
  319. * clock prescaler and divider.
  320. */
  321. ldr r0, =(PMC_CSS_PLLA_CLK | AT91MCK_PRES | AT91MCK_MDIV)
  322. str r0, [r1, #PMC_MCKR_OFF]
  323. 1:
  324. ldr r0, [r1, #PMC_SR_OFF]
  325. and r0, r0, #PMC_MCKRDY
  326. cmp r0, #0
  327. beq 1b
  328. #endif /* INIT_MAIN_OSCILLATOR_CLOCK */
  329. /* Enable instruction cache. */
  330. mrc p15, 0, r0, c1, c0, 0
  331. orr r0, r0, #(1 << CP15_CR1_I_BIT)
  332. mcr p15, 0, r0, c1, c0, 0
  333. /* Set the EBI slot cycle limit to 64. */
  334. ldr r1, =MATRIX_BASE
  335. ldr r0, [r1, #(MATRIX_SCFG_OFF + ( 4 * MATRIX_SLAVE_EBI))]
  336. and r0, r0, #0xffffff00
  337. orr r0, r0, #64
  338. str r0, [r1, #(MATRIX_SCFG_OFF + ( 4 * MATRIX_SLAVE_EBI))]
  339. /*
  340. * Enable SDRAM interface, if configured.
  341. *
  342. * _N_O_T_E_ : TESTED ON THE AT91SAM9260-EK NAD FOUND NOT WORKING.
  343. */
  344. #ifdef INIT_SDRAM
  345. #ifdef NUTMEM_SDRAM_BASE
  346. /* Initialize the matrix */
  347. ldr r1, =CCFG_BASE
  348. ldr r0, [r1, #CCFG_CSA_OFF]
  349. orr r0, r0, #CCFG_CS1A
  350. str r0, [r1, #CCFG_CSA_OFF]
  351. /* Enable upper 16 bit data bus at PIO C. */
  352. ldr r1, =PIOC_BASE
  353. ldr r0, =(_BV(PC16_D16_A) \
  354. | _BV(PC17_D17_A) \
  355. | _BV(PC18_D18_A) \
  356. | _BV(PC19_D19_A) \
  357. | _BV(PC20_D20_A) \
  358. | _BV(PC21_D21_A) \
  359. | _BV(PC22_D22_A) \
  360. | _BV(PC23_D23_A) \
  361. | _BV(PC24_D24_A) \
  362. | _BV(PC25_D25_A) \
  363. | _BV(PC26_D26_A) \
  364. | _BV(PC27_D27_A) \
  365. | _BV(PC28_D28_A) \
  366. | _BV(PC29_D29_A) \
  367. | _BV(PC30_D30_A) \
  368. | _BV(PC31_D31_A))
  369. str r0, [r1, #PIO_ASR_OFF]
  370. str r0, [r1, #PIO_PDR_OFF]
  371. /* SDRAM controller base address kept in r1. */
  372. ldr r1, =SDRAMC_BASE
  373. /* Set SDRAM characteristics in configuration register. */
  374. ldr r0, =(SDRAMC_CFG_NC | SDRAMC_CFG_NR \
  375. | SDRAMC_CFG_NB | SDRAMC_CFG_CAS \
  376. | (NUTMEM_SDRAM_TWR << SDRAMC_TWR_LSB) \
  377. | (NUTMEM_SDRAM_TRC << SDRAMC_TRC_LSB) \
  378. | (NUTMEM_SDRAM_TRP << SDRAMC_TRP_LSB) \
  379. | (NUTMEM_SDRAM_TRCD << SDRAMC_TRCD_LSB) \
  380. | (NUTMEM_SDRAM_TRAS << SDRAMC_TRAS_LSB) \
  381. | (NUTMEM_SDRAM_TXSR << SDRAMC_TXSR_LSB))
  382. str r0, [r1, #SDRAMC_CR_OFF]
  383. /* 200us delay minimum. */
  384. mov r3, #0x2000
  385. 1:
  386. subs r3, r3, #1
  387. bne 1b
  388. /* Leave with r3 = 0! */
  389. /* SDRAM base address kept in r2. */
  390. mov r2, #NUTMEM_SDRAM_BASE
  391. /* Issue SDRAM command: NOP. */
  392. ldr r0, =(SDRAMC_MODE_NOP)
  393. str r0, [r1, #SDRAMC_MR_OFF]
  394. str r3, [r2, #0]
  395. /* Issue SDRAM command: Precharge all. */
  396. ldr r0, =(SDRAMC_MODE_PRCGALL)
  397. str r0, [r1, #SDRAMC_MR_OFF]
  398. str r3, [r2, #0]
  399. /* Delay. */
  400. mov r3, #0x20000
  401. 1:
  402. subs r3, r3, #1
  403. bne 1b
  404. /* Issue 8 auto-refresh cycles. */
  405. ldr r0, =(SDRAMC_MODE_RFSH)
  406. str r0, [r1, #SDRAMC_MR_OFF]
  407. add r3, r3, #1
  408. str r3, [r2, #4]
  409. str r0, [r1, #SDRAMC_MR_OFF]
  410. add r3, r3, #1
  411. str r3, [r2, #8]
  412. str r0, [r1, #SDRAMC_MR_OFF]
  413. add r3, r3, #1
  414. str r3, [r2, #12]
  415. str r0, [r1, #SDRAMC_MR_OFF]
  416. add r3, r3, #1
  417. str r3, [r2, #16]
  418. str r0, [r1, #SDRAMC_MR_OFF]
  419. add r3, r3, #1
  420. str r3, [r2, #20]
  421. str r0, [r1, #SDRAMC_MR_OFF]
  422. add r3, r3, #1
  423. str r3, [r2, #24]
  424. str r0, [r1, #SDRAMC_MR_OFF]
  425. add r3, r3, #1
  426. str r3, [r2, #28]
  427. str r0, [r1, #SDRAMC_MR_OFF]
  428. add r3, r3, #1
  429. str r3, [r2, #32]
  430. /* Issue SDRAM command: Set mode register. */
  431. ldr r0, =(SDRAMC_MODE_LMR)
  432. str r0, [r1, #SDRAMC_MR_OFF]
  433. ldr r3, =(0xCAFEDEDE)
  434. str r3, [r2, #36]
  435. /* Set refresh rate count. */
  436. ldr r3, =695
  437. str r0, [r1, #SDRAMC_TR_OFF]
  438. /* Issue SDRAM command: Normal mode. */
  439. ldr r0, =(SDRAMC_MODE_NORMAL)
  440. str r0, [r1, #SDRAMC_MR_OFF]
  441. mov r0, #0
  442. str r3, [r2, #0]
  443. #endif /* NUTMEM_SDRAM_BASE */
  444. #endif /* ifdef INIT_SDRAM */
  445. /*
  446. * Enable external reset key.
  447. */
  448. ldr r0, =(RSTC_KEY | RSTC_URSTEN)
  449. ldr r1, =RSTC_MR
  450. str r0, [r1, #0]
  451. /*
  452. * Remap internal RAM to address 0 and copy vectors to this loacation.
  453. */
  454. mov r0, #(MATRIX_MRCR_RCB0 | MATRIX_MRCR_RCB1)
  455. ldr r1, =MATRIX_BASE
  456. str r0, [r1, #MATRIX_MRCR_OFF]
  457. ldr r0, =__vectors
  458. mov r1, #0
  459. ldmia r0!, {r2-r9}
  460. stmia r1!, {r2-r9}
  461. ldmia r0!, {r2-r9}
  462. stmia r1!, {r2-r9}
  463. b __set_stacks
  464. .ltorg
  465. /*
  466. * Section 2: Set stack pointers.
  467. */
  468. .section .init2,"ax",%progbits
  469. .global __set_stacks
  470. __set_stacks:
  471. /*
  472. * Set exception stack pointers and enable interrupts.
  473. */
  474. ldr r0, =__exp_stack
  475. msr CPSR_c, #ARM_MODE_FIQ | ARM_CPSR_I_BIT | ARM_CPSR_F_BIT
  476. mov r13, r0
  477. sub r0, r0, #FIQ_STACK_SIZE
  478. msr CPSR_c, #ARM_MODE_IRQ | ARM_CPSR_I_BIT | ARM_CPSR_F_BIT
  479. mov r13, r0
  480. sub r0, r0, #IRQ_STACK_SIZE
  481. msr CPSR_c, #ARM_MODE_ABORT | ARM_CPSR_I_BIT | ARM_CPSR_F_BIT
  482. mov r13, r0
  483. sub r0, r0, #ABT_STACK_SIZE
  484. msr CPSR_c, #ARM_MODE_UNDEF | ARM_CPSR_I_BIT | ARM_CPSR_F_BIT
  485. mov r13, r0
  486. sub r0, r0, #UND_STACK_SIZE
  487. msr CPSR_c, #ARM_MODE_SVC | ARM_CPSR_I_BIT | ARM_CPSR_F_BIT
  488. mov r13, r0
  489. b __enter_mode
  490. .ltorg
  491. /*
  492. * Section 3: Set ARM specific modes.
  493. */
  494. .section .init3,"ax",%progbits
  495. .global __enter_mode
  496. __enter_mode:
  497. /* Enter system mode. */
  498. msr CPSR_c, #ARM_MODE_SYS | ARM_CPSR_I_BIT | ARM_CPSR_F_BIT
  499. b __clear_bss
  500. .ltorg
  501. /*
  502. * Section 4: Clear bss and copy data.
  503. */
  504. .section .init4,"ax",%progbits
  505. .global __clear_bss
  506. __clear_bss:
  507. ldr r1, =__bss_start
  508. ldr r2, =__bss_end
  509. ldr r3, =0
  510. 1:
  511. cmp r1, r2
  512. strne r3, [r1], #+4
  513. bne 1b
  514. /*
  515. * Initialize user stack pointer.
  516. */
  517. ldr r13, =__stack
  518. b __call_rtos
  519. .ltorg
  520. /*
  521. * Section 5: Call RTOS
  522. */
  523. .section .init5,"ax",%progbits
  524. .global __call_rtos
  525. __call_rtos:
  526. /*
  527. * Jump to Nut/OS initialization.
  528. */
  529. ldr r0, =NutInit
  530. mov lr, pc
  531. bx r0
  532. .global __exit_loop
  533. __exit_loop:
  534. DEBUG_CHAR
  535. b __exit_loop
  536. .ltorg